From f38751f560c227c2df411b000502da5c3a5d7572 Mon Sep 17 00:00:00 2001 From: Ulty Date: Mon, 11 Sep 2023 08:49:49 +0200 Subject: [PATCH] COFantasy: bug fixes --- COFantasy/3.13/COFantasy.js | 7760 ++++++++++++++++++----------------- COFantasy/3.13/doc.html | 2747 +++++++------ COFantasy/COFantasy.js | 7760 ++++++++++++++++++----------------- COFantasy/ChangeLog.md | 4 + COFantasy/doc.html | 2747 +++++++------ 5 files changed, 10762 insertions(+), 10256 deletions(-) diff --git a/COFantasy/3.13/COFantasy.js b/COFantasy/3.13/COFantasy.js index e429abcd18..686a347288 100644 --- a/COFantasy/3.13/COFantasy.js +++ b/COFantasy/3.13/COFantasy.js @@ -37,48 +37,50 @@ const generateUUID = (function() { }; //--------------- end generateRowID ---------------------------------------- -const COF_BETA = false; +const COF_BETA = true; let COF_loaded = false; -// Le script utilise la partie COFantasy de la variable d'\xE9tat state -// Pour plus de facilit\xE9, on utilise stateCOF = state.COFantasy -// Champs utilis\xE9s: +// Le script utilise la partie COFantasy de la variable d'état state +// Pour plus de facilité, on utilise stateCOF = state.COFantasy +// Champs utilisés: // - options : les options de jeu -// - setting_arran : toutes les fiches utilisent les r\xE8gles Terres d'Arran +// - setting_arran : toutes les fiches utilisent les règles Terres d'Arran // - setting_mixte : on a un mixte de fiches classiques et Terres d'Arran -// - roundMarkerId : l'id du token utilis\xE9 pour l'aura d'initiative -// - combat : d\xE9fini si le jeu est en mode tour par tour, contient : +// - roundMarkerId : l'id du token utilisé pour l'aura d'initiative +// - combat : défini si le jeu est en mode tour par tour, contient : // - pageId : la pageid du combat // - activeTokenId : id du token dont c'est le tour -// - activeTokenName : nom du token dont c'est le tour, au cas o\xF9 l'id change -// - tour : num\xE9ro de tour dans le combat +// - activeTokenName : nom du token dont c'est le tour, au cas où l'id change +// - tour : numéro de tour dans le combat // - init : niveau d'initiative courant // - armeesDesMorts : map de token id vers perso // - auras : liste des auras actives // - aurasCounts : computeur pour id des auras // - usureOff : on ne compte plus l'usure du combat -// - personnageCibleCree : pour savoir si on a cr\xE9\xE9 un personnage cible (avec 0 PV pour centrer les aoe) -// - tablesCrees : pour savoir si on a cr\xE9\xE9 les tables par d\xE9faut -// - gameMacros : la liste des macros cr\xE9\xE9es par le script +// - personnageCibleCree : pour savoir si on a créé un personnage cible (avec 0 PV pour centrer les aoe) +// - tablesCrees : pour savoir si on a créé les tables par défaut +// - gameMacros : la liste des macros créées par le script // - chargeFantastique : tout ce dont on a besoin pour une charge fantastique en cours (TODO: passer sous combat) // - eventId : compteur d'events pour avoir une id unique -// - tokensTemps : liste de tokens \xE0 dur\xE9e de vie limit\xE9e, effac\xE9s \xE0 la fin du combat -// - effetAuD20 : les effets qui se produisent \xE0 chaque jet de d\xE9. -// chaque effet est d\xE9termin\xE9 par un champ, puis pour chaque champ, -// - min: valeur minimale du d\xE9 pour d\xE9clencher -// - max: valeur maximale du d\xE9 pour d\xE9clencher -// - fct: nom de la fonction \xE0 appeler -// - nomFin: nom \xE0 afficher pour le statut et mettre fin aux \xE9v\xE9nements +// - tokensTemps : liste de tokens à durée de vie limitée, effacés à la fin du combat +// - effetAuD20 : les effets qui se produisent à chaque jet de dé. +// chaque effet est déterminé par un champ, puis pour chaque champ, +// - min: valeur minimale du dé pour déclencher +// - max: valeur maximale du dé pour déclencher +// - fct: nom de la fonction à appeler +// - nomFin: nom à afficher pour le statut et mettre fin aux événements // par exemple, foudreDuTemps pour les foudres du temps -// - tenebresMagiques : \xE9tat g\xE9n\xE9ral de t\xE9n\xE8bres magiques -// - jetsEnCours : pour laisser le MJ montrer ou non un jet qui lui a \xE9t\xE9 montr\xE9 \xE0 lui seul +// - tenebresMagiques : état général de ténèbres magiques +// - jetsEnCours : pour laisser le MJ montrer ou non un jet qui lui a été montré à lui seul // - currentAttackDisplay : pour pouvoir remontrer des display aux joueurs // - pause : le jeu est en pause -// - prescience : un personnage sur la carte de combat a la capacit\xE9 prescience (TODO: passer sous combat) +// - prescience : un personnage sur la carte de combat a la capacité prescience (TODO: passer sous combat) // - nextPrescience : pour le changement de tour car prescience ne revient que d'un tour -// - afterDisplay : donn\xE9es \xE0 afficher apr\xE8s un display -// - version : la version du script en cours, pour d\xE9tecter qu'on change de version +// - afterDisplay : données à afficher après un display +// - version : la version du script en cours, pour détecter qu'on change de version +// statistiques : des statistiques pour les jets de dés +// statistiquesEnPause var COFantasy = COFantasy || function() { @@ -118,7 +120,7 @@ var COFantasy = COFantasy || function() { const defaultOptions = { regles: { - explications: "Options qui influent sur les r\xE8gles du jeu", + explications: "Options qui influent sur les règles du jeu", type: 'options', val: { divers: { @@ -126,105 +128,105 @@ var COFantasy = COFantasy || function() { type: 'options', val: { forme_d_arbre_amelioree: { - explications: "+50% \xE0 l'effet de la peau d'\xE9corce en forme d'arbre.", + explications: "+50% à l'effet de la peau d'écorce en forme d'arbre.", val: true, type: 'bool' }, poudre_explosif: { - explications: "Les armes \xE0 poudre font des d\xE9g\xE2ts explosifs", + explications: "Les armes à poudre font des dégâts explosifs", val: true, type: 'bool' }, interchangeable_attaque: { - explications: "La capacit\xE9 interchangeable donne moins de DEF mais plus d'attaque", + explications: "La capacité interchangeable donne moins de DEF mais plus d'attaque", val: true, type: 'bool' }, coups_critiques_etendus: { - explications: "Coup critique \xE0 une attaque d\xE8s qu'elle d\xE9passe DEF + 10", + explications: "Coup critique à une attaque dès qu'elle dépasse DEF + 10", val: false, type: 'bool' }, echec_critique_boule_de_feu: { - explications: "Nombre de m\xE8tre dont le centre d'une boule de feu peut \xEAtre d\xE9plac\xE9 de mani\xE8re al\xE9atoire en cas d'\xE9chec critique. La probabilit\xE9 est inversement proportionelle \xE0 la distance.", + explications: "Nombre de mètre dont le centre d'une boule de feu peut être déplacé de manière aléatoire en cas d'échec critique. La probabilité est inversement proportionelle à la distance.", val: 12, type: 'int' } } }, dommages: { - explications: "R\xE8gles optionnelles sur les dommages", + explications: "Règles optionnelles sur les dommages", type: 'options', val: { blessures_graves: { - explications: "Si on arrive \xE0 0 PV, on perd 1PR, et si on a plus de PR, on a une blessure grave.", + explications: "Si on arrive à 0 PV, on perd 1PR, et si on a plus de PR, on a une blessure grave.", val: true, type: 'bool' }, degats_importants: { - explications: "Si les DMs d\xE9passent CON+niveau en une attaque, on applique aussi la r\xE8gle de blessure grave. Si la valeur de cette option est 0, la r\xE8gles n'est pas appliqu\xE9e. Sinon, la r\xE8gle n'est appliqu\xE9e que si, de plus, les DMs d\xE9passent maxPV / valeur.", + explications: "Si les DMs dépassent CON+niveau en une attaque, on applique aussi la règle de blessure grave. Si la valeur de cette option est 0, la règles n'est pas appliquée. Sinon, la règle n'est appliquée que si, de plus, les DMs dépassent maxPV / valeur.", val: 3, type: 'int' }, dm_minimum: { - explications: "D\xE9g\xE2ts minimum d'une attaque ou autre source de DM.", + explications: "Dégâts minimum d'une attaque ou autre source de DM.", val: 0, type: 'int' }, crit_elementaire: { - explications: "Les DMs constants d'un autre type que celui de l'arme sont aussi multipli\xE9s en cas de critique", + explications: "Les DMs constants d'un autre type que celui de l'arme sont aussi multipliés en cas de critique", val: false, type: 'bool' }, max_rune_protection: { - explications: "Les DMs qu'une rune de protection est capable d'absorber sont limit\xE9s \xE0 10x le rang du forgesort dans la voie des runes", + explications: "Les DMs qu'une rune de protection est capable d'absorber sont limités à 10x le rang du forgesort dans la voie des runes", val: true, type: 'bool' }, dm_explosifs: { - explications: "Tous les d\xE9s de DM sont explosifs", + explications: "Tous les dés de DM sont explosifs", val: false, type: 'bool' } } }, haute_DEF: { - explications: "Options de jeu pour g\xE9rer la haute DEF", + explications: "Options de jeu pour gérer la haute DEF", type: 'options', val: { usure_DEF: { - explications: "Malus de -2 en DEF tous les n tours. Mettre \xE0 0 pour ne pas avoir de malus d'usure", + explications: "Malus de -2 en DEF tous les n tours. Mettre à 0 pour ne pas avoir de malus d'usure", val: 6, type: 'int' }, bonus_attaque_groupe: { - explications: "Lors d'une attaque de groupe, bonus \xE0 la touche par cr\xE9ature suppl\xE9mentaire", + explications: "Lors d'une attaque de groupe, bonus à la touche par créature supplémentaire", val: 2, type: 'int' }, crit_attaque_groupe: { - explications: "Lors d'une attaque de groupe, si le jet de touche d\xE9passe DEF + cette valeur, les dommages sont doubl\xE9s (0 = jamais)", + explications: "Lors d'une attaque de groupe, si le jet de touche dépasse DEF + cette valeur, les dommages sont doublés (0 = jamais)", val: 5, type: 'int' } } }, initiative: { - explications: "Options qui influent sur les r\xE8gles du jeu", + explications: "Options qui influent sur les règles du jeu", type: 'options', val: { initiative_variable: { - explications: "Ajoute 1d6 \xE0 l'initiative, lanc\xE9 une fois par combat par type de cr\xE9ature", + explications: "Ajoute 1d6 à l'initiative, lancé une fois par combat par type de créature", val: false, type: 'bool' }, initiative_variable_individuelle: { - explications: "Lancer l'initiative variable pour chaque cr\xE9ature (n\xE9cessite d'activer l'Initiative variable)", + explications: "Lancer l'initiative variable pour chaque créature (nécessite d'activer l'Initiative variable)", val: false, type: 'bool' }, joueurs_lancent_init: { - explications: "Fait appara\xEEtre un bouton pour que les joueurs lancent leur initiative (n\xE9cessite d'activer l'Initiative variable)", + explications: "Fait apparaître un bouton pour que les joueurs lancent leur initiative (nécessite d'activer l'Initiative variable)", val: false, type: 'bool' } @@ -235,12 +237,12 @@ var COFantasy = COFantasy || function() { type: 'options', val: { mana_totale: { - explications: "Tous les sorts ont un co\xFBt, celui des temp\xEAtes de mana est multipli\xE9 par 3", + explications: "Tous les sorts ont un coût, celui des tempêtes de mana est multiplié par 3", val: false, type: 'bool' }, contrecoup: { - explications: "Avec la Mana Totale, permet au lanceur de sort de payer un d\xE9ficit de PM en PV (COF p. 181)", + explications: "Avec la Mana Totale, permet au lanceur de sort de payer un déficit de PM en PV (COF p. 181)", val: false, type: 'bool' }, @@ -250,7 +252,7 @@ var COFantasy = COFantasy || function() { type: 'bool' }, elixirs_sorts: { - explications: "Toutes fabrications d'\xE9lixir sont consid\xE9r\xE9es comme des sorts (qui peuvent co\xFBter de la mana)", + explications: "Toutes fabrications d'élixir sont considérées comme des sorts (qui peuvent coûter de la mana)", val: true, type: 'bool' }, @@ -263,17 +265,17 @@ var COFantasy = COFantasy || function() { type: 'options', val: { MJ_voit_actions: { - explications: "\xC0 chaque nouveau personnage en combat, montre le choix d'actions au MJ, m\xEAme pour les PJs.", + explications: "À chaque nouveau personnage en combat, montre le choix d'actions au MJ, même pour les PJs.", val: false, type: 'bool' }, MJ_valide_affichage_attaques: { - explications: "Les r\xE9sultats des attaques sont d'abord montr\xE9es au MJ seul, qui peut ensuite les montrer aux joueurs", + explications: "Les résultats des attaques sont d'abord montrées au MJ seul, qui peut ensuite les montrer aux joueurs", val: false, type: 'bool' }, MJ_valide_affichage_jets: { - explications: "Les r\xE9sultats des jets de caract\xE9ristiques sont d'abord montr\xE9es au MJ seul, qui peut ensuite les montrer aux joueurs", + explications: "Les résultats des jets de caractéristiques sont d'abord montrées au MJ seul, qui peut ensuite les montrer aux joueurs", val: false, type: 'bool' }, @@ -298,96 +300,96 @@ var COFantasy = COFantasy || function() { type: 'bool' }, duree_effets: { - explications: "Le script indique la dur\xE9e des effets associ\xE9s aux tokens", + explications: "Le script indique la durée des effets associés aux tokens", val: false, type: 'bool' }, init_dynamique: { - explications: "Fait appara\xEEtre une aura dynamique sur le token qui a l'initiative", + explications: "Fait apparaître une aura dynamique sur le token qui a l'initiative", val: true, type: 'bool' }, markers_personnalises: { - explications: "Utilisation des markers personnalis\xE9s commen\xE7ant par cof", + explications: "Utilisation des markers personnalisés commençant par cof", val: true, type: 'bool' }, table_crit: { - explications: "Utilisation d'une table de critiques nomm\xE9e Echec-Critique-Contact", + explications: "Utilisation d'une table de critiques nommée Echec-Critique-Contact", val: false, type: 'bool' }, depense_mana: { - explications: "Le script pr\xE9cise la quantit\xE9 de mana utilis\xE9e dans le chat \xE0 chaque fois", + explications: "Le script précise la quantité de mana utilisée dans le chat à chaque fois", val: false, type: 'bool' } } }, images: { - explications: "Images par d\xE9faut", + explications: "Images par défaut", type: 'options', val: { image_init: { - explications: "Image utilis\xE9e pour indiquer le personnage dont c'est le tour", + explications: "Image utilisée pour indiquer le personnage dont c'est le tour", type: 'image', val: DEFAULT_DYNAMIC_INIT_IMG }, image_double: { - explications: 'Image utilis\xE9e pour la capacit\xE9 d\xE9doublement', + explications: 'Image utilisée pour la capacité dédoublement', type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/33854984/q10B3KtWsCxcMczLo4BSUw/thumb.png?1496303265" }, image_ombre: { - explications: "Image utilis\xE9e pour l'ombre mortelle", + explications: "Image utilisée pour l'ombre mortelle", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/2781735/LcllgIHvqvu0HAbWdXZbJQ/thumb.png?13900368485" }, image_arbre: { - explications: "Image utilis\xE9e pour la forme d'arbre", + explications: "Image utilisée pour la forme d'arbre", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/52767134/KEGYUXeKnxZr5dbDwQEO4Q/thumb.png?15248300835" }, image_mur_de_force: { - explication: "Image utilis\xE9e pour un mur de force sph\xE9rique", + explication: "Image utilisée pour un mur de force sphérique", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/33213510/5r3NGSso1QBJMJewTEKv0A/thumb.png?1495195634" }, image_mur_de_vent: { - explication: "Image utilis\xE9e pour un mur de vent sph\xE9rique", + explication: "Image utilisée pour un mur de vent sphérique", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/308931095/X5zH4itb9QI9La8O7KfMBQ/thumb.png?1665585092" }, prison_vegetale: { - explication: "Image utilis\xE9e pour la prison v\xE9g\xE9tale", + explication: "Image utilisée pour la prison végétale", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/254738719/c97DFw6JlEePDVXBf-MPsA/thumb.png?1636471250" }, zone_de_vie: { - explication: "Image utilis\xE9e pour les zones de vie", + explication: "Image utilisée pour les zones de vie", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/349749304/q3q75jWu9Izlci5YB688WA/thumb.png?1689005544" } } }, sons: { - explications: "Sons par d\xE9faut", + explications: "Sons par défaut", type: 'options', val: { attaque_echec_critique: { - explication: "Son utilis\xE9 pour les \xE9checs critiques d'attaques", + explication: "Son utilisé pour les échecs critiques d'attaques", type: 'son', val: '' }, attaque_reussite_critique: { - explication: "Son utilis\xE9 pour les r\xE9ussites critiques d'attaques", + explication: "Son utilisé pour les réussites critiques d'attaques", type: 'son', val: '' } } }, macros_a_jour: { - explications: "Met automatiquement les macros \xE0 jour", + explications: "Met automatiquement les macros à jour", type: 'bool', val: true } @@ -414,43 +416,43 @@ var COFantasy = COFantasy || function() { } } - //Liste de tables par d\xE9faut + //Liste de tables par défaut const gameTables = [{ name: "Echec-Critique-Contact", showplayers: false, items: [{ - name: "FOR - Bouscul\xE9 : le personnage est renvers\xE9 par son adversaire. Il subit un d\xE9 malus au test de FOR si l\x2019adversaire " + - "est d\x2019une cat\xE9gorie de taille sup\xE9rieure et b\xE9n\xE9ficie d\x2019un d\xE9 bonus dans le cas inverse. " + - "Il subit une attaque gratuite de la part d\x2019un adversaire pendant qu\x2019il est \xE9tal\xE9 au sol (-5 en DEF).", + name: "FOR - Bousculé : le personnage est renversé par son adversaire. Il subit un dé malus au test de FOR si l’adversaire " + + "est d’une catégorie de taille supérieure et bénéficie d’un dé bonus dans le cas inverse. " + + "Il subit une attaque gratuite de la part d’un adversaire pendant qu’il est étalé au sol (-5 en DEF).", weight: 1, }, { - name: "DEX - Maladresse : le personnage laisse tomber au sol l'objet avec lequel il attaque. S\x2019il essaye de le ramasser, " + + name: "DEX - Maladresse : le personnage laisse tomber au sol l'objet avec lequel il attaque. S’il essaye de le ramasser, " + "il subit une attaque gratuite.", weight: 1, }, { - name: "CON - Coup de mou: le personnage subit l\x2019\xE9tat affaibli pendant 3 rounds. Ou il peut annuler cet \xE9tat en reprenant" + - "son souffle par une action limit\xE9e.", + name: "CON - Coup de mou: le personnage subit l’état affaibli pendant 3 rounds. Ou il peut annuler cet état en reprenant" + + "son souffle par une action limitée.", weight: 1, }, { - name: "INT - Erreur tactique : le personnage subit une attaque (gratuite) d\x2019un adversaire \xE0 son contact.", + name: "INT - Erreur tactique : le personnage subit une attaque (gratuite) d’un adversaire à son contact.", weight: 1, }, { name: "SAG - Distrait : le personnage se laisse distraire et ne voit pas venir la prochaine attaque, " + - "l\x2019adversaire b\xE9n\xE9ficiera d\x2019un bonus de +10.", + "l’adversaire bénéficiera d’un bonus de +10.", weight: 1, }, { - name: "CHA - Ridicule : le personnage fait un faux mouvement \xE0 la fois douloureux et ridicule, il subit " + - "l\x2019\xE9tat \xE9tourdi pendant un round pour reprendre contenance.", + name: "CHA - Ridicule : le personnage fait un faux mouvement à la fois douloureux et ridicule, il subit " + + "l’état étourdi pendant un round pour reprendre contenance.", weight: 1, }, { - name: "Votre arme se brise. S\x2019il s\x2019agit d\x2019une arme magique, le d\xE9 DM est simplement r\xE9duit d'une cat\xE9gorie " + - "(2d6/d12=>d10=>d8=>d6=>d4=>d3) jusqu\x2019\xE0 la fin du combat.", + name: "Votre arme se brise. S’il s’agit d’une arme magique, le dé DM est simplement réduit d'une catégorie " + + "(2d6/d12=>d10=>d8=>d6=>d4=>d3) jusqu’à la fin du combat.", weight: 1, }, { - name: "Une pi\xE8ce d\x2019armure bouge et elle devient plus g\xEAnante que protectrice : malus en DEF et en attaque pour le reste du combat. Cuir : -1, Maille : -2, Plaque -3.", + name: "Une pièce d’armure bouge et elle devient plus gênante que protectrice : malus en DEF et en attaque pour le reste du combat. Cuir : -1, Maille : -2, Plaque -3.", weight: 1, }, { - name: "Simple \xE9chec de l'attaque", + name: "Simple échec de l'attaque", weight: 12, }, ], }, ]; @@ -534,7 +536,7 @@ var COFantasy = COFantasy || function() { return false; } - // Attention, def, la valeur par d\xE9faut, doit \xEAtre la m\xEAme que sur la fiche + // Attention, def, la valeur par défaut, doit être la même que sur la fiche // personnage peut ne pas avoir de token function ficheAttribute(personnage, name, def) { let attr = charAttribute(personnage.charId, name, { @@ -553,7 +555,7 @@ var COFantasy = COFantasy || function() { return attrAsInt(attr, def, defPresent); } - //Il faut une valeur par d\xE9faut, qui correspond \xE0 celle de la fiche + //Il faut une valeur par défaut, qui correspond à celle de la fiche function ficheAttributeAsBool(personnage, name, def) { let attr = charAttribute(personnage.charId, name, { caseInsensitive: true @@ -562,7 +564,7 @@ var COFantasy = COFantasy || function() { return attrAsBool(attr); } - //Attention \xE0 ne pas utiliser si l'attribut ne d\xE9pend pas du token + //Attention à ne pas utiliser si l'attribut ne dépend pas du token //defPresent est optionnel //personnage peut ne pas avoir de token function attributeAsInt(personnage, name, def, defPresent) { @@ -703,8 +705,8 @@ var COFantasy = COFantasy || function() { } - //Probl\xE8me : \xE7a ne peut pas marcher pour les boucliers en main gauche - //car \xE7a utilise lui-m\xEAme un bouclier... + //Problème : ça ne peut pas marcher pour les boucliers en main gauche + //car ça utilise lui-même un bouclier... function getPredicates(perso) { if (perso.predicates === undefined) { const estMook = perso.token && perso.token.get('bar1_link') === ''; @@ -718,12 +720,12 @@ var COFantasy = COFantasy || function() { raw += '\n' + perso.arme.predicats; if (perso.armeGauche && perso.armeGauche.predicats) raw += '\n' + perso.armeGauche.predicats; - } else if (perso.arme) { //possible si appel\xE9 depuis armesEnMain + } else if (perso.arme) { //possible si appelé depuis armesEnMain if (perso.arme.predicats) raw += '\n' + perso.arme.predicats; - } else { //il faut chercher les pr\xE9dicats des armes en main - //On n'appelle pas armesEnMain pour \xE9viter la r\xE9cursion - //et pour \xE9viter trop de calcul + } else { //il faut chercher les prédicats des armes en main + //On n'appelle pas armesEnMain pour éviter la récursion + //et pour éviter trop de calcul let attrArmes = tokenAttribute(perso, 'armeEnMain'); if (attrArmes.length > 0) { let att; @@ -811,7 +813,7 @@ var COFantasy = COFantasy || function() { caseInsensitive: true }); if (typePerso.length > 0 && typePerso[0].get('current') == 'PNJ') - return; //Les fiches de PNJ sont les m\xEAmes + return; //Les fiches de PNJ sont les mêmes let setting = charAttribute(c.id, 'option_setting', { caseInsensitive: true }); @@ -823,7 +825,7 @@ var COFantasy = COFantasy || function() { else charsGenerique.push(c); }); if (charsArran.length <= charsGenerique.length) { - log("Utilisation des r\xE8gles COF g\xE9n\xE9riques"); + log("Utilisation des règles COF génériques"); if (charsArran.length > 0) { error("Attention, des personnages suivent les options de jeu des Terres d'Arran (voir le log pour la liste)", charsArran); charsArran.forEach(function(c) { @@ -835,7 +837,7 @@ var COFantasy = COFantasy || function() { } return; } - log("Utilisation des r\xE8gles des Terres d'Arran"); + log("Utilisation des règles des Terres d'Arran"); if (charsGenerique.length > 0) { error("Attention, des personnages ne suivent pas les options de jeu des Terres d'Arran (voir le log pour la liste)", charsGenerique); charsGenerique.forEach(function(c) { @@ -869,7 +871,7 @@ var COFantasy = COFantasy || function() { effet_de_marker[m.tag] = effet; } else if (ms) { if (effet_de_marker[ms] && effet_de_marker[ms] != effet) { - sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le m\xEAme icone"); + sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le même icone"); } effet_de_marker[ms] = effet; } else { @@ -880,7 +882,7 @@ var COFantasy = COFantasy || function() { function splitIdName(idn) { let pos = idn.indexOf(' '); if (pos < 1 || pos >= idn.length) { - error("idName mal form\xE9", idn); + error("idName mal formé", idn); return; } let name = idn.substring(pos + 1); @@ -890,8 +892,8 @@ var COFantasy = COFantasy || function() { }; } - //Renvoie le token et le charId. Si l'id ne correspond \xE0 rien, cherche si - //on trouve un nom de token, sur la page pass\xE9e en argument (ou sinon + //Renvoie le token et le charId. Si l'id ne correspond à rien, cherche si + //on trouve un nom de token, sur la page passée en argument (ou sinon //sur la page active de la campagne) function persoOfId(id, name, pageId, allPages) { let token = getObj('graphic', id); @@ -926,14 +928,14 @@ var COFantasy = COFantasy || function() { } else return undefined; } if (tokens.length > 1) { - error("Ambig\xFCit\xE9 sur le choix d'un token : il y a " + - tokens.length + " tokens nomm\xE9s " + name, tokens); + error("Ambigüité sur le choix d'un token : il y a " + + tokens.length + " tokens nommés " + name, tokens); } token = tokens[0]; } let charId = token.get('represents'); if (charId === '') { - error("le token s\xE9lectionn\xE9 ne repr\xE9sente pas de personnage", token); + error("le token sélectionné ne représente pas de personnage", token); return undefined; } return { @@ -942,7 +944,7 @@ var COFantasy = COFantasy || function() { }; } - //Retourne le perso correspondant \xE0 un token id suivi du nom de token + //Retourne le perso correspondant à un token id suivi du nom de token //Permet d'avoir une information robuste en cas d'interruption du script //peuple tokName function persoOfIdName(idn, pageId, allPages) { @@ -950,7 +952,7 @@ var COFantasy = COFantasy || function() { if (sp === undefined) return; let perso = persoOfId(sp.id, sp.name, pageId, allPages); if (perso === undefined) { - log("Impossible de trouver le personnage correspondant \xE0 " + sp.name); + log("Impossible de trouver le personnage correspondant à " + sp.name); return; } perso.tokName = perso.token.get('name'); @@ -1008,7 +1010,7 @@ var COFantasy = COFantasy || function() { } if (sync != threadSync) return; if (token) { - // Cas sp\xE9ciaux du cavaliers + // Cas spéciaux du cavaliers let pageId = token.get('pageid'); let personnage = persoOfId(token.id); let monteSur = tokenAttribute(personnage, 'monteSur'); @@ -1047,7 +1049,7 @@ var COFantasy = COFantasy || function() { return false; }); } catch (uriError) { - log("Erreur de d\xE9codage URI dans la note GM de " + token.get('name') + " : " + gmNotes); + log("Erreur de décodage URI dans la note GM de " + token.get('name') + " : " + gmNotes); } roundMarker = createObj('graphic', roundMarkerSpec); if (roundMarker === undefined && localImage) { @@ -1061,12 +1063,12 @@ var COFantasy = COFantasy || function() { roundMarker = createObj('graphic', roundMarkerSpec); } if (roundMarker === undefined) { - error("Impossible de cr\xE9er le token pour l'aura dynamique", roundMarkerSpec); + error("Impossible de créer le token pour l'aura dynamique", roundMarkerSpec); return false; } stateCOF.roundMarkerId = roundMarker.id; if (roundMarkerSpec.layer === 'map') toFront(roundMarker); - // Ne pas amener une monture mont\xE9e en avant pour \xE9viter de cacher le cavalier + // Ne pas amener une monture montée en avant pour éviter de cacher le cavalier if (cavalier && monture) { toFront(monture.token); toFront(cavalier.token); @@ -1094,7 +1096,7 @@ var COFantasy = COFantasy || function() { token.set('aura2_radius', ''); token.set('showplayers_aura2', false); } else { - // Cas des tokens personnalis\xE9s + // Cas des tokens personnalisés if (statusForInitEnemy && statusForInitAlly) { token.set(statusForInitAlly, false); token.set(statusForInitEnemy, false); @@ -1102,14 +1104,14 @@ var COFantasy = COFantasy || function() { } } - //Appel\xE9 au lancement du script, mise \xE0 jour de certaines variables globales + //Appelé au lancement du script, mise à jour de certaines variables globales function setStateCOF() { stateCOF = state.COFantasy; - stateCOF.predicats = {}; //pr\xE9dicats par charId. + stateCOF.predicats = {}; //prédicats par charId. if (stateCOF.roundMarkerId) { roundMarker = getObj('graphic', stateCOF.roundMarkerId); if (roundMarker === undefined) { - log("Le marqueur d'init a chang\xE9 d'id"); + log("Le marqueur d'init a changé d'id"); let roundMarkers = findObjs({ _type: 'graphic', represents: '', @@ -1139,7 +1141,7 @@ var COFantasy = COFantasy || function() { } } if (!stateCOF.personnageCibleCree) { - //On cherche si un personnage cible existe d\xE9j\xE0 + //On cherche si un personnage cible existe déjà let persos = findObjs({ _type: 'character', name: 'Cible', @@ -1200,7 +1202,7 @@ var COFantasy = COFantasy || function() { } stateCOF.personnageCibleCree = true; } - //Cr\xE9ation des tables par d\xE9faut + //Création des tables par défaut if (!stateCOF.tablesCrees) { let allTables = findObjs({ _type: 'rollabletable', @@ -1257,7 +1259,7 @@ var COFantasy = COFantasy || function() { m.set('visibleto', ngm.visibleto); if (ngm.istokenaction != gm.istokenaction && m.get('istokenaction') == gm.istokenaction) m.set('istokenaction', ngm.istokenaction); - sendChat('COF', '/w GM Macro ' + ngm.name + ' mise \xE0 jour.'); + sendChat('COF', '/w GM Macro ' + ngm.name + ' mise à jour.'); }); } else { ngm = gameMacros.find(function(ngm) { @@ -1276,14 +1278,14 @@ var COFantasy = COFantasy || function() { m.set('visibleto', ngm.visibleto); if (ngm.istokenaction != gm.istokenaction && m.get('istokenaction') == gm.istokenaction) m.set('istokenaction', ngm.istokenaction); - sendChat('COF', '/w GM Macro ' + ngm.name + ' mise \xE0 jour.'); + sendChat('COF', '/w GM Macro ' + ngm.name + ' mise à jour.'); }); } else { macros.forEach(function(m) { if (m.get('name') != gm.name) return; if (m.get('action') != gm.action) return; m.remove(); - sendChat('COF', '/w GM Macro ' + gm.name + ' effac\xE9e.'); + sendChat('COF', '/w GM Macro ' + gm.name + ' effacée.'); }); } } @@ -1299,7 +1301,7 @@ var COFantasy = COFantasy || function() { return macro.get('name') == ngm.name; }); if (prev === undefined) { - sendChat('COF', '/w GM Macro ' + ngm.name + ' cr\xE9\xE9e.'); + sendChat('COF', '/w GM Macro ' + ngm.name + ' créée.'); if (ngm.inBar) inBar.push(ngm.name); mjs.forEach(function(playerId, i) { if (i === 0 || ngm.visibleto === '') { @@ -1311,10 +1313,10 @@ var COFantasy = COFantasy || function() { } }); } else { - //Peut-\xEAtre la premi\xE8re fois, v\xE9rifier les macros + //Peut-être la première fois, vérifier les macros if (stateCOF.macros) { - //ancienne version, et on avait copi\xE9 les macros - //on enl\xE8ve juste Escalier, et on remplace par Monter et Descendre + //ancienne version, et on avait copié les macros + //on enlève juste Escalier, et on remplace par Monter et Descendre let mesc = macros.find(function(m) { return m.get('name') == 'Escalier'; }); @@ -1344,7 +1346,7 @@ var COFantasy = COFantasy || function() { return macro.get('name') == m.name; }); if (prev === undefined) { - sendChat('COF', '/w GM Macro ' + m.name + ' cr\xE9\xE9e.'); + sendChat('COF', '/w GM Macro ' + m.name + ' créée.'); if (m.inBar) inBar.push(m.name); mjs.forEach(function(playerId, i) { if (i === 0 || m.visibleto === '') { @@ -1357,16 +1359,16 @@ var COFantasy = COFantasy || function() { } } if (inBar.length > 0) { - sendChat('COF', "/w GM Macros \xE0 mettre dans la barre d'action du MJ : " + inBar.join(', ')); + sendChat('COF', "/w GM Macros à mettre dans la barre d'action du MJ : " + inBar.join(', ')); } stateCOF.gameMacros = gameMacros; } - // R\xE9cup\xE9ration des token Markers attach\xE9s \xE0 la campagne image, nom, tag, Id + // Récupération des token Markers attachés à la campagne image, nom, tag, Id const markers = JSON.parse(Campaign().get('token_markers')); markers.forEach(function(m) { markerCatalog[m.name] = m; }); - // Option Markers personnalis\xE9s activ\xE9 + // Option Markers personnalisés activé if (stateCOF.options.affichage.val.markers_personnalises.val) { const cof_states_perso = { assomme: 'status_cof-assomme', @@ -1384,10 +1386,10 @@ var COFantasy = COFantasy || function() { blesse: 'status_cof-blesse', encombre: 'status_cof-encombre', penombre: 'status_cof-penombre', - //enseveli: 'status_edge-crack' -> \xC0 dessiner + //enseveli: 'status_edge-crack' -> À dessiner chef: 'status_cof-chef', }; - // On boucle sur la liste des \xE9tats pour v\xE9rifier que les markers sont bien pr\xE9sents ! + // On boucle sur la liste des états pour vérifier que les markers sont bien présents ! let markersAbsents = []; let ancientSet = true; for (let etat in cof_states_perso) { @@ -1429,7 +1431,7 @@ var COFantasy = COFantasy || function() { default: if (ms) { if (effet_de_marker[ms] && effet_de_marker[ms] != effet) { - sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le m\xEAme icone"); + sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le même icone"); } effet_de_marker[ms] = effet; } @@ -1445,7 +1447,7 @@ var COFantasy = COFantasy || function() { default: if (ms) { if (effet_de_marker[ms] && effet_de_marker[ms] != effet) { - sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le m\xEAme icone"); + sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le même icone"); } effet_de_marker[ms] = effet; } @@ -1455,9 +1457,9 @@ var COFantasy = COFantasy || function() { markersAbsents.forEach(function(m) { log("Marker " + m + " introuvable"); }); - log("Markers personnalis\xE9s activ\xE9s."); + log("Markers personnalisés activés."); } else { - log("Utilisation des markers par d\xE9faut"); + log("Utilisation des markers par défaut"); } } //Construction de la table markers => etat @@ -1476,7 +1478,7 @@ var COFantasy = COFantasy || function() { return res; } - // retourne un tableau contenant la liste des ID de joueurs connect\xE9s controllant le personnage li\xE9 au Token + // retourne un tableau contenant la liste des ID de joueurs connectés controllant le personnage lié au Token function getPlayerIds(perso) { let character = getObj('character', perso.charId); if (character === undefined) return; @@ -1525,7 +1527,7 @@ var COFantasy = COFantasy || function() { return res; } - //PNJ au sens de la fiche utilis\xE9e, pas forc\xE9ment en jeu + //PNJ au sens de la fiche utilisée, pas forcément en jeu //perso peut ne pas avoir de token function persoEstPNJ(perso) { if (perso.pnj) return true; @@ -1586,7 +1588,7 @@ var COFantasy = COFantasy || function() { return true; } - //Met le champ field \xE0 value du token dans evt, pour permettre le undo + //Met le champ field à value du token dans evt, pour permettre le undo //Retourne evt.affectes[token.id] function affectToken(token, field, value, evt) { evt.affectes = evt.affectes || {}; @@ -1656,7 +1658,7 @@ var COFantasy = COFantasy || function() { sendChat(dest, msg); } - //Chuchote le message \xE0 tous les joueurs pr\xE9sents qui controllent le + //Chuchote le message à tous les joueurs présents qui controllent le //personnage, plus le MJ function whisperChar(charId, msg) { let character = getObj('character', charId); @@ -1783,7 +1785,7 @@ var COFantasy = COFantasy || function() { // resultatDesSeuls (rempli par la fonction si true) //Renvoie 1dk + bonus, avec le texte //champs val et roll - //de peut \xEAtre un nombre > 0 ou bien le r\xE9sultat de parseDice + //de peut être un nombre > 0 ou bien le résultat de parseDice function rollDePlus(de, options) { options = options || {}; options.nbDes = options.nbDes || 1; @@ -1844,7 +1846,7 @@ var COFantasy = COFantasy || function() { return res; } - //Si evt est d\xE9fini, alors on consid\xE8re qu'il faut y mettre la valeur actuelle + //Si evt est défini, alors on considère qu'il faut y mettre la valeur actuelle function updateCurrentBar(perso, barNumber, val, evt, maxVal) { let token = perso.token; let prevToken; @@ -1891,7 +1893,7 @@ var COFantasy = COFantasy || function() { if (maxVal) aset.max = maxVal; attr.setWithWorker(aset); if (HTdeclared) HealthColors.Update(token, prevToken); - //Gestion du lien des PVs entre familier et son ma\xEEtre + //Gestion du lien des PVs entre familier et son maître if (barNumber == 1) { let nomPersoLie = predicateAsBool(perso, 'PVPartagesAvec'); if (nomPersoLie) { @@ -2052,7 +2054,7 @@ var COFantasy = COFantasy || function() { case 'FOR': return 'force'; case 'DEX': - if (accent) return 'dext\xE9rit\xE9'; + if (accent) return 'dextérité'; return 'dexterite'; case 'CON': return 'constitution'; @@ -2071,9 +2073,9 @@ var COFantasy = COFantasy || function() { return 'pnj_' + m.toLowerCase(); } - //Retourne le mod de la caract\xE9ristque enti\xE8re. + //Retourne le mod de la caractéristque entière. //si carac n'est pas une carac, retourne 0 - //perso peut ne pas avoir de token ou \xEAtre juste un charId + //perso peut ne pas avoir de token ou être juste un charId function modCarac(perso, carac) { if (perso.charId === undefined) perso = { charId: perso @@ -2131,11 +2133,11 @@ var COFantasy = COFantasy || function() { } //options peut contenir - // msg: un message \xE0 afficher + // msg: un message à afficher // maxVal: la valeur max de l'attribut - // secret: le message n'est pas affich\xE9 pour tout le monde. - // charAttr: si pr\xE9sent, on utilise un attribut de personnage - // renvoie l'attribut cr\xE9\xE9 ou mis \xE0 jour + // secret: le message n'est pas affiché pour tout le monde. + // charAttr: si présent, on utilise un attribut de personnage + // renvoie l'attribut créé ou mis à jour function setTokenAttr(personnage, attribute, value, evt, options) { let charId = personnage.charId; let token = personnage.token; @@ -2155,7 +2157,7 @@ var COFantasy = COFantasy || function() { }; let name = 'inconnu'; if (token) name = token.get('name'); - error("Cr\xE9ation d'un attribut undefined pour " + name, args); + error("Création d'un attribut undefined pour " + name, args); return; } let attr = findObjs({ @@ -2183,7 +2185,7 @@ var COFantasy = COFantasy || function() { let taille = taillePersonnage(personnage, 4); if (taille == 5) { arme.deuxMains = false; - sendPerso(personnage, "peut maintenant tenir " + arme.name + " \xE0 une main"); + sendPerso(personnage, "peut maintenant tenir " + arme.name + " à une main"); degainerArme(personnage, arme.label, evt); } } @@ -2197,11 +2199,11 @@ var COFantasy = COFantasy || function() { token.set('height', height); break; case 'formeDArbre': - //On copie les PVs pour pouvoir les restaurer \xE0 la fin de l'effet + //On copie les PVs pour pouvoir les restaurer à la fin de l'effet setTokenAttr(personnage, 'anciensPV', token.get('bar1_value'), evt, { maxVal: token.get('bar1_max') }); - //On va cr\xE9er une copie de token, mais avec une image d'arbre + //On va créer une copie de token, mais avec une image d'arbre let tokenFields = getTokenFields(token, pageId, personnage.charId); let tokenArbre; let imageArbre = predicateAsBool(personnage, 'tokenFormeDArbre'); @@ -2216,7 +2218,7 @@ var COFantasy = COFantasy || function() { if (tokenArbre) { evt.tokens = evt.tokens || []; evt.tokens.push(tokenArbre); - //On met l'ancien token dans le gmlayer, car si l'image vient du marketplace, il est impossible de le recr\xE9er depuis l'API + //On met l'ancien token dans le gmlayer, car si l'image vient du marketplace, il est impossible de le recréer depuis l'API setToken(token, 'layer', 'gmlayer', evt); setTokenAttr(personnage, 'changementDeToken', true, evt); replaceInTurnTracker(token.id, tokenArbre.id, evt); @@ -2314,7 +2316,7 @@ var COFantasy = COFantasy || function() { return attr; } - // evt peut \xEAtre undefined + // evt peut être undefined // options peut avoir les champs msg et secret function removeTokenAttr(personnage, attribute, evt, options) { attribute = fullAttributeName(personnage, attribute, options); @@ -2351,8 +2353,8 @@ var COFantasy = COFantasy || function() { }); } - //cherche l'attribut attribute de valeur par d\xE9faut def - //et lui ajoute la valeur val. Cr\xE9e l'attribut si besoin + //cherche l'attribut attribute de valeur par défaut def + //et lui ajoute la valeur val. Crée l'attribut si besoin //retourne la nouvelle valeur de l'attribut function addToAttributeAsInt(perso, attribute, def, val, evt) { evt.attributes = evt.attributes || []; @@ -2398,11 +2400,11 @@ var COFantasy = COFantasy || function() { //options: //fromTemp si on est en train de supprimer un effet temporaire - //affectToken si on a d\xE9j\xE0 chang\xE9 le statusmarkers (on vient donc d'un changement \xE0 la main d'un marker + //affectToken si on a déjà changé le statusmarkers (on vient donc d'un changement à la main d'un marker function setState(personnage, etat, value, evt, options) { let token = personnage.token; if (value && predicateAsBool(personnage, 'immunite_' + etat)) { - sendPerso(personnage, 'ne peut pas \xEAtre ' + stringOfEtat(etat, personnage)); + sendPerso(personnage, 'ne peut pas être ' + stringOfEtat(etat, personnage)); return false; } options = options || {}; @@ -2456,7 +2458,7 @@ var COFantasy = COFantasy || function() { } } } - if (!value) { //On enl\xE8ve le save si il y en a un + if (!value) { //On enlève le save si il y en a un removeTokenAttr(personnage, etat + 'Save', evt); removeTokenAttr(personnage, etat + 'SaveParTour', evt); } @@ -2482,7 +2484,7 @@ var COFantasy = COFantasy || function() { token.set('light_losangle', 0); } //Normalement, ne peut plus suivre personne ? - //Si il peut parce qu'il touche ou tient une corde, r\xE9utiliser la macro + //Si il peut parce qu'il touche ou tient une corde, réutiliser la macro //pour suivre nePlusSuivre(personnage, pageId, evt); } else { @@ -2499,7 +2501,7 @@ var COFantasy = COFantasy || function() { let attrInvisible = tokenAttribute(personnage, 'tokenInvisible'); if (value) { if (attrInvisible.length === 0) { - //On va cr\xE9er une copie de token, mais avec une image invisible et aura visible seulement de ceux qui contr\xF4lent le token + //On va créer une copie de token, mais avec une image invisible et aura visible seulement de ceux qui contrôlent le token let tokenFields = getTokenFields(token, pageId, personnage.charId); tokenFields.layer = 'objects'; tokenFields.aura1_radius = 0; @@ -2520,7 +2522,7 @@ var COFantasy = COFantasy || function() { } evt.tokens = evt.tokens || []; evt.tokens.push(tokenInvisible); - //On met l'ancien token dans le gmlayer, car si l'image vient du marketplace, il est impossible de le recr\xE9er depuis l'API + //On met l'ancien token dans le gmlayer, car si l'image vient du marketplace, il est impossible de le recréer depuis l'API setToken(token, 'layer', 'gmlayer', evt); setTokenAttr(personnage, 'tokenInvisible', token.id, evt, { maxVal: tokenInvisible.id @@ -2534,7 +2536,7 @@ var COFantasy = COFantasy || function() { } } } - } else { //On enl\xE8ve l'\xE9tat invisible + } else { //On enlève l'état invisible if (attrInvisible.length > 0) { let tokenOriginel = getObj('graphic', attrInvisible[0].get('current')); if (!tokenOriginel) { @@ -2551,7 +2553,7 @@ var COFantasy = COFantasy || function() { }); if (tokenOriginel.length > 0) tokenOriginel = tokenOriginel[0]; else { - error("Impossible de retrouver le token de d\xE9part de " + token.get('name') + " quand on enl\xE8ve l'\xE9tat invisible", attrInvisible); + error("Impossible de retrouver le token de départ de " + token.get('name') + " quand on enlève l'état invisible", attrInvisible); tokenOriginel = false; } } @@ -2571,7 +2573,7 @@ var COFantasy = COFantasy || function() { }); if (tokenCourant.length > 0) tokenCourant = tokenCourant[0]; else { - error("Impossible de retrouver le token visible de " + token.get('name') + " quand on enl\xE8ve l'\xE9tat invisible", attrInvisible); + error("Impossible de retrouver le token visible de " + token.get('name') + " quand on enlève l'état invisible", attrInvisible); tokenCourant = false; } } @@ -2611,7 +2613,7 @@ var COFantasy = COFantasy || function() { switch (etat) { case 'mort': { - //On s'assure de mettre les PV de la cible \xE0 0 (pour les insta kills sans dommages) + //On s'assure de mettre les PV de la cible à 0 (pour les insta kills sans dommages) if (token.get('bar1_value') > 0) updateCurrentBar(personnage, 1, 0, evt); nePlusSuivre(personnage, pageId, evt); lockToken(personnage, evt); @@ -2630,14 +2632,14 @@ var COFantasy = COFantasy || function() { removeTokenAttr(personnage, 'estMontePar', evt); removeTokenAttr(personnage, 'positionSurMonture', evt); } - //On lib\xE8re les personnages envelopp\xE9s, si il y en a. + //On libère les personnages enveloppés, si il y en a. let attrEnveloppe = tokenAttribute(personnage, 'enveloppe'); attrEnveloppe.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); if (cible) { let envDM = a.get('max'); if (envDM.startsWith('etreinte')) { - //On a une \xE9treinte, on enl\xE8ve donc l'\xE9tat immobilis\xE9 + //On a une étreinte, on enlève donc l'état immobilisé setState(cible, 'immobilise', false, evt); } evt.deletedAttributes = evt.deletedAttributes || []; @@ -2648,7 +2650,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); } else if (cube.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + cube.tokName); + sendPerso(cible, 'se libère de ' + cube.tokName); toFront(cible.token); evt.deletedAttributes.push(a); a.remove(); @@ -2659,14 +2661,14 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //Si le mort est envelopp\xE9, il est relach\xE9 + //Si le mort est enveloppé, il est relaché attrEnveloppe = tokenAttribute(personnage, 'enveloppePar'); attrEnveloppe.forEach(function(a) { let cube = persoOfIdName(a.get('current'), pageId); if (cube) { let envDiff = a.get('max'); if (envDiff.startsWith('etreinte')) { - //On a une \xE9treinte, on enl\xE8ve donc l'\xE9tat immobilis\xE9 + //On a une étreinte, on enlève donc l'état immobilisé setState(personnage, 'immobilise', false, evt); } evt.deletedAttributes = evt.deletedAttributes || []; @@ -2686,7 +2688,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages agripp\xE9s, si il y en a. + //On libère les personnages agrippés, si il y en a. let attrAgrippe = tokenAttribute(personnage, 'agrippe'); attrAgrippe.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2696,7 +2698,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); if (a.get('max')) setState(cible, 'immobilise', false, evt); evt.deletedAttributes.push(a); @@ -2708,7 +2710,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages d\xE9vor\xE9s, si il y en a. + //On libère les personnages dévorés, si il y en a. let attrDevore = tokenAttribute(personnage, 'devore'); attrDevore.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2718,7 +2720,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); setState(cible, 'immobilise', false, evt); evt.deletedAttributes.push(a); @@ -2729,7 +2731,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages \xE9cras\xE9s, si il y en a. + //On libère les personnages écrasés, si il y en a. let attrEcrase = tokenAttribute(personnage, 'ecrase'); attrEcrase.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2739,7 +2741,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); evt.deletedAttributes.push(a); a.remove(); @@ -2749,7 +2751,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages aval\xE9s, si il y en a. + //On libère les personnages avalés, si il y en a. let attrGobe = tokenAttribute(personnage, 'aGobe'); attrGobe.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2770,7 +2772,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages sous \xE9treinte et immolation + //On libère les personnages sous étreinte et immolation let attrEtreinteImmole = tokenAttribute(personnage, 'etreinteImmole'); attrEtreinteImmole.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2780,7 +2782,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); setState(cible, 'immobilise', false, evt); evt.deletedAttributes.push(a); @@ -2791,7 +2793,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages sous \xE9treinte de scorpion + //On libère les personnages sous étreinte de scorpion let attrEtreinteScorpion = tokenAttribute(personnage, 'etreinteScorpionSur'); attrEtreinteScorpion.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2802,7 +2804,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); evt.deletedAttributes.push(a); a.remove(); @@ -2850,7 +2852,7 @@ var COFantasy = COFantasy || function() { attaqueExplosion(msg); } } - //On termine les effets temporaires li\xE9s au personnage + //On termine les effets temporaires liés au personnage let etlAttr = tokenAttribute(personnage, 'effetsTemporairesLies'); if (etlAttr.length > 0) { etlAttr = etlAttr[0]; @@ -2873,7 +2875,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(etlAttr); etlAttr.remove(); } - //On enl\xE8ve les auras + //On enlève les auras if (stateCOF.combat && (predicateAsBool(personnage, 'auraDrainDeForce') || attributeAsBool(personnage, 'aura')) ) { @@ -2893,7 +2895,7 @@ var COFantasy = COFantasy || function() { } else if (charAttributeAsBool(personnage, 'armeeConjuree')) { removeFromTurnTracker(personnage, evt); deleteTokenWithUndo(personnage.token, evt); - sendPerso(personnage, 'dispara\xEEt'); + sendPerso(personnage, 'disparaît'); let armeeChar = getObj('character', personnage.charId); if (armeeChar) { evt.deletedCharacters = evt.deletedCharacters || []; @@ -2913,7 +2915,7 @@ var COFantasy = COFantasy || function() { armeeChar.remove(); } } else if (!estNonVivant(personnage)) { - //Cherche si certains peuvent siphoner l'\xE2me + //Cherche si certains peuvent siphoner l'âme let allToks = findObjs({ _type: 'graphic', @@ -2921,7 +2923,7 @@ var COFantasy = COFantasy || function() { _subtype: 'token', layer: 'objects' }); - //On cherche d'abord si un siphon des \xE2mes est prioritaire + //On cherche d'abord si un siphon des âmes est prioritaire let prioriteSiphon = []; allToks = allToks.filter(function(tok) { if (tok.id == token.id) return false; @@ -2946,7 +2948,7 @@ var COFantasy = COFantasy || function() { let jetSiphon = "(1d6"; if (bonus > 0) jetSiphon += '+' + bonus; jetSiphon += ")"; - sendChat('COF', "/w GM " + personnage.token.get('name') + " est un personnage joueur, possible qu'il ne soit pas vraiment mort mais juste inconscient. S'il est vraiment mort, faire le siphon des \xE2mes par " + siphoneur.token.get('name') + " \xE0 la main " + jetSiphon); + sendChat('COF', "/w GM " + personnage.token.get('name') + " est un personnage joueur, possible qu'il ne soit pas vraiment mort mais juste inconscient. S'il est vraiment mort, faire le siphon des âmes par " + siphoneur.token.get('name') + " à la main " + jetSiphon); } else { prioriteSiphon.sort(function(a, b) { return b.priorite - a.priorite; @@ -2961,7 +2963,7 @@ var COFantasy = COFantasy || function() { } let p = x.perso; if (fractionPriorite < 1) { - whisperChar(p.charId, "ne r\xE9ussit pas \xE0 siphoner l'\xE2me de " + token.get('name') + " un autre pouvoir l'a siphon\xE9e avant lui"); + whisperChar(p.charId, "ne réussit pas à siphoner l'âme de " + token.get('name') + " un autre pouvoir l'a siphonée avant lui"); return true; } let bonus = predicateAsInt(p, 'siphonDesAmes', 0); @@ -2971,7 +2973,7 @@ var COFantasy = COFantasy || function() { nbDes }); let soinTotal = soin.val; - //Le montant total des soins ne peut exc\xE9der les pv max du personnage qui vient de mourrir. + //Le montant total des soins ne peut excéder les pv max du personnage qui vient de mourrir. let display = true; if (soinTotal > pvMax) { soinTotal = pvMax; @@ -2980,12 +2982,12 @@ var COFantasy = COFantasy || function() { if (soinTotal < 1) soinTotal = 1; soin.val = soinTotal; soin.val = Math.ceil(soin.val * fractionPriorite / 100); - //Cherche si il y a un perso li\xE9 + //Cherche si il y a un perso lié let lie = personnageAmeLiee(p, pageId, allToks); soigneToken(p, soin.val, evt, function(s) { - let siphMsg = "siphone l'\xE2me de " + token.get('name') + - ". " + onGenre(p, 'Il', 'Elle') + " r\xE9cup\xE8re "; + let siphMsg = "siphone l'âme de " + token.get('name') + + ". " + onGenre(p, 'Il', 'Elle') + " récupère "; if (s == soinTotal) { if (display) siphMsg += soin.roll + " pv."; else siphMsg += s + " pv (jet " + soin.roll + ")."; @@ -3000,8 +3002,8 @@ var COFantasy = COFantasy || function() { let soin2 = soinTotal - s + Math.floor(s / 5); soigneToken(lie, soin2, evt, function(s) { let siphMsg = - "r\xE9cup\xE8re une partie de l'\xE2me de " + token.get('name') + - " siphon\xE9e par " + nomPerso(p) + ". " + onGenre(lie, 'Il', 'Elle') + " r\xE9cup\xE8re " + s + " pv."; + "récupère une partie de l'âme de " + token.get('name') + + " siphonée par " + nomPerso(p) + ". " + onGenre(lie, 'Il', 'Elle') + " récupère " + s + " pv."; if (s == soin2) { fraction = 0; } else { @@ -3010,15 +3012,15 @@ var COFantasy = COFantasy || function() { pvMax -= s; whisperChar(lie.charId, siphMsg); }, function() { - whisperChar(lie.charId, "sent qu'" + onGenre(lie, 'il', 'elle') + " aurait pu b\xE9n\xE9ficier d'une \xE2me"); + whisperChar(lie.charId, "sent qu'" + onGenre(lie, 'il', 'elle') + " aurait pu bénéficier d'une âme"); }); } }, function() { if (lie) { soigneToken(lie, soin.val, evt, function(s) { - let siphMsg = "siphone l'\xE2me de " + token.get('name') + - " gr\xE2ce \xE0 " + nomPerso(p) + ". " + onGenre(lie, 'Il', 'Elle') + " r\xE9cup\xE8re "; + let siphMsg = "siphone l'âme de " + token.get('name') + + " grâce à " + nomPerso(p) + ". " + onGenre(lie, 'Il', 'Elle') + " récupère "; if (s == soinTotal) { siphMsg += soin.roll + " pv."; fraction = 0; @@ -3030,11 +3032,11 @@ var COFantasy = COFantasy || function() { whisperChar(lie.charId, siphMsg); }, function() { whisperChar(p.charId, - "est d\xE9j\xE0 au maximum de point de vie. " + onGenre(p, 'Il', 'Elle') + " laisse \xE9chapper l'\xE2me de " + token.get('name')); + "est déjà au maximum de point de vie. " + onGenre(p, 'Il', 'Elle') + " laisse échapper l'âme de " + token.get('name')); }); } else { whisperChar(p.charId, - "est d\xE9j\xE0 au maximum de point de vie. " + onGenre(p, 'Il', 'Elle') + " laisse \xE9chapper l'\xE2me de " + token.get('name')); + "est déjà au maximum de point de vie. " + onGenre(p, 'Il', 'Elle') + " laisse échapper l'âme de " + token.get('name')); } }); }); @@ -3074,7 +3076,7 @@ var COFantasy = COFantasy || function() { } //fonction avec callback, mais synchrone - // n'ajoute pas evt \xE0 l'historique + // n'ajoute pas evt à l'historique function soigneToken(perso, soins, evt, callTrue, callMax, options) { options = options || {}; let token = perso.token; @@ -3111,7 +3113,7 @@ var COFantasy = COFantasy || function() { let ds = parseInt(a.get('current')); if (ds > 0) { if (an[0].length < 2) { - error("Match non trouv\xE9 pour les soins", an); + error("Match non trouvé pour les soins", an); return; } if (soinsImpossible.has(an[1])) { @@ -3179,7 +3181,7 @@ var COFantasy = COFantasy || function() { } } } - // On cherche si il y a des DM temporaires \xE0 soigner + // On cherche si il y a des DM temporaires à soigner if (bar1 > pvmax) { let hasMana = (ficheAttributeAsInt(perso, 'PM', 0) > 0); let dmgTemp; @@ -3224,7 +3226,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(perso, 'reactionAllergique')) { removeTokenAttr(perso, 'reactionAllergique', evt, { - msg: ": les soins mettent fin \xE0 la r\xE9action allergique" + msg: ": les soins mettent fin à la réaction allergique" }); } } @@ -3261,7 +3263,7 @@ var COFantasy = COFantasy || function() { return scale; } - // si le token est plus grand que thresh, r\xE9duit la distance + // si le token est plus grand que thresh, réduit la distance function tokenSize(tok, thresh) { let size = (tok.get('width') + tok.get('height')) / 2; if (size > thresh) return ((size - thresh) / 2); @@ -3307,7 +3309,7 @@ var COFantasy = COFantasy || function() { } //Distance en pixels entre un token et un segment - //le segment est donn\xE9 par ses extr\xE9mit\xE9s, sous forme de {x, y} + //le segment est donné par ses extrémités, sous forme de {x, y} function distancePixTokenSegment(token, pt1, pt2) { let pt = pointOfToken(token); let seg = { @@ -3317,26 +3319,26 @@ var COFantasy = COFantasy || function() { let vec = { x: pt.x - pt1.x, y: pt.y - pt1.y - }; //vecteur de pt1 \xE0 pt - //On regarde d'abord si le projet\xE9 de token sur (pt1, pt2) est dans le segment + }; //vecteur de pt1 à pt + //On regarde d'abord si le projeté de token sur (pt1, pt2) est dans le segment let ps = seg.x * vec.x + seg.y * vec.y; if (ps <= 0) { //On est avant pt1 return Math.sqrt(vec.x * vec.x + vec.y * vec.y); } let dseg = seg.x * seg.x + seg.y * seg.y; - if (ps >= dseg) { //On est apr\xE8s pt2, on retourne donc la distance pt pt2 + if (ps >= dseg) { //On est après pt2, on retourne donc la distance pt pt2 let x = pt.x - pt2.x; let y = pt.y - pt2.y; return Math.sqrt(x * x + y * y); } - //On calcule le d\xE9terminant de vec et seg + //On calcule le déterminant de vec et seg let det = vec.x * seg.y - vec.y * seg.x; //Et on divise par la longueur du segment return Math.abs(det) / Math.sqrt(dseg); } //options peut avoir les champs: - // - strict1 = true si on consid\xE8re que tok1 doit avoir une taille nulle + // - strict1 = true si on considère que tok1 doit avoir une taille nulle // - strict2 // - allonge function distanceCombat(tok1, tok2, pageId, options) { @@ -3344,7 +3346,7 @@ var COFantasy = COFantasy || function() { pageId = tok1.get('pageid'); } options = options || {}; - //perso mont\xE9s + //perso montés let pseudoTok1 = tok1; if (!options.strict1) { let perso1 = persoOfToken(tok1); @@ -3377,7 +3379,7 @@ var COFantasy = COFantasy || function() { } //Attention, seulement faire pour les tokens avec une image dans la librairie - //C'est toujours le cas pour un token cr\xE9\xE9 par le script + //C'est toujours le cas pour un token créé par le script function deleteTokenWithUndo(token, evt) { let tokenFields = getTokenFields(token); evt.deletedTokens = evt.deletedTokens || []; @@ -3385,8 +3387,8 @@ var COFantasy = COFantasy || function() { token.remove(); } - //L'argument effetC doit \xEAtre le nom complet, pas la base - //evt.deletedAttributes doit \xEAtre d\xE9fini + //L'argument effetC doit être le nom complet, pas la base + //evt.deletedAttributes doit être défini function enleverEffetAttribut(charId, effetC, attrName, extension, evt) { let attrSave = attributeExtending(charId, attrName, effetC, extension); attrSave. @@ -3396,14 +3398,14 @@ var COFantasy = COFantasy || function() { }); } - function finDEffet(attr, effet, attrName, charId, evt, options) { //L'effet arrive en fin de vie, doit \xEAtre supprim\xE9 + function finDEffet(attr, effet, attrName, charId, evt, options) { //L'effet arrive en fin de vie, doit être supprimé options = options || {}; evt.deletedAttributes = evt.deletedAttributes || []; let res; let newInit = []; let efComplet = effetComplet(effet, attrName); - //Si on a un attrSave, alors on a d\xE9j\xE0 imprim\xE9 le message de fin d'effet - if (options.attrSave) { //on a un attribut associ\xE9 \xE0 supprimer) + //Si on a un attrSave, alors on a déjà imprimé le message de fin d'effet + if (options.attrSave) { //on a un attribut associé à supprimer) evt.deletedAttributes.push(options.attrSave); options.attrSave.remove(); } else if (options.gardeAutresAttributs === undefined) { //On cherche si il y en a un @@ -3424,7 +3426,7 @@ var COFantasy = COFantasy || function() { let character; let combat = stateCOF.combat; switch (effet) { - case 'affecteParAura': //voir si l'aura est toujours l\xE0 + case 'affecteParAura': //voir si l'aura est toujours là if (combat && combat.auras && efComplet.length > 15) { let id = efComplet.substring(15, efComplet.length - 1); let aura = combat.auras.find(function(a) { @@ -3474,7 +3476,7 @@ var COFantasy = COFantasy || function() { if (arme && arme.armeDeGrand) { let taille = taillePersonnage(perso, 4); if (taille == 4 && arme.label != perso.attrArmeEnMain.get('max')) { - sendPerso(perso, "ne peut plus tenir " + arme.name + " \xE0 une main"); + sendPerso(perso, "ne peut plus tenir " + arme.name + " à une main"); degainerArme(perso, arme.label, evt, { deuxMains: true }); @@ -3673,22 +3675,22 @@ var COFantasy = COFantasy || function() { function(s) { options.print = function(m) {}; //Pour ne pas afficher le message final. let tempsEffectif = Math.ceil(s / regen); - sendPerso(perso, "r\xE9cup\xE8re encore " + s + " PV en " + tempsEffectif + " tours."); + sendPerso(perso, "récupère encore " + s + " PV en " + tempsEffectif + " tours."); }); } - //R\xE9g\xE9n\xE9ration d'une carac physique affaiblie de 1d4, si il y en a. + //Régénération d'une carac physique affaiblie de 1d4, si il y en a. if (attributeAsInt(perso, 'affaiblissementdeconstitution', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(perso, 'constitution', d4.val, evt); - sendPerso(perso, "r\xE9cup\xE8re " + d4.roll + " points de constitution"); + sendPerso(perso, "récupère " + d4.roll + " points de constitution"); } else if (attributeAsInt(perso, 'affaiblissementdeforce', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(perso, 'force', d4.val, evt); - sendPerso(perso, "r\xE9cup\xE8re " + d4.roll + " points de force"); + sendPerso(perso, "récupère " + d4.roll + " points de force"); } else if (attributeAsInt(perso, 'affaiblissementdedexterite', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(perso, 'dexterite', d4.val, evt); - sendPerso(perso, "r\xE9cup\xE8re " + d4.roll + " points de dext\xE9rit\xE9"); + sendPerso(perso, "récupère " + d4.roll + " points de dextérité"); } }); break; @@ -3697,7 +3699,7 @@ var COFantasy = COFantasy || function() { case 'arbreAnime': case 'objetAnime': case 'degradationZombie': //effacer le personnage - //Dans le cas d'un Zombie, diminuer la limite du n\xE9cromant si n\xE9cessaire + //Dans le cas d'un Zombie, diminuer la limite du nécromant si nécessaire if (effet == 'degradationZombie') { let attrNecromant = charAttribute(charId, 'necromant'); if (attrNecromant.length > 0) { @@ -3809,7 +3811,7 @@ var COFantasy = COFantasy || function() { abilities: charAbilities, allies: [] }; - // Retrait du perso de toutes les listes d'alli\xE9s + // Retrait du perso de toutes les listes d'alliés for (const [perso, alliesPerso] of Object.entries(alliesParPerso)) { if (alliesPerso.has(charId)) { deletedChar.allies.push(perso); @@ -3901,7 +3903,7 @@ var COFantasy = COFantasy || function() { if (pv == 0) { //jshint ignore:line mort(perso, undefined, evt); } else { - //On note qu'il l'a d\xE9j\xE0 fait pour qu'il ne puisse le refaire dans le combat + //On note qu'il l'a déjà fait pour qu'il ne puisse le refaire dans le combat setTokenAttr(perso, 'aAgiAZeroPV', true, evt); } }); @@ -3945,7 +3947,7 @@ var COFantasy = COFantasy || function() { }; if (getState(perso, 'mort')) return; if (!combat) { - sendChat('', "Il restait un effet retard\xE9 " + effetRetarde + " qui devait se d\xE9clencher pour " + token.get('name')); + sendChat('', "Il restait un effet retardé " + effetRetarde + " qui devait se déclencher pour " + token.get('name')); return; } let duree = getIntValeurOfEffet(perso, efComplet, 1); @@ -3977,7 +3979,7 @@ var COFantasy = COFantasy || function() { charId: charId }; if (getState(perso, 'mort')) return; - whisperChar(charId, "Le poison commence \xE0 faire effet !"); + whisperChar(charId, "Le poison commence à faire effet !"); setTokenAttr(perso, 'poisonAffaiblissantLong', true, evt, {}); }); break; @@ -3986,7 +3988,7 @@ var COFantasy = COFantasy || function() { let messageRetarde = efComplet.substring(15, efComplet.length - 1); iterTokensOfAttribute(charId, options.pageId, efComplet, attrName, function(token) { whisperChar(charId, messageRetarde); - //Puis on regarde si il y a une valeur \xE0 afficher + //Puis on regarde si il y a une valeur à afficher let perso = { token: token, charId: charId @@ -3999,7 +4001,7 @@ var COFantasy = COFantasy || function() { break; case 'tenebres': iterTokensOfAttribute(charId, options.pageId, efComplet, attrName, function(token) { - //Puis on regarde si il y a une valeur \xE0 afficher + //Puis on regarde si il y a une valeur à afficher let perso = { token: token, charId: charId @@ -4011,7 +4013,7 @@ var COFantasy = COFantasy || function() { break; case 'brumes': iterTokensOfAttribute(charId, options.pageId, efComplet, attrName, function(token) { - //Puis on regarde si il y a une valeur \xE0 afficher + //Puis on regarde si il y a une valeur à afficher let perso = { token: token, charId: charId @@ -4104,7 +4106,7 @@ var COFantasy = COFantasy || function() { } evt.deletedAttributes.push(attr); attr.remove(); - //D\xE9bloque les tokens si l'effet les immobilisait + //Débloque les tokens si l'effet les immobilisait switch (effet) { case 'bloqueManoeuvre': case 'prisonVegetale': @@ -4131,7 +4133,7 @@ var COFantasy = COFantasy || function() { } } - //retourne le personnage du compagnon s'il est pr\xE9sent et actif + //retourne le personnage du compagnon s'il est présent et actif function compagnonPresent(personnage, nomCompagnon) { let compagnon = predicateAsBool(personnage, nomCompagnon); if (compagnon) { @@ -4199,7 +4201,7 @@ var COFantasy = COFantasy || function() { } //Pour savoir si un personnage est un personnage joueur - // -> fiche de PJ + d\xE9 de vie + token li\xE9 + controll\xE9 par au moins un joueur. + // -> fiche de PJ + dé de vie + token lié + controllé par au moins un joueur. function estPJ(perso) { if (persoEstPNJ(perso)) return false; let dv = ficheAttributeAsInt(perso, 'DV', 0); @@ -4219,50 +4221,50 @@ var COFantasy = COFantasy || function() { }); }*/ - /* \xC9v\xE9nements, utilis\xE9s pour les undo, en particulier undo pour refaire - * une action quand une r\xE8gle le permet (utilisation de points de chance, etc..) - * Champ d'un \xE9v\xE9nement (variables evt en g\xE9n\xE9ral dans le code): + /* Événements, utilisés pour les undo, en particulier undo pour refaire + * une action quand une règle le permet (utilisation de points de chance, etc..) + * Champ d'un événement (variables evt en général dans le code): * id : identificateur unique (int) - * type : description de l'\xE9v\xE9nement (string) - * affectes : liste de tokens affect\xE9s par l'\xE9v\xE9nement - * tokens : liste des tokens cr\xE9\xE9s - * deletedTokens : liste de tokens effac\xE9s - * !!!!! -> ne garde pas les tokens effac\xE9s si on n'est pas s\xFBr que son image est au bon endroit. Typiquement, on ne va le faire que pour les tokens cr\xE9es dans le script - * attributes : liste de attributs cr\xE9\xE9s ou modifi\xE9s - * deletesAttributes: lites des attributs effac\xE9s - * characters : liste des personnages cr\xE9\xE9s + * type : description de l'événement (string) + * affectes : liste de tokens affectés par l'événement + * tokens : liste des tokens créés + * deletedTokens : liste de tokens effacés + * !!!!! -> ne garde pas les tokens effacés si on n'est pas sûr que son image est au bon endroit. Typiquement, on ne va le faire que pour les tokens crées dans le script + * attributes : liste de attributs créés ou modifiés + * deletesAttributes: lites des attributs effacés + * characters : liste des personnages créés * characterNames : liste de character * name - * defaultTokens : liste de tokens par d\xE9faut (objet) + * defaultTokens : liste de tokens par défaut (objet) * (character, defaultToken) - * deletedCharacters: liste des personnages effac\xE9s - * combat : valeur de la variable d'\xE9tat combat + * deletedCharacters: liste des personnages effacés + * combat : valeur de la variable d'état combat * updateNextInitSet: valeur de l'ensemble des tokens dont il faut recalculer l'init - * turnorder : le turnorder (si il a chang\xE9) + * turnorder : le turnorder (si il a changé) * initiativepage : true si le turnorder est actif - * personnage : le perso qui 'fait' l'\xE9v\xE9nement - * succes : stoque si l'attaque \xE9tait un succ\xE8s (bool) - * action : sauvegarde des param\xE8tres de l'evt, pour la rejouer - * - caracteristique : carac test\xE9e (pour un jet) + * personnage : le perso qui 'fait' l'événement + * succes : stoque si l'attaque était un succès (bool) + * action : sauvegarde des paramètres de l'evt, pour la rejouer + * - caracteristique : carac testée (pour un jet) * - titre : titre du jet - * - playerId : id du joueur qui a lanc\xE9 l'action - * - selected : cibles s\xE9lectionn\xE9s des l'action + * - playerId : id du joueur qui a lancé l'action + * - selected : cibles sélectionnés des l'action * - attaquant: personnage attaquant (TODO: voir si doublon avec personnage) * - cibles: liste des cibles d'attaque, avec leurs tags - * - weaponStats: stats de l'arme (ou attaque) utilis\xE9e - * - rolls: les jets de l'action, pour les avoir \xE0 l'identique - * les d\xE9g\xE2ts sont stoqu\xE9s dans chaque cible, dans cible.rollsDmg + * - weaponStats: stats de l'arme (ou attaque) utilisée + * - rolls: les jets de l'action, pour les avoir à l'identique + * les dégâts sont stoqués dans chaque cible, dans cible.rollsDmg * - attack: les jets de l'attaque - * - etat_e_index_targetid: save pour entrer dans l'\xE9tat e + * - etat_e_index_targetid: save pour entrer dans l'état e * - effet_e_index_targetid: save pour l'effet e - * - attaquant_pietinement_targetid: jet de l'attaquant pour le pi\xE9tinement - * - defenseur_pietinement_targetid: jet de du d\xE9fenseur pour le pi\xE9tinement + * - attaquant_pietinement_targetid: jet de l'attaquant pour le piétinement + * - defenseur_pietinement_targetid: jet de du défenseur pour le piétinement * - options : options de l'action - * attenteResultat : permet de savoir que le jet est en attente de d\xE9cision pour savoir si c'est un succ\xE8s ou non (quand il n'y a pas de difficult\xE9 donn\xE9e et que le personnage est sous l'emprise d'une mal\xE9diction) + * attenteResultat : permet de savoir que le jet est en attente de décision pour savoir si c'est un succès ou non (quand il n'y a pas de difficulté donnée et que le personnage est sous l'emprise d'une malédiction) */ function addEvent(evt) { if (evt.id) { - error("Tentative d'ajouter un \xE9v\xE9nement d\xE9j\xE0 dans l'historique", evt); + error("Tentative d'ajouter un événement déjà dans l'historique", evt); return; } evt.id = stateCOF.eventId++; @@ -4302,11 +4304,11 @@ var COFantasy = COFantasy || function() { } } - //Si evt n'est pas d\xE9fini, annule le dernier evt + //Si evt n'est pas défini, annule le dernier evt function undoEvent(evt) { if (evt === undefined) { if (eventHistory.length === 0) { - sendChat('COF', "/w GM Historique d'\xE9v\xE8nements vide"); + sendChat('COF', "/w GM Historique d'évènements vide"); return; } evt = eventHistory.pop(); @@ -4344,7 +4346,7 @@ var COFantasy = COFantasy || function() { } if (evt.defaultTokens) { evt.defaultTokens.forEach(function(dt) { - //On cherche d'abord un token qui repr\xE9sente dt.character + //On cherche d'abord un token qui représente dt.character let tokens = findObjs({ _type: 'graphic', represents: dt.character.id @@ -4429,7 +4431,7 @@ var COFantasy = COFantasy || function() { }); }); } - // On le remet chez ses alli\xE9s + // On le remet chez ses alliés if (character.allies.length > 0) { Object.values(character.allies).forEach(function(allie) { let alliesPerso = alliesParPerso[allie] || new Set(); @@ -4497,7 +4499,7 @@ var COFantasy = COFantasy || function() { } if (_.has(evt, 'combat')) { let combat = stateCOF.combat; - //regarde si le token actif a chang\xE9 + //regarde si le token actif a changé if (evt.combat && (!combat || evt.combat.activeTokenId != combat.activeTokenId) && stateCOF.options.affichage.val.init_dynamique.val) { @@ -4527,14 +4529,14 @@ var COFantasy = COFantasy || function() { stateCOF.tokensTemps.push(tt); }); } - if (evt.tokensTemps) { //ceux pour lesquels on a diminu\xE9 la dur\xE9e + if (evt.tokensTemps) { //ceux pour lesquels on a diminué la durée evt.tokensTemps.forEach(function(tt) { if (tt.tt) tt.tt.duree = tt.ancienneDuree; }); } } - //origin peut \xEAtre un message ou un nom de joueur + //origin peut être un message ou un nom de joueur function sendPlayer(origin, msg, playerId) { let dest = origin; if (origin.who) { @@ -4544,7 +4546,7 @@ var COFantasy = COFantasy || function() { } if (dest.includes('"')) { sendChat('COF', msg); - log("Impossible d'envoyer des messages priv\xE9s \xE0 " + dest + " car le nom contient des guillemets"); + log("Impossible d'envoyer des messages privés à " + dest + " car le nom contient des guillemets"); } sendChat('COF', '/w "' + dest + '" ' + msg); } @@ -4574,7 +4576,7 @@ var COFantasy = COFantasy || function() { case 'FOR': return "de force"; case 'DEX': - return "de dext\xE9rit\xE9"; + return "de dextérité"; case 'CON': return "de constitution"; case 'SAG': @@ -4588,7 +4590,7 @@ var COFantasy = COFantasy || function() { } } - //msg peut \xEAtre un message ou un playerId + //msg peut être un message ou un playerId function peutController(msg, perso) { if (msg === undefined) return true; let playerId = getPlayerIdFromMsg(msg); @@ -4621,12 +4623,12 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let action = evt.action; if (action === undefined) { - error("Erreur interne du bouton de confirmation: l'\xE9v\xE8nement n'a pas d'action", cmd); + error("Erreur interne du bouton de confirmation: l'évènement n'a pas d'action", cmd); return; } let options = action.currentOptions || {}; @@ -4667,7 +4669,7 @@ var COFantasy = COFantasy || function() { let prev = aff.prev; let tok = aff.affecte; if (prev === undefined || tok === undefined) { - error("Pas d'\xE9tat pr\xE9c\xE9dant", aff); + error("Pas d'état précédant", aff); return; } let prevTok; @@ -4676,7 +4678,7 @@ var COFantasy = COFantasy || function() { tok.set(key, val); }); if (HTdeclared) HealthColors.Update(tok, prevTok); - sendChat("COF", "\xC9tat de " + tok.get("name") + " restaur\xE9."); + sendChat("COF", "État de " + tok.get("name") + " restauré."); }); } @@ -4693,7 +4695,7 @@ var COFantasy = COFantasy || function() { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string } - //Remplace une macro ou ability par sa d\xE9finition (r\xE9cursivement) + //Remplace une macro ou ability par sa définition (récursivement) function replaceAction(action, perso, macros, abilities) { let remplacement = false; if (action.indexOf('#') >= 0) { @@ -4710,7 +4712,7 @@ var COFantasy = COFantasy || function() { if (!remplacement) macros = macros.filter(function(m, k) { return (k != i); - }); //Pour \xE9viter la r\xE9cursion + }); //Pour éviter la récursion remplacement = true; } }); @@ -4726,7 +4728,7 @@ var COFantasy = COFantasy || function() { let daName = '%' + aName; if (action.indexOf(daName) >= 0) { action = action.replace(daName, a.get('action')); - if (!remplacement) abilities = abilities.splice(i); //Pour \xE9viter la r\xE9cursion + if (!remplacement) abilities = abilities.splice(i); //Pour éviter la récursion remplacement = true; } daName = '%{selected|' + aName + '}'; @@ -4735,7 +4737,7 @@ var COFantasy = COFantasy || function() { if (!remplacement) abilities = abilities.filter(function(m, k) { return (k != i); - }); //Pour \xE9viter la r\xE9cursion + }); //Pour éviter la récursion remplacement = true; } }); @@ -4847,7 +4849,7 @@ var COFantasy = COFantasy || function() { armeDeCreatureFeerique(perso, weaponStats, 3); break; default: - //On cherche si c'est une arme \xE0 2 mains + //On cherche si c'est une arme à 2 mains //Ne devrait pas servir, on a toujours un type, maintenant let t = weaponStats.name.toLowerCase(); if (t.includes('2 mains') || t.includes('deux mains')) { @@ -4862,19 +4864,19 @@ var COFantasy = COFantasy || function() { } } } - //Informations dans le champ sp\xE9cial + //Informations dans le champ spécial let champDivers = weaponStats.divers; if (champDivers === '') champDivers = weaponStats.predicats; else if (weaponStats.predicats !== '') champDivers += '\n' + weaponStats.predicats; let pred = predicateOfRaw(champDivers); - //On transfert les pr\xE9dicats connus dans weaponStats + //On transfert les prédicats connus dans weaponStats if (pred.charge) weaponStats.charge = toInt(pred.charge, 1); weaponStats.eclaire = toInt(pred.eclaire); weaponStats.eclaireFaible = toInt(pred.eclaireFaible); weaponStats.batarde = pred.batarde; if (weaponStats.batarde && weaponStats.deuxMains) { - error("L'arme " + weaponStats.name + " est d\xE9clar\xE9e comme bat\xE2rde, il faudrait en faire une arme \xE0 une main par d\xE9faut", weaponStats); + error("L'arme " + weaponStats.name + " est déclarée comme batârde, il faudrait en faire une arme à une main par défaut", weaponStats); weaponStats.deuxMains = undefined; } if (pred.armeDeGrand) { @@ -4883,17 +4885,17 @@ var COFantasy = COFantasy || function() { if (taille < 5) weaponStats.deuxMains = true; else weaponStats.deuxMains = false; } - //Identification des cat\xE9gories d'armes utilis\xE9es en jeu + //Identification des catégories d'armes utilisées en jeu identifierArme(weaponStats, pred, 'arc', /\barc\b/i); - identifierArme(weaponStats, pred, 'arbalete', /\barbal[e\xE8]te\b/i); - identifierArme(weaponStats, pred, 'baton', /\bb[a\xE2]ton\b/i); + identifierArme(weaponStats, pred, 'arbalete', /\barbal[eè]te\b/i); + identifierArme(weaponStats, pred, 'baton', /\bb[aâ]ton\b/i); identifierArme(weaponStats, pred, 'hache', /\bhache\b/i); - identifierArme(weaponStats, pred, 'epee', /\b[e\xE9]p[e\xE9]e\b/i); - identifierArme(weaponStats, pred, 'epieu', /\b[e\xE9]pieu\b/i); + identifierArme(weaponStats, pred, 'epee', /\b[eé]p[eé]e\b/i); + identifierArme(weaponStats, pred, 'epieu', /\b[eé]pieu\b/i); identifierArme(weaponStats, pred, 'fronde', /\bfronde\b/i); identifierArme(weaponStats, pred, 'marteau', /\bmarteau\b/i); identifierArme(weaponStats, pred, 'masse', /\bmasse\b/i); - identifierArme(weaponStats, pred, 'rapiere', /\brapi[e\xE8]re\b/i); + identifierArme(weaponStats, pred, 'rapiere', /\brapi[eè]re\b/i); identifierArme(weaponStats, pred, 'poudre', /\bpoudre\b/i); identifierArme(weaponStats, pred, 'sabre', /\b(katana|wakizachi|boken|demi-lame|vivelame|sabre)\b/i); if (weaponStats.arc && predicateAsBool(perso, 'arcDeMaitre')) { @@ -4926,8 +4928,8 @@ var COFantasy = COFantasy || function() { bar2 = parseInt(token.get('bar2_value')); if (isNaN(bar2)) { if (token.get('bar1_link') === '') bar2 = 0; - else { //devrait \xEAtre li\xE9 \xE0 la mana courante - sendPerso(personnage, "*** Attention, la barre de mana du token n'est pas li\xE9e \xE0 la mana de la fiche ***"); + else { //devrait être lié à la mana courante + sendPerso(personnage, "*** Attention, la barre de mana du token n'est pas liée à la mana de la fiche ***"); bar2 = parseInt(manaAttr[0].get('current')); } } @@ -4970,7 +4972,7 @@ var COFantasy = COFantasy || function() { } //depasse est un string qui commence par --depasseLimite - //args doit \xEAtre d\xE9fini et contient des valeur \xE0 modifier : + //args doit être défini et contient des valeur à modifier : // - mana // - text function peutDepasserLimite(depasse, perso, attrName, args) { @@ -5034,7 +5036,7 @@ var COFantasy = COFantasy || function() { if (attributeAsInt(perso, ressourceParJour, limiteParJour) > 0) { return false; } - //Reste le cas o\xF9 on peut d\xE9passer cette limite par jour + //Reste le cas où on peut dépasser cette limite par jour let depasse = options.find(function(o) { return o.startsWith('depasseLimite '); }); @@ -5078,7 +5080,7 @@ var COFantasy = COFantasy || function() { return ai; } - //Enl\xE8ve les cha\xEEnes de type ?{..} pour \xEAtre s\xFBr que l'action est impossible + //Enlève les chaînes de type ?{..} pour être sûr que l'action est impossible function removeUserInputs(act) { let m = act.match(/\?\{[^\}]*\}/g); if (!m) return act; @@ -5100,7 +5102,7 @@ var COFantasy = COFantasy || function() { if (labelArmePrincipale) perso.arme = getWeaponStats(perso, labelArmePrincipale); let labelArmeGauche = attr[0].get('max'); if (labelArmeGauche) { - if (labelArmeGauche == labelArmePrincipale) { //arme tenue \xE0 2 mains + if (labelArmeGauche == labelArmePrincipale) { //arme tenue à 2 mains perso.arme.deuxMains = true; } else { perso.armeGauche = getWeaponStats(perso, labelArmeGauche); @@ -5118,7 +5120,7 @@ var COFantasy = COFantasy || function() { function listAllMunitions(perso) { if (perso.munitions) return perso.munitions; let rawList = extractRepeating(perso, 'munitions'); - let liste = {}; //liste tri\xE9e par label de munition + let liste = {}; //liste triée par label de munition for (let pref in rawList) { let ra = rawList[pref]; if (ra.labelmunition === undefined) ra.labelmunition = 0; @@ -5133,11 +5135,11 @@ var COFantasy = COFantasy || function() { return liste; } - //Les options de l'arme doivent d\xE9j\xE0 \xEAtre dans act + //Les options de l'arme doivent déjà être dans act function demandeMunition(perso, weaponStats, options, act) { if (act.includes('--munition')) return act; let typeMunition; - if (weaponStats.arc) typeMunition = 'Fl\xE8che'; + if (weaponStats.arc) typeMunition = 'Flèche'; else if (weaponStats.arbalete) typeMunition = 'Carreau'; else if (weaponStats.poudre) typeMunition = 'Balle'; else if (weaponStats.fronde) typeMunition = 'Autre'; //TODO: ajouter le type bille sur la fiche @@ -5146,7 +5148,7 @@ var COFantasy = COFantasy || function() { let munitionsDeType = []; for (let label in munitions) { let munition = munitions[label]; - let tm = fieldAsString(munition, 'typemunition', 'Fl\xE8che'); + let tm = fieldAsString(munition, 'typemunition', 'Flèche'); if (tm != typeMunition) return; let nb = fieldAsInt(munition, 'qtemunition', 1); if (nb > 0) munitionsDeType.push(munition); @@ -5166,7 +5168,7 @@ var COFantasy = COFantasy || function() { // - overlay // - buttonStyle // - attackStats - // et la fonction peut \xE9crire actionImpossible = true dans options. + // et la fonction peut écrire actionImpossible = true dans options. function bouton(action, text, perso, options) { if (action === undefined || action.trim() === '') return text; else action = action.trim(); @@ -5179,12 +5181,12 @@ var COFantasy = COFantasy || function() { if (character) perso.name = character.get('name'); else perso.name = nomPerso(perso); } - //Cas de plusieurs actions apr\xE8s expansion + //Cas de plusieurs actions après expansion let actions = action.split('\n'); //Cherche le picto et le style let style = ''; let picto = ''; - let groupe; //Pour g\xE9n\xE9rer un bouton d'attaque de groupe. \xC0 revoir + let groupe; //Pour générer un bouton d'attaque de groupe. À revoir actions = actions.map(function(act) { act = act.trim(); if (act.startsWith("/as ")) { @@ -5195,7 +5197,7 @@ var COFantasy = COFantasy || function() { let actSansChoix = removeUserInputs(act); const args = actSansChoix.split(' --'); let defRessource = ''; - if (act.startsWith('!cof-guerison ')) defRessource = 'gu\xE9rison'; + if (act.startsWith('!cof-guerison ')) defRessource = 'guérison'; let dai = { text }; @@ -5203,13 +5205,13 @@ var COFantasy = COFantasy || function() { options.actionImpossible = true; else text = dai.text; if (!options.actionImpossible) { - if (act.startsWith('!cof-soin ') && !actSansChoix.includes('--limitePar') && !actSansChoix.includes('--dose')) { //Limitations sp\xE9ficiques + if (act.startsWith('!cof-soin ') && !actSansChoix.includes('--limitePar') && !actSansChoix.includes('--dose')) { //Limitations spéficiques let rangSoin = predicateAsInt(perso, 'voieDesSoins', 0); let cmd = args[0].split(' '); if (cmd.includes('leger')) { let soinsLegers = attributeAsInt(perso, 'soinsLegers', 0); if (soinsLegers >= rangSoin) { - //Peut-\xEAtre qu'on peut encore d\xE9passer la limite + //Peut-être qu'on peut encore dépasser la limite let depasse = actSansChoix.indexOf('--depasseLimite '); if (depasse > 0) { let dp = { @@ -5224,7 +5226,7 @@ var COFantasy = COFantasy || function() { } else if (cmd.includes('modere')) { let soinsModeres = attributeAsInt(perso, 'soinsModeres', 0); if (soinsModeres >= rangSoin) { - //Peut-\xEAtre qu'on peut encore d\xE9passer la limite + //Peut-être qu'on peut encore dépasser la limite let depasse = actSansChoix.indexOf('--depasseLimite '); if (depasse > 0) { let dp = { @@ -5251,7 +5253,7 @@ var COFantasy = COFantasy || function() { } else if (act.startsWith('!cof-attack ')) { let cmd = act.split(' '); if (cmd.length > 3 && cmd[3] == '-1') { - //Selon l'arme en main, une action peut \xEAtre possible ou non + //Selon l'arme en main, une action peut être possible ou non let weaponStats = armesEnMain(perso); if (weaponStats) { options.attackStats = options.attackStats || weaponStats; @@ -5303,7 +5305,7 @@ var COFantasy = COFantasy || function() { } act = demandeMunition(perso, attackStats, options, act); } - //On cherche la port\xE9e dans les options (\xE7a a la priorit\xE9) + //On cherche la portée dans les options (ça a la priorité) args.forEach(function(o) { if (o.startsWith('portee ')) { let p = parseInt(o.substring(7)); @@ -5424,13 +5426,13 @@ var COFantasy = COFantasy || function() { } } if (act.indexOf('@{selected') !== -1) { - // cas sp\xE9cial pour @{selected|token_id} o\xF9 l'on remplace toutes les occurences par token.id + // cas spécial pour @{selected|token_id} où l'on remplace toutes les occurences par token.id act = act.replace(new RegExp(escapeRegExp('@{selected|token_id}'), 'g'), tid); act = act.replace(new RegExp(escapeRegExp('@{selected|token_name}'), 'g'), nomPerso(perso)); let tmp = act.split('@{selected'); tmp.forEach(function(elem) { if (elem.startsWith('|')) { - // attribut demand\xE9 + // attribut demandé let attribute_name = elem.substring(0, elem.indexOf("}")).substr(1); let carac = caracOfMod(attribute_name); let replacement; @@ -5468,12 +5470,12 @@ var COFantasy = COFantasy || function() { act.indexOf('--enVue') == -1 && act.indexOf('--disque') == -1 && act.indexOf('--target ' + tid) == -1) { - //Si on n'a pas de cible, on fait comme si le token \xE9tait s\xE9lectionn\xE9. + //Si on n'a pas de cible, on fait comme si le token était sélectionné. let add_token = " --target " + tid; if (act.indexOf(' --allie') >= 0) { if (act.indexOf('--lanceur') == -1) add_token = " --lanceur " + tid; - else add_token = ""; //La cible sont les alli\xE9s de --lanceur. + else add_token = ""; //La cible sont les alliés de --lanceur. } if (act.indexOf(' --message ') != -1) act = act.replace(' --message ', add_token + ' --message '); else act += add_token; @@ -5509,8 +5511,8 @@ var COFantasy = COFantasy || function() { } } - //Fonction s\xE9par\xE9e pour pouvoir envoyer un frame \xE0 plusieurs joueurs - // playerId peut \xEAtre undefined (en particulier pour envoyer au mj) + //Fonction séparée pour pouvoir envoyer un frame à plusieurs joueurs + // playerId peut être undefined (en particulier pour envoyer au mj) function addFramedHeader(display, playerId, chuchote) { let perso1 = display.perso1; let perso2 = display.perso2; @@ -5648,9 +5650,9 @@ var COFantasy = COFantasy || function() { display.header = res; } - //Si options.chuchote est vrai, la frame est chuchot\xE9e au joueur qui fait l'action - //Si options.chuchote est un nom, on chuchote la frame \xE0 ce nom - //Pour retarder la d\xE9cision sur la cible de chuchotement, utiliser options.retarder + //Si options.chuchote est vrai, la frame est chuchotée au joueur qui fait l'action + //Si options.chuchote est un nom, on chuchote la frame à ce nom + //Pour retarder la décision sur la cible de chuchotement, utiliser options.retarder function startFramedDisplay(playerId, action, perso, options) { options = options || {}; if (options.secret) { @@ -5721,7 +5723,7 @@ var COFantasy = COFantasy || function() { display.output += ""; } - //newLine indique qu'on commence une nouvelle rang\xE9e + //newLine indique qu'on commence une nouvelle rangée function addCellInFramedDisplay(display, cell, size, newLine, fond) { size = size || 100; if (display.endColumn) { @@ -5733,7 +5735,8 @@ var COFantasy = COFantasy || function() { display.output += '' + cell + ''; } - function endFramedDisplay(display) { + //Termine le carde et l'envoie dans le chat + function sendFramedDisplay(display) { if (display.header === undefined) { error("Pas de titre pour le cadre", display); return; @@ -5741,7 +5744,7 @@ var COFantasy = COFantasy || function() { let res = display.header + display.output; res += ''; // line_content res += ''; // all_content - return res; + sendChat('', res); } function nomLimiteCapa(capa, unite) { @@ -5760,7 +5763,7 @@ var COFantasy = COFantasy || function() { nomLimite += 'Jour'; break; default: - error("Unit\xE9 d'utilisation de capacit\xE9 " + capa + " non reconnue", unite); + error("Unité d'utilisation de capacité " + capa + " non reconnue", unite); return; } return nomLimite + '__' + capa; @@ -5793,14 +5796,14 @@ var COFantasy = COFantasy || function() { expliquer("Perte de substance : -10 aux interactions sociales"); bonus -= 10; if (perteDeSubstance >= 15) { - expliquer("Perte de substance : faire un test de CHA 15 pour se faire remarquer \xE0 chaque tour"); + expliquer("Perte de substance : faire un test de CHA 15 pour se faire remarquer à chaque tour"); } } } return bonus; } - //expliquer est optionnel, et si pr\xE9sent, il faut msg + //expliquer est optionnel, et si présent, il faut msg function malusArmure(personnage, expliquer, msg) { let malusArmure = 0; if (personnage.malusArmure === undefined) { @@ -5825,7 +5828,7 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'graceFelineVoleur')) { let bonusGraceFeline = modCarac(personnage, 'charisme'); if (bonusGraceFeline > 0) { - expliquer("Gr\xE2ce f\xE9line : +" + bonusGraceFeline + " en acrobaties"); + expliquer("Grâce féline : +" + bonusGraceFeline + " en acrobaties"); bonus += bonusGraceFeline; } } @@ -5835,7 +5838,7 @@ var COFantasy = COFantasy || function() { } let a = predicateAsInt(personnage, 'ameFeline', 0); if (a > 0) { - expliquer("\xC2me f\xE9line : +" + a + " en acrobaties"); + expliquer("Âme féline : +" + a + " en acrobaties"); bonus += a; } break; @@ -5850,18 +5853,18 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'graceFelineVoleur')) { let bonusGraceFeline = modCarac(personnage, 'charisme'); if (bonusGraceFeline > 0) { - expliquer("Gr\xE2ce f\xE9line : +" + bonusGraceFeline + " en course"); + expliquer("Grâce féline : +" + bonusGraceFeline + " en course"); bonus += bonusGraceFeline; } } let a = predicateAsInt(personnage, 'ameFeline', 0); if (a > 0) { - expliquer("\xC2me f\xE9line : +" + a + " en course"); + expliquer("Âme féline : +" + a + " en course"); bonus += a; } a = predicateAsInt(personnage, 'vitesseDuFelin', 0); if (a > 0) { - expliquer("Vitesse du f\xE9lin : +" + a + " en course"); + expliquer("Vitesse du félin : +" + a + " en course"); bonus += a; } break; @@ -5872,10 +5875,10 @@ var COFantasy = COFantasy || function() { bonus += 5; } break; - case 'discr\xE9tion': + case 'discrétion': case 'discretion': if (attributeAsBool(personnage, 'foretVivanteEnnemie')) { - expliquer("For\xEAt hostile : -5 en discr\xE9tion"); + expliquer("Forêt hostile : -5 en discrétion"); bonus -= 5; } let perteDeSubstance = 0; @@ -5883,31 +5886,31 @@ var COFantasy = COFantasy || function() { perteDeSubstance = attributeAsInt(personnage, 'perteDeSubstance', 0); if (perteDeSubstance >= 5) { if (perteDeSubstance < 7) { - expliquer("Perte de substance : +2 en discr\xE9tion"); + expliquer("Perte de substance : +2 en discrétion"); bonus += 2; } else if (perteDeSubstance < 10) { - expliquer("Perte de substance : +5 en discr\xE9tion"); + expliquer("Perte de substance : +5 en discrétion"); bonus += 5; } else { - expliquer("Perte de substance : +10 en discr\xE9tion"); + expliquer("Perte de substance : +10 en discrétion"); bonus += 10; } } if (predicateAsBool(personnage, 'toutPetit') && !attributeAsBool(personnage, 'grandeTaille')) { - expliquer("Tout petit : +5 en discr\xE9tion"); + expliquer("Tout petit : +5 en discrétion"); bonus += 5; } break; case 'intimidation': bonus += bonusArgumentDeTaille(personnage, expliquer); if (predicateAsBool(personnage, 'ordreDuChevalierDragon') && attributeAsBool(personnage, 'monteSur')) { - expliquer("Chevalier Dragon mont\xE9 : +5 en intimidation"); + expliquer("Chevalier Dragon monté : +5 en intimidation"); bonus += 5; } bonus += bonusInteractionsSociales(personnage, expliquer); if (predicateAsBool(personnage, 'batonDesRunesMortes') && (attributeAsBool(personnage, 'runeLizura') || attributeAsBool(personnage, 'runeMitrah'))) { - expliquer("Recouvert" + eForFemale(personnage) + " de la boue noire du b\xE2ton : +5 aux tests d'intimidation"); + expliquer("Recouvert" + eForFemale(personnage) + " de la boue noire du bâton : +5 aux tests d'intimidation"); bonus += 5; } break; @@ -5916,18 +5919,18 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'graceFelineVoleur')) { let bonusGraceFeline = modCarac(personnage, 'charisme'); if (bonusGraceFeline > 0) { - expliquer("Gr\xE2ce f\xE9line : +" + bonusGraceFeline + " en escalade"); + expliquer("Grâce féline : +" + bonusGraceFeline + " en escalade"); bonus += bonusGraceFeline; } } let a = predicateAsInt(personnage, 'ameFeline', 0); if (a > 0) { - expliquer("\xC2me f\xE9line : +" + a + " en escalade"); + expliquer("Âme féline : +" + a + " en escalade"); bonus += a; } a = predicateAsInt(personnage, 'vitesseDuFelin', 0); if (a > 0) { - expliquer("Vitesse du f\xE9lin : +" + a + " en escalade"); + expliquer("Vitesse du félin : +" + a + " en escalade"); bonus += a; } break; @@ -5935,20 +5938,20 @@ var COFantasy = COFantasy || function() { case 'mentir': bonus += bonusInteractionsSociales(personnage, expliquer); break; - case 'n\xE9gociation': + case 'négociation': case 'negociation': bonus += bonusArgumentDeTaille(personnage, expliquer); bonus += bonusInteractionsSociales(personnage, expliquer); break; case 'orientation': if (attributeAsBool(personnage, 'foretVivanteEnnemie')) { - expliquer("For\xEAt hostile : -5 en orientation"); + expliquer("Forêt hostile : -5 en orientation"); bonus -= 5; } break; case 'perception': if (attributeAsBool(personnage, 'foretVivanteEnnemie')) { - expliquer("For\xEAt hostile : -5 en perception"); + expliquer("Forêt hostile : -5 en perception"); bonus -= 5; } if (compagnonPresent(personnage, 'guetteur')) { @@ -5964,7 +5967,7 @@ var COFantasy = COFantasy || function() { case 'persuasion': bonus += bonusArgumentDeTaille(personnage, expliquer); if (predicateAsBool(personnage, 'ordreDuChevalierDragon') && attributeAsBool(personnage, 'monteSur')) { - expliquer("Chevalier Dragon mont\xE9 : +5 en persuasion"); + expliquer("Chevalier Dragon monté : +5 en persuasion"); bonus += 5; } bonus += bonusInteractionsSociales(personnage, expliquer); @@ -5975,25 +5978,25 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'graceFelineVoleur')) { let bonusGraceFeline = modCarac(personnage, 'charisme'); if (bonusGraceFeline > 0) { - expliquer("Gr\xE2ce f\xE9line : +" + bonusGraceFeline + " en saut"); + expliquer("Grâce féline : +" + bonusGraceFeline + " en saut"); bonus += bonusGraceFeline; } } let a = predicateAsInt(personnage, 'ameFeline', 0); if (a > 0) { - expliquer("\xC2me f\xE9line : +" + a + " en saut"); + expliquer("Âme féline : +" + a + " en saut"); bonus += a; } a = predicateAsInt(personnage, 'vitesseDuFelin', 0); if (a > 0) { - expliquer("Vitesse du f\xE9lin : +" + a + " en saut"); + expliquer("Vitesse du félin : +" + a + " en saut"); bonus += a; } break; } case 'survie': if (attributeAsBool(personnage, 'foretVivanteEnnemie')) { - expliquer("For\xEAt hostile : -5 en survie"); + expliquer("Forêt hostile : -5 en survie"); bonus -= 5; } break; @@ -6021,7 +6024,7 @@ var COFantasy = COFantasy || function() { let bonusChantDesHeros = getIntValeurOfEffet(personnage, 'chantDesHeros', 1); let chantDesHerosIntense = attributeAsInt(personnage, 'chantDesHerosTempeteDeManaIntense', 0); bonusChantDesHeros += chantDesHerosIntense; - expliquer("Chant des h\xE9ros : +" + bonusChantDesHeros + " au jet"); + expliquer("Chant des héros : +" + bonusChantDesHeros + " au jet"); bonus += bonusChantDesHeros; if (chantDesHerosIntense && evt) removeTokenAttr(personnage, 'chantDesHerosTempeteDeManaIntense', evt); @@ -6030,7 +6033,7 @@ var COFantasy = COFantasy || function() { let bonusBenediction = getIntValeurOfEffet(personnage, 'benediction', 1); let benedictionIntense = attributeAsInt(personnage, 'benedictionTempeteDeManaIntense', 0); bonusBenediction += benedictionIntense; - expliquer("B\xE9n\xE9diction : +" + bonusBenediction + " au jet"); + expliquer("Bénédiction : +" + bonusBenediction + " au jet"); bonus += bonusBenediction; if (benedictionIntense && evt) removeTokenAttr(personnage, 'benedictionTempeteDeManaIntense', evt); @@ -6045,7 +6048,7 @@ var COFantasy = COFantasy || function() { removeTokenAttr(personnage, 'inspirationTempeteDeManaIntense', evt); } if (attributeAsBool(personnage, 'lameDeLigneePerdue')) { - expliquer("Lame de lign\xE9e perdue : -1 au jet"); + expliquer("Lame de lignée perdue : -1 au jet"); bonus -= 1; } if (attributeAsBool(personnage, 'strangulation')) { @@ -6056,7 +6059,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'nueeDInsectes')) { let malusNuee = 2 + attributeAsInt(personnage, 'nueeDInsectesTempeteDeManaIntense', 0); - expliquer("Nu\xE9e d\'insectes : -" + malusNuee + " au jet"); + expliquer("Nuée d\'insectes : -" + malusNuee + " au jet"); bonus -= malusNuee; if (malusNuee > 2 && evt) removeTokenAttr(personnage, 'nueeDInsectesTempeteDeManaIntense', evt); @@ -6064,13 +6067,13 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(personnage, 'nueeDeCriquets')) { let malusNueeCriquets = 3 + attributeAsInt(personnage, 'nueeDeCriquetsTempeteDeManaIntense', 0); - expliquer("Nu\xE9e de criquets : -" + malusNueeCriquets + " au jet"); + expliquer("Nuée de criquets : -" + malusNueeCriquets + " au jet"); bonus -= malusNueeCriquets; if (malusNueeCriquets > 3 && evt) removeTokenAttr(personnage, 'nueeDeCriquetsTempeteDeManaIntense', evt); } if (attributeAsBool(personnage, 'nueeDeScorpions')) { - expliquer("Nu\xE9e de scorpions : -3 au jet"); + expliquer("Nuée de scorpions : -3 au jet"); bonus -= 3; } if (attributeAsBool(personnage, 'etatExsangue')) { @@ -6078,12 +6081,12 @@ var COFantasy = COFantasy || function() { bonus -= 2; } if (attributeAsBool(personnage, 'putrefactionOutrTombe')) { - expliquer("Putr\xE9fi\xE9 : -2 au jet"); + expliquer("Putréfié : -2 au jet"); bonus -= 2; } let fortifie = attributeAsInt(personnage, 'fortifie', 0); if (fortifie > 0) { - expliquer("Fortifi\xE9 : +3 au jet"); + expliquer("Fortifié : +3 au jet"); bonus += 3; if (evt) { fortifie--; @@ -6098,18 +6101,18 @@ var COFantasy = COFantasy || function() { !predicateAsBool(personnage, 'porteurDuBouclierDeGrabuge') && !attributeAsBool(personnage, 'sangDeLArbreCoeur')) { let malusOndesCorruptrices = attributeAsInt(personnage, 'ondesCorruptrices', 2); - let msgOndesCorruptrices = "Naus\xE9eu" + onGenre(personnage, "x", "se"); + let msgOndesCorruptrices = "Nauséeu" + onGenre(personnage, "x", "se"); msgOndesCorruptrices += " : -" + malusOndesCorruptrices; expliquer(msgOndesCorruptrices + " aux tests"); bonus -= malusOndesCorruptrices; } if (attributeAsBool(personnage, 'fievreux')) { bonus -= 2; - expliquer("Fi\xE9vreu" + onGenre(personnage, 'x', 'se') + " : -2 aux tests"); + expliquer("Fiévreu" + onGenre(personnage, 'x', 'se') + " : -2 aux tests"); } if (attributeAsBool(personnage, 'secoue')) { bonus -= 2; - expliquer("Secou\xE9" + eForFemale(personnage) + " : -2 aux tests"); + expliquer("Secoué" + eForFemale(personnage) + " : -2 aux tests"); } let bonusCondition = attributeAsInt(personnage, 'modificateurTests', 0); if (bonusCondition != 0) { @@ -6117,7 +6120,7 @@ var COFantasy = COFantasy || function() { if (bonusCondition > 0) { expliquer("Bonus de condition : +" + bonusCondition); } else { - expliquer("P\xE9nalit\xE9 de condition : " + bonusCondition); + expliquer("Pénalité de condition : " + bonusCondition); } } if (attributeAsBool(personnage, 'sensDuDevoir')) { @@ -6149,7 +6152,7 @@ var COFantasy = COFantasy || function() { options.bonusPreds.forEach(function(pred) { let bonusPred = predicateAsInt(personnage, pred, 0); if (bonusPred !== 0) { - expliquer("Pr\xE9dicat " + pred + " : " + ((bonusPred < 0) ? "-" : "+") + bonusPred); + expliquer("Prédicat " + pred + " : " + ((bonusPred < 0) ? "-" : "+") + bonusPred); bonus += bonusPred; } }); @@ -6206,12 +6209,12 @@ var COFantasy = COFantasy || function() { } //retourne un entier - // evt n'est d\xE9fini que si la caract\xE9ristique est effectivement utilis\xE9e + // evt n'est défini que si la caractéristique est effectivement utilisée function bonusTestCarac(carac, personnage, options, testId, evt, explications) { const expliquer = function(msg) { if (explications) explications.push(msg); }; - // D'abord la partie qui d\xE9pend de la caract\xE9ristique + // D'abord la partie qui dépend de la caractéristique let bonus = modCarac(personnage, caracOfMod(carac)); if (!persoEstPNJ(personnage)) { bonus += ficheAttributeAsInt(personnage, carac + "_BONUS", 0); @@ -6235,11 +6238,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'aspectDuDemon')) { bonusAspectDuDemon = getIntValeurOfEffet(personnage, 'aspectDuDemon', 2); - expliquer("Aspect du d\xE9mon : +" + bonusAspectDuDemon + " au jet de DEX"); + expliquer("Aspect du démon : +" + bonusAspectDuDemon + " au jet de DEX"); bonus += bonusAspectDuDemon; } if (attributeAsBool(personnage, 'osBrises')) { - expliquer("Des os sont bris\xE9s : -2 au jet de DEX"); + expliquer("Des os sont brisés : -2 au jet de DEX"); bonus -= 2; } if (attributeAsBool(personnage, 'espaceExigu')) { @@ -6252,19 +6255,19 @@ var COFantasy = COFantasy || function() { bonus -= 1; } if (attributeAsBool(personnage, 'reactionAllergique')) { - expliquer("D\xE9mangeaisons : -2 au jet de DEX"); + expliquer("Démangeaisons : -2 au jet de DEX"); bonus -= 2; } let conditions = attributeAsInt(personnage, 'conditionsHostiles', 0, 2); if (conditions > 0 && (!predicateAsBool(personnage, 'marcheSylvestre') || conditions > 4)) { let msgConditions = "Conditions "; if (conditions < 5) msgConditions += "hostiles"; - else msgConditions += "extr\xEAmes"; + else msgConditions += "extrêmes"; msgConditions += " : -" + conditions + " au jet de DEX"; expliquer(msgConditions); bonus -= conditions; } - if (expertiseSpecialisee == 'dex' || expertiseSpecialisee == 'dexterite' || expertiseSpecialisee == 'dext\xE9rit\xE9') { + if (expertiseSpecialisee == 'dex' || expertiseSpecialisee == 'dexterite' || expertiseSpecialisee == 'dextérité') { expliquer("Expertise : +5 aux jets de DEX"); bonus += 5; } @@ -6283,11 +6286,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'aspectDuDemon')) { bonusAspectDuDemon = getIntValeurOfEffet(personnage, 'aspectDuDemon', 2); - expliquer("Aspect du d\xE9mon : +" + bonusAspectDuDemon + " au jet de FOR"); + expliquer("Aspect du démon : +" + bonusAspectDuDemon + " au jet de FOR"); bonus += bonusAspectDuDemon; } if (attributeAsBool(personnage, 'osBrises')) { - expliquer("Des os sont bris\xE9s : -2 au jet de FOR"); + expliquer("Des os sont brisés : -2 au jet de FOR"); bonus -= 2; } if (attributeAsBool(personnage, 'espaceExigu')) { @@ -6308,7 +6311,7 @@ var COFantasy = COFantasy || function() { bonusInt += ficheAttributeAsInt(personnage, "INT_BONUS", 0); } if (bonusInt > bonusCarac) { - let msgGrosseTete = "Grosse t\xEAte : "; + let msgGrosseTete = "Grosse tête : "; if (bonusInt > 0) msgGrosseTete += '+'; msgGrosseTete += bonusInt + " au lieu de "; if (bonusCarac > 0) msgGrosseTete += '+'; @@ -6321,7 +6324,7 @@ var COFantasy = COFantasy || function() { if (conditions > 0 && (!predicateAsBool(personnage, 'marcheSylvestre') || conditions > 4)) { let msgConditions = "Conditions "; if (conditions < 5) msgConditions += "hostiles"; - else msgConditions += "extr\xEAmes"; + else msgConditions += "extrêmes"; msgConditions += " : -" + conditions + " au jet de FOR"; expliquer(msgConditions); bonus -= conditions; @@ -6336,7 +6339,7 @@ var COFantasy = COFantasy || function() { { if (attributeAsBool(personnage, 'secretsDeLAuDela')) { bonus += 5; - expliquer("Secrets de l'au-del\xE0 : +5"); + expliquer("Secrets de l'au-delà : +5"); } if (expertiseSpecialisee == 'int' || expertiseSpecialisee == 'intelligence') { expliquer("Expertise : +5 aux jets d'INT"); @@ -6358,7 +6361,7 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'batonDesRunesMortes') && (attributeAsBool(personnage, 'runeLizura') || attributeAsBool(personnage, 'runeMitrah'))) { if (!options.competence || options.competence.trim().toLowerCase() != 'intimidation') { - expliquer("Recouvert" + eForFemale(personnage) + " de la boue noire du b\xE2ton : -10 aux tests de CHA"); + expliquer("Recouvert" + eForFemale(personnage) + " de la boue noire du bâton : -10 aux tests de CHA"); bonus -= 10; } } @@ -6377,13 +6380,13 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'controleDuMetabolisme')) { let mod = modCarac(personnage, 'charisme'); if (mod > 0) { - expliquer("Controle du m\xE9tabolisme : +" + mod + " au jet de CON"); + expliquer("Controle du métabolisme : +" + mod + " au jet de CON"); bonus += mod; } } if (attributeAsBool(personnage, 'aspectDuDemon')) { bonusAspectDuDemon = getIntValeurOfEffet(personnage, 'aspectDuDemon', 2); - expliquer("Aspect du d\xE9mon : +" + bonusAspectDuDemon + " au jet de CON"); + expliquer("Aspect du démon : +" + bonusAspectDuDemon + " au jet de CON"); bonus += bonusAspectDuDemon; } if (expertiseSpecialisee == 'con' || expertiseSpecialisee == 'constitution') { @@ -6432,7 +6435,7 @@ var COFantasy = COFantasy || function() { } } } else { - let msgComp = "Comp\xE9tence " + options.competence + " : "; + let msgComp = "Compétence " + options.competence + " : "; if (bonusCompetence === 0) { msgComp += 0; } else { @@ -6462,7 +6465,7 @@ var COFantasy = COFantasy || function() { // Puis la partie commune options = options || {}; bonus += bonusTestToutesCaracs(personnage, options, testId, evt, expliquer); - //Pas besoin de mettre la valeur de caract\xE9ristique si c'est le seul bonus + //Pas besoin de mettre la valeur de caractéristique si c'est le seul bonus if (explications && explications.length == 1) explications.pop(); return bonus; } @@ -6524,7 +6527,7 @@ var COFantasy = COFantasy || function() { fct = tremblementDeTerre; break; default: - error("Impossible de trouver la fonction li\xE9e \xE0 l'effet " + e, ev); + error("Impossible de trouver la fonction liée à l'effet " + e, ev); return; } } @@ -6540,38 +6543,38 @@ var COFantasy = COFantasy || function() { let pl = getPlayerIds(perso); if (pl === undefined) return; let playerId; - if (pl.length > 0) playerId = pl[0]; //Utilis\xE9 juste pour la couleur + if (pl.length > 0) playerId = pl[0]; //Utilisé juste pour la couleur let display = startFramedDisplay(playerId, titre, perso, { chuchote: 'GM' }); switch (d6.val) { case 1: { - let commande = '!cof-dmg 4d6 --psave DEX 15 --titre \xC9boulement majeur'; - addLineToFramedDisplay(display, "\xC9boulement majeur : s\xE9lectionnez les tokens dans la zone et " + boutonSimple(commande, 'cliquez ici')); + let commande = '!cof-dmg 4d6 --psave DEX 15 --titre Éboulement majeur'; + addLineToFramedDisplay(display, "Éboulement majeur : sélectionnez les tokens dans la zone et " + boutonSimple(commande, 'cliquez ici')); break; } case 2: case 3: { - let commande = '!cof-dmg 2d6 --psave DEX 15 --titre \xC9boulement mineur'; - addLineToFramedDisplay(display, "\xC9boulement mineur : choisissez un personnage au hasard et " + boutonSimple(commande, 'cliquez ici')); + let commande = '!cof-dmg 2d6 --psave DEX 15 --titre Éboulement mineur'; + addLineToFramedDisplay(display, "Éboulement mineur : choisissez un personnage au hasard et " + boutonSimple(commande, 'cliquez ici')); break; } case 6: { let commande = '!cof-set-state renverse true --save DEX 12'; - addLineToFramedDisplay(display, "Le sol tremble et se fissure : s\xE9lectionnez les personnages dans une zone d'environ 10 m\xE8tres et " + boutonSimple(commande, 'cliquez ici')); + addLineToFramedDisplay(display, "Le sol tremble et se fissure : sélectionnez les personnages dans une zone d'environ 10 mètres et " + boutonSimple(commande, 'cliquez ici')); break; } default: // 4 ou 5 { let commande = '!cof-effet-temp tremblementMineur 1'; - addLineToFramedDisplay(display, "Tremblement mineur : s\xE9lectionnez les personnages dans la zone et " + boutonSimple(commande, 'cliquez ici')); + addLineToFramedDisplay(display, "Tremblement mineur : sélectionnez les personnages dans la zone et " + boutonSimple(commande, 'cliquez ici')); break; } } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } function foudreDuTemps(perso, d20roll) { @@ -6582,14 +6585,14 @@ var COFantasy = COFantasy || function() { let pl = getPlayerIds(perso); if (pl === undefined) return; let playerId; - if (pl.length > 0) playerId = pl[0]; //Utilis\xE9 juste pour la couleur + if (pl.length > 0) playerId = pl[0]; //Utilisé juste pour la couleur let display = startFramedDisplay(playerId, titre, perso); let explications = []; let np = nomPerso(perso); switch (d6.val) { case 1: { - addLineToFramedDisplay(display, np + " est frapp\xE9" + eForFemale(perso) + " de plein fouet !"); + addLineToFramedDisplay(display, np + " est frappé" + eForFemale(perso) + " de plein fouet !"); let options = { partialSave: { carac: 'DEX', @@ -6621,11 +6624,11 @@ var COFantasy = COFantasy || function() { dmg.display = buildinline(dmg.roll.inlinerolls[dmgRollNumber], dmg.type); dealDamage(perso, dmg, [], evt, false, options, explications, function(dmgDisplay, dmgFinal) { addLineToFramedDisplay(display, - np + " re\xE7oit " + dmgDisplay + " DM"); + np + " reçoit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); return; @@ -6639,7 +6642,7 @@ var COFantasy = COFantasy || function() { save: { carac: 'FOR', seuil: 10, - msgPour: "pour ne pas \xEAtre tomber" + msgPour: "pour ne pas être tomber" } }; let evt = { @@ -6655,7 +6658,7 @@ var COFantasy = COFantasy || function() { addEvent(evt); let saveOpts = { msgPour: options.msgPour, - msgRate: ", rat\xE9.", + msgRate: ", raté.", }; let expliquer = function(s) { explications.push(s); @@ -6668,7 +6671,7 @@ var COFantasy = COFantasy || function() { textDist = distance.val / 2; seuil = 2; } - textDist += distance.val > seuil ? ' m\xE8tres' : ' m\xE8tre'; + textDist += distance.val > seuil ? ' mètres' : ' mètre'; sendChat('', '[[2d6]]', function(resDmg) { let afterEvaluateDmg = resDmg[0].content.split(' '); let dmgRollNumber = rollNumber(afterEvaluateDmg[0]); @@ -6678,16 +6681,16 @@ var COFantasy = COFantasy || function() { type: 'electrique' }; dealDamage(perso, dmg, [], evt, false, options, explications, function(dmgDisplay, dmgFinal) { - addLineToFramedDisplay(display, np + " est projet\xE9" + eForFemale(perso) + " de " + textDist + " par la foudre, et subit " + dmgDisplay + " DM"); + addLineToFramedDisplay(display, np + " est projeté" + eForFemale(perso) + " de " + textDist + " par la foudre, et subit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); if (reussite) { - addLineToFramedDisplay(display, np + " r\xE9siste, la distance de projection passe de " + distance.roll + " \xE0 " + (distance.val / 2)); + addLineToFramedDisplay(display, np + " résiste, la distance de projection passe de " + distance.roll + " à " + (distance.val / 2)); } else { setState(perso, 'renverse', true, evt); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); }); @@ -6697,14 +6700,14 @@ var COFantasy = COFantasy || function() { { addLineToFramedDisplay(display, np + " est dans la zone d'impact !"); if (getState(perso, 'affaibli')) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } let options = { save: { carac: 'CON', seuil: 10, - msgPour: ' pour ne pas \xEAtre affaibli' + eForFemale(perso) + msgPour: ' pour ne pas être affaibli' + eForFemale(perso) } }; const evt = { @@ -6732,17 +6735,17 @@ var COFantasy = COFantasy || function() { return ficheAttributeAsInt(perso, 'pc', 3); } - // Test de caract\xE9ristique + // Test de caractéristique // options : bonusAttrs, bonusPreds, bonus, roll - // Apr\xE8s le test, lance callback(testRes, explications - // testRes.texte est l'affichage du jet de d\xE9 - // testRes.reussite indique si le jet est r\xE9ussi + // Après le test, lance callback(testRes, explications + // testRes.texte est l'affichage du jet de dé + // testRes.reussite indique si le jet est réussi // testRes.echecCritique, testRes.critique pour le type // testRes.valeur pour la valeur totale du jet - // testRes.rerolls pour le texte avec les boutons de rerolls adapt\xE9s. - // testRes.modifiers pour les boutons qui peuvent \xEAtre activ\xE9s sur le roll, qu'il soit r\xE9ussi ou non. - // Pour que les boutons de rerolls fonctionnent, le type d'\xE9v\xE8nement doit \xEAtre support\xE9 par redoEvent() - // ne rajoute pas evt \xE0 l'historique + // testRes.rerolls pour le texte avec les boutons de rerolls adaptés. + // testRes.modifiers pour les boutons qui peuvent être activés sur le roll, qu'il soit réussi ou non. + // Pour que les boutons de rerolls fonctionnent, le type d'évènement doit être supporté par redoEvent() + // ne rajoute pas evt à l'historique function testCaracteristique(personnage, carac, seuil, testId, options, evt, callback) { //asynchrone options = options || {}; let testRes = {}; @@ -6846,10 +6849,10 @@ var COFantasy = COFantasy || function() { boutonSimple("!cof-bouton-chance " + evt.id + " " + testId, "Chance") + " (reste " + pc + " PC)"; } - if (stateCOF.combat && attributeAsBool(personnage, 'runeForgesort_\xE9nergie') && - attributeAsInt(personnage, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0 && + if (stateCOF.combat && attributeAsBool(personnage, 'runeForgesort_énergie') && + attributeAsInt(personnage, 'limiteParCombat_runeForgesort_énergie', 1) > 0 && (carac == 'FOR' || carac == 'CON' || carac == 'DEX')) { - testRes.rerolls += '
' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'\xE9nergie"); + testRes.rerolls += '
' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'énergie"); } if (stateCOF.combat && capaciteDisponible(personnage, 'petitVeinard', 'combat')) { testRes.rerolls += '
' + boutonSimple("!cof-bouton-petit-veinard " + evt.id + " " + testId, "Petit veinard"); @@ -6870,18 +6873,18 @@ var COFantasy = COFantasy || function() { testRes.modifiers += "
" + boutonSimple("!cof-pacte-sanglant " + evt.id + " 5 " + testId, "Pacte sanglant (+5)"); } } - if (jetCache) sendChat('COF', "/w GM Jet cach\xE9 : " + buildinline(roll) + bonusText); + if (jetCache) sendChat('COF', "/w GM Jet caché : " + buildinline(roll) + bonusText); callback(testRes, explications); }); } catch (e) { - error("Erreur pendant l'\xE9valuation de " + rollExpr + " dans un test de caract\xE9ristiques"); + error("Erreur pendant l'évaluation de " + rollExpr + " dans un test de caractéristiques"); log(e.name + ": " + e.message); } } //callback peut prendre en argument une structure avec les champs: // - texte: Le texte du jet - // - total : Le r\xE9sultat total du jet + // - total : Le résultat total du jet // - echecCritique, critique pour indiquer si 1 ou 20 // - roll: le inlineroll function jetCaracteristique(personnage, carac, options, testId, evt, callback) { @@ -6922,15 +6925,15 @@ var COFantasy = COFantasy || function() { total: d20roll + bonusCarac, }; if (d20roll <= plageEC) { - rtext += " -> \xE9chec critique"; + rtext += " -> échec critique"; rt.echecCritique = true; } else if (d20roll == 20) { - rtext += " -> r\xE9ussite critique"; + rtext += " -> réussite critique"; rt.critique = true; } else if (bonusCarac !== 0 && !jetCache) rtext += " = " + rt.total; rt.texte = rtext; rt.roll = roll; - if (jetCache) sendChat('COF', "/w GM Jet cach\xE9 de caract\xE9ristique : " + buildinline(roll) + bonusText); + if (jetCache) sendChat('COF', "/w GM Jet caché de caractéristique : " + buildinline(roll) + bonusText); callback(rt, explications); }); } @@ -6952,9 +6955,9 @@ var COFantasy = COFantasy || function() { } if (display.retarde) { addFramedHeader(display, cmd[1], false); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } @@ -6978,12 +6981,12 @@ var COFantasy = COFantasy || function() { }; addLineToFramedDisplay(display, boutonSimple('!cof-montrer-resultats-jet ' + playerId, "Montrer aux joueurs")); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); if (!playerIsGM(playerId)) { let dest = joueurJ.get('displayname'); if (dest.includes('"')) { sendChat('COF', display.action); - log("Impossible d'envoyer des messages priv\xE9s \xE0 " + dest + " car le nom contient des guillemets"); + log("Impossible d'envoyer des messages privés à " + dest + " car le nom contient des guillemets"); } sendChat('COF', '/w "' + dest + '" ' + display.action); } @@ -6992,10 +6995,10 @@ var COFantasy = COFantasy || function() { } if (display.retarde) { addFramedHeader(display, playerId, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); - } else sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); + } else sendFramedDisplay(display); } function jetPerso(perso, caracteristique, difficulte, titre, playerId, options) { @@ -7021,12 +7024,12 @@ var COFantasy = COFantasy || function() { if (difficulte === undefined) { jetCaracteristique(perso, caracteristique, options, testId, evt, function(rt, explications) { - addLineToFramedDisplay(display, "R\xE9sultat : " + rt.texte); + addLineToFramedDisplay(display, "Résultat : " + rt.texte); explications.forEach(function(m) { addLineToFramedDisplay(display, m, 80); }); addStatistics(playerId, ["Jet de carac", caracteristique], rt.roll); - // Maintenant, on diminue la mal\xE9diction si le test est un \xE9chec + // Maintenant, on diminue la malédiction si le test est un échec let attrMalediction = tokenAttribute(perso, 'malediction'); if (attrMalediction.length > 0) { if (rt.echecCritique) @@ -7034,8 +7037,8 @@ var COFantasy = COFantasy || function() { else if (!rt.critique) { let action = "!cof-resultat-jet " + evt.id; let ligne = "L'action est-elle "; - ligne += bouton(action + " reussi", "r\xE9ussie", perso); - ligne += " ou " + bouton(action + " rate", "rat\xE9e", perso); + ligne += bouton(action + " reussi", "réussie", perso); + ligne += " ou " + bouton(action + " rate", "ratée", perso); ligne += " ?"; addLineToFramedDisplay(display, ligne); evt.attenteResultat = true; @@ -7048,10 +7051,10 @@ var COFantasy = COFantasy || function() { '
' + boutonSimple("!cof-bouton-chance " + evt.id + " " + testId, "Chance") + " (reste " + pc + " PC)"; } - if (stateCOF.combat && attributeAsBool(perso, 'runeForgesort_\xE9nergie') && - attributeAsInt(perso, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0 && + if (stateCOF.combat && attributeAsBool(perso, 'runeForgesort_énergie') && + attributeAsInt(perso, 'limiteParCombat_runeForgesort_énergie', 1) > 0 && (caracteristique == 'FOR' || caracteristique == 'CON' || caracteristique == 'DEX')) { - boutonsReroll += '
' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'\xE9nergie"); + boutonsReroll += '
' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'énergie"); } if (stateCOF.combat && capaciteDisponible(perso, 'petitVeinard', 'combat')) { boutonsReroll += '
' + boutonSimple("!cof-bouton-petit-veinard " + evt.id + " " + testId, "Petit veinard"); @@ -7077,14 +7080,15 @@ var COFantasy = COFantasy || function() { } else { testCaracteristique(perso, caracteristique, difficulte, testId, options, evt, function(tr, explications) { - addLineToFramedDisplay(display, "R\xE9sultat : " + tr.texte); + addLineToFramedDisplay(display, "Résultat : " + tr.texte); explications.forEach(function(m) { addLineToFramedDisplay(display, m, 80); }); if (tr.reussite) { - addLineToFramedDisplay(display, "C'est r\xE9ussi." + tr.modifiers); + let msgReussite = options.messageSiSucces || "C'est réussi."; + addLineToFramedDisplay(display, msgReussite + tr.modifiers); } else { - let msgRate = "C'est rat\xE9." + tr.rerolls + tr.modifiers; + let msgRate = "C'est raté." + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, msgRate); } sendDisplayJetPerso(display, playerId, options); @@ -7097,8 +7101,8 @@ var COFantasy = COFantasy || function() { function boutonsCompetences(display, perso, carac, msg, fond) { let action = msg.content; action = action.replace(/ --competences /, ''); - action = action.replace(/ --competences/, ''); //au cas o\xF9 ce serait le dernier argument - let args = action.substring(9); //on enl\xE8ve !cof-jet + action = action.replace(/ --competences/, ''); //au cas où ce serait le dernier argument + let args = action.substring(9); //on enlève !cof-jet if (!args.startsWith(carac)) action = "!cof-jet " + carac + " " + args; let overlay; switch (carac) { @@ -7106,7 +7110,7 @@ var COFantasy = COFantasy || function() { overlay = 'Force'; break; case 'DEX': - overlay = 'Dext\xE9rit\xE9'; + overlay = 'Dextérité'; break; case 'CON': overlay = 'Constitution'; @@ -7153,8 +7157,8 @@ var COFantasy = COFantasy || function() { addCellInFramedDisplay(display, cell, 80, false, fond); } - // prend une distance en m\xE8tre et retourne une distance dans l'unit\xE9 - // utilis\xE9e sur la page du personnage + // prend une distance en mètre et retourne une distance dans l'unité + // utilisée sur la page du personnage function scaleDistance(perso, distance) { if (perso.scale) return distance * perso.scale; let pageId = perso.pageId; @@ -7188,7 +7192,7 @@ var COFantasy = COFantasy || function() { perso.scale = 39.3701; break; default: - sendChat('COF', "Attention, unit\xE9 de mesure de la page (" + unit + ") non reconnue"); + sendChat('COF', "Attention, unité de mesure de la page (" + unit + ") non reconnue"); perso.scale = 1; } return distance * perso.scale; @@ -7210,9 +7214,9 @@ var COFantasy = COFantasy || function() { return pageId; } - // si d\xE9fini, callback est appel\xE9 \xE0 chaque \xE9l\xE9ment de selected + // si défini, callback est appelé à chaque élément de selected // qui n'est pas un personnage - // iter seulement sur les \xE9l\xE9ment qui correspondent \xE0 des personnages + // iter seulement sur les élément qui correspondent à des personnages function iterSelected(selected, iter, callback) { selected.forEach(function(sel) { let token = getObj('graphic', sel._id); @@ -7249,9 +7253,9 @@ var COFantasy = COFantasy || function() { return true; } - //traduction des coordon\xE9es de path en coordon\xE9es r\xE9elles sur la carte + //traduction des coordonées de path en coordonées réelles sur la carte function translatePathCoordinates(x, y, p) { - //D'abord on calcule les coordonn\xE9es relatives au centre + //D'abord on calcule les coordonnées relatives au centre x -= p.width / 2; y -= p.height / 2; //Puis on applique le scale @@ -7262,7 +7266,7 @@ var COFantasy = COFantasy || function() { let s = Math.sin(p.angle); x = c * x + s * y; y = c * y - s * x; - //Et finalement on ajoute les coordonn\xE9es du centre + //Et finalement on ajoute les coordonnées du centre x += p.left; y += p.top; return { @@ -7297,7 +7301,7 @@ var COFantasy = COFantasy || function() { }); return chemin; }); - //On rajoute les portes ferm\xE9es. + //On rajoute les portes fermées. let doors = findObjs({ _type: 'door', _pageid: pageId, @@ -7319,7 +7323,7 @@ var COFantasy = COFantasy || function() { return murs; } - //v\xE9rifie si de la nouvelle position on peut voir le suivi + //vérifie si de la nouvelle position on peut voir le suivi function obstaclePresent(nsx, nsy, pt, murs) { if (nsx == pt.x && nsy == pt.y) return false; let ps = { @@ -7438,7 +7442,7 @@ var COFantasy = COFantasy || function() { if (saufAllies) allies = (new Set(allies)).add(actif.charId); } else { if (msg.selected === undefined || msg.selected.length === 0) { - error("Pas d'alli\xE9 car pas de token s\xE9lectionn\xE9", msg); + error("Pas d'allié car pas de token sélectionné", msg); return; } iterSelected(msg.selected, function(personnage) { @@ -7467,7 +7471,7 @@ var COFantasy = COFantasy || function() { let ci = tok.get('represents'); if (ci === '') return; if (!allies.has(ci)) return; - //On enl\xE8ve le token actif, mais seulement pour allies + //On enlève le token actif, mais seulement pour allies if (cmdSplit[0] == 'allies') { if (actives.indexOf(function(perso) { return perso.charId == ci; @@ -7498,7 +7502,7 @@ var COFantasy = COFantasy || function() { return; case 'target': if (cmdSplit.length < 2) { - error("Il manque l'id de la cible (apr\xE8s --target)", cmd); + error("Il manque l'id de la cible (après --target)", cmd); return; } selected.push({ @@ -7515,7 +7519,7 @@ var COFantasy = COFantasy || function() { centre = actif; rayon = parseInt(cmdSplit[1]); } else { - error("Pas assez d'arguments pour d\xE9finir un disque", cmdSplit); + error("Pas assez d'arguments pour définir un disque", cmdSplit); return; } } else { @@ -7527,7 +7531,7 @@ var COFantasy = COFantasy || function() { rayon = parseInt(cmdSplit[2]); } if (isNaN(rayon) || rayon < 0) { - error("Rayon du disque mal d\xE9fini", cmdSplit); + error("Rayon du disque mal défini", cmdSplit); return; } let tokenCentre = centre.token; @@ -7535,17 +7539,17 @@ var COFantasy = COFantasy || function() { if (cmdSplit.length > 3) { portee = parseInt(cmdSplit[3]); if (isNaN(portee) || portee < 0) { - error("La port\xE9e du disque est mal form\xE9e", cmdSplit); + error("La portée du disque est mal formée", cmdSplit); return; } if (actif === undefined) { - error("Pas de token s\xE9lectionn\xE9 pour calculer la distance du disque", msg); + error("Pas de token sélectionné pour calculer la distance du disque", msg); return; } if (distanceCombat(tokenCentre, actif.token, pageId, { strict1: true }) > portee) { - sendPerso(actif, "Le centre de l'effet est plac\xE9 trop loin (port\xE9e " + portee + " m)"); + sendPerso(actif, "Le centre de l'effet est placé trop loin (portée " + portee + " m)"); return; } } @@ -7571,7 +7575,7 @@ var COFantasy = COFantasy || function() { layer: 'objects' }); allToksDisque.forEach(function(obj) { - if (actif && portee === 0 && obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-m\xEAme + if (actif && portee === 0 && obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-même let objCharId = obj.get('represents'); if (objCharId === '') return; if (getState({ @@ -7596,8 +7600,8 @@ var COFantasy = COFantasy || function() { spawnFx(tokenCentre.get('left'), tokenCentre.get('top'), options.targetFx, pageId); } if (tokenCentre.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir le disque - tokenCentre.remove(); //On l'enl\xE8ve, normalement plus besoin + //C'est juste un token utilisé pour définir le disque + tokenCentre.remove(); //On l'enlève, normalement plus besoin delete options.targetFx; } return; @@ -7607,7 +7611,7 @@ var COFantasy = COFantasy || function() { observateur = persoOfId(cmdSplit[1], cmdSplit[1], pageId); } if (observateur === undefined) { - error("Impossible de trouver la personne \xE0 partir de laquelle on s\xE9lectionne les tokens en vue", msg); + error("Impossible de trouver la personne à partir de laquelle on sélectionne les tokens en vue", msg); return; } page = page || getObj("page", pageId); @@ -7625,7 +7629,7 @@ var COFantasy = COFantasy || function() { layer: 'objects' }); tokensEnVue.forEach(function(obj) { - if (actif && obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-m\xEAme + if (actif && obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-même let objCharId = obj.get('represents'); if (objCharId === '') return; if (obj.get('bar1_max') == 0) return; // jshint ignore:line @@ -7641,12 +7645,12 @@ var COFantasy = COFantasy || function() { return; case 'alliesEnVue': if (actif === undefined) { - error("Impossible de trouver la personne dont on s\xE9lectionne les lli\xE9s en vue", msg); + error("Impossible de trouver la personne dont on sélectionne les lliés en vue", msg); return; } let alliesEnVue = alliesParPerso[actif.charId]; if (alliesEnVue === undefined) { - log("Personnage sans alli\xE9", actif); + log("Personnage sans allié", actif); return; } page = page || getObj("page", pageId); @@ -7664,7 +7668,7 @@ var COFantasy = COFantasy || function() { layer: 'objects' }); tokensAlliesEnVue.forEach(function(obj) { - if (obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-m\xEAme + if (obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-même let objCharId = obj.get('represents'); if (objCharId === '') return; if (!alliesEnVue.has(objCharId)) return; @@ -7704,7 +7708,7 @@ var COFantasy = COFantasy || function() { } } - //msg peut \xEAtre directement le playerId ou un message + //msg peut être directement le playerId ou un message function getPlayerIdFromMsg(msg) { if (msg.playerid === undefined) return msg; let playerId = msg.playerid; @@ -7741,7 +7745,7 @@ var COFantasy = COFantasy || function() { //!cof-jet [carac] [difficulte] // - carac : FOR, DEX, CON, INT, SAG, CHA - // Les tokens s\xE9lectionn\xE9s sont ceux qui doivent faire le jet + // Les tokens sélectionnés sont ceux qui doivent faire le jet function jet(msg) { let opts = msg.content.split(' --'); let cmd = opts.shift().split(' '); @@ -7754,13 +7758,13 @@ var COFantasy = COFantasy || function() { switch (args[0]) { case 'nom': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } args.shift(); let nom = args.join(' '); if (options.nom && options.nom != nom) { - error("Nom du jet d\xE9fini deux fois !", options.nom); + error("Nom du jet défini deux fois !", options.nom); } options.nom = nom; if (options.competence) { @@ -7770,26 +7774,26 @@ var COFantasy = COFantasy || function() { return; case 'attribut': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } options.bonusAttrs.push(args[1]); return; case 'predicat': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } options.bonusPreds.push(args[1]); return; case 'bonus': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } let bonus = parseInt(args[1]); if (isNaN(bonus)) { - error("Le bonus doit \xEAtre un nombre", opts); + error("Le bonus doit être un nombre", opts); return; } options.bonus = (options.bonus || 0) + bonus; @@ -7800,30 +7804,34 @@ var COFantasy = COFantasy || function() { return; case 'plageEchecCritique': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } let plageEC = parseInt(args[1]); if (isNaN(plageEC) || plageEC < 0 || plageEC > 19) { - error("La plage d'\xE9checs critqiques doit \xEAtre un nombre positif inf\xE9rieur \xE0 19", opts); + error("La plage d'échecs critqiques doit être un nombre positif inférieur à 19", opts); return; } options.plageEchecCritique = plageEC; + return; + case 'succes': + options.messageSiSucces = args.slice(1).join(' '); + return; } }); getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Utilisation de !cof-jet sans s\xE9lection de token", playerId); + sendPlayer(msg, "Utilisation de !cof-jet sans sélection de token", playerId); return; } - if (cmd.length < 2) { //On demande la carac et la comp\xE9tence, si d\xE9finies dans un handout Comp\xE9tence + if (cmd.length < 2) { //On demande la carac et la compétence, si définies dans un handout Compétence if (options.nom) { - error("Il manque la caract\xE9ristique \xE0 utiliser pour la comp\xE9tence " + options.nom, msg.content); + error("Il manque la caractéristique à utiliser pour la compétence " + options.nom, msg.content); return; } let fond = listeCompetences.nombre > 25; iterSelected(selected, function(perso) { - let display = startFramedDisplay(playerId, "Jet de caract\xE9ristique", perso, { + let display = startFramedDisplay(playerId, "Jet de caractéristique", perso, { chuchote: true }); startTableInFramedDisplay(display); @@ -7834,7 +7842,7 @@ var COFantasy = COFantasy || function() { boutonsCompetences(display, perso, 'INT', msg); boutonsCompetences(display, perso, 'CHA', msg, fond); endTableInFramedDisplay(display); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); //fin de iterSelected return; } @@ -7848,11 +7856,11 @@ var COFantasy = COFantasy || function() { let display = startFramedDisplay(playerId, "Jet " + deCarac(caracteristique), perso, { chuchote: true }); - addLineToFramedDisplay(display, "Choisissez la comp\xE9tence"); + addLineToFramedDisplay(display, "Choisissez la compétence"); startTableInFramedDisplay(display); boutonsCompetences(display, perso, caracteristique, msg); endTableInFramedDisplay(display); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); //fin de iterSelected return; } @@ -7887,7 +7895,7 @@ var COFantasy = COFantasy || function() { } if (options.bonus) titre += " (" + ((options.bonus > 0) ? '+' : '') + options.bonus + ")"; - if (difficulte !== undefined) titre += " difficult\xE9 " + difficulte; + if (difficulte !== undefined) titre += " difficulté " + difficulte; iterSelected(selected, function(perso) { jetPerso(perso, caracteristique, difficulte, titre, playerId, options); }); //fin de iterSelected @@ -7902,7 +7910,7 @@ var COFantasy = COFantasy || function() { } const evt = findEvent(args[1]); if (evt === undefined) { - error("Le jet est trop ancien ou \xE9te annul\xE9", args); + error("Le jet est trop ancien ou éte annulé", args); return; } if (evt.personnage === undefined) { @@ -7913,12 +7921,12 @@ var COFantasy = COFantasy || function() { let message = evt.type + " "; if (args[2] == 'rate') { diminueMalediction(evt.personnage, evt); - message += "rat\xE9."; - } else message += "r\xE9ussi."; + message += "raté."; + } else message += "réussi."; sendPerso(evt.personnage, message); delete evt.attenteResultat; } else { - sendPlayer(msg, "R\xE9sultat d\xE9j\xE0 d\xE9cid\xE9"); + sendPlayer(msg, "Résultat déjà décidé"); } } @@ -7938,7 +7946,7 @@ var COFantasy = COFantasy || function() { function optionsDeTempeteDeMana(msg) { if (tempeteDeManaCourante.vide) { - error("Pas de temp\xEAte de mana en cours", tempeteDeManaCourante); + error("Pas de tempête de mana en cours", tempeteDeManaCourante); return; } let perso = tempeteDeManaCourante.perso; @@ -7988,7 +7996,7 @@ var COFantasy = COFantasy || function() { tempeteDeManaCourante.intense = it; } } - let title = "Temp\xEAte de mana"; + let title = "Tempête de mana"; if (tempeteDeManaCourante.cout) { title += " de puissance " + tempeteDeManaCourante.cout; } @@ -8003,14 +8011,14 @@ var COFantasy = COFantasy || function() { if (tempeteDeManaCourante.dureeDeBase && tempeteDeManaCourante.dm === undefined && tempeteDeManaCourante.soins === undefined) - ajouterOptionTempete(display, "duree", "Dur\xE9e", restant); + ajouterOptionTempete(display, "duree", "Durée", restant); if (tempeteDeManaCourante.porteeDeBase) - ajouterOptionTempete(display, "portee", "Port\xE9e", restant); + ajouterOptionTempete(display, "portee", "Portée", restant); ajouterOptionTempete(display, "rapide", "Rapide", restant); if (tempeteDeManaCourante.altruistePossible) { let la = 'Magie altruiste : '; if (restant || tempeteDeManaCourante.altruiste) { - let tla = "S\xE9lectionner"; + let tla = "Sélectionner"; if (tempeteDeManaCourante.altruiste) { tla = nomPerso(tempeteDeManaCourante.altruiste); } @@ -8043,7 +8051,7 @@ var COFantasy = COFantasy || function() { } v = v.replace(/--tempeteDeMana/, vopt); addLineToFramedDisplay(display, boutonSimple(v, "Valider")); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } function setTempeteDeMana(playerId, perso, cmd, options) { @@ -8069,7 +8077,7 @@ var COFantasy = COFantasy || function() { if (max === undefined || max > niveau - (mana / cout_par_effet)) max = Math.floor(niveau - (mana / cout_par_effet)); if (max < 1) { - sendPerso(perso, "ne peut pas d\xE9penser plus de mana en temp\xEAte de mana (niveau " + niveau + ", mana d\xE9j\xE0 d\xE9pens\xE9e " + mana + ")"); + sendPerso(perso, "ne peut pas dépenser plus de mana en tempête de mana (niveau " + niveau + ", mana déjà dépensée " + mana + ")"); return; } tempeteDeManaCourante.max = max; @@ -8118,7 +8126,7 @@ var COFantasy = COFantasy || function() { } else { let intensite = parseInt(ta); if (isNaN(ta) || ta <= 0) { - error("Option de temp\xEAte de mana " + ta + " non reconnue", cmd); + error("Option de tempête de mana " + ta + " non reconnue", cmd); break; } options.tempeteDeManaIntense = options.tempeteDeManaIntense || 0; @@ -8225,7 +8233,7 @@ var COFantasy = COFantasy || function() { } case 'predicatCible': if (args.length < 2) { - error("Il manque le pr\xE9dicat de la cible", args); + error("Il manque le prédicat de la cible", args); return; } let valeur; @@ -8253,8 +8261,8 @@ var COFantasy = COFantasy || function() { } let valeurDeAttaque = parseInt(args[1]); if (isNaN(valeurDeAttaque)) { - error("La condition de d\xE9 d'attaque doit \xEAtre un nombre", args); - // on continue expr\xE8s pour tomber dans le cas par d\xE9faut + error("La condition de dé d'attaque doit être un nombre", args); + // on continue exprès pour tomber dans le cas par défaut } else { return { type: 'deAttaque', @@ -8282,7 +8290,7 @@ var COFantasy = COFantasy || function() { function getFx(cmd, argName, obj, funName) { if (cmd.length < 2) { - let errMsg = "Il manque un argument \xE0 l'option --" + argName; + let errMsg = "Il manque un argument à l'option --" + argName; if (funName) errMsg += " de " + funName; sendChat("COF", errMsg); return; @@ -8306,7 +8314,8 @@ var COFantasy = COFantasy || function() { let dm = { nbDe: 0, dice: 4, - bonus: 0 + bonus: 0, + id: generateUUID() }; let exprDM = expr.trim().toLowerCase(); let indexD = exprDM.indexOf('d'); @@ -8314,7 +8323,7 @@ var COFantasy = COFantasy || function() { dm.nbDe = parseInt(exprDM.substring(0, indexD)); if (isNaN(dm.nbDe) || dm.nbDe < 0) { if (msg) - error("Expression de " + msg + ' ' + exprDM + " mal form\xE9e", expr); + error("Expression de " + msg + ' ' + exprDM + " mal formée", expr); return; } exprDM = exprDM.substring(indexD + 1); @@ -8363,12 +8372,12 @@ var COFantasy = COFantasy || function() { } const res = parseCarac(cmd[1]); if (res === undefined) { - error("Le premier argument de save n'est pas une caract\xE9ristique", cmd); + error("Le premier argument de save n'est pas une caractéristique", cmd); return; } res.seuil = parseInt(cmd[2]); if (isNaN(res.seuil)) { - error("Le deuxi\xE8me argument de --psave n'est pas un nombre", cmd); + error("Le deuxième argument de --psave n'est pas un nombre", cmd); return; } if (cmd.length > 3) { @@ -8380,7 +8389,7 @@ var COFantasy = COFantasy || function() { case 'carac': case 'carac2': case 'seuil': - error("Argument suppl\xE9mentaire de save inconnu", cmd); + error("Argument supplémentaire de save inconnu", cmd); return; case 'tempete': let ti = 1; @@ -8392,12 +8401,12 @@ var COFantasy = COFantasy || function() { return; case 'contact': if (oa.length < 2) { - error("Il manque la difficult\xE9 pour les cibles au contact"); + error("Il manque la difficulté pour les cibles au contact"); return; } let diff = parseInt(oa[1]); if (isNaN(diff)) { - error("La difficult\xE9 pour les cibles au contact n'est pas un nombre"); + error("La difficulté pour les cibles au contact n'est pas un nombre"); return; } res.contact = diff; @@ -8411,8 +8420,8 @@ var COFantasy = COFantasy || function() { } //juste le traitement d'une liste d'options - // lastEtat : dernier de etats et effets - // lastType : dernier type de d\xE9g\xE2ts inflig\xE9s + // lastEtat : dernier de etats et effets, pour savoir à quoi appliquer --save + // lastType : dernier type de dégâts infligés // scope : pour les conditionnelles function parseAttackOptions(attaquant, optArgs, lastEtat, lastType, scope, playerId, msg, targetToken, attackLabel, weaponStats, options) { optArgs.forEach(function(arg) { @@ -8483,7 +8492,7 @@ var COFantasy = COFantasy || function() { case 'tirDeBarrage': case 'test': case 'traquenard': - case 'tueurDeGeants': //obsol\xE8te + case 'tueurDeGeants': //obsolète case 'tueurDeGrands': case 'grenaille': case 'attaqueArmeeConjuree': @@ -8501,7 +8510,7 @@ var COFantasy = COFantasy || function() { return; case 'aussiArmeDeJet': if (cmd.length < 2) { - error("Il faut pr\xE9ciser l'arme associ\xE9e \xE0 celle-ci pour --aussiArmeDeJet", cmd); + error("Il faut préciser l'arme associée à celle-ci pour --aussiArmeDeJet", cmd); return; } options.aussiArmeDeJet = cmd[1]; @@ -8511,7 +8520,7 @@ var COFantasy = COFantasy || function() { options.avantage = options.avantage || 1; options.avantage++; return; - case 'd\xE9savantage': + case 'désavantage': case 'desavantage': options.avantage = options.avantage || 1; options.avantage--; @@ -8532,7 +8541,7 @@ var COFantasy = COFantasy || function() { case 'nom': case 'special': if (cmd.length < 1) { - error("Il manque le nom apr\xE8s l'option --" + cmd[0], cmd); + error("Il manque le nom après l'option --" + cmd[0], cmd); return; } options[cmd[0]] = cmd.slice(1).join(' ').trim(); @@ -8540,7 +8549,7 @@ var COFantasy = COFantasy || function() { case 'toucher': case 'modifiePortee': if (cmd.length < 1) { - error("Il manque la valeur apr\xE8s l'option --" + cmd[0], cmd); + error("Il manque la valeur après l'option --" + cmd[0], cmd); return; } let intArg = parseInt(cmd[1]); @@ -8552,7 +8561,7 @@ var COFantasy = COFantasy || function() { return; case 'crit': if (cmd.length < 1) { - error("Il manque la valeur apr\xE8s l'option --crit", cmd); + error("Il manque la valeur après l'option --crit", cmd); return; } let crit = parseInt(cmd[1]); @@ -8566,15 +8575,15 @@ var COFantasy = COFantasy || function() { return; case 'dm': if (cmd.length < 1) { - error("Il manque la valeur apr\xE8s l'option --dm", cmd); + error("Il manque la valeur après l'option --dm", cmd); return; } - let dm = parseDice(cmd.slice(1).join(''), 'd\xE9g\xE2ts'); + let dm = parseDice(cmd.slice(1).join(''), 'dégâts'); if (dm) options.dm = dm; return; case 'portee': if (cmd.length < 1) { - error("Il manque la valeur apr\xE8s l'option --portee", cmd); + error("Il manque la valeur après l'option --portee", cmd); return; } let portee = parseInt(cmd[1]); @@ -8594,7 +8603,7 @@ var COFantasy = COFantasy || function() { return; case 'attaqueMagiqueDe': if (cmd.length < 1) { - error("Il manque le nom du personnage apr\xE8s l'option --attaqueMagiqueDe", cmd); + error("Il manque le nom du personnage après l'option --attaqueMagiqueDe", cmd); return; } let attaqueMagiqueDe = cmd.slice(1).join(' '); @@ -8603,22 +8612,22 @@ var COFantasy = COFantasy || function() { name: attaqueMagiqueDe }); if (ficheAttaqueMagique.length === 0) { - error("Il n'existe pas de personnage nomm\xE9 " + attaqueMagiqueDe, cmd); + error("Il n'existe pas de personnage nommé " + attaqueMagiqueDe, cmd); return; } if (ficheAttaqueMagique.length > 1) { - error("Attention, il existe plus d'un pesonnage nomm\xE9 " + attaqueMagiqueDe, cmd); + error("Attention, il existe plus d'un pesonnage nommé " + attaqueMagiqueDe, cmd); } let amCid = { charId: ficheAttaqueMagique[0].id }; let toucher = computeArmeAtk(amCid, '@{ATKMAG}'); if (isNaN(toucher)) { - error("Impossible de d\xE9terminer l'attaque de " + attaqueMagiqueDe, toucher); + error("Impossible de déterminer l'attaque de " + attaqueMagiqueDe, toucher); return; } if (options.toucher !== undefined) { - error("Attention, on a \xE0 la fois une option toucher et une option attaqueMagiqueDe. On ignore l'option --toucher", optArgs); + error("Attention, on a à la fois une option toucher et une option attaqueMagiqueDe. On ignore l'option --toucher", optArgs); } options.toucher = toucher; return; @@ -8639,14 +8648,14 @@ var COFantasy = COFantasy || function() { } scope.ignoreRD = parseInt(cmd[1]); if (isNaN(scope.ignoreRD) || scope.ignoreRD < 1) { - log("Pas un nombre positif apr\xE8s --ignoreRD, interpr\xE9t\xE9 comme ignore toute la RD"); + log("Pas un nombre positif après --ignoreRD, interprété comme ignore toute la RD"); scope.ignoreRD = undefined; scope.ignoreTouteRD = true; } return; case 'tueurDe': if (cmd.length < 2) { - log("Il faut pr\xE9ciser --tueurDe quoi"); + log("Il faut préciser --tueurDe quoi"); return; } options.tueurDe = options.tueurDe || []; @@ -8657,7 +8666,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { niveauMagie = parseInt(cmd[1]); if (isNaN(niveauMagie) || niveauMagie < 1) { - error("Le niveau de magie doit \xEAtre au moins 1", cmd); + error("Le niveau de magie doit être au moins 1", cmd); niveauMagie = 1; } } @@ -8668,16 +8677,16 @@ var COFantasy = COFantasy || function() { return; case 'tempsRecharge': if (cmd.length < 3) { - error("Il manque un argument \xE0 l'option --tempsRecharge de !cof-attack", cmd); + error("Il manque un argument à l'option --tempsRecharge de !cof-attack", cmd); return; } if (!estEffetTemp(cmd[1])) { - error("Le premier argument de l'option --tempsRecharge doit \xEAtre un effet temporaire r\xE9pertori\xE9", cmd); + error("Le premier argument de l'option --tempsRecharge doit être un effet temporaire répertorié", cmd); return; } let tr = parseInt(cmd[2]); if (isNaN(tr)) { - error("Le deuxi\xE8me argument de l'option --tempsRecharge doit \xEAtre un nombre", cmd); + error("Le deuxième argument de l'option --tempsRecharge doit être un nombre", cmd); return; } options.tempsRecharge = { @@ -8687,7 +8696,7 @@ var COFantasy = COFantasy || function() { return; case 'plus': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --plus de !cof-attack", cmd); + error("Il manque un argument à l'option --plus de !cof-attack", cmd); return; } let val = arg.substring(arg.indexOf(' ') + 1); @@ -8699,7 +8708,7 @@ var COFantasy = COFantasy || function() { break; case 'plusCrit': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --plusCrit de !cof-attack", cmd); + error("Il manque un argument à l'option --plusCrit de !cof-attack", cmd); return; } let valCrit = arg.substring(arg.indexOf(' ') + 1); @@ -8712,7 +8721,7 @@ var COFantasy = COFantasy || function() { case 'dmSiRate': case 'dmCible': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --" + cmd[0] + " de !cof-attack", cmd); + error("Il manque un argument à l'option --" + cmd[0] + " de !cof-attack", cmd); return; } let valDm = arg.substring(arg.indexOf(' ') + 1); @@ -8723,7 +8732,7 @@ var COFantasy = COFantasy || function() { break; case 'effet': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --effet de !cof-attack", cmd); + error("Il manque un argument à l'option --effet de !cof-attack", cmd); return; } let effet = cmd[1]; @@ -8736,7 +8745,7 @@ var COFantasy = COFantasy || function() { duree = parseInt(cmd[2]); if (isNaN(duree) || duree < 1) { error( - "Le deuxi\xE8me argument de --effet doit \xEAtre un nombre positif", + "Le deuxième argument de --effet doit être un nombre positif", cmd); return; } @@ -8762,7 +8771,7 @@ var COFantasy = COFantasy || function() { typeDmg: lastType }; } else { - error(cmd[1] + " n'est pas un effet temporaire r\xE9pertori\xE9", cmd); + error(cmd[1] + " n'est pas un effet temporaire répertorié", cmd); return; } scope.effets = scope.effets || []; @@ -8770,7 +8779,7 @@ var COFantasy = COFantasy || function() { return; case 'valeur': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --valeur de !cof-attack", cmd); + error("Il manque un argument à l'option --valeur de !cof-attack", cmd); return; } if (scope.effets === undefined || scope.effets.length === 0) { @@ -8816,10 +8825,10 @@ var COFantasy = COFantasy || function() { case 'etatSi': case 'etat': if (cmd.length < 3 && cmd[0] == 'etatSi') { - error("Il manque un argument \xE0 l'option --etatSi de !cof-attack", cmd); + error("Il manque un argument à l'option --etatSi de !cof-attack", cmd); return; } else if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --etat de !cof-attack", cmd); + error("Il manque un argument à l'option --etat de !cof-attack", cmd); return; } let etat = cmd[1]; @@ -8841,7 +8850,7 @@ var COFantasy = COFantasy || function() { if (cmd[0] == 'etat' && cmd.length > 3) { if (!isCarac(cmd[2]) && (cmd[2].length != 6 || !isCarac(cmd[2].substring(0, 3)) || !isCarac(cmd[2].substring(3, 6)))) { - error("Caract\xE9ristique du jet de sauvegarde incorrecte", cmd); + error("Caractéristique du jet de sauvegarde incorrecte", cmd); return; } lastEtat.saveCarac = cmd[2]; @@ -8851,7 +8860,7 @@ var COFantasy = COFantasy || function() { } else { lastEtat.saveDifficulte = parseInt(cmd[3]); if (isNaN(lastEtat.saveDifficulte)) { - error("Difficult\xE9 du jet de sauvegarde incorrecte", cmd); + error("Difficulté du jet de sauvegarde incorrecte", cmd); delete lastEtat.saveCarac; delete lastEtat.saveDifficulte; } @@ -8861,7 +8870,7 @@ var COFantasy = COFantasy || function() { return; case 'peur': if (cmd.length < 3) { - error("Il manque un argument \xE0 l'option --peur de !cof-attack", cmd); + error("Il manque un argument à l'option --peur de !cof-attack", cmd); return; } scope.peur = { @@ -8869,10 +8878,10 @@ var COFantasy = COFantasy || function() { duree: parseInt(cmd[2]) }; if (isNaN(scope.peur.seuil)) { - error("Le premier argument de --peur doit \xEAtre un nombre (le seuil)", cmd); + error("Le premier argument de --peur doit être un nombre (le seuil)", cmd); } if (isNaN(scope.peur.duree) || scope.peur.duree <= 0) { - error("Le deuxi\xE8me argument de --peur doit \xEAtre un nombre positif (la dur\xE9e)", cmd); + error("Le deuxième argument de --peur doit être un nombre positif (la durée)", cmd); } return; case 'feu': @@ -8903,7 +8912,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { vampirise = parseInt(cmd[1]); if (isNaN(vampirise)) { - error("Il faut un pourcentage entier comme argument \xE0 --vampirise", cmd); + error("Il faut un pourcentage entier comme argument à --vampirise", cmd); vampirise = 100; } } @@ -8934,7 +8943,7 @@ var COFantasy = COFantasy || function() { break; case 'disparition': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --disparition de !cof-attack", cmd); + error("Il manque un argument à l'option --disparition de !cof-attack", cmd); return; } let disparition = parseInt(cmd[1]); @@ -8986,7 +8995,7 @@ var COFantasy = COFantasy || function() { case 'save': if (lastEtat) { if (lastEtat.save) { - error("Red\xE9finition de la condition de save pour un effet", optArgs); + error("Redéfinition de la condition de save pour un effet", optArgs); } let saveParams = parseSave(cmd); if (saveParams) { @@ -9004,7 +9013,7 @@ var COFantasy = COFantasy || function() { case 'saveParJour': if (lastEtat) { if (lastEtat[cmd[0]]) { - error("Red\xE9finition de la condition de save pour un effet", optArgs); + error("Redéfinition de la condition de save pour un effet", optArgs); } let saveParTourParams = parseSave(cmd); if (saveParTourParams) { @@ -9025,12 +9034,12 @@ var COFantasy = COFantasy || function() { case 'mana': { if (cmd.length < 2) { - error("Usage : --mana co\xFBt", cmd); + error("Usage : --mana coût", cmd); return; } let mana = parseInt(cmd[1]); if (isNaN(mana) || mana < 0) { - error("Le co\xFBt en mana doit \xEAtre un nombre positif"); + error("Le coût en mana doit être un nombre positif"); return; } if (scope.mana === undefined) scope.mana = 0; @@ -9044,7 +9053,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { cout = parseInt(cmd[1]); if (isNaN(cout) || cout < 0) { - error("Le co\xFBt de la magie rapide n'est pas un entier positif", cmd); + error("Le coût de la magie rapide n'est pas un entier positif", cmd); cout = 1; } } @@ -9062,7 +9071,7 @@ var COFantasy = COFantasy || function() { } else { let base = parseInt(cmd[1]); if (isNaN(base)) { - error("L'argument de --magieEnArmure doit \xEAtre un nombre ou mana", cmd); + error("L'argument de --magieEnArmure doit être un nombre ou mana", cmd); return; } options.magieEnArmure = { @@ -9080,7 +9089,7 @@ var COFantasy = COFantasy || function() { } let rang = parseInt(cmd[1]); if (isNaN(rang) || rang < 1) { - error("Le rang doit \xEAtre un nombre positif"); + error("Le rang doit être un nombre positif"); return; } scope.rang = rang; @@ -9094,7 +9103,7 @@ var COFantasy = COFantasy || function() { } let bAtt = parseInt(cmd[1]); if (isNaN(bAtt)) { - error("Le bonus (" + cmd[0] + ") doit \xEAtre un nombre"); + error("Le bonus (" + cmd[0] + ") doit être un nombre"); return; } if (scope[cmd[0]] === undefined) scope[cmd[0]] = 0; @@ -9108,7 +9117,7 @@ var COFantasy = COFantasy || function() { } let b2Att = parseInt(cmd[1]); if (isNaN(b2Att)) { - error("Le bonus (" + cmd[0] + ") doit \xEAtre un nombre"); + error("Le bonus (" + cmd[0] + ") doit être un nombre"); return; } if (options[cmd[0]] === undefined) options[cmd[0]] = 0; @@ -9154,12 +9163,12 @@ var COFantasy = COFantasy || function() { } return; case 'munition': - if (options.munition) { //on \xE9vite la r\xE9cursion - error("Plusieurs options --munition. Seule la premi\xE8re est prise en compte", cmd); + if (options.munition) { //on évite la récursion + error("Plusieurs options --munition. Seule la première est prise en compte", cmd); return; } if (cmd.length < 2) { - error("Pour les munitions, il faut pr\xE9ciser le label de la munition", cmd); + error("Pour les munitions, il faut préciser le label de la munition", cmd); return; } let labelMunition = cmd[1]; @@ -9189,13 +9198,13 @@ var COFantasy = COFantasy || function() { } return; } - sendPlayer(msg, "Utilisez plut\xF4t les munitions d\xE9finies sur la fiche", playerId); - //Compatibilit\xE9 avec ancienne version: - let tauxPertes = 100; //Par d\xE9faut, les munitions sont perdues + sendPlayer(msg, "Utilisez plutôt les munitions définies sur la fiche", playerId); + //Compatibilité avec ancienne version: + let tauxPertes = 100; //Par défaut, les munitions sont perdues if (cmd.length > 2) tauxPertes = parseInt(cmd[2]); if (isNaN(tauxPertes) || tauxPertes < 0 || tauxPertes > 100) { - error("Le taux de pertes des munitions doit \xEAtre un nombre entre 0 et 100"); + error("Le taux de pertes des munitions doit être un nombre entre 0 et 100"); tauxPertes = 100; } options.munition = { @@ -9205,7 +9214,7 @@ var COFantasy = COFantasy || function() { return; case "ligne": if (options.aoe) { - error("Deux options pour d\xE9finir une aoe", optArgs); + error("Deux options pour définir une aoe", optArgs); return; } options.aoe = { @@ -9214,7 +9223,7 @@ var COFantasy = COFantasy || function() { return; case 'disque': if (options.aoe) { - error("Deux options pour d\xE9finir une aoe", optArgs); + error("Deux options pour définir une aoe", optArgs); return; } if (cmd.length < 2) { @@ -9235,14 +9244,14 @@ var COFantasy = COFantasy || function() { return; case 'cone': if (options.aoe) { - error("Deux options pour d\xE9finir une aoe", optArgs); + error("Deux options pour définir une aoe", optArgs); return; } let angle = 90; if (cmd.length > 1) { angle = parseInt(cmd[1]); if (isNaN(angle) || angle < 0 || angle > 360) { - error("Param\xE8tre d'angle du cone incorrect", cmd); + error("Paramètre d'angle du cone incorrect", cmd); angle = 90; } } @@ -9258,7 +9267,7 @@ var COFantasy = COFantasy || function() { } let targetS = persoOfId(cmd[1]); if (targetS === undefined) { - error("Cible suppl\xE9mentaire invalide", cmd); + error("Cible supplémentaire invalide", cmd); return; } if (targetToken.id == targetS.token.id) return; @@ -9314,12 +9323,12 @@ var COFantasy = COFantasy || function() { return; case 'limiteParJour': if (cmd.length < 2) { - error("Il manque la limite journali\xE8re", cmd); + error("Il manque la limite journalière", cmd); return; } let limiteParJour = parseInt(cmd[1]); if (isNaN(limiteParJour) || limiteParJour < 1) { - error("La limite journali\xE8re doit \xEAtre un nombre positif", cmd); + error("La limite journalière doit être un nombre positif", cmd); return; } scope.limiteParJour = limiteParJour; @@ -9335,7 +9344,7 @@ var COFantasy = COFantasy || function() { } let limiteParCombat = parseInt(cmd[1]); if (isNaN(limiteParCombat) || limiteParCombat < 1) { - error("La limite par combat doit \xEAtre un nombre positif", cmd); + error("La limite par combat doit être un nombre positif", cmd); return; } scope.limiteParCombat = limiteParCombat; @@ -9351,7 +9360,7 @@ var COFantasy = COFantasy || function() { } let limiteParTour = parseInt(cmd[1]); if (isNaN(limiteParTour) || limiteParTour < 1) { - error("La limite par tour doit \xEAtre un nombre positif", cmd); + error("La limite par tour doit être un nombre positif", cmd); return; } scope.limiteParTour = limiteParTour; @@ -9362,14 +9371,14 @@ var COFantasy = COFantasy || function() { return; case 'decrAttribute': if (cmd.length < 2) { - error("Erreur interne d'une commande g\xE9n\xE9r\xE9e par bouton", cmd); + error("Erreur interne d'une commande générée par bouton", cmd); return; } let attr = getObj('attribute', cmd[1]); if (attr === undefined) { attr = tokenAttribute(attaquant, cmd[1]); if (attr.length === 0) { - log("Attribut \xE0 changer perdu"); + log("Attribut à changer perdu"); log(cmd); return; } @@ -9379,7 +9388,7 @@ var COFantasy = COFantasy || function() { return; case 'decrLimitePredicatParTour': if (cmd.length < 2) { - error("Erreur interne d'une commande g\xE9n\xE9r\xE9e par bouton", cmd); + error("Erreur interne d'une commande générée par bouton", cmd); return; } scope.decrLimitePredicatParTour = cmd[1]; @@ -9391,7 +9400,7 @@ var COFantasy = COFantasy || function() { } let forceMin = parseInt(cmd[1]); if (isNaN(forceMin)) { - error("La force minimum doit \xEAtre un nombre", cmd); + error("La force minimum doit être un nombre", cmd); return; } scope.forceMinimum = forceMin; @@ -9403,7 +9412,7 @@ var COFantasy = COFantasy || function() { } let arcComposite = parseInt(cmd[1]); if (isNaN(arcComposite)) { - error("Le bonus d'arc composite doit \xEAtre un nombre", cmd); + error("Le bonus d'arc composite doit être un nombre", cmd); return; } scope.arcComposite = arcComposite; @@ -9419,7 +9428,7 @@ var COFantasy = COFantasy || function() { scope.dmgCoef += incrDmgCoef; return; } - scope.dmgCoef++; //Par d\xE9faut, incr\xE9mente de 1 + scope.dmgCoef++; //Par défaut, incrémente de 1 return; case 'toucheDoubleDmg': options.toucheDoubleDmg = true; @@ -9437,7 +9446,7 @@ var COFantasy = COFantasy || function() { scope.diviseDmg *= divise; return; } - scope.diviseDmg *= 2; //Par d\xE9faut, divise par 2 + scope.diviseDmg *= 2; //Par défaut, divise par 2 return; case 'divisePortee': scope.divisePortee = (scope.divisePortee || 1); @@ -9450,7 +9459,7 @@ var COFantasy = COFantasy || function() { scope.divisePortee *= divise; return; } - scope.divisePortee *= 2; //Par d\xE9faut, divise par 2 + scope.divisePortee *= 2; //Par défaut, divise par 2 return; case 'incrCritCoef': scope.critCoef = (scope.critCoef || 1); @@ -9463,7 +9472,7 @@ var COFantasy = COFantasy || function() { scope.critCoef += incrCritCoef; return; } - scope.critCoef++; //Par d\xE9faut, incr\xE9mente de 1 + scope.critCoef++; //Par défaut, incrémente de 1 return; case 'if': let ifCond = parseCondition(cmd.slice(1)); @@ -9514,7 +9523,7 @@ var COFantasy = COFantasy || function() { } let iteL = psElse.ite[psElse.ite.length - 1]; if (iteL.else) { - error("Il y a d\xE9j\xE0 un --else pour ce --if", cmd); + error("Il y a déjà un --else pour ce --if", cmd); return; } delete scope.parentScope; @@ -9527,7 +9536,7 @@ var COFantasy = COFantasy || function() { } case 'message': if (cmd.length < 2) { - error("Il manque le message apr\xE8s --message", cmd); + error("Il manque le message après --message", cmd); return; } scope.messages = scope.messages || []; @@ -9535,11 +9544,11 @@ var COFantasy = COFantasy || function() { return; case 'allonge': if (cmd.length < 2) { - error("Il manque le message apr\xE8s --allonge", cmd); + error("Il manque le message après --allonge", cmd); return; } if (options.allonge !== undefined) { - log("Red\xE9finition de l'allong"); + log("Redéfinition de l'allong"); } options.allonge = parseFloat(cmd[1]); if (isNaN(options.allonge)) { @@ -9562,7 +9571,7 @@ var COFantasy = COFantasy || function() { scope.enveloppe.expression = cmd[3]; } if (scope.enveloppe.expression === undefined) { - error("Il n'est pas encore possible d'utiliser l'option --enveloppe sans expression si le label de l'attaque n'est pas d\xE9fini", cmd); + error("Il n'est pas encore possible d'utiliser l'option --enveloppe sans expression si le label de l'attaque n'est pas défini", cmd); scope.enveloppe = undefined; } return; @@ -9589,7 +9598,7 @@ var COFantasy = COFantasy || function() { case 'imgAttackSuccesChampion': case 'imgAttackSuccesCritique': if (cmd.length < 1) { - error("Il manque une image apr\xE8s --" + cmd[0], cmd); + error("Il manque une image après --" + cmd[0], cmd); return; } options[cmd[0]] = cmd[1]; @@ -9602,12 +9611,12 @@ var COFantasy = COFantasy || function() { case 'soundAttackSuccesChampion': case 'soundAttackSuccesCritique': if (cmd.length < 1) { - error("Il manque le son apr\xE8s --" + cmd[0], cmd); + error("Il manque le son après --" + cmd[0], cmd); return; } options[cmd[0]] = cmd.slice(1).join(' '); return; - //Anciennes variantes, gard\xE9es pour la compatibilit\xE9 + //Anciennes variantes, gardées pour la compatibilité case 'img-attack-echec-critique': case 'img-attack-echec': case 'img-attack-echec-clignotement': @@ -9617,7 +9626,7 @@ var COFantasy = COFantasy || function() { case 'img-attack-succes-champion': case 'img-attack-succes-critique': if (cmd.length < 1) { - error("Il manque une image apr\xE8s --" + cmd[0], cmd); + error("Il manque une image après --" + cmd[0], cmd); return; } let imgCmd = @@ -9635,7 +9644,7 @@ var COFantasy = COFantasy || function() { case 'sound-attack-succes-champion': case 'sound-attack-succes-critique': if (cmd.length < 2) { - error("Il manque le son apr\xE8s --" + cmd[0], cmd); + error("Il manque le son après --" + cmd[0], cmd); return; } let soundCmd = cmd[0].replace('-a', 'A').replace('-e', 'E').replace('-c', 'C').replace('-n', 'N').replace('-s', 'S').replace('-t', 'T'); @@ -9661,7 +9670,7 @@ var COFantasy = COFantasy || function() { case 'FOR': carac = 'force'; break; - case 'dext\xE9rit\xE9': + case 'dextérité': case 'DEX': carac = 'dexterite'; break; @@ -9682,29 +9691,30 @@ var COFantasy = COFantasy || function() { carac = 'random'; break; default: - error("Le premier argument de affaiblirCarac n'est pas une caract\xE9ristique", cmd); + error("Le premier argument de affaiblirCarac n'est pas une caractéristique", cmd); return; } - let valAff = parseInt(cmd[2]); - if (isNaN(valAff)) { - error("Le deuxi\xE8me argument de --affaiblirCarac doit \xEAtre un nombre", cmd); + let valAff = parseDice(cmd[2]); + if (!valAff || !dePositif(valAff)) { + error("Le deuxième argument de --affaiblirCarac doit être un nombre", cmd); return; } if (valAff === 0) return; - scope.affaiblissementsCarac = scope.affaiblissementsCarac || []; - scope.affaiblissementsCarac.push({ + lastEtat = { carac, val: valAff - }); + }; + scope.affaiblissementsCarac = scope.affaiblissementsCarac || []; + scope.affaiblissementsCarac.push(lastEtat); return; case 'difficulteCarac': if (cmd.length < 2) { - error("Il manque la caract\xE9ristique \xE0 laquelle mesurer le jet d'attaque", cmd); + error("Il manque la caractéristique à laquelle mesurer le jet d'attaque", cmd); return; } options.difficulteCarac = parseCarac(cmd[1]); if (options.difficulteCarac === undefined) { - error("L'argument de --difficulteCarac n'est pas une caract\xE9ristique", cmd); + error("L'argument de --difficulteCarac n'est pas une caractéristique", cmd); } return; case 'attackId': @@ -9737,7 +9747,7 @@ var COFantasy = COFantasy || function() { } } }); - closeIte(scope); //pour fermer les endif mal form\xE9s et \xE9viter les boucles + closeIte(scope); //pour fermer les endif mal formés et éviter les boucles return { lastEtat, lastType, @@ -9769,7 +9779,7 @@ var COFantasy = COFantasy || function() { } let pageId = attaquant.token.get('pageid'); let targetToken = getObj('graphic', args[2]); - if (targetToken === undefined) { //reste la possibilit\xE9 de trouver un token de ce nom + if (targetToken === undefined) { //reste la possibilité de trouver un token de ce nom let tokens = findObjs({ _type: 'graphic', _subtype: 'token', @@ -9777,12 +9787,12 @@ var COFantasy = COFantasy || function() { name: args[2] }); if (tokens.length == 0) { - error("le second argument de !cof-attack doit \xEAtre un token", args[2]); + error("le second argument de !cof-attack doit être un token", args[2]); return; } if (tokens.length > 1) { - error("Ambig\xFCit\xE9 sur le choix d'un token : il y a " + - tokens.length + " tokens nomm\xE9s " + args[2], tokens); + error("Ambigüité sur le choix d'un token : il y a " + + tokens.length + " tokens nommés " + args[2], tokens); } targetToken = tokens[0]; } @@ -9793,7 +9803,7 @@ var COFantasy = COFantasy || function() { let weaponStats; let attaqueArray; try { - attaqueArray = JSON.parse(attackLabel); //plus document\xE9 depuis 2020 + attaqueArray = JSON.parse(attackLabel); //plus documenté depuis 2020 } catch (e) {} if (Array.isArray(attaqueArray) && attaqueArray.length > 4 && attaqueArray[1].length > 1 && attaqueArray[3].length > 3) { @@ -9840,10 +9850,10 @@ var COFantasy = COFantasy || function() { return; } if (weaponStats.deuxMains && attributeAsBool(attaquant, 'espaceExigu')) { - sendPerso(attaquant, "ne peut pas utiliser d'arme \xE0 deux mains dans un espace aussi exigu."); + sendPerso(attaquant, "ne peut pas utiliser d'arme à deux mains dans un espace aussi exigu."); return; } - //Si c'est aussi une arme de jet, et que le personnage attaque \xE0 distance, on va utiliser la version arme de jet de l'attaque. + //Si c'est aussi une arme de jet, et que le personnage attaque à distance, on va utiliser la version arme de jet de l'attaque. let msgIndex = msg.content; let indexAussiJet = msgIndex.indexOf('--aussiArmeDeJet '); if (indexAussiJet == -1 && weaponStats.options) { @@ -9854,19 +9864,22 @@ var COFantasy = COFantasy || function() { let labelAussiJet = parseInt(msgIndex.substring(indexAussiJet + 17)); if (isNaN(labelAussiJet)) { error("Label --aussiArmeDeJet n'est pas un entier", msgIndex.substring(indexAussiJet + 17)); + indexAussiJet = 0; } else { let armeAssociee = getWeaponStats(attaquant, labelAussiJet); if (armeAssociee === undefined) { error("Label --aussiArmeDeJet pas une attaque", labelAussiJet); + indexAussiJet = 0; } else { if (distanceCombat(attaquant.token, targetToken) > 0) weaponStats = armeAssociee; + else indexAussiJet = 0; } } } //Ajout des options de l'arme let wo = weaponStats.options.trim(); - //Pour la partie options, il est possible qu'elle soit d\xE9j\xE0 pass\xE9e en ligne de commande + //Pour la partie options, il est possible qu'elle soit déjà passée en ligne de commande if (wo !== '' && ((optArgs.length < 1 || !optArgs[0].startsWith('attaqueOptions'))) || indexAussiJet > 0) { wo = ' ' + wo; wo.split(' --').reverse().forEach(function(o) { @@ -9910,7 +9923,7 @@ var COFantasy = COFantasy || function() { break; case 'magique': options.magique = true; - options.type = 'energie'; //Les d\xE9g\xE2ts magiques sans type associ\xE9 sont suppos\xE9s de type \xE9nergie, l'\xE9quivalent de force dans PF1 + options.type = 'energie'; //Les dégâts magiques sans type associé sont supposés de type énergie, l'équivalent de force dans PF1 break; case 'tranchant': case 'percant': @@ -9919,7 +9932,7 @@ var COFantasy = COFantasy || function() { break; } let lastEtat; //dernier de etats et effets - let lastType = options.type; //dernier type de d\xE9g\xE2ts inflig\xE9s + let lastType = options.type; //dernier type de dégâts infligés let scope = options; //Pour les conditionnelles parseAttackOptions(attaquant, optArgs, lastEtat, lastType, scope, playerId, msg, targetToken, attackLabel, weaponStats, options); let bene = predicateAsInt(attaquant, 'benedictionSuperieure', 0); @@ -9933,7 +9946,7 @@ var COFantasy = COFantasy || function() { options.additionalDmg = options.additionalDmg || []; if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, rang: options.rang, @@ -9959,7 +9972,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -9976,7 +9989,7 @@ var COFantasy = COFantasy || function() { } } else { if (options.tempeteDeManaDuree) { - sendPlayerAndGM(msg, playerId, "Attention, l'option temp\xEAte de mana pour la dur\xE9e n'est pas prise en compte. Utiliser l'option --pasDeDmg si le sort ne fait pas de DM"); + sendPlayerAndGM(msg, playerId, "Attention, l'option tempête de mana pour la durée n'est pas prise en compte. Utiliser l'option --pasDeDmg si le sort ne fait pas de DM"); options.tempeteDeManaDuree = false; if (options.tempeteDeMana && options.tempeteDeMana.cout) options.tempeteDeMana.cout--; @@ -10006,30 +10019,30 @@ var COFantasy = COFantasy || function() { if (f) f(evt); } - // Fait d\xE9penser de la mana, dep doit contenir une d\xE9pense possible + // Fait dépenser de la mana, dep doit contenir une dépense possible function depenseMana(perso, dep, msg, evt) { if (!dep || dep.cout_null) return; updateCurrentBar(perso, 2, dep.pm, evt); msg = msg || ''; if (dep.depense_pv) { - let source = reglesOptionelles.mana.val.brulure_de_magie.val ? "de la Br\xFBlure de Magie" : "du Contrecoup"; + let source = reglesOptionelles.mana.val.brulure_de_magie.val ? "de la Brûlure de Magie" : "du Contrecoup"; updateCurrentBar(perso, 1, dep.pv, evt); let pre = 'p'; if (stateCOF.options.affichage.val.depense_mana.val && dep.depense_pm > 0) - pre = "d\xE9pense " + dep.depense_pm + " PM et p"; - sendPerso(perso, pre + "erd " + dep.depense_pv + " PV \xE0 cause " + source + " pour " + msg); + pre = "dépense " + dep.depense_pm + " PM et p"; + sendPerso(perso, pre + "erd " + dep.depense_pv + " PV à cause " + source + " pour " + msg); } else { if (stateCOF.options.affichage.val.depense_mana.val) - sendPerso(perso, "d\xE9pense " + dep.depense_pm + " PM pour " + msg); + sendPerso(perso, "dépense " + dep.depense_pm + " PM pour " + msg); } let niveau = ficheAttributeAsInt(perso, 'niveau', 1); if (reglesOptionelles.mana.val.mana_totale.val) { if (dep.depense_pm > niveau * 3) { - sendPerso(perso, "Attention, la d\xE9pense totale de mana est sup\xE9rieure au niveau * 3"); + sendPerso(perso, "Attention, la dépense totale de mana est supérieure au niveau * 3"); } } else { if (dep.depense_pm > niveau) { - sendPerso(perso, "Attention, la d\xE9pense totale de mana est sup\xE9rieure au niveau"); + sendPerso(perso, "Attention, la dépense totale de mana est supérieure au niveau"); } } return; @@ -10058,7 +10071,7 @@ var COFantasy = COFantasy || function() { case 'animal': return estAnimal(perso); case 'demon': - case 'd\xE9mon': + case 'démon': return estDemon(perso); case 'dragon': return estDraconique(perso); @@ -10066,9 +10079,9 @@ var COFantasy = COFantasy || function() { case 'elfe-noir': return estElfeNoir(perso); case 'fee': - case 'f\xE9e': + case 'fée': return estFee(perso); - case 'g\xE9ant': + case 'géant': case 'geant': return estGeant(perso); case 'gobelin': @@ -10084,7 +10097,7 @@ var COFantasy = COFantasy || function() { } } - //Si l'attribut est un mod. de caract\xE9ristique, va chercher le + //Si l'attribut est un mod. de caractéristique, va chercher le //bon attribut, selon que perso est un PNJ ou nom function valAttribute(perso, originalAttr, caracAttr) { if (caracAttr) { @@ -10096,10 +10109,10 @@ var COFantasy = COFantasy || function() { return charAttributeAsInt(perso, originalAttr, 0); } - //test si l'attribut est pr\xE9sent et si sa valeur est bonne + //test si l'attribut est présent et si sa valeur est bonne // options peut contenir - // fiche : si on cherche un attribut de fiche, et dans ce cas, le champ def donne la valeur par d\xE9faut - // local : si c'est un attribut diff\xE9rent selon le mook + // fiche : si on cherche un attribut de fiche, et dans ce cas, le champ def donne la valeur par défaut + // local : si c'est un attribut différent selon le mook function testAttribut(perso, attrName, valeur, options) { let attr; if (options.fiche) { @@ -10117,7 +10130,7 @@ var COFantasy = COFantasy || function() { if (cond == 'toujoursVrai') return true; switch (cond.type) { case 'moins': - // Au cas o\xF9 on utilise les MOD au lieu de l'attribut de base: + // Au cas où on utilise les MOD au lieu de l'attribut de base: let caracAttr = caracOfMod(cond.attribute); let attackerAttr = valAttribute(attaquant, cond.attribute, caracAttr); let resMoins = true; @@ -10175,13 +10188,13 @@ var COFantasy = COFantasy || function() { case 'deAttaque': if (options && options.auto) return false; if (deAttaque === undefined) { - error("Condition de d\xE9 d'attaque non support\xE9e ici", cond); + error("Condition de dé d'attaque non supportée ici", cond); return true; } return deAttaque >= cond.seuil; case 'echecCritique': if (deAttaque === undefined) { - error("Condition de d\xE9 d'attaque non support\xE9e ici", cond); + error("Condition de dé d'attaque non supportée ici", cond); return true; } return deAttaque == 1; @@ -10225,7 +10238,7 @@ var COFantasy = COFantasy || function() { case 'mana': case 'bonusAttaque': case 'bonusContreArmure': - case 'bonusContreBouclier': //num\xE9riques additives + case 'bonusContreBouclier': //numériques additives opt[field] = opt[field] || 0; opt[field] += branch[field]; break; @@ -10272,11 +10285,11 @@ var COFantasy = COFantasy || function() { attr.set('current', oldval - 1); break; case 'decrLimitePredicatParTour': - //Ne fait que diminuer l'attribut, n'emp\xEAche pas l'attaque + //Ne fait que diminuer l'attribut, n'empêche pas l'attaque let pred = branch.decrLimitePredicatParTour; let test = testLimiteUtilisationsCapa(attaquant, pred, 'tour', "ne peut plus utiliser " + pred + " ce tour", - "Attaque impossible, pas de pr\xE9dicat " + pred); + "Attaque impossible, pas de prédicat " + pred); if (test === undefined) break; utiliseCapacite(attaquant, test, evt); break; @@ -10295,7 +10308,7 @@ var COFantasy = COFantasy || function() { if (etat.aTraiter === 0) callback(); } - //Evaluation r\xE9cursive des if-then-else + //Evaluation récursive des if-then-else function evalITE(attaquant, target, deAttaque, options, phase, evt, explications, scope, callback, inTarget, etatParent) { etatParent = etatParent || {}; if (scope.ite === undefined || scope.ite.length < 1) { @@ -10364,7 +10377,7 @@ var COFantasy = COFantasy || function() { callIfAllDone(etatParent, callback); return true; } - let msgPour = " pour r\xE9sister \xE0 un effet"; + let msgPour = " pour résister à un effet"; let msgRate = ", " + nomPerso(target) + " rate son jet de sauvegarde"; let saveOpts = { msgPour: msgPour, @@ -10378,7 +10391,7 @@ var COFantasy = COFantasy || function() { }; const saveId = condInTarget ? 'ifSave_' + etatParent.aTraiter + '_' + target.token.id : 'ifSave_' + etatParent.aTraiter + '_' + attaquant.token.id; - if (phase > 0) { //le save a d\xE9j\xE0 \xE9t\xE9 r\xE9solu + if (phase > 0) { //le save a déjà été résolu condInTarget = true; resCondition = target.saveResults && target.saveResults[saveId]; break; @@ -10394,7 +10407,7 @@ var COFantasy = COFantasy || function() { branch = ite.else; target.saveResults[saveId] = true; } else { - branch = ite.then; //on teste si le save est rat\xE9 + branch = ite.then; //on teste si le save est raté target.saveResults[saveId] = false; } if (branch === undefined) { @@ -10417,7 +10430,7 @@ var COFantasy = COFantasy || function() { else branch = ite.else; if (branch === undefined) { callIfAllDone(etatParent, callback); - return condInTarget; //On garde l'ite si on d\xE9pend de la cible + return condInTarget; //On garde l'ite si on dépend de la cible } //On copie les champs de scope dans options ou dans target if (phase === 0) @@ -10430,7 +10443,7 @@ var COFantasy = COFantasy || function() { }); } - // Retourne tous les attributs dans attrs, de nom name ou commen\xE7ant par name_ + // Retourne tous les attributs dans attrs, de nom name ou commençant par name_ function allAttributesNamed(attrs, name) { let reg = new RegExp("^" + name + "($|_|\\()"); return attrs.filter(function(obj) { @@ -10546,7 +10559,7 @@ var COFantasy = COFantasy || function() { already = already || new Set(); let pid = [perso.charId, perso.token.id]; if (already.has(pid)) { - error("Il y a un cycle d'initiatives d\xE9riv\xE9es les unes des autres impliquant " + nomPerso(perso), already); + error("Il y a un cycle d'initiatives dérivées les unes des autres impliquant " + nomPerso(perso), already); return perso; } let persoD = initDerivee(perso, already); @@ -10577,7 +10590,7 @@ var COFantasy = COFantasy || function() { // retourne undefined sinon } - //ne rajoute pas evt \xE0 l'historique + //ne rajoute pas evt à l'historique function persoInit(perso, evt, already) { let persoD = initDerivee(perso); if (persoD) perso = persoD; @@ -10591,13 +10604,13 @@ var COFantasy = COFantasy || function() { init += ficheAttributeAsInt(perso, 'mod_initiative', 0); } if (attributeAsBool(perso, 'formeDArbre')) init = 7; - //R\xE8gle optionelle : +1d6, \xE0 lancer en entrant en combat + //Règle optionelle : +1d6, à lancer en entrant en combat if (reglesOptionelles.initiative.val.initiative_variable.val) { let bonusVariable; let jetPartage; if (reglesOptionelles.initiative.val.initiative_variable_individuelle.val) { // Un jet par perso mook bonusVariable = attributeAsInt(perso, 'bonusInitVariable', 0); - } else { //Un seul pour tous les mook du m\xEAme personnage + } else { //Un seul pour tous les mook du même personnage bonusVariable = charAttributeAsInt(perso, 'bonusInitVariable', 0); jetPartage = true; } @@ -10611,7 +10624,7 @@ var COFantasy = COFantasy || function() { let msgSecret = perso.token.get('layer') == 'gmlayer'; if (!jetCache) { msg += onGenre(perso, 'Il', 'Elle') + " fait " + rollD6.roll; - msg += " \xE0 son jet d'initiative"; + msg += " à son jet d'initiative"; } setTokenAttr(perso, 'bonusInitVariable', bonusVariable, evt, { msg: msg, @@ -10626,9 +10639,9 @@ var COFantasy = COFantasy || function() { init += attributeAsInt(perso, 'bonusInitEmbuscade', 0); // Familier if (compagnonPresent(perso, 'familier')) init += 2; - // Sixi\xE8me sens en sort + // Sixième sens en sort if (attributeAsBool(perso, 'sixiemeSens')) init += 2; - // Voie du chef d'arm\xE9e rangs 2 et 3 (Capitaine) + // Voie du chef d'armée rangs 2 et 3 (Capitaine) let bonusCapitaine = aUnCapitaine(perso, evt); if (bonusCapitaine) init += parseInt(bonusCapitaine); if (predicateAsBool(perso, 'graceFeline')) { @@ -10655,16 +10668,16 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(perso, 'intelligenceDuCombat')) { init += modCarac(perso, 'intelligence'); } - // R\xE9flexes felins de la Voie du pourfendeur + // Réflexes felins de la Voie du pourfendeur init += predicateAsInt(perso, 'reflexesFelins', 0); - // \xC2me f\xE9line (f\xE9lis) + // Âme féline (félis) init += predicateAsInt(perso, 'ameFeline', 0); init += predicateAsInt(perso, 'vitesseDuFelin', 0); init += predicateAsInt(perso, 'espritVide', 0, 3); init += predicateAsInt(perso, 'pasDuVent', 0, 1); //Prescience de l'ensorceleur if (attributeAsBool(perso, 'prescienceUtilisee')) init += 10; - //For\xEAt vivante + //Forêt vivante if (attributeAsBool(perso, 'foretVivanteEnnemie')) { init -= 5; } @@ -10688,12 +10701,12 @@ var COFantasy = COFantasy || function() { }); } - //ne rajoute pas evt \xE0 l'historique - //options: recompute : si pas encore agi, on remet \xE0 sa place dans le turn order - //already est l\xE0 pour \xE9viter les r\xE9cursions infinies + //ne rajoute pas evt à l'historique + //options: recompute : si pas encore agi, on remet à sa place dans le turn order + //already est là pour éviter les récursions infinies //boutonRoll: vient de l'utilisation d'un bouton de roll function initiative(selected, evt, recompute, already, boutonRoll) { //set initiative for selected tokens - // Toujours appel\xE9 quand on entre en combat + // Toujours appelé quand on entre en combat // Initialise le compteur de tour, si besoin // Assumption: all tokens that have not acted yet are those before the turn // counter. @@ -10703,7 +10716,7 @@ var COFantasy = COFantasy || function() { // Tokens appearing before the turn are sorted if (!Campaign().get('initiativepage')) evt.initiativepage = false; let debutCombat = false; - if (!stateCOF.combat) { //actions de d\xE9but de combat + if (!stateCOF.combat) { //actions de début de combat evt.combat = false; stateCOF.combat = { tour: 1, @@ -10718,7 +10731,7 @@ var COFantasy = COFantasy || function() { }]), initiativepage: true }); - removeAllAttributes('transeDeGu\xE9rison', evt); + removeAllAttributes('transeDeGuérison', evt); debutCombat = true; } const combat = stateCOF.combat; @@ -10726,7 +10739,7 @@ var COFantasy = COFantasy || function() { Campaign().set('initiativepage', true); } let to = getTurnOrder(combat, evt); - if (to.pasAgi.length === 0) { // Fin de tour, on met le tour \xE0 la fin et on retrie + if (to.pasAgi.length === 0) { // Fin de tour, on met le tour à la fin et on retrie to.pasAgi = to.dejaAgi; to.dejaAgi = []; } @@ -10736,7 +10749,7 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(perso) { let pageId = perso.token.get('pageid'); combat.pageId = pageId; - //Si besoin, on stoque les PVs de d\xE9but de combat + //Si besoin, on stoque les PVs de début de combat if (!attributeAsBool(perso, 'PVsDebutCombat')) { setTokenAttr(perso, 'PVsDebutCombat', perso.token.get('bar1_value'), evt); } @@ -10761,7 +10774,7 @@ var COFantasy = COFantasy || function() { } } let init = persoInit(perso, evt); - // On place le token \xE0 sa place dans la liste du tour + // On place le token à sa place dans la liste du tour let dejaIndex = to.dejaAgi.findIndex(function(elt) { return (elt.id == perso.token.id); @@ -10778,7 +10791,7 @@ var COFantasy = COFantasy || function() { updateNextInit(perso); return true; } else { - return false; //On enl\xE8ve le perso des pasAgi + return false; //On enlève le perso des pasAgi } } push = false; //Sinon, comme on ne recalcule pas, on le laisse @@ -10826,7 +10839,7 @@ var COFantasy = COFantasy || function() { }; addAura(perso, aura, aurasCreees, combat, evt); }); - //Les autres persos qui entrent en combat en m\xEAme temps + //Les autres persos qui entrent en combat en même temps let ajouterEnCombat = predicatesNamed(perso, 'entrerEnCombatAvec'); if (ajouterEnCombat.length > 0) { let aec = new Set(ajouterEnCombat); @@ -10858,7 +10871,7 @@ var COFantasy = COFantasy || function() { to.dejaAgi[dejaIndex].pr = init; } }); - if (debutCombat) { //On cherche si un des personnages de la carte a la capacit\xE9 Prescience + if (debutCombat) { //On cherche si un des personnages de la carte a la capacité Prescience let allToks = findObjs({ _type: 'graphic', @@ -10874,7 +10887,7 @@ var COFantasy = COFantasy || function() { }; return capaciteDisponible(perso, 'prescience', 'combat'); }); - if (prescience) { //Il faut stoquer les positions de tous les token pour le retour en arri\xE8re. + if (prescience) { //Il faut stoquer les positions de tous les token pour le retour en arrière. stateCOF.prescience = { evt: evt, dernieresPositions: [] @@ -10921,7 +10934,7 @@ var COFantasy = COFantasy || function() { function initiativeInterface(msg) { getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - error("Dans !cof-init : rien \xE0 faire, pas de token selectionn\xE9", msg); + error("Dans !cof-init : rien à faire, pas de token selectionné", msg); return; } aura_token_on_turn = msg.content.indexOf('--aura') !== -1; @@ -11047,7 +11060,7 @@ var COFantasy = COFantasy || function() { }); return r !== undefined; } catch (uriError) { - log("Erreur de d\xE9codage URI dans la note GM de " + token.get('name') + " : " + gmNotes); + log("Erreur de décodage URI dans la note GM de " + token.get('name') + " : " + gmNotes); } } return false; @@ -11057,9 +11070,9 @@ var COFantasy = COFantasy || function() { return false; } - // bonus d'attaque d'un token, ind\xE9pendament des options + // bonus d'attaque d'un token, indépendament des options // Mise en commun pour attack et attaque-magique - // options pour modifier \xE9ventuellement l'affichage si pas de DM et pour mettre \xE0 jour options.bonusDM si pr\xE9sent + // options pour modifier éventuellement l'affichage si pas de DM et pour mettre à jour options.bonusDM si présent function bonusDAttaque(personnage, explications, evt, options) { explications = explications || []; let tempAttkMod; // Utilise la barre 3 de l'attaquant @@ -11086,7 +11099,7 @@ var COFantasy = COFantasy || function() { attributeAsInt(personnage, 'chantDesHerosTempeteDeManaIntense', 0); bonusChantDesHeros += chantDesHerosIntense; attBonus += bonusChantDesHeros; - explications.push("Chant des h\xE9ros => +" + bonusChantDesHeros + " en Attaque"); + explications.push("Chant des héros => +" + bonusChantDesHeros + " en Attaque"); if (chantDesHerosIntense) removeTokenAttr(personnage, 'chantDesHerosTempeteDeManaIntense', evt); } @@ -11095,7 +11108,7 @@ var COFantasy = COFantasy || function() { let benedictionIntense = attributeAsInt(personnage, 'benedictionTempeteDeManaIntense', 0); bonusBenediction += benedictionIntense; attBonus += bonusBenediction; - explications.push("B\xE9n\xE9diction => +" + bonusBenediction + " en Attaque"); + explications.push("Bénédiction => +" + bonusBenediction + " en Attaque"); if (benedictionIntense) removeTokenAttr(personnage, 'benedictionTempeteDeManaIntense', evt); } @@ -11110,17 +11123,17 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'lameDeLigneePerdue')) { attBonus -= 1; - explications.push("Lame de lign\xE9e perdue => -1 en Attaque"); + explications.push("Lame de lignée perdue => -1 en Attaque"); } if (attributeAsBool(personnage, 'strangulation')) { let malusStrangulation = 1 + attributeAsInt(personnage, 'dureeStrangulation', 0); attBonus -= malusStrangulation; - explications.push("L'attaquant est \xE9trangl\xE9 => -" + malusStrangulation + " en Attaque"); + explications.push("L'attaquant est étranglé => -" + malusStrangulation + " en Attaque"); } if (getState(personnage, 'renverse')) { attBonus -= 5; - explications.push("Attaquant \xE0 terre => -5 en Attaque"); + explications.push("Attaquant à terre => -5 en Attaque"); } let attrPosture = tokenAttribute(personnage, 'postureDeCombat'); if (attrPosture.length > 0) { @@ -11143,7 +11156,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'cadavreAnime')) { attBonus -= 4; - explications.push("Cadavre anim\xE9 => -2 en Attaque"); + explications.push("Cadavre animé => -2 en Attaque"); } let bonusCapitaine = aUnCapitaine(personnage, evt); if (bonusCapitaine) { @@ -11158,13 +11171,13 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(personnage, 'forceDeGeant')) { let bonusForceDeGeant = getIntValeurOfEffet(personnage, 'forceDeGeant', 2); attBonus += bonusForceDeGeant; - explications.push("Force de g\xE9ant => +" + bonusForceDeGeant + " en Attaque"); + explications.push("Force de géant => +" + bonusForceDeGeant + " en Attaque"); } if (attributeAsBool(personnage, 'nueeDInsectes')) { let malusNuee = 2 + attributeAsInt(personnage, 'nueeDInsectesTempeteDeManaIntense', 0); attBonus -= malusNuee; - explications.push("Nu\xE9e d\'insectes => -" + malusNuee + " en Attaque"); + explications.push("Nuée d\'insectes => -" + malusNuee + " en Attaque"); if (malusNuee > 2) removeTokenAttr(personnage, 'nueeDInsectesTempeteDeManaIntense', evt); } @@ -11172,13 +11185,13 @@ var COFantasy = COFantasy || function() { let malusNueeCriquets = 3 + attributeAsInt(personnage, 'nueeDeCriquetsTempeteDeManaIntense', 0); attBonus -= malusNueeCriquets; - explications.push("Nu\xE9e de criquets => -" + malusNueeCriquets + " en Attaque"); + explications.push("Nuée de criquets => -" + malusNueeCriquets + " en Attaque"); if (malusNueeCriquets > 3) removeTokenAttr(personnage, 'nueeDeCriquetsTempeteDeManaIntense', evt); } if (attributeAsBool(personnage, 'nueeDeScorpions')) { attBonus -= 3; - explications.push("Nu\xE9e de scorpions => -3 en Attaque"); + explications.push("Nuée de scorpions => -3 en Attaque"); } if (attributeAsBool(personnage, 'etatExsangue')) { attBonus -= 2; @@ -11186,7 +11199,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'armeBrulante')) { attBonus -= 2; - explications.push("Arme br\xFBlante => -2 en Attaque"); + explications.push("Arme brûlante => -2 en Attaque"); } if (marcheSylvestreActive(personnage)) { attBonus += 2; @@ -11194,11 +11207,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'prisonVegetale')) { attBonus -= getIntValeurOfEffet(personnage, 'prisonVegetale', 2); - explications.push("Prison v\xE9g\xE9tale : -2 en Attaque"); + explications.push("Prison végétale : -2 en Attaque"); } if (attributeAsBool(personnage, 'toiles')) { attBonus -= getIntValeurOfEffet(personnage, 'toiles', 2); - explications.push("Entrav\xE9 : -2 en Attaque"); + explications.push("Entravé : -2 en Attaque"); } if (attributeAsBool(personnage, 'masqueDuPredateur')) { let bonusMasque = getIntValeurOfEffet(personnage, 'masqueDuPredateur', modCarac(personnage, 'sagesse')); @@ -11206,10 +11219,10 @@ var COFantasy = COFantasy || function() { bonusMasque += masqueIntense; attBonus += bonusMasque; if (options && options.bonusDM !== undefined) { - explications.push("Masque du pr\xE9dateur : +" + bonusMasque + " en Attaque et DM"); + explications.push("Masque du prédateur : +" + bonusMasque + " en Attaque et DM"); options.bonusDM += bonusMasque; } else { - explications.push("Masque du pr\xE9dateur : +" + bonusMasque + " en Attaque"); + explications.push("Masque du prédateur : +" + bonusMasque + " en Attaque"); } if (masqueIntense) removeTokenAttr(personnage, 'masqueDuPredateurTempeteDeManaIntense', evt); @@ -11218,15 +11231,15 @@ var COFantasy = COFantasy || function() { getIntValeurOfEffet(personnage, 'masqueDuPredateurAmeLiee', 1); attBonus += bonusMasque; if (options && options.bonusDM !== undefined) { - explications.push("Masque du pr\xE9dateur li\xE9 : +" + bonusMasque + " en Attaque et DM"); + explications.push("Masque du prédateur lié : +" + bonusMasque + " en Attaque et DM"); options.bonusDM += bonusMasque; } else { - explications.push("Masque du pr\xE9dateur li\xE9 : +" + bonusMasque + " en Attaque"); + explications.push("Masque du prédateur lié : +" + bonusMasque + " en Attaque"); } } if (attributeAsBool(personnage, 'armeSecreteBarde')) { attBonus -= 10; - explications.push("D\xE9stabilis\xE9 par une action de charme => -10 en Attaque"); + explications.push("Déstabilisé par une action de charme => -10 en Attaque"); } if (attributeAsBool(personnage, 'espaceExigu')) { let bonusForce = modCarac(personnage, 'force'); @@ -11238,28 +11251,28 @@ var COFantasy = COFantasy || function() { attBonus -= 1; } if (attributeAsBool(personnage, 'agrippeParUnDemon')) { - explications.push("agripp\xE9 : -3 en Attaque"); + explications.push("agrippé : -3 en Attaque"); attBonus -= 3; } if (attributeAsBool(personnage, 'ondesCorruptrices') && !attributeAsBool(personnage, 'sangDeLArbreCoeur') && !predicateAsBool(personnage, 'porteurDuBouclierDeGrabuge')) { let malus = attributeAsInt(personnage, 'ondesCorruptrices', 2); - explications.push("naus\xE9eux : -" + malus + " aux tests"); + explications.push("nauséeux : -" + malus + " aux tests"); attBonus -= malus; } if (attributeAsBool(personnage, 'inconfort')) { let inconfortValeur = attributeAsInt(personnage, 'inconfortValeur', 0); attBonus -= inconfortValeur; - explications.push("G\xEAne due \xE0 l'armure : -" + inconfortValeur); + explications.push("Gêne due à l'armure : -" + inconfortValeur); } if (attributeAsBool(personnage, 'putrefactionOutreTombe')) { attBonus -= 2; - explications.push("Putr\xE9faction => -2 en Attaque"); + explications.push("Putréfaction => -2 en Attaque"); } if (attributeAsBool(personnage, 'secoue')) { attBonus -= 2; - let msg = "Secou\xE9" + eForFemale(personnage) + " => -2 en Attaque"; + let msg = "Secoué" + eForFemale(personnage) + " => -2 en Attaque"; explications.push(msg); } if (attributeAsBool(personnage, 'bonusAttaqueTemp')) { @@ -11280,7 +11293,7 @@ var COFantasy = COFantasy || function() { let bonus = getIntValeurOfEffet(personnage, 'detournerLeRegard', 2); let msg; if (bonus < 5) { - msg = "D\xE9tourne le regard"; + msg = "Détourne le regard"; } else { msg = "Ferme les yeux"; } @@ -11311,8 +11324,8 @@ var COFantasy = COFantasy || function() { switch (ficheAttribute(perso, 'taille', '').trim().toLowerCase()) { case "minuscule": return 1; - case "tr\xE8s petit": - case "tr\xE8s petite": + case "très petit": + case "très petite": case "tres petit": return 2; case "petit": @@ -11326,13 +11339,13 @@ var COFantasy = COFantasy || function() { case "grand": case "grande": return 5; - case "\xE9norme": + case "énorme": case "enorme": return 6; case "colossal": case "colossale": return 7; - default: //On passe \xE0 la m\xE9thode suivante + default: //On passe à la méthode suivante } if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); @@ -11353,7 +11366,7 @@ var COFantasy = COFantasy || function() { case 'demi-orque': case 'orque': case 'gnome': - case '\xE2me-forg\xE9e': + case 'âme-forgée': return 4; case 'centaure': case 'demi-ogre': @@ -11366,11 +11379,11 @@ var COFantasy = COFantasy || function() { //Retourne un encodage des tailes : // 1 : minuscule - // 2 : tr\xE8s petit + // 2 : très petit // 3 : petit // 4 : moyen // 5 : grand - // 6 : \xE9norme + // 6 : énorme // 7 : colossal function taillePersonnage(perso, def) { if (perso.taille) return perso.taille; @@ -11380,19 +11393,27 @@ var COFantasy = COFantasy || function() { return taille; } - //tm doit \xEAtre stateCOF.tenebresMagiques, et bien d\xE9fini. + //tm doit être stateCOF.tenebresMagiques, et bien défini. function eclaireParFioleDeLumiere(perso, tm) { let fio = tm.fioleDeLumiere; if (fio === undefined || fio.porteur === undefined) return false; return distanceCombat(fio.porteur.token, perso.token) < fio.distance; } + function defenseBouclier(perso) { + let defense = 0; + if (ficheAttributeAsInt(perso, 'defbouclieron', 0) > 0) { + defense += ficheAttributeAsInt(perso, 'defbouclier', 0); + defense += predicateAsInt(perso, 'bouclierDeLaFoi', 0, 1); + } + return defense; + } + function defenseArmure(perso) { let defense = 0; if (ficheAttributeAsInt(perso, 'defarmureon', 0) > 0) defense = ficheAttributeAsInt(perso, 'defarmure', 0); - if (ficheAttributeAsInt(perso, 'defbouclieron', 0) > 0) - defense += ficheAttributeAsInt(perso, 'defbouclier', 0); + defense += defenseBouclier(perso); return defense; } @@ -11402,7 +11423,7 @@ var COFantasy = COFantasy || function() { if (options.difficultePVmax) { let pvmax = parseInt(target.token.get('bar1_max')); if (isNaN(pvmax)) { - error("Points de vie de " + nomPerso(target) + " mal form\xE9s", + error("Points de vie de " + nomPerso(target) + " mal formés", target.token.get('bar1_max')); return 0; } @@ -11410,7 +11431,7 @@ var COFantasy = COFantasy || function() { } else if (options.difficultePV) { let pv = parseInt(target.token.get('bar1_value')); if (isNaN(pv)) { - error("Points de vie de " + nomPerso(target) + " mal form\xE9s", + error("Points de vie de " + nomPerso(target) + " mal formés", target.token.get('bar1_value')); return 0; } @@ -11472,7 +11493,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'armureDuMage')) { let bonusArmureDuMage = getIntValeurOfEffet(target, 'armureDuMage', 4); - if (defense > 12) defense += bonusArmureDuMage / 2; // On a d\xE9j\xE0 une armure physique, \xE7a ne se cumule pas. + if (defense > 12) defense += bonusArmureDuMage / 2; // On a déjà une armure physique, ça ne se cumule pas. else defense += bonusArmureDuMage; } defense += ficheAttributeAsInt(target, 'DEFDIV', 0); @@ -11482,7 +11503,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(target, 'inconfort')) { let inconfortValeur = attributeAsInt(target, "inconfortValeur", 0); defense -= inconfortValeur; - explications.push("L'adversaire est g\xEAn\xE9 par son armure : -" + inconfortValeur + " en DEF"); + explications.push("L'adversaire est gêné par son armure : -" + inconfortValeur + " en DEF"); } let formeDarbre; if (attributeAsBool(target, 'formeDArbre')) { @@ -11491,12 +11512,12 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'statueDeBois')) defense = 10; else if (attributeAsBool(target, 'petrifie')) defense = 5; - // Malus de d\xE9fense global pour les longs combats + // Malus de défense global pour les longs combats let combat = stateCOF.combat; if (combat && reglesOptionelles.haute_DEF.val.usure_DEF.val && !combat.usureOff && combat.tour > 1) defense -= (Math.floor((combat.tour - 1) / reglesOptionelles.haute_DEF.val.usure_DEF.val) * 2); - // Autres modificateurs de d\xE9fense + // Autres modificateurs de défense defense += attributeAsInt(target, 'defenseTotale', 0); let pacifisme = predicateAsInt(target, 'pacifisme', 0, 5); if (pacifisme > 0 && !attributeAsBool(target, 'attributDeCombat_pacifismeAnnule')) @@ -11517,14 +11538,14 @@ var COFantasy = COFantasy || function() { bonusPeau = Math.ceil(bonusPeau * 1.5); } defense += bonusPeau; - explications.push("Peau d'\xE9corce : +" + bonusPeau + " en DEF"); + explications.push("Peau d'écorce : +" + bonusPeau + " en DEF"); if (peauIntense && evt && !options.test) removeTokenAttr(target, 'peauDEcorceTempeteDeManaIntense', evt); } if (attributeAsBool(target, 'peauDEcorceAmeLiee')) { let bonus = getIntValeurOfEffet(target, 'peauDEcorceAmeLiee', 1); defense += bonus; - explications.push("Peau d'\xE9corce li\xE9e : +" + bonus + " en DEF"); + explications.push("Peau d'écorce liée : +" + bonus + " en DEF"); } if (attributeAsBool(target, 'champDeProtection')) { let bonusChamp = @@ -11544,13 +11565,13 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'sixiemeSens')) { defense += 2; - explications.push("Sixi\xE8me sens : +2 DEF"); + explications.push("Sixième sens : +2 DEF"); } if (getState(target, 'surpris')) defense -= 5; if (getState(target, 'renverse')) defense -= 5; if (getState(target, 'aveugle') || attributeAsBool(target, 'aveugleManoeuvre')) { if (options.contact && predicateAsBool(target, 'radarMental') && attaquant && !estNonVivant(attaquant)) { - explications.push(tokenName + " est aveugle, mais b\xE9n\xE9ficie de son radar mental"); + explications.push(tokenName + " est aveugle, mais bénéficie de son radar mental"); } else { defense -= 5; } @@ -11560,7 +11581,7 @@ var COFantasy = COFantasy || function() { if (getState(target, 'invisible') && attaquant && !attributeAsBool(attaquant, 'detectionDeLInvisible')) { if (options.distance) { if (options.tirAveugle) { - explications.push("Cible invisible, mais " + nomPerso(attaquant) + " sait tirer \xE0 l'aveugle"); + explications.push("Cible invisible, mais " + nomPerso(attaquant) + " sait tirer à l'aveugle"); } else { defense += 10; explications.push("Invisible : +10 en DEF"); @@ -11596,13 +11617,13 @@ var COFantasy = COFantasy || function() { defense += modCarac(target, 'intelligence'); } if (attributeAsBool(target, 'armeSecreteBarde')) { - explications.push(tokenName + " est d\xE9stabilis\xE9 par une action de charme => -10 en DEF"); + explications.push(tokenName + " est déstabilisé par une action de charme => -10 en DEF"); defense -= 10; } if (options.metal && attributeAsBool(target, 'magnetisme')) { let magnetisme = getIntValeurOfEffet(target, 'magnetisme', 5); defense += magnetisme; - explications.push(tokenName + " contr\xF4le le magn\xE9tisme (+" + magnetisme + " DEF)"); + explications.push(tokenName + " contrôle le magnétisme (+" + magnetisme + " DEF)"); } if (attributeAsBool(target, 'diversionManoeuvre')) { let diversion = getIntValeurOfEffet(target, 'diversionManoeuvre', -5); @@ -11611,7 +11632,7 @@ var COFantasy = COFantasy || function() { } if (options.attaqueMentale && predicateAsBool(target, 'bouclierPsi')) { defense += 5; - explications.push(tokenName + " b\xE9n\xE9ficie d'un bouclier psi => +5 DEF"); + explications.push(tokenName + " bénéficie d'un bouclier psi => +5 DEF"); } if (attributeAsBool(target, 'monteSur')) { if (predicateAsBool(target, 'montureLoyale')) { @@ -11620,7 +11641,7 @@ var COFantasy = COFantasy || function() { } if (options.contact && predicateAsBool(target, "horsDePortee")) { defense += 5; - explications.push(tokenName + " est hors de port\xE9e sur sa monture => +5 DEF"); + explications.push(tokenName + " est hors de portée sur sa monture => +5 DEF"); } } let attrsProtegePar = findObjs({ @@ -11636,20 +11657,20 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes = evt.deletedAttributes || []; evt.deletedAttributes.push(attr); attr.remove(); - sendPerso(target, "n'est plus prot\xE9g\xE9 : son protecteur n'est pas sur la page"); + sendPerso(target, "n'est plus protégé : son protecteur n'est pas sur la page"); } return; } let nameProtecteur = nomPerso(protecteur); if (!isActive(protecteur)) { - explications.push(nameProtecteur + " n'est pas en \xE9tat de prot\xE9ger " + + explications.push(nameProtecteur + " n'est pas en état de protéger " + tokenName); return; } let distTargetProtecteur = distanceCombat(target.token, protecteur.token, pageId); if (distTargetProtecteur > 0) { explications.push(nameProtecteur + " est trop loin de " + - tokenName + " pour le prot\xE9ger"); + tokenName + " pour le protéger"); return; } if (ficheAttributeAsInt(protecteur, 'defbouclieron', 0) === 0) { @@ -11661,9 +11682,9 @@ var COFantasy = COFantasy || function() { } let defBouclierProtecteur; if (persoEstPNJ(protecteur)) defBouclierProtecteur = 2; - else defBouclierProtecteur = ficheAttributeAsInt(protecteur, 'defbouclier', 0); + else defBouclierProtecteur = ficheAttributeAsInt(protecteur, 'defbouclier', 0) + predicateAsInt(protecteur, 'bouclierDeLaFoi', 0, 1); defense += defBouclierProtecteur; - explications.push(nameProtecteur + " prot\xE8ge " + + explications.push(nameProtecteur + " protège " + tokenName + " de son bouclier (+" + defBouclierProtecteur + " DEF)"); } }); @@ -11685,7 +11706,7 @@ var COFantasy = COFantasy || function() { let attaqueAOutrance = attributeAsInt(target, 'attaqueAOutrance', 0); if (attaqueAOutrance) { defense -= attaqueAOutrance; - explications.push("Attaque \xE0 outrance => -" + attaqueAOutrance + " DEF"); + explications.push("Attaque à outrance => -" + attaqueAOutrance + " DEF"); } let niveau = ficheAttributeAsInt(target, 'niveau', 1); let instinctSurvie = predicateAsInt(target, 'instinctDeSurvie', 0, niveau * 5); @@ -11699,7 +11720,7 @@ var COFantasy = COFantasy || function() { defense += predicateAsInt(target, 'DEF_magie', 0); if (predicateAsBool(target, 'chasseurDeSorciere')) { defense += 2; - explications.push("Chasseur de sorci\xE8re => +2 DEF"); + explications.push("Chasseur de sorcière => +2 DEF"); } } if (marcheSylvestreActive(target)) { @@ -11708,11 +11729,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'prisonVegetale')) { defense -= getIntValeurOfEffet(target, 'prisonVegetale', 2); - explications.push("Prison v\xE9g\xE9tale => -2 DEF"); + explications.push("Prison végétale => -2 DEF"); } if (attributeAsBool(target, 'toiles')) { defense -= getIntValeurOfEffet(target, 'toiles', 2); - explications.push("Entrav\xE9 => -2 DEF"); + explications.push("Entravé => -2 DEF"); } if (attributeAsBool(target, 'protectionContreLeMal') && (attaquant && estMauvais(attaquant))) { @@ -11738,7 +11759,7 @@ var COFantasy = COFantasy || function() { explications.push(msgRage + " du berserk => " + modRage + " DEF"); defense += modRage; } else if (attributeAsBool(target, 'frenesieMinotaure')) { - explications.push("Fren\xE9sie => -2 en DEF"); + explications.push("Frenésie => -2 en DEF"); defense -= 2; } let combatEnPhalange = predicateAsBool(target, 'combatEnPhalange'); @@ -11795,36 +11816,36 @@ var COFantasy = COFantasy || function() { defense += predicateAsInt(target, 'voieDesRunes', 0, 1); if (attributeAsBool(target, 'attaqueRisquee')) { defense -= 4; - explications.push("Suite \xE0 une attaque risqu\xE9e, -4 en DEF"); + explications.push("Suite à une attaque risquée, -4 en DEF"); } let armeTarget = armesEnMain(target); //peuple target.arme et armeGauche - //gestion de l'\xE9pieu + //gestion de l'épieu if (attaquant) { if (armeTarget && armeTarget.epieu && !armesEnMain(attaquant)) { defense += 2; - explications.push("\xC9pieu contre une attaque sans arme => +2 DEF"); + explications.push("Épieu contre une attaque sans arme => +2 DEF"); } } if (options.distance) { let bonusCouvert = attributeAsInt(target, 'bonusCouvert'); if (bonusCouvert) { if (attaquant && predicateAsBool(attaquant, 'joliCoup')) { - explications.push("Cible \xE0 couvert, mais " + nomPerso(attaquant) + " sait bien viser"); + explications.push("Cible à couvert, mais " + nomPerso(attaquant) + " sait bien viser"); } else { defense += bonusCouvert; - explications.push("Cible \xE0 couvert => +" + bonusCouvert + " DEF"); + explications.push("Cible à couvert => +" + bonusCouvert + " DEF"); } } if (attributeAsBool(target, 'progresserACouvert')) { if (attaquant && predicateAsBool(attaquant, 'joliCoup')) { - explications.push("Cible \xE0 couvert de bouclier, mais " + nomPerso(attaquant) + " sait bien viser"); + explications.push("Cible à couvert de bouclier, mais " + nomPerso(attaquant) + " sait bien viser"); } else { defense += 5; - explications.push("Cible \xE0 couvert de bouclier => +5 DEF"); + explications.push("Cible à couvert de bouclier => +5 DEF"); } } } - //Chair \xE0 canon + //Chair à canon if (capaciteDisponible(target, 'chairACanon', 'tour')) { let tokensChairACanon = findObjs({ _type: 'graphic', @@ -11866,15 +11887,15 @@ var COFantasy = COFantasy || function() { switch (taillePersonnage(attaquant, 4)) { case 5: defense += 2; - explications.push(nomPerso(target) + " r\xE9duit la distance => +2 en DEF"); + explications.push(nomPerso(target) + " réduit la distance => +2 en DEF"); break; case 6: defense += 3; - explications.push(nomPerso(target) + " r\xE9duit la distance => +3 en DEF"); + explications.push(nomPerso(target) + " réduit la distance => +3 en DEF"); break; case 7: defense += 4; - explications.push(nomPerso(target) + " r\xE9duit la distance => +4 en DEF"); + explications.push(nomPerso(target) + " réduit la distance => +4 en DEF"); } } if (attaquant && predicateAsBool(target, 'insignifiant')) { @@ -11891,11 +11912,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'etreinteImmole')) { defense -= 5; - explications.push(nomPerso(target) + " \xE9treint quelqu'un => -5 en DEF"); + explications.push(nomPerso(target) + " étreint quelqu'un => -5 en DEF"); } if (attributeAsBool(target, 'etreinteScorpionRatee')) { defense -= 5; - explications.push(nomPerso(target) + " est \xE9treint par un scorpion => -5 DEF"); + explications.push(nomPerso(target) + " est étreint par un scorpion => -5 DEF"); } if (attaquant && predicateAsBool(target, 'langageSombreHetre') && estElfeNoir(attaquant)) { defense += 1; @@ -11903,7 +11924,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'presenceGlaciale')) { let defenseGlaciale = getIntValeurOfEffet(target, 'presenceGlaciale', 4); - explications.push("Pr\xE9sence glaciale => +" + defenseGlaciale + " en DEF"); + explications.push("Présence glaciale => +" + defenseGlaciale + " en DEF"); defense += defenseGlaciale; } if (attributeAsBool(target, 'cyclone')) { @@ -11935,24 +11956,24 @@ var COFantasy = COFantasy || function() { defense += 10; } if (options.contact && attributeAsBool(target, 'tenirADistance')) { - explications.push("Tient l'ennemi \xE0 distance => +5 en DEF"); + explications.push("Tient l'ennemi à distance => +5 en DEF"); defense += 5; } let tm = stateCOF.tenebresMagiques; if (tm) { if (estDemon(target)) { if (eclaireParFioleDeLumiere(target, tm)) { - explications.push("Aveugl\xE9 par la fiole de lumi\xE8re => -2 en DEF"); + explications.push("Aveuglé par la fiole de lumière => -2 en DEF"); defense -= 2; } } else if (attaquant && !eclaireParFioleDeLumiere(attaquant, tm)) { - explications.push("T\xE9n\xE8bres magiques => -5 en DEF"); + explications.push("Ténèbres magiques => -5 en DEF"); defense -= 5; } } if (attributeAsBool(target, 'agrippeParUnDemon')) { - explications.push("agripp\xE9 => -3 en DEF"); + explications.push("agrippé => -3 en DEF"); defense -= 3; } if (estNecromancie(options) && attributeAsBool(target, 'sangDeLArbreCoeur')) { @@ -11960,7 +11981,7 @@ var COFantasy = COFantasy || function() { defense += 5; } if (predicateAsBool(target, 'liberateurDeDorn') && estGeant(attaquant)) { - explications.push('Lib\xE9rateur de Dorn => +2 en DEF'); + explications.push('Libérateur de Dorn => +2 en DEF'); defense += 2; } let pirouettes = predicateAsInt(target, 'pirouettes', 0); @@ -11978,14 +11999,14 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'paradeCroisee')) { let bonus = getIntValeurOfEffet(target, 'paradeCroisee', 2); - explications.push("Parade crois\xE9e => +" + bonus + " en DEF"); + explications.push("Parade croisée => +" + bonus + " en DEF"); defense += bonus; } let conditions = attributeAsInt(target, 'conditionsHostiles', 0, 2); if (conditions > 0 && (!predicateAsBool(target, 'marcheSylvestre') || conditions > 4)) { let msgConditions = "Conditions "; if (conditions < 5) msgConditions += "hostiles"; - else msgConditions += "extr\xEAmes"; + else msgConditions += "extrêmes"; msgConditions += " : -" + conditions + " en DEF"; explications.push(msgConditions); defense -= conditions; @@ -12005,7 +12026,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(target, 'detournerLeRegard')) { let bonus = getIntValeurOfEffet(target, 'detournerLeRegard', 2); if (bonus < 5) { - explications.push("D\xE9tourne le regard => -" + bonus + " en DEF"); + explications.push("Détourne le regard => -" + bonus + " en DEF"); } else { explications.push("Ferme les yeux => -" + bonus + " en DEF"); } @@ -12013,13 +12034,13 @@ var COFantasy = COFantasy || function() { } defense += predicateAsInt(target, 'DEF', 0); if (attaquant && predicateAsBool(target, 'armeDeLEte') && predicateAsBool(attaquant, 'creatureDeLHiver')) { - explications.push("Prot\xE9g\xE9 par une arme de l'\xE9t\xE9 => +25 en DEF"); + explications.push("Protégé par une arme de l'été => +25 en DEF"); defense += 25; } return defense; } - // renvoie l'attribut cr\xE9\xE9 ou mis \xE0 jour + // renvoie l'attribut créé ou mis à jour function setAttrDuree(perso, attr, duree, evt, msg, secret) { let options = { maxVal: getInit(), @@ -12029,23 +12050,23 @@ var COFantasy = COFantasy || function() { return setTokenAttr(perso, attr, duree, evt, options); } - //Tous les bonus de DM normalement calcul\xE9s dans bonusAttaqueA + //Tous les bonus de DM normalement calculés dans bonusAttaqueA function bonusDMA(attaquant, weaponName, evt, explications, options) { if (options.pasDeDmg) return; options.bonusDM = 0; if (attributeAsBool(attaquant, 'baroudHonneurActif')) { - explications.push(nomPerso(attaquant) + " porte une derni\xE8re attaque et s'effondre"); + explications.push(nomPerso(attaquant) + " porte une dernière attaque et s'effondre"); mort(attaquant, function(m) { explications.push(m); }, evt); removeTokenAttr(attaquant, 'baroudHonneurActif', evt); } if (attributeAsBool(attaquant, 'reactionViolente')) { - explications.push("R\xE9action violente => +1d6 DM"); + explications.push("Réaction violente => +1d6 DM"); options.reactionViolente = true; } if (attributeAsBool(attaquant, 'drainDeForce')) { - explications.push("Force drain\xE9e => -2 aux DM"); + explications.push("Force drainée => -2 aux DM"); options.drainDeForce = true; } if (options.contact) { @@ -12056,11 +12077,11 @@ var COFantasy = COFantasy || function() { explications.push(msg); } if (attributeAsBool(attaquant, 'enrage')) { - explications.push("Enrag\xE9 => +1d6 DM"); + explications.push("Enragé => +1d6 DM"); options.enrage = true; } if (attributeAsBool(attaquant, 'rage')) { - explications.push("Enrag\xE9 => +2 DM"); + explications.push("Enragé => +2 DM"); options.rage = true; } let rageBerserk = tokenAttribute(attaquant, 'rageDuBerserk'); @@ -12074,7 +12095,7 @@ var COFantasy = COFantasy || function() { options.rageBerserk = 1; } } else if (attributeAsBool(attaquant, 'frenesieMinotaure')) { - explications.push("Fr\xE9n\xE9sie : +1d6 aux DM"); + explications.push("Frénésie : +1d6 aux DM"); options.rageBerserk = 1; } if (predicateAsBool(attaquant, 'ambidextreDuelliste')) { @@ -12144,7 +12165,7 @@ var COFantasy = COFantasy || function() { let gobant = persoOfIdName(attrGobe[0].get('current'), attaquant.token.get('pageid')); if (gobant === undefined) { - error("Attribut estGobePar mal form\xE9", attrGobe[0].get('current')); + error("Attribut estGobePar mal formé", attrGobe[0].get('current')); attrGobe[0].remove(); unlockToken(attaquant, evt); } else { @@ -12163,7 +12184,7 @@ var COFantasy = COFantasy || function() { let energieImpie = attributeAsInt(attaquant, 'energieImpie', 0); if (energieImpie) { options.bonusDM += energieImpie; - explications.push("\xC9nergie impie => +" + energieImpie + " DM"); + explications.push("Énergie impie => +" + energieImpie + " DM"); } if (options.arcComposite) { let force = modCarac(attaquant, 'force'); @@ -12178,7 +12199,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(attaquant, 'fievreux')) { options.fievreux = true; - explications.push("Fi\xE9vreu" + onGenre(attaquant, 'x', 'se') + " => -2 DM"); + explications.push("Fiévreu" + onGenre(attaquant, 'x', 'se') + " => -2 DM"); } if (options.expertDuCombatDM && !options.pasDeDmg) { let valDesExpert = options.rolls.expertDuCombatDM || rollDePlus(6); @@ -12205,7 +12226,7 @@ var COFantasy = COFantasy || function() { let masqueIntense = attributeAsInt(attaquant, 'masqueDuPredateurTempeteDeManaIntense', 0); bonusMasque += masqueIntense; options.bonusDM += bonusMasque; - explications.push("Masque du pr\xE9dateur : +" + bonusMasque + " aux DM"); + explications.push("Masque du prédateur : +" + bonusMasque + " aux DM"); if (masqueIntense) removeTokenAttr(attaquant, 'masqueDuPredateurTempeteDeManaIntense', evt); } else if (attributeAsBool(attaquant, 'masqueDuPredateurAmeLiee')) { @@ -12213,7 +12234,7 @@ var COFantasy = COFantasy || function() { getIntValeurOfEffet(attaquant, 'masqueDuPredateurAmeLiee', 1); if (bonusMasque > 0) { options.bonusDM += bonusMasque; - explications.push("Masque du pr\xE9dateur li\xE9 : +" + bonusMasque + " aux DM"); + explications.push("Masque du prédateur lié : +" + bonusMasque + " aux DM"); } } if (options.attaqueFlamboyante && options.contact) { @@ -12226,7 +12247,7 @@ var COFantasy = COFantasy || function() { let bonus = getIntValeurOfEffet(attaquant, 'detournerLeRegard', 2); let msg; if (bonus < 5) { - msg = "D\xE9tourne le regard"; + msg = "Détourne le regard"; } else { msg = "Ferme les yeux"; } @@ -12237,7 +12258,7 @@ var COFantasy = COFantasy || function() { return; } - //Bonus en Attaque qui ne d\xE9pendent pas du d\xE9fenseur + //Bonus en Attaque qui ne dépendent pas du défenseur //Remplit le champs options.bonusDM (en partant de 0) function bonusAttaqueA(attaquant, weaponName, evt, explications, options) { let attBonus = 0; @@ -12249,16 +12270,16 @@ var COFantasy = COFantasy || function() { attBonus += 2; if (options.tirDouble.stats && options.tirDouble.stats.name) { explications.push(nomPerso(attaquant) + " tire avec " + - weaponName + " et " + options.tirDouble.stats.name + " \xE0 la fois !"); + weaponName + " et " + options.tirDouble.stats.name + " à la fois !"); } else { explications.push(nomPerso(attaquant) + " tire avec 2 " + - weaponName + "s \xE0 la fois !"); + weaponName + "s à la fois !"); } } if (options.chance) { attBonus += options.chance; let pc = options.chance / 10; - explications.push(pc + " point" + ((pc > 1) ? "s" : "") + " de chance d\xE9pens\xE9 => +" + options.chance + " en Attaque"); + explications.push(pc + " point" + ((pc > 1) ? "s" : "") + " de chance dépensé => +" + options.chance + " en Attaque"); } if (options.semonce) { attBonus += 5; @@ -12276,7 +12297,7 @@ var COFantasy = COFantasy || function() { } if (options.attaqueAssuree) { attBonus += 5; - explications.push("Attaque assur\xE9e => +5 en Attaque et DM/2"); + explications.push("Attaque assurée => +5 en Attaque et DM/2"); } if (ficheAttributeAsBool(attaquant, 'attaque_dm_temp_check')) { options.attaqueDmTemp = true; @@ -12300,11 +12321,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(attaquant, 'criDuPredateur')) { attBonus += 1; - explications.push("Cri du pr\xE9dateur => +1 en attaque"); + explications.push("Cri du prédateur => +1 en attaque"); } if (attributeAsBool(attaquant, 'baroudHonneurActif')) { attBonus += 5; - explications.push(nomPerso(attaquant) + " porte une derni\xE8re attaque et s'effondre"); + explications.push(nomPerso(attaquant) + " porte une dernière attaque et s'effondre"); mort(attaquant, function(m) { explications.push(m); }, evt); @@ -12319,7 +12340,7 @@ var COFantasy = COFantasy || function() { let cavalierEm = predicateAsInt(attaquant, 'cavalierEmerite'); if (cavalierEm) { attBonus += cavalierEm; - let explCavalierEmerite = "avalier \xE9m\xE9rite => +" + cavalierEm + " en Attaque"; + let explCavalierEmerite = "avalier émérite => +" + cavalierEm + " en Attaque"; if (options.displayName) { explCavalierEmerite = nomPerso(attaquant) + " est un c" + explCavalierEmerite; } else { @@ -12343,15 +12364,15 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(attaquant, 'reactionViolente')) { attBonus += 2; if (options.pasDeDmg) - explications.push("R\xE9action violente => +2 en Attaque"); + explications.push("Réaction violente => +2 en Attaque"); else { - explications.push("R\xE9action violente => +2 en Attaque et +1d6 DM"); + explications.push("Réaction violente => +2 en Attaque et +1d6 DM"); options.reactionViolente = true; } } if (attributeAsBool(attaquant, 'drainDeForce')) { attBonus -= 2; - let msg = "Force drain\xE9e => -2 en Attaque"; + let msg = "Force drainée => -2 en Attaque"; if (options.pasDeDmg || !options.contact) explications.push(msg); else explications.push(msg + " et aux DM"); options.drainDeForce = true; @@ -12359,7 +12380,7 @@ var COFantasy = COFantasy || function() { let energieImpie = attributeAsInt(attaquant, 'energieImpie', 0); if (energieImpie) { attBonus += energieImpie; - let msg = "\xC9nergie impie => +" + energieImpie + " en Attaque"; + let msg = "Énergie impie => +" + energieImpie + " en Attaque"; if (!options.pasDeDmg) { msg += " et aux DM"; options.bonusDM += energieImpie; @@ -12379,21 +12400,21 @@ var COFantasy = COFantasy || function() { attBonus += 5; options.enrage = true; if (options.pasDeDmg) - explications.push("Enrag\xE9 => +5 en Attaque"); + explications.push("Enragé => +5 en Attaque"); else - explications.push("Enrag\xE9 => +5 en Attaque et +1d6 DM"); + explications.push("Enragé => +5 en Attaque et +1d6 DM"); } if (attributeAsBool(attaquant, 'rage')) { attBonus += 2; if (options.pasDeDmg) - explications.push("Enrag\xE9 => +2 en Attaque"); + explications.push("Enragé => +2 en Attaque"); else - explications.push("Enrag\xE9 => +2 en Attaque et +2 DM"); + explications.push("Enragé => +2 en Attaque et +2 DM"); options.rage = true; } if (attributeAsBool(attaquant, 'aspectDuDemon')) { attBonus += getIntValeurOfEffet(attaquant, 'aspectDuDemon', 2); - explications.push("Aspect de d\xE9mon => +2 en Attaque"); + explications.push("Aspect de démon => +2 en Attaque"); } let rageBerserk = tokenAttribute(attaquant, 'rageDuBerserk'); if (rageBerserk.length > 0) { @@ -12420,9 +12441,9 @@ var COFantasy = COFantasy || function() { } else if (attributeAsBool(attaquant, 'frenesieMinotaure')) { attBonus += 2; if (options.pasDeDmg) - explications.push("Fr\xE9n\xE9sie : +2 en Attaque"); + explications.push("Frénésie : +2 en Attaque"); else - explications.push("Fr\xE9n\xE9sie : +2 en Attaque et +1d6 aux DM"); + explications.push("Frénésie : +2 en Attaque et +1d6 aux DM"); options.rageBerserk = 1; } if (ficheAttributeAsBool(attaquant, 'attaque_risquee_check')) { @@ -12430,7 +12451,7 @@ var COFantasy = COFantasy || function() { } if (options.attaqueRisquee) { attBonus += 2; - explications.push("Attaque risqu\xE9e => +2 en Attaque"); + explications.push("Attaque risquée => +2 en Attaque"); if (!options.test) { setAttrDuree(attaquant, 'attaqueRisquee', 1, evt); } @@ -12489,7 +12510,7 @@ var COFantasy = COFantasy || function() { pv = parseInt(attaquant.token.get('bar1_value')); if (pv <= frenesie) { attBonus += 2; - explications.push("Fr\xE9n\xE9sie => +2 en Attaque"); + explications.push("Frénésie => +2 en Attaque"); } } if (predicateAsBool(attaquant, 'hausserLeTon')) { @@ -12533,18 +12554,18 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(attaquant, 'enerve')) { attBonus -= 2; - explications.push("Attaquant \xE9nerv\xE9 => -2 en Attaque"); + explications.push("Attaquant énervé => -2 en Attaque"); } if (attributeAsBool(attaquant, 'osBrises')) { attBonus -= 2; - explications.push("Des os sont bris\xE9s => -2 en Attaque"); + explications.push("Des os sont brisés => -2 en Attaque"); } let attrGobe = tokenAttribute(attaquant, 'estGobePar'); if (attrGobe.length > 0) { let gobant = persoOfIdName(attrGobe[0].get('current'), attaquant.token.get('pageid')); if (gobant === undefined) { - error("Attribut estGobePar mal form\xE9", attrGobe[0].get('current')); + error("Attribut estGobePar mal formé", attrGobe[0].get('current')); attrGobe[0].remove(); unlockToken(attaquant, evt); } else { @@ -12586,7 +12607,7 @@ var COFantasy = COFantasy || function() { } if (actif) { attBonus += 1; - explications.push("Arme de pr\xE9dil\xE9ction => +1 en Attaque"); + explications.push("Arme de prédiléction => +1 en Attaque"); } } if (options.arcComposite) { @@ -12609,7 +12630,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(attaquant, 'fievreux')) { attBonus -= 2; options.fievreux = true; - explications.push("Fi\xE9vreu" + onGenre(attaquant, 'x', 'se') + " => -2 en Att. et DM"); + explications.push("Fiévreu" + onGenre(attaquant, 'x', 'se') + " => -2 en Att. et DM"); } if (options.expertDuCombatTouche) { let valDesExpert = options.rolls.expertDuCombatTouche || rollDePlus(6); @@ -12682,7 +12703,7 @@ var COFantasy = COFantasy || function() { if (conditions > 0 && (!predicateAsBool(attaquant, 'marcheSylvestre') || conditions > 4)) { let msgConditions = "Conditions "; if (conditions < 5) msgConditions += "hostiles"; - else msgConditions += "extr\xEAmes"; + else msgConditions += "extrêmes"; msgConditions += " : -" + conditions + " en attaque"; explications.push(msgConditions); attBonus -= conditions; @@ -12713,15 +12734,20 @@ var COFantasy = COFantasy || function() { value: '1d6', }); } + if (estMortVivant(attaquant) && dansAuraDeProfanation(attaquant)) { + attBonus += 1; + options.bonusDM += 1; + explications.push("Aura de profanation => +1 Attaque et DM"); + } return attBonus; } - //Tous les bonus de DM normalement calcul\xE9s dans bonusAttaqueD + //Tous les bonus de DM normalement calculés dans bonusAttaqueD function bonusDMD(attaquant, target, portee, pageId, evt, explications, options) { let chasseurEmerite = predicateAsBool(attaquant, 'chasseurEmerite') && estAnimal(target); if (chasseurEmerite) { - let explChasseurEmerite = "hasseur \xE9m\xE9rite => +2 aux DM"; + let explChasseurEmerite = "hasseur émérite => +2 aux DM"; if (options.displayName) { explChasseurEmerite = nomPerso(attaquant) + ' est un c' + explChasseurEmerite; } else { @@ -12740,7 +12766,7 @@ var COFantasy = COFantasy || function() { }); }); if (ennemiJure) { - let explEnnemiJure = "Attaque sur ennemi jur\xE9 => + 1d6 aux DM"; + let explEnnemiJure = "Attaque sur ennemi juré => + 1d6 aux DM"; if (options.aoe) explEnnemiJure += " contre " + nomPerso(target); explications.push(explEnnemiJure); target.ennemiJure = true; @@ -12766,7 +12792,7 @@ var COFantasy = COFantasy || function() { let attrFeinte = tokenAttribute(target, 'feinte_' + nomPerso(attaquant)); if (attrFeinte.length > 0 && attrFeinte[0].get('current')) { let niveauTouche = attrFeinte[0].get('max'); - if (niveauTouche > 0) { //La feinte avait touch\xE9 cette cible + if (niveauTouche > 0) { //La feinte avait touché cette cible let msgFeinte = "Feinte => "; let faireMouche = predicateAsInt(attaquant, 'faireMouche', 0); if (faireMouche > 0) { @@ -12791,7 +12817,7 @@ var COFantasy = COFantasy || function() { let cibleAgrippee = persoOfIdName(a.get('current'), pageId); if (cibleAgrippee && cibleAgrippee.id == target.id && !attributeAsBool(cibleAgrippee, 'agrippeParUnDemon')) { - explications.push("Cible agripp\xE9e => +1d6 DM"); + explications.push("Cible agrippée => +1d6 DM"); target.estAgrippee = true; } }); @@ -12814,15 +12840,15 @@ var COFantasy = COFantasy || function() { } } if (predicateAsBool(attaquant, 'liberateurDeDorn') && estGeant(target)) { - explications.push("Lib\xE9rateur de Dorn => +2d6 DM"); + explications.push("Libérateur de Dorn => +2d6 DM"); target.cibleLiberateurDeDorn = true; } if (predicateAsBool(attaquant, 'liberateurDeKerserac') && (estGeant(target) || estInsecte(target) || estElfeNoir(target))) { - explications.push("Lib\xE9rateur de Kerserac => +1d6 DM"); + explications.push("Libérateur de Kerserac => +1d6 DM"); target.cibleLiberateurDeKerserac = true; } if (predicateAsBool(attaquant, 'liberateurDAnathazerin') && (estInsecte(target) || estElfeNoir(target))) { - explications.push("Lib\xE9rateur d'Anathazer\xEFn => +2d6 DM"); + explications.push("Libérateur d'Anathazerïn => +2d6 DM"); target.cibleLiberateurDAnathazerin = true; } let attrMeneurCible = tokenAttribute(target, 'meneurDHommesCible'); @@ -12832,7 +12858,7 @@ var COFantasy = COFantasy || function() { if (meneurDHommes && alliesParPerso[meneurDHommes.charId] && alliesParPerso[meneurDHommes.charId].has(attaquant.charId)) { target.cibleMeneurDHommes = true; - explications.push(nomPerso(meneurDHommes) + " a d\xE9sign\xE9 " + nomPerso(target) + + explications.push(nomPerso(meneurDHommes) + " a désigné " + nomPerso(target) + " comme la cible des attaques du groupe : +1d6 DM"); } } @@ -12848,22 +12874,22 @@ var COFantasy = COFantasy || function() { return; } - //Bonus d'attaque qui d\xE9pendent de la cible + //Bonus d'attaque qui dépendent de la cible function bonusAttaqueD(attaquant, target, portee, pageId, evt, explications, options) { let attBonus = 0; if (target.bonusAttaque) attBonus += target.bonusAttaque; if (getState(attaquant, 'aveugle')) { if (options.distance) { if (options.tirAveugle) { - explications.push("Attaquant aveugl\xE9, mais il sait tirer \xE0 l'aveugle"); + explications.push("Attaquant aveuglé, mais il sait tirer à l'aveugle"); } else { attBonus -= 10; - explications.push("Attaquant aveugl\xE9 => -10 en Attaque \xE0 distance"); + explications.push("Attaquant aveuglé => -10 en Attaque à distance"); } } else { if (!predicateAsBool(attaquant, 'radarMental') || estNonVivant(target)) { attBonus -= 5; - explications.push("Attaquant aveugl\xE9 => -5 en Attaque"); + explications.push("Attaquant aveuglé => -5 en Attaque"); } } } else if (attributeAsBool(attaquant, 'aveugleManoeuvre')) { @@ -12871,24 +12897,24 @@ var COFantasy = COFantasy || function() { attBonus -= 5; options.aveugleManoeuvre = true; if (options.pasDeDmg) - explications.push("Attaquant aveugl\xE9 => -5 en Attaque"); + explications.push("Attaquant aveuglé => -5 en Attaque"); else - explications.push("Attaquant aveugl\xE9 => -5 en Attaque et aux DM"); + explications.push("Attaquant aveuglé => -5 en Attaque et aux DM"); } } else if (getState(attaquant, 'invisible') && !attributeAsBool(target, 'detectionDeLInvisible')) { attBonus += 5; explications.push("Attaque venant d'un personnage invisible => +5 en Attaque"); } else if (options.distance && getState(attaquant, 'penombre')) { if (options.tirAveugle) { - explications.push("Attaquant dans la p\xE9nombre, mais il sait tirer \xE0 l'aveugle"); + explications.push("Attaquant dans la pénombre, mais il sait tirer à l'aveugle"); } else { attBonus -= 5; - explications.push("Attaquant dans la p\xE9nombre => -5 en Attaque \xE0 distance"); + explications.push("Attaquant dans la pénombre => -5 en Attaque à distance"); } } if (options.mainsDEnergie) { - if (options.aoe) error("Mains d'\xE9nergie n'est pas compatible avec les AOE", options.aoe); - // On v\xE9rifie si la cible porte une armure + if (options.aoe) error("Mains d'énergie n'est pas compatible avec les AOE", options.aoe); + // On vérifie si la cible porte une armure let targetArmorDef = 0; if (persoEstPNJ(target)) { if (ficheAttributeAsBool(target, 'defarmureon', false)) targetArmorDef = 5; @@ -12897,11 +12923,11 @@ var COFantasy = COFantasy || function() { } if (isNaN(targetArmorDef) || targetArmorDef === 0) { attBonus += 2; - explications.push("Mains d'\xE9nergie => +2 en Attaque (cible sans armure)"); + explications.push("Mains d'énergie => +2 en Attaque (cible sans armure)"); } else { let bonusMain = Math.min(5, 2 + targetArmorDef); attBonus += bonusMain; - explications.push("Mains d'\xE9nergie => +" + bonusMain + " en Attaque"); + explications.push("Mains d'énergie => +" + bonusMain + " en Attaque"); } } if (options.aoe === undefined && options.auto === undefined && portee > 0) { @@ -12913,7 +12939,7 @@ var COFantasy = COFantasy || function() { predicateAsBool(attaquant, 'chasseurEmerite') && estAnimal(target); if (chasseurEmerite) { attBonus += 2; - let explChasseurEmerite = "hasseur \xE9m\xE9rite => +2 en Attaque"; + let explChasseurEmerite = "hasseur émérite => +2 en Attaque"; if (options.displayName) { explChasseurEmerite = nomPerso(attaquant) + ' est un c' + explChasseurEmerite; } else { @@ -12935,7 +12961,7 @@ var COFantasy = COFantasy || function() { if (ennemiJure) { let ejSag = modCarac(attaquant, 'sagesse'); attBonus += ejSag; - let explEnnemiJure = "Attaque sur ennemi jur\xE9 => +" + ejSag + " en attaque"; + let explEnnemiJure = "Attaque sur ennemi juré => +" + ejSag + " en attaque"; if (!options.pasDeDmg) explEnnemiJure += " et +1d6 aux DM"; if (options.aoe) explEnnemiJure += " contre " + nomPerso(target); explications.push(explEnnemiJure); @@ -12970,9 +12996,9 @@ var COFantasy = COFantasy || function() { if (options.tueurDeGeants && estGeant(target)) { attBonus += 2; if (options.pasDeDmg) - explications.push("Tueur de g\xE9ant => +2 en Attaque"); + explications.push("Tueur de géant => +2 en Attaque"); else - explications.push("Tueur de g\xE9ant => +2 att. et 2d6 DM"); + explications.push("Tueur de géant => +2 att. et 2d6 DM"); target.tueurDeGeants = true; } if (options.tueurDe) { @@ -12996,7 +13022,7 @@ var COFantasy = COFantasy || function() { attBonus += bonusFeinte; let msgFeinte = "Feinte => +" + bonusFeinte + " en attaque"; let niveauTouche = attrFeinte[0].get('max'); - if (niveauTouche > 0) { //La feinte avait touch\xE9 cette cible + if (niveauTouche > 0) { //La feinte avait touché cette cible let faireMouche = predicateAsInt(attaquant, 'faireMouche', 0); if (faireMouche > 0) { if (options.contact && !options.pasDeDmg) { @@ -13026,7 +13052,7 @@ var COFantasy = COFantasy || function() { }); if (expose) { attBonus += 10; - explications.push("L'adversaire est expos\xE9 : +10"); + explications.push("L'adversaire est exposé : +10"); } } if (options.contact) { @@ -13035,7 +13061,7 @@ var COFantasy = COFantasy || function() { ficheAttributeAsInt(attaquant, 'force', 10) <= ficheAttributeAsInt(target, 'force', 10) && parseInt(attaquant.token.get("bar1_max")) <= parseInt(target.token.get("bar1_max"))) { attBonus -= 2; - explications.push("Effray\xE9 => -2 en Attaque"); + explications.push("Effrayé => -2 en Attaque"); } } let attrAgrippe = tokenAttribute(attaquant, 'agrippe'); @@ -13045,9 +13071,9 @@ var COFantasy = COFantasy || function() { !attributeAsBool(cibleAgrippee, 'agrippeParUnDemon')) { attBonus += 5; if (options.pasDeDmg) - explications.push("Cible agripp\xE9e => +5 em Attaque"); + explications.push("Cible agrippée => +5 em Attaque"); else - explications.push("Cible agripp\xE9e => +5 att. et 1d6 DM"); + explications.push("Cible agrippée => +5 att. et 1d6 DM"); target.estAgrippee = true; } }); @@ -13064,7 +13090,7 @@ var COFantasy = COFantasy || function() { _pageid: pageId, layer: 'objects' }); - //On compte les tokens au contact de l'attaquant et du d\xE9fenseur et alli\xE9s de l'attaquant + //On compte les tokens au contact de l'attaquant et du défenseur et alliés de l'attaquant let allies = alliesParPerso[attaquant.charId]; if (allies) { let alliesAuContact = 0; @@ -13122,7 +13148,7 @@ var COFantasy = COFantasy || function() { if (tm) { if (estDemon(attaquant)) { if (eclaireParFioleDeLumiere(attaquant, tm)) { - explications.push("Aveugl\xE9 par la fiole de lumi\xE8re => -2 en Attaque"); + explications.push("Aveuglé par la fiole de lumière => -2 en Attaque"); attBonus -= 2; } } else if (!eclaireParFioleDeLumiere(target, tm)) { @@ -13147,34 +13173,34 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(attaquant, 'liberateurDeDorn') && estGeant(target)) { attBonus += 2; if (options.pasDeDmg) { - explications.push("Lib\xE9rateur de Dorn => +2 en attaque"); + explications.push("Libérateur de Dorn => +2 en attaque"); } else { - explications.push("Lib\xE9rateur de Dorn => +2 en attaque et +2d6 DM"); + explications.push("Libérateur de Dorn => +2 en attaque et +2d6 DM"); target.cibleLiberateurDeDorn = true; } } if (predicateAsBool(attaquant, 'liberateurDeKerserac') && (estGeant(target) || estInsecte(target) || estElfeNoir(target))) { attBonus += 2; if (options.pasDeDmg) { - explications.push("Lib\xE9rateur de Kerserac => +2 en attaque"); + explications.push("Libérateur de Kerserac => +2 en attaque"); } else { - explications.push("Lib\xE9rateur de Kerserac => +2 en attaque et +1d6 DM"); + explications.push("Libérateur de Kerserac => +2 en attaque et +1d6 DM"); target.cibleLiberateurDeKerserac = true; } } if (predicateAsBool(attaquant, 'liberateurDAnathazerin') && (estInsecte(target) || estElfeNoir(target))) { attBonus += 2; if (options.pasDeDmg) { - explications.push("Lib\xE9rateur d'Anathazer\xEFn => +2 en attaque"); + explications.push("Libérateur d'Anathazerïn => +2 en attaque"); } else { - explications.push("Lib\xE9rateur d'Anathazer\xEFn => +2 en attaque et +2d6 DM"); + explications.push("Libérateur d'Anathazerïn => +2 en attaque et +2d6 DM"); target.cibleLiberateurDAnathazerin = true; } } if (predicateAsBool(attaquant, 'tenacite')) { let bonus = attributeAsInt(target, 'attributDeCombat_tenaciteDe' + nomPerso(attaquant), 0); if (bonus > 0) { - explications.push("T\xE9nacit\xE9 => +" + bonus + " en attaque"); + explications.push("Ténacité => +" + bonus + " en attaque"); attBonus += bonus; } } @@ -13186,7 +13212,7 @@ var COFantasy = COFantasy || function() { alliesParPerso[meneurDHommes.charId].has(attaquant.charId)) { attBonus += 2; if (!options.pasDeDmg) target.cibleMeneurDHommes = true; - explications.push(nomPerso(meneurDHommes) + " a d\xE9sign\xE9 " + nomPerso(target) + + explications.push(nomPerso(meneurDHommes) + " a désigné " + nomPerso(target) + " comme la cible des attaques du groupe : +2 attaque, +1d6 DM"); } } @@ -13252,14 +13278,14 @@ var COFantasy = COFantasy || function() { if (res.length === 0) { let ace = tokenAttribute(perso, classeEffet); if (ace.length > 0) { - error(nomPerso(perso) + " a une classe d'effets " + classeEffet + " mais pas d'effet associ\xE9", ace); + error(nomPerso(perso) + " a une classe d'effets " + classeEffet + " mais pas d'effet associé", ace); ace[0].remove(); } } return res; } - //Si le d\xE9passement de limite est possible, renvoie un nouveau depMana, sinon renvoie false + //Si le dépassement de limite est possible, renvoie un nouveau depMana, sinon renvoie false function depasseLimite(perso, nomAttr, msgImpossible, msg, evt, options) { if (options.depasseLimite) { options.mana = options.mana || 0; @@ -13276,8 +13302,8 @@ var COFantasy = COFantasy || function() { return false; } - //Retourne true si il existe une limite qui emp\xEAche de lancer le sort - //N'ajoute pas l'\xE9v\xE9nement \xE0 l'historique + //Retourne true si il existe une limite qui empêche de lancer le sort + //N'ajoute pas l'événement à l'historique //explications est optionnel function limiteRessources(personnage, options, defResource, msg, evt, explications) { let depMana = { @@ -13301,8 +13327,8 @@ var COFantasy = COFantasy || function() { } if (m > 0) { if (reglesOptionelles.mana.val.mana_totale.val) options.mana += m; - //Le plus coh\xE9rent avec la mana totale consiste \xE0 diviser ce malus par 3, - //arrondi au sup\xE9rieur + //Le plus cohérent avec la mana totale consiste à diviser ce malus par 3, + //arrondi au supérieur else options.mana += Math.ceil(m / 3); } } @@ -13311,7 +13337,7 @@ var COFantasy = COFantasy || function() { depMana = depenseManaPossible(personnage, options.mana, msg); if (!depMana) return true; } else { - error("Impossible de savoir qui doit d\xE9penser de la mana", options); + error("Impossible de savoir qui doit dépenser de la mana", options); return true; } } @@ -13320,7 +13346,7 @@ var COFantasy = COFantasy || function() { let utilisations; if (options.limiteParJour) { if (!personnage) { - error("Impossible de savoir \xE0 qui appliquer la limite journali\xE8re", options); + error("Impossible de savoir à qui appliquer la limite journalière", options); return true; } if (options.limiteParJourRessource) @@ -13389,7 +13415,7 @@ var COFantasy = COFantasy || function() { } else sendPerso(personnage, msgCombat, true); } } else { - error("Impossible de savoir \xE0 qui appliquer la limite par combat", options); + error("Impossible de savoir à qui appliquer la limite par combat", options); return true; } } @@ -13428,7 +13454,7 @@ var COFantasy = COFantasy || function() { } else sendPerso(personnage, msgCombat, options.secret); } } else { - error("Impossible de savoir \xE0 qui appliquer la limite par tour", options); + error("Impossible de savoir à qui appliquer la limite par tour", options); return true; } } @@ -13442,7 +13468,7 @@ var COFantasy = COFantasy || function() { setAttrDuree(personnage, options.tempsRecharge.effet, options.tempsRecharge.duree, evt); } } else { - error("Impossible de savoir \xE0 qui s'applique le temps de recharge", options); + error("Impossible de savoir à qui s'applique le temps de recharge", options); return true; } } @@ -13456,7 +13482,7 @@ var COFantasy = COFantasy || function() { } setTokenAttr(personnage, 'dose_' + options.dose, doses - 1, evt); } else { - error("Impossible de savoir qui doit d\xE9penser la dose", options); + error("Impossible de savoir qui doit dépenser la dose", options); return true; } } @@ -13470,7 +13496,7 @@ var COFantasy = COFantasy || function() { } setTokenAttr(personnage, nomAttr, currentAttr + 1, evt); } else { - error("Impossible de savoir \xE0 qui appliquer la limitation", options); + error("Impossible de savoir à qui appliquer la limitation", options); return true; } } @@ -13500,11 +13526,11 @@ var COFantasy = COFantasy || function() { if (personnage) { let test = testLimiteUtilisationsCapa(personnage, pred, 'tour', "ne peut plus utiliser " + pred + " ce tour", - "Action impossible, pas de pr\xE9dicat " + pred); + "Action impossible, pas de prédicat " + pred); if (test === undefined) return true; utiliseCapacite(personnage, test, evt); } else { - error("Impossible de savoir \xE0 qui appliquer la limitation du pr\xE9dicat " + pred, options); + error("Impossible de savoir à qui appliquer la limitation du prédicat " + pred, options); return true; } } @@ -13514,8 +13540,8 @@ var COFantasy = COFantasy || function() { //asynchrone //callback(resultat, crit, roll1, roll2): - // resultat peut \xEAtre 0, 1 ou 2 : 0 = match null, 1 le perso 1 gagne, 2 le perso 2 gagne. - // crit peut \xEAtre 1 si un des deux perso a fait une r\xE9ussite critique et pas l'autre, -1 si un des personnage a fait un \xE9chec critique et pas l'autre, et 0 sinon + // resultat peut être 0, 1 ou 2 : 0 = match null, 1 le perso 1 gagne, 2 le perso 2 gagne. + // crit peut être 1 si un des deux perso a fait une réussite critique et pas l'autre, -1 si un des personnage a fait un échec critique et pas l'autre, et 0 sinon function testOppose(rollId, perso1, carac1, options1, perso2, carac2, options2, explications, evt, callback) { if (carac2 === undefined) carac2 = carac1; let nom1 = nomPerso(perso1); @@ -13555,9 +13581,9 @@ var COFantasy = COFantasy || function() { let texte1 = "Jet " + deCarac(carac1) + " de " + nom1 + " : " + rt1.texte; if (reussite == 2) { if ((carac1 == 'FOR' || carac1 == 'DEX' || carac1 == 'CON') && - attributeAsBool(perso1, 'runeForgesort_\xE9nergie') && - attributeAsInt(perso1, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0) { - texte1 += "
" + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + rollId + "_roll1", "Rune d'\xE9nergie"); + attributeAsBool(perso1, 'runeForgesort_énergie') && + attributeAsInt(perso1, 'limiteParCombat_runeForgesort_énergie', 1) > 0) { + texte1 += "
" + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + rollId + "_roll1", "Rune d'énergie"); } if (!rt1.echecCritique && !rt2.critique) { let pcPerso1 = pointsDeChance(perso1); @@ -13587,9 +13613,9 @@ var COFantasy = COFantasy || function() { let texte2 = "Jet " + deCarac(carac2) + " de " + nom2 + " : " + rt2.texte; if (reussite == 1) { if ((carac2 == 'FOR' || carac2 == 'DEX' || carac2 == 'CON') && - attributeAsBool(perso2, 'runeForgesort_\xE9nergie') && - attributeAsInt(perso2, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0) { - texte2 += "
" + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + rollId + "_roll2", "Rune d'\xE9nergie"); + attributeAsBool(perso2, 'runeForgesort_énergie') && + attributeAsInt(perso2, 'limiteParCombat_runeForgesort_énergie', 1) > 0) { + texte2 += "
" + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + rollId + "_roll2", "Rune d'énergie"); } if (!rt2.echecCritique && !rt1.critique) { let pcPerso2 = pointsDeChance(perso2); @@ -13617,14 +13643,14 @@ var COFantasy = COFantasy || function() { explications.push(m); }); callback(reussite, crit, rt1.roll, rt2.roll); - }); //Fin du jet du deuxi\xE8me perso + }); //Fin du jet du deuxième perso }); //Fin du jet du premier perso } function bonusPlusViteQueSonOmbre(perso, arme) { let p = predicateAsBool(perso, 'plusViteQueSonOmbre'); if (!p) return 0; - // L'arme doit \xEAtre charg\xE9e + // L'arme doit être chargée if (arme.charge && attributeAsInt(perso, 'charge_' + arme.label, 0) === 0) return 0; if (p === true) { @@ -13643,7 +13669,7 @@ var COFantasy = COFantasy || function() { return 0; } - // prend en compte l'unit\xE9 de mesure utilis\xE9e sur la page + // prend en compte l'unité de mesure utilisée sur la page function ajouteUneLumiere(perso, nomLumiere, radius, dimRadius, evt) { radius = scaleDistance(perso, radius); if (dimRadius !== '') dimRadius = scaleDistance(perso, dimRadius); @@ -13654,7 +13680,7 @@ var COFantasy = COFantasy || function() { let brightLight = radius; if (udl) { if (isNaN(brightLight) || brightLight < 0) { - error("Lumi\xE8re avec un rayon n\xE9gatif", radius); + error("Lumière avec un rayon négatif", radius); return; } } @@ -13662,7 +13688,7 @@ var COFantasy = COFantasy || function() { if (ct.get('bar1_link') === '') attrName += "_" + ct.get('name'); if (ct.get('bar1_max')) { let lumiereSurPerso; - //Cas particulier o\xF9 le personnage est un vrai personnage qui ne fait pas de lumi\xE8re + //Cas particulier où le personnage est un vrai personnage qui ne fait pas de lumière if (!udl && !ct.get('light_radius')) { lumiereSurPerso = true; setToken(ct, 'light_radius', radius, evt); @@ -13707,7 +13733,7 @@ var COFantasy = COFantasy || function() { name: nomLumiere, }); if (tokLumiere === undefined) { - error("Probl\xE8me lors de la cr\xE9ation du token de lumi\xE8re", perso); + error("Problème lors de la création du token de lumière", perso); return; } evt.tokens = [tokLumiere]; @@ -13729,7 +13755,7 @@ var COFantasy = COFantasy || function() { setToken(tokLumiere, 'light_dimradius', dimRadius, evt); setToken(tokLumiere, 'light_otherplayers', true, evt); } - if (ct.get('bar1_max')) { //Lumi\xE8re li\xE9e \xE0 un token + if (ct.get('bar1_max')) { //Lumière liée à un token let attr = createObj('attribute', { characterid: perso.charId, name: attrName, @@ -13739,14 +13765,14 @@ var COFantasy = COFantasy || function() { evt.attributes = [{ attribute: attr, }]; - } else { //cible temporaire, \xE0 effacer + } else { //cible temporaire, à effacer ct.remove(); } } - //renvoie le nom de l'arme si l'arme est d\xE9j\xE0 tenue en main + //renvoie le nom de l'arme si l'arme est déjà tenue en main // options.seulementDroite permet de ne rengainer que l'arme droite - // options.deuxMains permet de prendre une arme \xE0 2 mains + // options.deuxMains permet de prendre une arme à 2 mains function degainerArme(perso, labelArme, evt, options) { let pageId = perso.pageId; if (pageId === undefined) { @@ -13764,11 +13790,11 @@ var COFantasy = COFantasy || function() { nouvelleArme = getWeaponStats(perso, labelArme); if (nouvelleArme && nouvelleArme.armeGauche) options.gauche = true; let nouvelleArmeGauche; - let labelArmeGauche; //d\xE9finie seulement si on d\xE9gaine l'arme gauche - // et toujours diff\xE9rent de labelArme + let labelArmeGauche; //définie seulement si on dégaine l'arme gauche + // et toujours différent de labelArme if (options.armeGaucheLabel) { if (options.armeGaucheLabel == labelArme) { - sendPerso("ne peut d\xE9gainer la m\xEAme arme dans les deux mains"); + sendPerso("ne peut dégainer la même arme dans les deux mains"); return; } if (options.gauche) { @@ -13778,7 +13804,7 @@ var COFantasy = COFantasy || function() { options.gauche = false; //vrai seulement si on ne sort que l'arme gauche nouvelleArme = getWeaponStats(perso, options.armeGaucheLabel); if (nouvelleArme && nouvelleArme.armeGauche) { - sendPerso("ne peut d\xE9gainer 2 armes gauches \xE0 la fois"); + sendPerso("ne peut dégainer 2 armes gauches à la fois"); return; } } else { @@ -13810,7 +13836,7 @@ var COFantasy = COFantasy || function() { if (labelArmeActuelleGauche == labelArme) rienAFaire = true; else { changementDePrise = true; - message += "prend son arme \xE0 deux mains"; + message += "prend son arme à deux mains"; attrArmeActuelle.set('max', labelArme); } } @@ -13820,24 +13846,24 @@ var COFantasy = COFantasy || function() { if (labelArmeActuelle == labelArme) { if (labelArmeActuelleGauche == labelArme) { changementDePrise = true; - message += "prend son arme \xE0 une main"; + message += "prend son arme à une main"; if (!labelArmeGauche) { attrArmeActuelle.set('max', ''); } } else { - if (labelArmeGauche) //on d\xE9gaine 2 armes + if (labelArmeGauche) //on dégaine 2 armes rienAFaire = labelArmeActuelleGauche == labelArmeGauche; else rienAFaire = true; } } } if (rienAFaire) { - //Pas besoin de d\xE9gainer. + //Pas besoin de dégainer. if (options.weaponStats) return options.weaponStats.name; if (nouvelleArme) return nouvelleArme.name; return; } - //On d\xE9gaine une nouvelle arme, il faut rengainer l'ancienne + //On dégaine une nouvelle arme, il faut rengainer l'ancienne if (labelArmeActuelle) { //dans ce cas, pas options.gauche ancienneArme = getWeaponStats(perso, labelArmeActuelle); if (ancienneArme === undefined) { @@ -13885,8 +13911,8 @@ var COFantasy = COFantasy || function() { } } else attrArmeActuelle = undefined; const estMook = perso.token && perso.token.get('bar1_link') === ''; - //Puis on d\xE9gaine - //mais on v\xE9rifie que l'arme existe, sinon c'est juste un ordre de rengainer + //Puis on dégaine + //mais on vérifie que l'arme existe, sinon c'est juste un ordre de rengainer if (nouvelleArme === undefined) { if (attrArmeActuelle) { if (options.seulementDroite && labelArmeActuelleGauche) { @@ -13905,7 +13931,7 @@ var COFantasy = COFantasy || function() { } if (nouvelleArmeGauche) { if (ficheAttributeAsInt(perso, 'defbouclieron', 0)) { - sendPerso(perso, "enl\xE8ve son bouclier", options.secret); + sendPerso(perso, "enlève son bouclier", options.secret); setFicheAttr(perso, 'defbouclieron', 0, evt, { default: 0 }); @@ -13913,7 +13939,7 @@ var COFantasy = COFantasy || function() { } if (nouvelleArme.deuxMains || options.deuxMains) { if (ficheAttributeAsInt(perso, 'defbouclieron', 0)) { - sendPerso(perso, "enl\xE8ve son bouclier", options.secret); + sendPerso(perso, "enlève son bouclier", options.secret); setFicheAttr(perso, 'defbouclieron', 0, evt, { default: 0 }); @@ -13965,17 +13991,17 @@ var COFantasy = COFantasy || function() { } if (options.messages) { if (changementDePrise) { - if (nouvelleArmeGauche) message += ", et d\xE9gaine " + nouvelleArmeGauche.name; + if (nouvelleArmeGauche) message += ", et dégaine " + nouvelleArmeGauche.name; } else { - message += "d\xE9gaine " + nouvelleArme.name; + message += "dégaine " + nouvelleArme.name; if (nouvelleArmeGauche) message += " et " + nouvelleArmeGauche.name; } options.messages.push(message); } else { if (changementDePrise) { - if (nouvelleArmeGauche) message += ", et d\xE9gaine " + nouvelleArmeGauche.name; + if (nouvelleArmeGauche) message += ", et dégaine " + nouvelleArmeGauche.name; } else { - message = "d\xE9gaine " + nouvelleArme.name; + message = "dégaine " + nouvelleArme.name; if (nouvelleArmeGauche) message += " et " + nouvelleArmeGauche.name; } sendPerso(perso, message, options.secret); @@ -14021,7 +14047,7 @@ var COFantasy = COFantasy || function() { }); return !regenPossible; } - //On enl\xE8ve les doublons de cibles qui partagent leurs PVs; + //On enlève les doublons de cibles qui partagent leurs PVs; function enleveDoublonsPartagePV(cibles) { let ciblesAvecPVsPartages = new Set(); //va aussi peupler le champ name des cibles @@ -14040,9 +14066,9 @@ var COFantasy = COFantasy || function() { ciblesAvecPVsPartages.add(cp); }); } else if (persoEstPNJ(target)) { - //cible la moins prioritaire, on l'enl\xE8ve si on trouve un autre repr\xE9sentant + //cible la moins prioritaire, on l'enlève si on trouve un autre représentant let representantPresent = cibles.find(function(target2, index2) { - if (index2 <= index) return false; //d\xE9j\xE0 trait\xE9 + if (index2 <= index) return false; //déjà traité if (target2.name === undefined) { let target2Char = getObj('character', target2.charId); if (target2Char === undefined) return false; @@ -14057,7 +14083,7 @@ var COFantasy = COFantasy || function() { //N'a pas de familier mais n'est pas un PNJ //On cherche si il existe un autre perso plus prioritaire. let representantFamilier = cibles.find(function(target2, index2) { - if (index2 < index) return false; //d\xE9j\xE0 trait\xE9 + if (index2 < index) return false; //déjà traité if (target2.name === undefined) { let target2Char = getObj('character', target2.charId); if (target2Char === undefined) return false; @@ -14071,8 +14097,8 @@ var COFantasy = COFantasy || function() { predicateAsBool(target2, 'guetteur'); }); if (representantFamilier) return false; - ciblePartagee.forEach(function(attr) { - ciblesAvecPVsPartages.add(attr.get('current')); + ciblePartagee.forEach(function(cp) { + ciblesAvecPVsPartages.add(cp); }); } } @@ -14100,11 +14126,11 @@ var COFantasy = COFantasy || function() { //Options automatically set by some attributes if (attributeAsBool(attaquant, 'paralysieRoublard')) { if (attributeAsBool(attaquant, 'enrage')) { - sendPerso(attaquant, "est trop enrag\xE9 pour sentir la douleur"); + sendPerso(attaquant, "est trop enragé pour sentir la douleur"); } else if (predicateAsBool(attaquant, 'proprioception')) { - sendPerso(attaquant, "est immunis\xE9 \xE0 la douleur"); + sendPerso(attaquant, "est immunisé à la douleur"); } else { - sendPerso(attaquant, "ne peut pas attaquer car il est paralys\xE9 de douleur"); + sendPerso(attaquant, "ne peut pas attaquer car il est paralysé de douleur"); attackCallback(options); return; } @@ -14151,7 +14177,7 @@ var COFantasy = COFantasy || function() { weaponStats.attDice = options.dm.dice; weaponStats.attDMBonusCommun = options.dm.bonus; } else if (weaponStats.batarde && weaponStats.deuxMains) { - let dm = parseDice(weaponStats.batarde, 'd\xE9g\xE2ts'); + let dm = parseDice(weaponStats.batarde, 'dégâts'); if (dm) { weaponStats.attNbDices = dm.nbDe; weaponStats.attDice = dm.dice; @@ -14198,7 +14224,7 @@ var COFantasy = COFantasy || function() { if (stats2.divers && stats2.divers.includes('d3')) stats2.attDice = 3; options.tirDouble.stats = stats2; } - //Pour les explosions, la port\xE9e est 0 mais avec un disque + //Pour les explosions, la portée est 0 mais avec un disque if (options.explosion) { if (options.aoe === undefined) { options.aoe = { @@ -14206,7 +14232,7 @@ var COFantasy = COFantasy || function() { rayon: portee }; } else if (options.aoe.type != 'disque') { - error("Option explosion ignor\xE9e, car l'attaque est une aoe qui n'est pas un disque", options); + error("Option explosion ignorée, car l'attaque est une aoe qui n'est pas un disque", options); } } if (portee > 0) { @@ -14233,9 +14259,9 @@ var COFantasy = COFantasy || function() { } options.contact = true; } - //Ce qui peut emp\xEAcher l'attaque quelles que soient les cibles + //Ce qui peut empêcher l'attaque quelles que soient les cibles if (options.avecd12 && ((estAffaibli(attaquant) && !predicateAsBool(attaquant, 'insensibleAffaibli')) || getState(attaquant, 'immobilise'))) { - sendPerso(attaquant, "ne peut pas utiliser cette capacit\xE9 quand il est affaibli."); + sendPerso(attaquant, "ne peut pas utiliser cette capacité quand il est affaibli."); attackCallback(options); return; } @@ -14250,7 +14276,7 @@ var COFantasy = COFantasy || function() { attackCallback(options); return; } - //Pour l'option grenaille implicite, il faut v\xE9rifier que toutes les charge de l'arme sont des charges de grenaille + //Pour l'option grenaille implicite, il faut vérifier que toutes les charge de l'arme sont des charges de grenaille let chargesArme = []; let attackLabel = weaponStats.label; if (attackLabel) { @@ -14318,18 +14344,18 @@ var COFantasy = COFantasy || function() { options.fx = options.fx || effet.id; } if (options.eclairDEnergie && !options.redo) { - //On augmente le nombre de d\xE9s de 1 et on utilise l'attaque magique + //On augmente le nombre de dés de 1 et on utilise l'attaque magique weaponStats.attNbDices++; weaponStats.attSkill = '@{ATKMAG}'; options.contondant = undefined; options.type = 'energie'; options.messages = options.messages || []; - options.messages.push("\xC9clair d'\xE9nergie !"); + options.messages.push("Éclair d'énergie !"); } - //D\xE9termination de la (ou des) cible(s) + //Détermination de la (ou des) cible(s) let nomCiblePrincipale; //Utilise pour le cas mono-cible let cibles = []; - if (options.redo) { //Dans ce cas les cibles sont pr\xE9cis\xE9es dans targetToken + if (options.redo) { //Dans ce cas les cibles sont précisées dans targetToken cibles = targetToken; if (cibles.length === 0) { error("Attaque sans cible", targetToken); @@ -14343,7 +14369,7 @@ var COFantasy = COFantasy || function() { let page; nomCiblePrincipale = targetToken.get('name'); if (options.aoe) { - //cas de la boule de feu qui fait un \xE9chec critique : on d\xE9place la cible si elle est artificielle + //cas de la boule de feu qui fait un échec critique : on déplace la cible si elle est artificielle if (!options.redo && (options.demiAuto || options.toucheDoubleDmg) && (!options.triche || options.triche == 'echecCritique') && targetToken.get('bar1_max') == 0) { // jshint ignore:line @@ -14423,12 +14449,12 @@ var COFantasy = COFantasy || function() { }; } if (targetToken.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir la ligne + //C'est juste un token utilisé pour définir la ligne if (options.fx) { spawnFxBetweenPoints(pta, ptt, options.fx, pageId); } cibles = []; - targetToken.remove(); //On l'enl\xE8ve, normalement plus besoin + targetToken.remove(); //On l'enlève, normalement plus besoin } let allToks = findObjs({ @@ -14445,7 +14471,7 @@ var COFantasy = COFantasy || function() { token: obj, charId: objCharId }; - if (nePeutPlusPrendreDM(cible, options)) return; //pas de d\xE9g\xE2ts aux morts + if (nePeutPlusPrendreDM(cible, options)) return; //pas de dégâts aux morts let distToTrajectory = distancePixTokenSegment(obj, pta, ptt); if (distToTrajectory > (obj.get('width') + obj.get('height')) / 4 + PIX_PER_UNIT / 4) return; @@ -14461,8 +14487,8 @@ var COFantasy = COFantasy || function() { { if (distanceTarget > portee) { sendPlayer(playerName, - "Le centre du disque vis\xE9 est trop loin pour " + weaponName + - " (distance " + distanceTarget + ", port\xE9e " + portee + ")", + "Le centre du disque visé est trop loin pour " + weaponName + + " (distance " + distanceTarget + ", portée " + portee + ")", playerId); attackCallback(options); return; @@ -14490,7 +14516,7 @@ var COFantasy = COFantasy || function() { } let t = attributeAsInt(cadavre, 'a0PVDepuis', 0); if (t < combat.tour - 1) { - sendPlayer(playerName, "La mort de " + nomPerso(cadavre) + " n'est pas assez r\xE9cente", playerId); + sendPlayer(playerName, "La mort de " + nomPerso(cadavre) + " n'est pas assez récente", playerId); attackCallback(options); return; } @@ -14510,7 +14536,7 @@ var COFantasy = COFantasy || function() { }); allToksDisque.forEach(function(obj) { if ((options.explosion || portee === 0) && - obj.id == tokenOrigine.id) return; //on ne se cible pas si le centre de l'aoe est soi-m\xEAme + obj.id == tokenOrigine.id) return; //on ne se cible pas si le centre de l'aoe est soi-même if (obj.get('bar1_max') == 0) return; // jshint ignore:line let objCharId = obj.get('represents'); if (objCharId === '') return; @@ -14518,7 +14544,7 @@ var COFantasy = COFantasy || function() { token: obj, charId: objCharId }; - if (nePeutPlusPrendreDM(cible, options)) return; //pas de d\xE9g\xE2ts aux morts + if (nePeutPlusPrendreDM(cible, options)) return; //pas de dégâts aux morts let distanceCentre = distanceCombat(targetToken, obj, pageId, { strict1: true @@ -14539,10 +14565,10 @@ var COFantasy = COFantasy || function() { cibles.push(cible); }); if (targetToken.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir le disque - targetToken.remove(); //On l'enl\xE8ve, normalement plus besoin + //C'est juste un token utilisé pour définir le disque + targetToken.remove(); //On l'enlève, normalement plus besoin } - // La nouvelle port\xE9e (pour ne rien \xE9liminer \xE0 l'\xE9tape suivante + // La nouvelle portée (pour ne rien éliminer à l'étape suivante portee += options.aoe.rayon; break; } @@ -14553,12 +14579,12 @@ var COFantasy = COFantasy || function() { } let vecCentre = vecteurUnitaire(pta, ptt); let cosAngle = Math.cos(options.aoe.angle * Math.PI / 360.0); - //Pour \xE9viter des artfacts d'arrondi: + //Pour éviter des artfacts d'arrondi: cosAngle = (Math.floor(cosAngle * 1000000)) / 1000000; if (targetToken.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir le cone + //C'est juste un token utilisé pour définir le cone cibles = []; - targetToken.remove(); //On l'enl\xE8ve, normalement plus besoin + targetToken.remove(); //On l'enlève, normalement plus besoin } page = page || getObj("page", pageId); murs = getWalls(page, pageId, murs); @@ -14577,12 +14603,12 @@ var COFantasy = COFantasy || function() { token: obj, charId: objCharId }; - if (nePeutPlusPrendreDM(cible, options)) return; //pas de d\xE9g\xE2ts aux morts + if (nePeutPlusPrendreDM(cible, options)) return; //pas de dégâts aux morts let pt = pointOfToken(obj); let vecObj = vecteurUnitaire(pta, pt); if (vecCentre.x * vecObj.x + vecCentre.y * vecObj.y < cosAngle) return; - // La distance sera compar\xE9e \xE0 la port\xE9e plus loin + // La distance sera comparée à la portée plus loin let objChar = getObj('character', objCharId); if (objChar === undefined) return; if (murs) { @@ -14600,16 +14626,16 @@ var COFantasy = COFantasy || function() { return; } } else { - if (tokenOrigine.id == targetToken.id && !options.echecTotal) { //m\xEAme token pour attaquant et cible + if (tokenOrigine.id == targetToken.id && !options.echecTotal) { //même token pour attaquant et cible sendPerso(attaquant, "s'attaque " + onGenre(attaquant, "lui", "elle") + - "-m\xEAme ? Probablement une erreur \xE0 la s\xE9lection de la cible. On annule"); + "-même ? Probablement une erreur à la sélection de la cible. On annule"); attackCallback(options); return; } let targetCharId = targetToken.get("represents"); if (targetCharId === "") { - error("Le token cibl\xE9 (" + nomCiblePrincipale + ") doit repr\xE9senter un personnage ", targetToken); + error("Le token ciblé (" + nomCiblePrincipale + ") doit représenter un personnage ", targetToken); attackCallback(options); return; } @@ -14635,7 +14661,7 @@ var COFantasy = COFantasy || function() { }); } } - //Les conditions qui peuvent emp\xEAcher l'attaque + //Les conditions qui peuvent empêcher l'attaque if (options.conditionAttaquant !== undefined) { if (!testCondition(options.conditionAttaquant, attaquant, cibles)) { sendPerso(attaquant, "ne peut pas utiliser " + weaponName); @@ -14643,7 +14669,7 @@ var COFantasy = COFantasy || function() { return; } } - //dernieresCiblesAttaquees contient en current les cibles attaqu\xE9es, et en max les cibles sur lesquelles on a fait des ripostes + //dernieresCiblesAttaquees contient en current les cibles attaquées, et en max les cibles sur lesquelles on a fait des ripostes let attrCiblesAttaquees = tokenAttribute(attaquant, 'dernieresCiblesAttaquees'); let ripostesDuTour = new Set(); if (attrCiblesAttaquees.length > 0) { @@ -14664,16 +14690,16 @@ var COFantasy = COFantasy || function() { return false; } if (options.seulementVivant && estNonVivant(target)) { - sendPlayer(playerName, "cette attaque n'affecte que les cr\xE9atures vivantes", playerId); + sendPlayer(playerName, "cette attaque n'affecte que les créatures vivantes", playerId); return false; } if (options.attaqueMentale) { if (predicateAsBool(target, 'sansEsprit')) { - sendPlayer(playerName, "cette attaque n'affecte que les cr\xE9atures pensantes", playerId); + sendPlayer(playerName, "cette attaque n'affecte que les créatures pensantes", playerId); return false; } if (predicateAsBool(target, 'vegetatif')) { - sendPlayer(playerName, "cette attaque n'affecte pas les cr\xE9atures v\xE9g etatives", playerId); + sendPlayer(playerName, "cette attaque n'affecte pas les créatures vég etatives", playerId); return false; } } @@ -14682,14 +14708,14 @@ var COFantasy = COFantasy || function() { return false; } if (attributeAsBool(attaquant, 'tenuADistanceManoeuvre(' + target.token.id + ')')) { - sendPerso(attaquant, "est tenu \xE0 distance de " + nomPerso(target) + ", " + onGenre(attaquant, "il", "elle") + " ne peut pas l'attaquer ce tour."); + sendPerso(attaquant, "est tenu à distance de " + nomPerso(target) + ", " + onGenre(attaquant, "il", "elle") + " ne peut pas l'attaquer ce tour."); return false; } if (charAttributeAsBool(target, 'armeeConjuree')) { return options.attaqueArmeeConjuree; } if (ripostesDuTour.has(target.token.id)) { - sendPerso(attaquant, "a d\xE9j\xE0 fait une riposte contre " + nomPerso(target)); + sendPerso(attaquant, "a déjà fait une riposte contre " + nomPerso(target)); return false; } if (options.ricochets) { @@ -14697,7 +14723,7 @@ var COFantasy = COFantasy || function() { return c.token.id == target.token.id; }); if (dejaTouche) { - sendPerso(attaquant, nomPerso(target) + " a d\xE9j\xE0 \xE9t\xE9 touch\xE9 par un pr\xE9c\xE9dent ricochet de cette attaque"); + sendPerso(attaquant, nomPerso(target) + " a déjà été touché par un précédent ricochet de cette attaque"); return false; } } @@ -14705,7 +14731,7 @@ var COFantasy = COFantasy || function() { }); if (cibles.length === 0) { if (options.aoe) { - sendPlayer(playerName, "aucune cible dans l'aire d'effet de " + weaponName + ", action annul\xE9e", + sendPlayer(playerName, "aucune cible dans l'aire d'effet de " + weaponName + ", action annulée", playerId); } attackCallback(options); @@ -14716,7 +14742,7 @@ var COFantasy = COFantasy || function() { let optDistance = {}; options.portee = portee; if (options.contact) optDistance.allonge = options.allonge; - // Si l'attaquant est mont\xE9, distance mesur\xE9e \xE0 partir de sa monture + // Si l'attaquant est monté, distance mesurée à partir de sa monture if (tokenOrigine.id == attackingToken.id) { let attrMonture = tokenAttribute(attaquant, 'monteSur'); if (attrMonture.length > 0) { @@ -14726,7 +14752,7 @@ var COFantasy = COFantasy || function() { } } cibles = cibles.filter(function(target) { - // Si la cible est mont\xE9e, distance mesur\xE9e vers sa monture + // Si la cible est montée, distance mesurée vers sa monture let pseudoTargetToken = target.token; let attrMonture = tokenAttribute(target, 'monteSur'); if (attrMonture.length > 0) { @@ -14740,7 +14766,7 @@ var COFantasy = COFantasy || function() { if (target.distance > portee && target.msgEsquiveFatale === undefined && !(target.chairACanon || target.intercepter)) { if (options.aoe || options.auto) return false; //distance stricte if (target.distance > (predicateAsBool(attaquant, 'tirParabolique') ? 3 : 2) * portee) return false; - // On peut aller jusqu'\xE0 2x portee si unique cible et jet d'attaque, 3x si le personnage a Tir Parabolique + // On peut aller jusqu'à 2x portee si unique cible et jet d'attaque, 3x si le personnage a Tir Parabolique return true; } if (target.distance === 0 && options.seulementDistance) { @@ -14750,7 +14776,7 @@ var COFantasy = COFantasy || function() { return true; }); } - //On enl\xE8ve les alli\xE9s si l'option saufAllies est active + //On enlève les alliés si l'option saufAllies est active if (options.saufAllies) { let allies = new Set(); allies = alliesParPerso[attaquant.charId] || allies; @@ -14759,7 +14785,7 @@ var COFantasy = COFantasy || function() { return !(allies.has(target.charId)); }); } - //On v\xE9rifie que les cibles sont assez proches les unes des autres + //On vérifie que les cibles sont assez proches les unes des autres if (options.ciblesDansDisque && cibles.length > 1) { let l1, l2, t1, t2; cibles.forEach(function(target) { @@ -14772,7 +14798,7 @@ var COFantasy = COFantasy || function() { }); let maxpix = options.ciblesDansDisque * PIX_PER_UNIT / computeScale(pageId); if ((l2 - l1) > 2 * maxpix || (t2 - t1) > 2 * maxpix) { - sendPlayer(playerName, "Cibles trop \xE9loign\xE9es les unes des autres"); + sendPlayer(playerName, "Cibles trop éloignées les unes des autres"); attackCallback(options); return; } @@ -14783,14 +14809,14 @@ var COFantasy = COFantasy || function() { x: (l1 + l2) / 2, y: (t1 + t2) / 2 }; - //C'est approch\xE9, mais s\xFBrement assez bon pour ce qui nous occupe + //C'est approché, mais sûrement assez bon pour ce qui nous occupe let tropLoin = cibles.some(function(target) { let pt = pointOfToken(target.token); attackCallback(options); return (distancePoints(centre, pt) > maxpix + 1); }); if (tropLoin) { - sendPlayer(playerName, "Cibles trop \xE9loign\xE9es les unes des autres"); + sendPlayer(playerName, "Cibles trop éloignées les unes des autres"); attackCallback(options); return; } @@ -14798,16 +14824,16 @@ var COFantasy = COFantasy || function() { } if (cibles.length === 0) { if (options.aoe) { - sendPlayer(playerName, "aucune cible dans l'aire d'effet de " + weaponName + ", action annul\xE9e", + sendPlayer(playerName, "aucune cible dans l'aire d'effet de " + weaponName + ", action annulée", playerId); return; } if (!options.seulementDistance) { - sendPerso(attaquant, "est hors de port\xE9e de " + nomCiblePrincipale + " pour une attaque utilisant " + weaponName + ", action annul\xE9e"); + sendPerso(attaquant, "est hors de portée de " + nomCiblePrincipale + " pour une attaque utilisant " + weaponName + ", action annulée"); } return; } - //On enl\xE8ve les doublons de cibles qui partagent leurs PVs; + //On enlève les doublons de cibles qui partagent leurs PVs; cibles = enleveDoublonsPartagePV(cibles); let evt = options.evt || { type: "Attaque", @@ -14826,7 +14852,7 @@ var COFantasy = COFantasy || function() { evt.action = evt.action || { options: JSON.parse(JSON.stringify(options)) //pour la chance etc. }; - //On met \xE0 jour l'arme en main, si n\xE9cessaire + //On met à jour l'arme en main, si nécessaire if (weaponStats.arme || weaponStats.armeGauche || (weaponStats.divers && weaponStats.divers.toLowerCase().includes('arme'))) { options.weaponStats = weaponStats; options.messages = options.messages || []; @@ -14837,7 +14863,7 @@ var COFantasy = COFantasy || function() { if (options.contact && weaponStats.arme && predicateAsBool(attaquant, 'frappeDuVide')) { if (attributeAsBool(attaquant, 'limiteParTour_frappeDuVidePossible')) options.frappeDuVide = true; - //Il faut noter la premi\xE8re attaque au contact + //Il faut noter la première attaque au contact setTokenAttr(attaquant, 'limiteParCombat_dejaFrappeContact', true, evt); } let riposte = predicateAsBool(attaquant, 'riposte'); @@ -14845,7 +14871,7 @@ var COFantasy = COFantasy || function() { if (attaqueEnMeute > 0) options.attaqueEnMeute = attaqueEnMeute; options.lienEpique = predicateAsBool(attaquant, 'lienEpique'); if (riposte || options.attaqueEnMeute || options.lienEpique) { - //Dans ce cas, il faut stoquer les cibles attaqu\xE9es + //Dans ce cas, il faut stoquer les cibles attaquées //(dans le cas de riposte, pour ne pas les re-proposer en riposte let listeCibles = cibles.map(function(target) { @@ -14859,7 +14885,7 @@ var COFantasy = COFantasy || function() { } else { setTokenAttr(attaquant, 'dernieresCiblesAttaquees', listeCibles, evt); } - } else { //L'attribut existe d\xE9j\xE0 + } else { //L'attribut existe déjà attrCiblesAttaquees = attrCiblesAttaquees[0]; evt.attributes = evt.attributes || []; let attaquesDuTour = attrCiblesAttaquees.get('current'); @@ -14884,7 +14910,7 @@ var COFantasy = COFantasy || function() { let explications = []; if (options.messages) explications = [...options.messages]; if (options.magieRapide) explications.push("Magie rapide"); - //On fait les tests pour les cibles qui b\xE9n\xE9ficieraient d'un sanctuaire + //On fait les tests pour les cibles qui bénéficieraient d'un sanctuaire let ciblesATraiter = cibles.length; let cibleTraitee = function() { ciblesATraiter--; @@ -14906,10 +14932,10 @@ var COFantasy = COFantasy || function() { let testId = 'sanctuaire_' + cible.token.id; testCaracteristique(attaquant, 'SAG', 15, testId, options, evt, function(tr) { if (tr.reussite) { - cible.messages.push(nomPerso(attaquant) + " r\xE9ussit \xE0 passer outre le sanctuaire de " + nomPerso(cible) + " (jet de SAG " + tr.texte + "≥15)" + tr.modifiers); + cible.messages.push(nomPerso(attaquant) + " réussit à passer outre le sanctuaire de " + nomPerso(cible) + " (jet de SAG " + tr.texte + "≥15)" + tr.modifiers); cibleTraitee(); } else { - let msgRate = "ne peut se r\xE9soudre \xE0 attaquer " + nomPerso(cible) + " (sanctuaire, jet de SAG " + tr.texte + "< 15)" + tr.rerolls + tr.modifiers; + let msgRate = "ne peut se résoudre à attaquer " + nomPerso(cible) + " (sanctuaire, jet de SAG " + tr.texte + "< 15)" + tr.rerolls + tr.modifiers; sendPerso(attaquant, msgRate); attaqueImpossible = true; } @@ -14918,14 +14944,14 @@ var COFantasy = COFantasy || function() { cibleTraitee(); } }; - // Attaque de Disparition avec jet oppos\xE9 + // Attaque de Disparition avec jet opposé if (options.disparition) { - //L'immunit\xE9 aux attaques sournoise est test\xE9e plus loin et ne devrait - //pas emp\xEAcher le bonus de +5 \xE0 l'attaque. + //L'immunité aux attaques sournoise est testée plus loin et ne devrait + //pas empêcher le bonus de +5 à l'attaque. let rollId = 'disparition_' + cible.token.id; let options1 = {...options }; - options1.competence = 'discr\xE9tion'; + options1.competence = 'discrétion'; let options2 = {...options }; options2.competence = 'perception'; @@ -14933,13 +14959,13 @@ var COFantasy = COFantasy || function() { cible.messages, evt, function(resultat, crit, rt1, rt2) { if (resultat != 2) { - cible.messages.push(nomPerso(attaquant) + " r\xE9apparait \xE0 c\xF4t\xE9 de " + nomPerso(cible) + " et lui porte une attaque mortelle !"); + cible.messages.push(nomPerso(attaquant) + " réapparait à côté de " + nomPerso(cible) + " et lui porte une attaque mortelle !"); // rajout des bonus de sournoise options.bonusAttaque = (options.bonusAttaque || 0) + 5; options.sournoise = options.sournoise || 0; options.sournoise += options.disparition; } else { - cible.messages.push(nomPerso(cible) + " rep\xE8re " + nomPerso(attaquant) + " \xE0 temps pour r\xE9agir."); + cible.messages.push(nomPerso(cible) + " repère " + nomPerso(attaquant) + " à temps pour réagir."); } evalSanctuaire(); }); //fin de testOppose (asynchrone) @@ -14951,16 +14977,16 @@ var COFantasy = COFantasy || function() { explications.push("Tentative d'acrobatie pour surprendre " + nomPerso(cible)); testCaracteristique(attaquant, 'DEX', 15, rollId, rollOptions, evt, function(tr, expl) { - explications.push("R\xE9sultat : " + tr.texte + tr.modifiers); + explications.push("Résultat : " + tr.texte + tr.modifiers); expl.forEach(function(m) { explications.push(m); }); if (tr.reussite) { - explications.push("R\xE9ussite : " + nomPerso(attaquant) + " peut faire une attaque sournoise"); + explications.push("Réussite : " + nomPerso(attaquant) + " peut faire une attaque sournoise"); options.sournoise = options.sournoise || 0; options.sournoise += options.attaqueAcrobatique; } else { - explications.push("Rat\xE9, " + nomPerso(attaquant) + " r\xE9alise une attaque normale" + tr.rerolls); + explications.push("Raté, " + nomPerso(attaquant) + " réalise une attaque normale" + tr.rerolls); } evalSanctuaire(); }); @@ -14968,7 +14994,7 @@ var COFantasy = COFantasy || function() { }); } - // On affiche les options d'attaque \xE0 droite + // On affiche les options d'attaque à droite function afficherOptionsAttaque(perso, opt_display) { let action_opts = '!cof-options-d-attaque --target ' + perso.token.id; let text_opts = ''; @@ -14981,11 +15007,11 @@ var COFantasy = COFantasy || function() { } if (ficheAttributeAsInt(perso, 'attaque_risquee_check')) { if (text_opts !== '') text_opts += '
'; - text_opts += "Risqu\xE9e"; + text_opts += "Risquée"; } if (ficheAttributeAsInt(perso, 'attaque_assuree_check')) { if (text_opts !== '') text_opts += '
'; - text_opts += "Assur\xE9e"; + text_opts += "Assurée"; } if (ficheAttributeAsInt(perso, 'attaque_dm_temp_check')) { if (text_opts !== '') text_opts += '
'; @@ -15022,7 +15048,7 @@ var COFantasy = COFantasy || function() { let rawList; if (persoEstPNJ(perso)) rawList = extractRepeating(perso, 'pnjatk'); else rawList = extractRepeating(perso, 'armes'); - let liste = {}; //liste tri\xE9e par label d'attaque + let liste = {}; //liste triée par label d'attaque for (let pref in rawList) { let ra = rawList[pref]; if (ra.armelabel === undefined) ra.armelabel = 0; @@ -15047,7 +15073,7 @@ var COFantasy = COFantasy || function() { let rang = parseInt(ra.actionrang); if (isNaN(rang) || rang < 0) rang = 0; if (actions[rang]) { - error("Plusieurs actions de m\xEAme rang " + rang + " dans la liste d'actions du tour", ra); + error("Plusieurs actions de même rang " + rang + " dans la liste d'actions du tour", ra); continue; } actions[rang] = ra; @@ -15056,11 +15082,11 @@ var COFantasy = COFantasy || function() { return actions; } - // on r\xE9cup\xE8re la valeur de l'action dont chaque Macro #/Ability % est mis dans un tableau 'action' + // on récupère la valeur de l'action dont chaque Macro #/Ability % est mis dans un tableau 'action' //Pour chaque action, on a une commande, un texte et des options. //On appelle f(commande, texte, macros, attackStats) - // le dernier argument est optionnel, et n'est l\xE0 que pour \xE9viter d'avoir \xE0 recalculer attackStats - //actionsDuTour peut \xEAtre un nombre entre 0 et 4 (listes sur la fiche), ou + // le dernier argument est optionnel, et n'est là que pour éviter d'avoir à recalculer attackStats + //actionsDuTour peut être un nombre entre 0 et 4 (listes sur la fiche), ou // une ability function treatActions(perso, actionsDuTour, abilities, f) { let actions; // La liste des actions @@ -15121,7 +15147,7 @@ var COFantasy = COFantasy || function() { } else { actionCode = action.trim(); if (actionCode === '') return; - if (actionCode.startsWith('//')) return; //Ligne comment\xE9e + if (actionCode.startsWith('//')) return; //Ligne commentée } let actionCommands = actionCode.split(' '); actionCommands = actionCommands.filter(function(c) { @@ -15198,7 +15224,7 @@ var COFantasy = COFantasy || function() { case '!options': found = true; if (actionCommands.length > 1) { - options = actionCode.substring(8); //d\xE9marre par ' ' + options = actionCode.substring(8); //démarre par ' ' } break; case '!attaques': @@ -15246,8 +15272,8 @@ var COFantasy = COFantasy || function() { if (found) { actionsAAfficher = true; } else { - // Si on n'a toujours rien trouv\xE9, on ajoute un petit log - log('Ability et macro non trouv\xE9 : ' + actionCode); + // Si on n'a toujours rien trouvé, on ajoute un petit log + log('Ability et macro non trouvé : ' + actionCode); } }); } @@ -15272,7 +15298,7 @@ var COFantasy = COFantasy || function() { } else if (action == 'Attaques en traitre') { actions = findListeActions(attaquant, 'AttaqueEnTraitre', abilities); if (actions === undefined) - actions = findListeActions(attaquant, 'Attaques en tra\xEEtre', abilities); + actions = findListeActions(attaquant, 'Attaques en traître', abilities); } } let actionsOpportunite = []; @@ -15296,7 +15322,7 @@ var COFantasy = COFantasy || function() { }); actionsOpportunite.reverse(); } else { - //On affiche l'attaque avec l'arme en main + les attaques naturelles coch\xE9es + //On affiche l'attaque avec l'arme en main + les attaques naturelles cochées let listeAttaques = listAllAttacks(attaquant); for (let label in listeAttaques) { let arme = listeAttaques[label]; @@ -15318,14 +15344,14 @@ var COFantasy = COFantasy || function() { retarde: true, }; afficherOptionsAttaque(attaquant, opt_display); - //On cr\xE9e un display sans le header + //On crée un display sans le header let display = startFramedDisplay(undefined, "Attaque " + type + " possible", attaquant, opt_display); cibles.forEach(function(target) { - if (target.name === undefined) { //TODO v\xE9rifier que c'est utile + if (target.name === undefined) { //TODO vérifier que c'est utile let targetChar = getObj('character', target.charId); if (targetChar === undefined) { - error('Impossible de trouver le personnage repr\xE9sentant ' + nomPerso(target), target); + error('Impossible de trouver le personnage représentant ' + nomPerso(target), target); return; } target.name = targetChar.get('name'); @@ -15347,15 +15373,15 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, bouton(cmd, action.text, attaquant)); }); }); - // on envoie la liste aux joueurs qui g\xE8rent l'attaquant + // on envoie la liste aux joueurs qui gèrent l'attaquant let playerIds = getPlayerIds(attaquant); playerIds.forEach(function(playerid) { addFramedHeader(display, playerid, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); if (playerIds.length === 0) { addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } @@ -15403,15 +15429,15 @@ var COFantasy = COFantasy || function() { function immuniseAsphyxie(target, expliquer) { if (predicateAsBool(target, 'creatureArtificielle') || estNonVivant(target)) { - if (expliquer) expliquer("L'asphyxie est sans effet sur une cr\xE9ature non-vivante"); + if (expliquer) expliquer("L'asphyxie est sans effet sur une créature non-vivante"); return true; } if (estDemon(target)) { - if (expliquer) expliquer("L'asphyxie est sans effet sur un d\xE9mon"); + if (expliquer) expliquer("L'asphyxie est sans effet sur un démon"); return true; } if (predicateAsBool(target, 'vegetatif')) { - if (expliquer) expliquer("L'asphyxie est sans effet sur une cr\xE9ature v\xE9g\xE9tative"); + if (expliquer) expliquer("L'asphyxie est sans effet sur une créature végétative"); return true; } return false; @@ -15434,9 +15460,9 @@ var COFantasy = COFantasy || function() { // Fonction asynchrone // displayRes est optionnel, et peut avoir 2 arguments - // - un texte affichant le jet de d\xE9g\xE2ts - // - la valeur finale des d\xE9g\xE2ts inflig\xE9s - // crit est un bool\xE9en, il augmente de 1 (ou options.critCoef) le coefficient (option.dmgCoef) et active certains effets + // - un texte affichant le jet de dégâts + // - la valeur finale des dégâts infligés + // crit est un booléen, il augmente de 1 (ou options.critCoef) le coefficient (option.dmgCoef) et active certains effets function dealDamage(target, dmg, otherDmg, evt, crit, options, explications, displayRes) { if (options === undefined) options = {}; let expliquer = function(msg) { @@ -15452,7 +15478,7 @@ var COFantasy = COFantasy || function() { (options.aoe === undefined && attributeAsBool(target, 'formeGazeuse')) || (predicateAsBool(target, 'apparition') && !options.energiePositive)) { - expliquer("L'attaque passe \xE0 travers de " + nomPerso(target)); + expliquer("L'attaque passe à travers de " + nomPerso(target)); if (displayRes) displayRes('0', 0, 0); return 0; } @@ -15477,7 +15503,7 @@ var COFantasy = COFantasy || function() { options.aoe.type == 'cone' && predicateAsBool(options.attaquant, 'ennemiDuBatonDesRunesMortes') && predicateAsBool(target, 'batonDesRunesMortes') && attributeAsBool(target, 'runeLizura')) { - expliquer("Lizura => immunit\xE9 au souffle de " + nomPerso(options.attaquant)); + expliquer("Lizura => immunité au souffle de " + nomPerso(options.attaquant)); if (displayRes) displayRes('0', 0, 0); return 0; } @@ -15488,7 +15514,7 @@ var COFantasy = COFantasy || function() { if (target.diviseDmg) diviseDmg *= target.diviseDmg; if (options.attaquant && predicateAsBool(options.attaquant, 'creatureDeLHiver') && predicateAsBool(target, 'armeDeLEte')) { diviseDmg += 4; - expliquer("L'arme de l'\xE9t\xE9 divise les d\xE9g\xE2ts de l'attaque"); + expliquer("L'arme de l'été divise les dégâts de l'attaque"); } if (options.attaqueEnEtantGobe) diviseDmg *= 2; if (options.sortilege && predicateAsBool(target, 'esquiveDeLaMagie')) @@ -15506,25 +15532,25 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(target, 'armureLourdeGuerrier') && ficheAttributeAsBool(target, 'defarmureon', false) && ficheAttributeAsInt(target, 'defarmure', 0) >= 7) { - expliquer("L'armure lourde de " + nomPerso(target) + " lui permet d'ignorer les d\xE9g\xE2ts critiques"); + expliquer("L'armure lourde de " + nomPerso(target) + " lui permet d'ignorer les dégâts critiques"); } else if (predicateAsBool(target, 'immuniteAuxCritiques')) { - expliquer("Le succ\xE8s critique est sans effet"); + expliquer("Le succès critique est sans effet"); } else { if (options.critCoef) critCoef = options.critCoef; if (target.critCoef) critCoef += target.critCoef; dmgCoef += critCoef; if (predicateAsBool(target, 'armureProtection') && ficheAttributeAsBool(target, 'defarmureon', false)) { - expliquer("L'armure de protection de " + nomPerso(target) + " le prot\xE8ge du critique"); + expliquer("L'armure de protection de " + nomPerso(target) + " le protège du critique"); diviseDmg++; } else if (predicateAsBool(target, 'bouclierProtection') && ficheAttributeAsInt(target, 'defbouclieron', 0)) { - expliquer("Le bouclier de protection de " + nomPerso(target) + " le prot\xE8ge du critique"); + expliquer("Le bouclier de protection de " + nomPerso(target) + " le protège du critique"); diviseDmg++; } else if (predicateAsBool(target, 'anneauProtection')) { - expliquer("L'anneau de protection de " + nomPerso(target) + " le prot\xE8ge du critique"); + expliquer("L'anneau de protection de " + nomPerso(target) + " le protège du critique"); diviseDmg++; } if (predicateAsBool(target, 'bouclierProtection') && ficheAttributeAsBool(target, 'defbouclieron', false)) { - expliquer("Le bouclier de protection de " + nomPerso(target) + " le prot\xE8ge du critique"); + expliquer("Le bouclier de protection de " + nomPerso(target) + " le protège du critique"); diviseDmg++; } } @@ -15590,13 +15616,13 @@ var COFantasy = COFantasy || function() { dmgTotal = x.dmgTotal; } addToDmgTotal(0, dmgTotal, dmg, expliquer, evt); - //On trie les DM suppl\xE9mentaires selon leur type + //On trie les DM supplémentaires selon leur type let dmgParType = {}; otherDmg.forEach(function(d) { if (_.has(dmgParType, d.type)) dmgParType[d.type].push(d); else dmgParType[d.type] = [d]; }); - // Dommages de m\xEAme type que le principal, mais \xE0 part, donc non affect\xE9s par les critiques + // Dommages de même type que le principal, mais à part, donc non affectés par les critiques let mainDmgType = dmg.type; let dmgExtra = dmgParType[mainDmgType]; if (dmgExtra && dmgExtra.length > 0 && !immuniseAuType(target, mainDmgType, options.attaquant)) { @@ -15630,8 +15656,8 @@ var COFantasy = COFantasy || function() { // Effets quand on rentre en combat // attaquant est optionnel - // exlications doit \xEAtre d\xE9fini - // ne rajoute pas evt \xE0 l'historique + // exlications doit être défini + // ne rajoute pas evt à l'historique // revoie stateCOF.combat, garanti non false function entrerEnCombat(attaquant, cibles, explications, evt) { let selected = []; @@ -15674,7 +15700,7 @@ var COFantasy = COFantasy || function() { return initiative(selected, evt); //ne recalcule pas l'init } - //capa est le nom d'un pr\xE9dicat. Si le pr\xE9dicat est num\xE9rique, cela donne + //capa est le nom d'un prédicat. Si le prédicat est numérique, cela donne //la limite, sinon la limite est 1 // retourne // - utilisations: les nombre d'utilisations restantes, @@ -15696,7 +15722,7 @@ var COFantasy = COFantasy || function() { attribut = attribut[0]; utilisations = parseInt(attribut.get('current')); if (isNaN(utilisations)) { - error("Resource pour " + capa + " mal form\xE9e", attribut); + error("Resource pour " + capa + " mal formée", attribut); return; } } @@ -15886,7 +15912,7 @@ var COFantasy = COFantasy || function() { return attCar + ficheAttributeAsInt(attaquant, 'niveau', 1) + attDiv; } - //Retourne le label de l'attaque \xE0 l'arme de jet. + //Retourne le label de l'attaque à l'arme de jet. function estAussiArmeDeJet(options) { if (options.startsWith('-')) options = ' ' + options; options = options.split(' --'); @@ -15981,7 +16007,7 @@ var COFantasy = COFantasy || function() { }, }); } else { - let exprDuree = parseDice(value, 'dur\xE9e'); + let exprDuree = parseDice(value, 'durée'); let duree = randomInteger(6); if (exprDuree) { if (exprDuree.nbDe <= 0) { @@ -16008,7 +16034,7 @@ var COFantasy = COFantasy || function() { } else { error("Type de poison " + typePoison + " non reconnu.", poisonAttr); } - explications.push("L'arme est empoisonn\xE9e"); + explications.push("L'arme est empoisonnée"); return defPoison; } @@ -16021,7 +16047,7 @@ var COFantasy = COFantasy || function() { let nombreMunitionsEmpoisonnees = parseInt(infosPoisonMunitions.substring(index + 1)); if (!isNaN(seuil) && !isNaN(nombreMunitionsEmpoisonnees) && nombreMunitionsEmpoisonnees > 0) { let defPoison = effetPoison(poisonAttr, seuil, attaquant, explications, options); - explications.push("L'arme est empoisonn\xE9e"); + explications.push("L'arme est empoisonnée"); if (nombreMunitionsEmpoisonnees == 1) { evt.deletedAttributes = evt.deletedAttributes || []; evt.deletedAttributes.push(poisonAttr); @@ -16038,15 +16064,15 @@ var COFantasy = COFantasy || function() { } } - //N'ajoute pas evt \xE0 l'historique + //N'ajoute pas evt à l'historique function resoudreAttaque(attaquant, cibles, attackLabel, weaponName, weaponStats, playerId, pageId, evt, explications, options, chargesArme) { let attackingCharId = attaquant.charId; let attackingToken = attaquant.token; let attackerTokName = nomPerso(attaquant); - attaquant.additionalDmg = [...options.additionalDmg]; // Reset du calcul des dommages additionnels li\xE9s \xE0 l'attaquant + attaquant.additionalDmg = [...options.additionalDmg]; // Reset du calcul des dommages additionnels liés à l'attaquant let sujetAttaquant = onGenre(attaquant, 'il', 'elle'); if (options.contact) { - //Prise en compte du corps \xE9l\xE9mentaire + //Prise en compte du corps élémentaire let typeCorpsElem = predicateAsBool(attaquant, 'corpsElementaire'); if (typeCorpsElem && typeCorpsElem !== true) { let nbDes = predicateAsInt(attaquant, 'nbCorpsElementaire', 1); @@ -16061,7 +16087,7 @@ var COFantasy = COFantasy || function() { // Les armes de jet if (weaponStats.armeDeJet && !estMook && !(options.ricochets && options.ricochets.cibles.length > 0)) { if (weaponStats.nbArmesDeJet < 1) { - sendPerso(attaquant, "plus de " + weaponName + " \xE0 lancer."); + sendPerso(attaquant, "plus de " + weaponName + " à lancer."); return; } let attrName = weaponStats.prefixe + 'armejetqte'; @@ -16077,12 +16103,12 @@ var COFantasy = COFantasy || function() { if (attr.length > 0) { attr = attr[0]; if (attr.length > 1) { - error("Plus d'un attribut pour la quantit\xE9 d'armes de jet", attr); + error("Plus d'un attribut pour la quantité d'armes de jet", attr); attr[1].remove(); } max = parseInt(attr.get('max')); if (isNaN(max) || max < 1) { - error("Maximum de " + weaponName + " mal form\xE9, v\xE9rifier sur la fiche", attr); + error("Maximum de " + weaponName + " mal formé, vérifier sur la fiche", attr); max = 1; } evt.attributes.push({ @@ -16101,19 +16127,19 @@ var COFantasy = COFantasy || function() { attribute: attr, }); } - //On cherche si l'arme de jet est empoison\xE9e + //On cherche si l'arme de jet est empoisonée let poisonAttr = tokenAttribute(attaquant, 'enduitDePoison_' + attackLabel); effetPoisonSurMunitions(poisonAttr, attaquant, explications, options, evt); let restant = weaponStats.nbArmesDeJet; if (randomInteger(100) < weaponStats.tauxDePerte) { if (weaponStats.tauxDePerte < 100) - explications.push(weaponName + " n'est pas r\xE9cup\xE9rable"); + explications.push(weaponName + " n'est pas récupérable"); attr.set('max', max - 1); options.armeDeJetPerdue = true; } restant--; attr.set('current', restant); - if (!options.armeDeJetPerdue) { //pr\xE9pare pour un \xE9ventuel retour en main + if (!options.armeDeJetPerdue) { //prépare pour un éventuel retour en main options.attrArmeDeJet = { attribute: attr, restant: restant @@ -16122,33 +16148,33 @@ var COFantasy = COFantasy || function() { if (restant === 0) { degainerArmeLancee(attaquant, attackLabel, evt); } - explications.push("Il reste " + restant + " " + weaponName + " \xE0 " + attackerTokName); + explications.push("Il reste " + restant + " " + weaponName + " à " + attackerTokName); } } if (options.aussiArmeDeJet && !estMook) { let armeAssociee = getWeaponStats(attaquant, options.aussiArmeDeJet); if (armeAssociee && armeAssociee.armeDeJet) { if (armeAssociee.nbArmesDeJet < 1) { - sendPerso(attaquant, "a d\xE9j\xE0 lanc\xE9 tous ses " + weaponName); + sendPerso(attaquant, "a déjà lancé tous ses " + weaponName); return; } } else { - error("L'arme de label " + options.aussiArmeDeJet + " n'est pas une arme de jet, option ignor\xE9e", armeAssociee); + error("L'arme de label " + options.aussiArmeDeJet + " n'est pas une arme de jet, option ignorée", armeAssociee); } } // Munitions if (options.munition) { if (estMook) { - error("Les munitions ne sont pas support\xE9es pour les tokens qui ne sont pas li\xE9es \xE0 un personnage", attackingToken); + error("Les munitions ne sont pas supportées pour les tokens qui ne sont pas liées à un personnage", attackingToken); } - if (options.munition.nom) { //Ancienne variante, obsol\xE8te depuis mars 2023 + if (options.munition.nom) { //Ancienne variante, obsolète depuis mars 2023 let munitionsAttr = findObjs({ _type: 'attribute', _characterid: attackingCharId, name: 'munition_' + options.munition.nom }); if (munitionsAttr.length === 0) { - sendPerso(attaquant, ": Pas de munition nomm\xE9e " + options.munition.nom); + sendPerso(attaquant, ": Pas de munition nommée " + options.munition.nom); return; } munitionsAttr = munitionsAttr[0]; @@ -16161,7 +16187,7 @@ var COFantasy = COFantasy || function() { } let munitionsMax = parseInt(munitionsAttr.get('max')); if (isNaN(munitionsMax)) { - error("Attribut de munitions mal form\xE9", munitionsMax); + error("Attribut de munitions mal formé", munitionsMax); return; } evt.attributes = evt.attributes || []; @@ -16170,7 +16196,7 @@ var COFantasy = COFantasy || function() { current: munitions, max: munitionsMax }); - //On cherche si la munition est empoisonn\xE9e + //On cherche si la munition est empoisonnée let poisonAttr = tokenAttribute(attaquant, 'enduitDePoison_munition_' + options.munition.nom); effetPoisonSurMunitions(poisonAttr, attaquant, explications, options, evt); munitions--; @@ -16180,12 +16206,12 @@ var COFantasy = COFantasy || function() { if (randomInteger(100) < options.munition.taux) munitionsMax--; } explications.push("Il reste " + munitions + " " + - options.munition.nom.replace(/_/g, ' ') + " \xE0 " + attackerTokName); + options.munition.nom.replace(/_/g, ' ') + " à " + attackerTokName); munitionsAttr.set('current', munitions); munitionsAttr.set('max', munitionsMax); } else { //Utilisation d'une munition de la fiche let m = options.munition; - let typeMunition = fieldAsString(m, 'typemunition', 'Fl\xE8che'); + let typeMunition = fieldAsString(m, 'typemunition', 'Flèche'); let nom = fieldAsString(m, 'nommunition', typeMunition); let munitions = fieldAsInt(m, 'qtemunition', 1); if (munitions < 1 || (options.tirDouble && munitions < 2)) { @@ -16195,7 +16221,7 @@ var COFantasy = COFantasy || function() { return; } let label = fieldAsString(m, 'labelmunition', '0'); - //On cherche si la munition est empoisonn\xE9e + //On cherche si la munition est empoisonnée let poisonAttr = tokenAttribute(attaquant, 'enduitDePoison_munition_' + label); effetPoisonSurMunitions(poisonAttr, attaquant, explications, options, evt); let munitionsMax = fieldAsInt(m, 'qtemunition_max', munitions); @@ -16219,8 +16245,8 @@ var COFantasy = COFantasy || function() { } else { msgm += "reste " + munitions + " "; } - msgm += nom + " \xE0 " + attackerTokName; - if (taux < 100 && perte > 0) msgm += ", et la munition utilis\xE9e n'est pas r\xE9cup\xE9rable"; + msgm += nom + " à " + attackerTokName; + if (taux < 100 && perte > 0) msgm += ", et la munition utilisée n'est pas récupérable"; explications.push(msgm); evt.attributes = evt.attributes || []; let name = m.prefixe + 'qtemunition'; @@ -16253,7 +16279,7 @@ var COFantasy = COFantasy || function() { } } } - // Armes charg\xE9es + // Armes chargées if (options.semonce === undefined && options.tirDeBarrage === undefined) { if (attackLabel && weaponStats && weaponStats.charge) { let currentCharge = 0; @@ -16261,7 +16287,7 @@ var COFantasy = COFantasy || function() { currentCharge = parseInt(chargesArme[0].get('current')); } if (isNaN(currentCharge) || currentCharge < 1) { - sendPerso(attaquant, "ne peut pas attaquer avec " + weaponName + " car elle n'est pas charg\xE9e"); + sendPerso(attaquant, "ne peut pas attaquer avec " + weaponName + " car elle n'est pas chargée"); return; } if (options.tirDouble && @@ -16269,7 +16295,7 @@ var COFantasy = COFantasy || function() { currentCharge < 2) { sendPerso(attaquant, "ne peut pas faire de tir double avec ses" + weaponName + "s car " + - sujetAttaquant + " n'en a pas au moins 2 charg\xE9es"); + sujetAttaquant + " n'en a pas au moins 2 chargées"); return; } evt.attributes = evt.attributes || []; @@ -16278,7 +16304,7 @@ var COFantasy = COFantasy || function() { if (chargesGrenaille.length > 0) { let currentChargeGrenaille = parseInt(chargesGrenaille[0].get('current')); if (isNaN(currentChargeGrenaille) || currentChargeGrenaille < 1) { - sendPerso(attaquant, "ne peut pas attaquer avec " + weaponName + " car elle n'est pas charg\xE9e en grenaille"); + sendPerso(attaquant, "ne peut pas attaquer avec " + weaponName + " car elle n'est pas chargée en grenaille"); return; } if (options.tirDouble && @@ -16286,7 +16312,7 @@ var COFantasy = COFantasy || function() { currentChargeGrenaille < 2) { sendPerso(attaquant, "ne peut pas faire de tir double de grenaille avec ses" + weaponName + "s car " + - sujetAttaquant + " n'en a pas au moins 2 charg\xE9es de grenaille"); + sujetAttaquant + " n'en a pas au moins 2 chargées de grenaille"); return; } evt.attributes.push({ @@ -16307,7 +16333,7 @@ var COFantasy = COFantasy || function() { if (options.tirDouble && (!options.tirDouble.stats || options.tirDouble.label == attackLabel)) currentCharge -= 2; else currentCharge -= 1; - //Si l'arme n'est plus charg\xE9e, on peut perdre le bonus d'initiative + //Si l'arme n'est plus chargée, on peut perdre le bonus d'initiative if (currentCharge === 0 && bonusPlusViteQueSonOmbre(attaquant, weaponStats)) { updateNextInit(attaquant); @@ -16325,7 +16351,7 @@ var COFantasy = COFantasy || function() { if (chargesSecondeArme.length > 0) { let currentCharge2 = parseInt(chargesSecondeArme[0].get('current')); if (isNaN(currentCharge2) || currentCharge2 < 1) { - sendPerso(attaquant, "ne peut pas faire de tir double avec " + secondNom + " car ce n'est pas charg\xE9"); + sendPerso(attaquant, "ne peut pas faire de tir double avec " + secondNom + " car ce n'est pas chargé"); return; } evt.attributes = evt.attributes || []; @@ -16334,7 +16360,7 @@ var COFantasy = COFantasy || function() { if (chargesGrenaille2.length > 0) { let currentChargeGrenaille2 = parseInt(chargesGrenaille2[0].get('current')); if (isNaN(currentChargeGrenaille2) || currentChargeGrenaille2 < 1) { - sendPerso(attaquant, "ne peut pas faire de tir double avec " + secondNom + " car ce n'est pas charg\xE9 en grenaille"); + sendPerso(attaquant, "ne peut pas faire de tir double avec " + secondNom + " car ce n'est pas chargé en grenaille"); return; } evt.attributes.push({ @@ -16358,9 +16384,9 @@ var COFantasy = COFantasy || function() { } // Effets quand on rentre en combat entrerEnCombat(attaquant, cibles, explications, evt); - // On commence par le jet d'attaque de base : juste le ou les d\xE9s d'attaque - // et le modificateur d'arme et de caract\xE9ritiques qui apparaissent dans - // la description de l'attaque. Il faut quand m\xEAme tenir compte des + // On commence par le jet d'attaque de base : juste le ou les dés d'attaque + // et le modificateur d'arme et de caractéritiques qui apparaissent dans + // la description de l'attaque. Il faut quand même tenir compte des // chances de critique let crit = critEnAttaque(attaquant, weaponStats, options); let dice = 20; @@ -16376,7 +16402,7 @@ var COFantasy = COFantasy || function() { } } else if (getState(attaquant, 'immobilise')) { dice = 12; - explications.push("Attaquant immobilis\xE9 => D12 au lieu de D20 en Attaque"); + explications.push("Attaquant immobilisé => D12 au lieu de D20 en Attaque"); } else if (attributeAsBool(attaquant, 'mortMaisNAbandonnePas')) { dice = 12; explications.push("Attaquant mort mais n'abandonne pas => D12 au lieu de D20 en Attaque"); @@ -16400,7 +16426,7 @@ var COFantasy = COFantasy || function() { if (options.avantage !== undefined) { if (options.avantage > 0) nbDe = options.avantage; else { - nbDe = 2 - options.avantage; //d\xE9savantage + nbDe = 2 - options.avantage; //désavantage plusFort = false; } } @@ -16417,7 +16443,7 @@ var COFantasy = COFantasy || function() { // toEvaluateAttack inlines // 0: attack roll // 1: attack skill expression - // 2: d\xE9 de poudre + // 2: dé de poudre let toEvaluateAttack = attackExpression(attaquant, nbDe, dice, crit, plusFort, weaponStats); if (options.poudre) toEvaluateAttack += " [[1d20]]"; @@ -16456,17 +16482,17 @@ var COFantasy = COFantasy || function() { retarde: options.secret, auto: options.auto || options.ouvertureMortelle }); - // Cas des armes \xE0 poudre + // Cas des armes à poudre if (options.poudre && !predicateAsBool(attaquant, 'chimiste')) { let poudreNumber = rollNumber(afterEvaluateAttack[2]); let dePoudre = rollsAttack.inlinerolls[poudreNumber].results.total; explications.push( - "D\xE9 de poudre : " + buildinline(rollsAttack.inlinerolls[poudreNumber])); + "Dé de poudre : " + buildinline(rollsAttack.inlinerolls[poudreNumber])); if (dePoudre === 1) { evt.succes = false; if (d20roll === 1) { explications.push( - weaponName + " explose ! L'arme est compl\xE8tement d\xE9truite"); + weaponName + " explose ! L'arme est complètement détruite"); sendChat("", "[[2d6]]", function(res) { let rolls = res[0]; let explRoll = rolls.inlinerolls[0]; @@ -16487,7 +16513,7 @@ var COFantasy = COFantasy || function() { } else { explications.push( "La poudre explose dans " + weaponName + - ". L'arme est inutilisable jusqu'\xE0 la fin du combat"); + ". L'arme est inutilisable jusqu'à la fin du combat"); sendChat("", "[[1d6]]", function(res) { let rolls = res[0]; let explRoll = rolls.inlinerolls[0]; @@ -16524,7 +16550,7 @@ var COFantasy = COFantasy || function() { options.projection = true; } } - //Modificateurs en Attaque qui ne d\xE9pendent pas de la cible + //Modificateurs en Attaque qui ne dépendent pas de la cible let attBonusCommun = 0; if (!options.auto) { attBonusCommun = @@ -16535,7 +16561,7 @@ var COFantasy = COFantasy || function() { } if (options.traquenard) { if (attributeAsBool(attaquant, 'traquenardImpossible')) { - sendPerso(attaquant, "ne peut pas faire de traquenard, car ce n'est pas sa premi\xE8re attaque du combat"); + sendPerso(attaquant, "ne peut pas faire de traquenard, car ce n'est pas sa première attaque du combat"); return; } options.traquenard = persoInit(attaquant, evt); @@ -16543,27 +16569,27 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(attaquant, 'traquenard') && !attributeAsBool(attaquant, 'traquenardImpossible')) { setTokenAttr(attaquant, 'traquenardImpossible', true, evt); } - if (options.feinte) explications.push("Mais c'\xE9tait une feinte..."); + if (options.feinte) explications.push("Mais c'était une feinte..."); let mainDmgType = options.type || 'normal'; if (options.sortilege) options.ignoreObstacles = true; let echecCritique; - //Calcul des cibles touch\xE9es + //Calcul des cibles touchées //(et on ajuste le jet pour la triche) let ciblesTouchees = []; let count = cibles.length; cibles.forEach(function(target) { - // reset les champs de target qui vont \xEAtre recalcul\xE9s + // reset les champs de target qui vont être recalculés target.additionalDmg = []; target.effets = []; target.dmgCoef = 0; target.critCoef = 0; target.diviseDmg = 1; if (attributeAsBool(attaquant, 'menaceManoeuvre(' + target.token.id + ')')) { - explications.push(nomPerso(attaquant) + " attaque " + nomPerso(target) + " malgr\xE9 la menace. " + nomPerso(target) + " a droit \xE0 une attaque au contact gratuite."); + explications.push(nomPerso(attaquant) + " attaque " + nomPerso(target) + " malgré la menace. " + nomPerso(target) + " a droit à une attaque au contact gratuite."); removeTokenAttr(attaquant, 'menaceManoeuvre(' + target.token.id + ')', evt); setTokenAttr(attaquant, 'attaqueMalgreMenace(' + target.token.id + ')', 1, evt); } else if (attributeAsBool(attaquant, 'menaceManoeuvre(' + target.token.id + ',crit)')) { - explications.push(nomPerso(attaquant) + " attaque " + nomPerso(target) + " malgr\xE9 la menace. " + nomPerso(target) + " a droit \xE0 une attaque au contact gratuite (DM x 2 !)."); + explications.push(nomPerso(attaquant) + " attaque " + nomPerso(target) + " malgré la menace. " + nomPerso(target) + " a droit à une attaque au contact gratuite (DM x 2 !)."); removeTokenAttr(attaquant, 'menaceManoeuvre(' + target.token.id + ',crit)', evt); setTokenAttr(attaquant, 'attaqueMalgreMenace(' + target.token.id + ')', 2, evt); } @@ -16587,7 +16613,7 @@ var COFantasy = COFantasy || function() { target.percute = target.percute || options.percute; target.maxDmg = target.maxDmg || options.maxDmg; target.kiai = target.kiai || options.kiai; - //Les bonus d'attaque qui d\xE9pendent de la cible + //Les bonus d'attaque qui dépendent de la cible let bad = 0; if (!options.auto) bad = bonusAttaqueD(attaquant, target, weaponStats.portee, pageId, evt, target.messages, options); @@ -16596,7 +16622,7 @@ var COFantasy = COFantasy || function() { let amm = 'attaqueMalgreMenace(' + attaquant.token.id + ')'; if (options.contact && cibles.length == 1) { if (attributeAsBool(target, amm)) { - target.messages.push('Attaque automatique suite \xE0 une menace ignor\xE9e'); + target.messages.push('Attaque automatique suite à une menace ignorée'); options.auto = true; if (attributeAsInt(target, amm, 1) > 1) options.dmFoisDeux = true; target.additionalDmg.push({ @@ -16615,9 +16641,9 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '2' + options.d6 }); - target.messages.push(attackerTokName + " fait un traquenard \xE0 " + nomPerso(target)); + target.messages.push(attackerTokName + " fait un traquenard à " + nomPerso(target)); } else { - target.messages.push(attackerTokName + " n'est pas assez rapide pour faire un traquenard \xE0 " + nomPerso(target)); + target.messages.push(attackerTokName + " n'est pas assez rapide pour faire un traquenard à " + nomPerso(target)); } } let defautCuirasse = @@ -16650,7 +16676,7 @@ var COFantasy = COFantasy || function() { } let touche = true; let critique = false; - // Calcule si touch\xE9, et les messages de d\xE9gats et attaque + // Calcule si touché, et les messages de dégats et attaque if (options.auto) { addAttackSound("soundAttackSucces", weaponStats.divers, options); } else if (!options.interposer) { @@ -16714,7 +16740,7 @@ var COFantasy = COFantasy || function() { if (target.chatimentDuMale) { target.chatimentDuMaleRoll = target.chatimentDuMaleRoll || randomInteger(dice); target.chatimentDuMaleLowRoll = target.chatimentDuMaleRoll; - target.messages.push("B\xE9n\xE9diction de Ma\xEBdra => relance \xE0 " + target.chatimentDuMaleRoll + " du jet d'attaque contre un m\xE2le"); + target.messages.push("Bénédiction de Maëdra => relance à " + target.chatimentDuMaleRoll + " du jet d'attaque contre un mâle"); if (target.chatimentDuMaleRoll > targetd20roll) { targetd20roll = target.chatimentDuMaleRoll; target.chatimentDuMaleLowRoll = target.d20roll; @@ -16727,11 +16753,11 @@ var COFantasy = COFantasy || function() { if (getState(target, 'paralyse')) { paralyse = true; if (!options.attaqueAssuree) - target.messages.push("Cible paralys\xE9e => r\xE9ussite critique automatique"); + target.messages.push("Cible paralysée => réussite critique automatique"); } else if (getState(target, 'mort')) { paralyse = true; if (!options.attaqueAssuree) - target.messages.push("Cible inconsciente => r\xE9ussite critique automatique"); + target.messages.push("Cible inconsciente => réussite critique automatique"); } if (targetd20roll >= 15) { if (predicateAsBool(attaquant, 'champion')) @@ -16750,13 +16776,13 @@ var COFantasy = COFantasy || function() { setTokenAttr(attaquant, 'etreinteImmole', idName(target), evt); setTokenAttr(target, 'etreinteImmolePar', idName(attaquant), evt); setState(target, 'immobilise', true, evt); - target.messages.push(nomPerso(attaquant) + " \xE9treint " + nomPerso(target) + " et s'immole !"); + target.messages.push(nomPerso(attaquant) + " étreint " + nomPerso(target) + " et s'immole !"); target.etreinteImmole = true; } if (options.etreinteScorpion) { setTokenAttr(attaquant, 'etreinteScorpionSur', idName(target), evt); setTokenAttr(target, 'etreinteScorpionPar', idName(attaquant), evt); - target.messages.push(nomPerso(attaquant) + " \xE9treint " + nomPerso(target) + " !"); + target.messages.push(nomPerso(attaquant) + " étreint " + nomPerso(target) + " !"); } if (targetd20roll >= 16 && options.contact) { let ecraser = predicateAsBool(attaquant, 'ecraser'); @@ -16777,7 +16803,7 @@ var COFantasy = COFantasy || function() { } let faireMouche; if (targetd20roll == 1 && options.chance === undefined) { - attackResult = " => \xE9chec critique"; + attackResult = " => échec critique"; attackResult += addAttackImg("imgAttackEchecCritique", weaponStats.divers, options); addAttackSound('soundAttackEchecCritique', weaponStats.divers, options); if (options.demiAuto) { @@ -16796,7 +16822,7 @@ var COFantasy = COFantasy || function() { } else if ((paralyse || options.ouvertureMortelle || targetd20roll == 20 || (targetd20roll >= target.crit && attackRoll >= defense) || (reglesOptionelles.divers.val.coups_critiques_etendus.val && attackRoll > defense + 9)) && !options.attaqueAssuree) { - attackResult = " => r\xE9ussite critique"; + attackResult = " => réussite critique"; attackResult += addAttackImg("imgAttackSuccesCritique", weaponStats.divers, options); addAttackSound('soundAttackSuccesCritique', weaponStats.divers, options); touche = true; @@ -16813,12 +16839,12 @@ var COFantasy = COFantasy || function() { } resetTenacite(attaquant, target, evt); } else if (options.champion || targetd20roll == 20 || paralyse) { - attackResult = " => succ\xE8s"; + attackResult = " => succès"; attackResult += addAttackImg("imgAttackSuccesChampion", weaponStats.divers, options); addAttackSound("soundAttackSuccesChampion", weaponStats.divers, options); resetTenacite(attaquant, target, evt); } else if (attackRoll < defense && targetd20roll < target.crit) { - attackResult = " => \xE9chec"; + attackResult = " => échec"; attackResult += addAttackImg("imgAttackEchec", weaponStats.divers, options); addAttackSound('soundAttackEchec', weaponStats.divers, options); evt.succes = false; @@ -16834,8 +16860,8 @@ var COFantasy = COFantasy || function() { } else touche = false; increaseTenacite(attaquant, target, evt); } else if (targetd20roll % 2 && attributeAsBool(target, 'clignotement')) { - target.messages.push(nomPerso(target) + " dispara\xEEt au moment o\xF9 l'attaque aurait du l" + onGenre(target, 'e', 'a') + " toucher"); - attackResult = " => \xE9chec"; + target.messages.push(nomPerso(target) + " disparaît au moment où l'attaque aurait du l" + onGenre(target, 'e', 'a') + " toucher"); + attackResult = " => échec"; attackResult += addAttackImg("imgAttackEchecClignotement", weaponStats.divers, options); addAttackSound('soundAttackEchecClignotement', weaponStats.divers, options); target.clignotement = true; @@ -16849,8 +16875,8 @@ var COFantasy = COFantasy || function() { target.dmgCoef--; evt.succes = false; } else touche = false; - } else { // Touch\xE9 normal - attackResult = " => succ\xE8s"; + } else { // Touché normal + attackResult = " => succès"; attackResult += addAttackImg("imgAttackSucces", weaponStats.divers, options); addAttackSound("soundAttackSucces", weaponStats.divers, options); resetTenacite(attaquant, target, evt); @@ -16863,7 +16889,7 @@ var COFantasy = COFantasy || function() { else if (attBonus < 0) bonusTexte += attBonus; if (ficheAttributeAsBool(attaquant, 'jets_caches', false)) { attRollValue = attackRoll; - sendChat('COF', "/w GM Jet cach\xE9 d'attaque : " + buildinline(rollsAttack.inlinerolls[attRollNumber]) + bonusTexte); + sendChat('COF', "/w GM Jet caché d'attaque : " + buildinline(rollsAttack.inlinerolls[attRollNumber]) + bonusTexte); } else { attRollValue = buildinline(rollsAttack.inlinerolls[attRollNumber]) + bonusTexte; } @@ -16919,7 +16945,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '2' + options.d6 }); - target.messages.push("Ch\xE2timent du m\xE2le => +2d6 DM"); + target.messages.push("Châtiment du mâle => +2d6 DM"); } } if (predicateAsBool(attaquant, 'batonDesRunesMortes') && attributeAsBool(attaquant, 'runeMelianil')) { @@ -16931,7 +16957,7 @@ var COFantasy = COFantasy || function() { target.messages.push("Melianil => +1d6 DM"); } if (attributeAsBool(target, 'momentDePerfection')) { - target.messages.push("Gr\xE2ce \xE0 son instant de perfection, " + nomPerso(target) + " \xE9vite le coup !"); + target.messages.push("Grâce à son instant de perfection, " + nomPerso(target) + " évite le coup !"); touche = false; evt.succes = false; } @@ -16944,7 +16970,7 @@ var COFantasy = COFantasy || function() { } } else { //Effet si on ne touche pas if (attributeAsBool(attaquant, 'momentDePerfection')) { - target.messages.push("Gr\xE2ce \xE0 son instant de perfection, " + nomPerso(attaquant) + " touche !"); + target.messages.push("Grâce à son instant de perfection, " + nomPerso(attaquant) + " touche !"); touche = true; evt.succes = true; } else { @@ -16996,18 +17022,18 @@ var COFantasy = COFantasy || function() { let id = target.rollImageDecalee; if (id.val > 4) { target.touche = false; - target.messages.push(id.roll + ": l'attaque passe \xE0 travers l'image de " + nomPerso(target)); + target.messages.push(id.roll + ": l'attaque passe à travers l'image de " + nomPerso(target)); } else { - target.messages.push(id.roll + ": malgr\xE9 l'image l\xE9g\xE8rement d\xE9cal\xE9e de " + nomPerso(target) + " l'attaque touche"); + target.messages.push(id.roll + ": malgré l'image légèrement décalée de " + nomPerso(target) + " l'attaque touche"); } } else if (predicateAsBool(target, 'estUneIllusion')) { target.touche = false; - target.messages.push(nomPerso(target) + " disparait et se mat\xE9rialise un peu plus loin"); + target.messages.push(nomPerso(target) + " disparait et se matérialise un peu plus loin"); } } if (target.touche) { ciblesTouchees.push(target); - //Possibilit\xE9s d'annuler l'attaque + //Possibilités d'annuler l'attaque if (!options.pasDeDmg && isActive(target) && attributeAsBool(target, 'runeForgesort_protection') && attributeAsInt(target, 'limiteParCombat_runeForgesort_protection', 1) > 0) { @@ -17016,7 +17042,7 @@ var COFantasy = COFantasy || function() { options.preDmg[target.token.id].runeForgesort_protection = true; } if (!options.auto) { - //Seulement si elle n'est pas automatiquement r\xE9ussie + //Seulement si elle n'est pas automatiquement réussie if (isActive(target)) { if (!options.pasDeDmg && options.contact && !options.ignoreTouteRD) { @@ -17075,7 +17101,7 @@ var COFantasy = COFantasy || function() { } if (!options.aoe && capaciteDisponible(target, 'esquiveFatale', 'combat')) { if (target.ennemisAuContact === undefined) { - error(nomPerso(target) + " a la possibilit\xE9 d'une esquive fatale, mais les ennemis au contact ne sont pas calcul\xE9s", target); + error(nomPerso(target) + " a la possibilité d'une esquive fatale, mais les ennemis au contact ne sont pas calculés", target); } else { let ciblesEsquiveFatale = target.ennemisAuContact.filter(function(tok) { return (tok.id != attaquant.token.id); @@ -17131,7 +17157,7 @@ var COFantasy = COFantasy || function() { options.preDmg[target.token.id] = options.preDmg[target.token.id] || {}; options.preDmg[target.token.id].chairACanon = target.chairACanon; } - //Interception par un alli\xE9 + //Interception par un allié let alliesAvecInterception = []; if (target.alliesAuContact === undefined) { let allies = alliesParPerso[target.charId] || new Set(); @@ -17158,6 +17184,7 @@ var COFantasy = COFantasy || function() { charId: ci }; if (!isActive(perso)) return; + if (getState(perso, 'renverse')) return; if (persoImmobilise(perso) && distanceCombat(tok, attaquant.token, pageId) > 0) return; @@ -17180,7 +17207,7 @@ var COFantasy = COFantasy || function() { alliesAvecInterception.push(perso); }); } - //On enl\xE8ve les alli\xE9s qui sont cibles de l'attaque + //On enlève les alliés qui sont cibles de l'attaque alliesAvecInterception = alliesAvecInterception.filter(function(p) { return cibles.every(function(c) { return c.token.id != p.token.id; @@ -17214,11 +17241,11 @@ var COFantasy = COFantasy || function() { } resolvePreDmgOptions(attaquant, ciblesTouchees, echecCritique, attackLabel, weaponStats, d20roll, display, options, evt, explications, pageId, cibles); } - }, true); //comme on est dans une boucle qui d\xE9pend de la cible, inTarget doit \xEAtre vrai - }); //fin de d\xE9termination de toucher des cibles + }, true); //comme on est dans une boucle qui dépend de la cible, inTarget doit être vrai + }); //fin de détermination de toucher des cibles }); // fin du jet d'attaque asynchrone } catch (e) { - error("Erreur pendant l'\xE9valuation de " + toEvaluateAttack + " du test d'attaque", weaponStats); + error("Erreur pendant l'évaluation de " + toEvaluateAttack + " du test d'attaque", weaponStats); log(e.name + ": " + e.message); } } @@ -17229,11 +17256,11 @@ var COFantasy = COFantasy || function() { function stringOfEtat(etat, perso) { if (etat == 'invisible') return etat; - else if (etat == 'penombre') return "dans la p\xE9nombre"; + else if (etat == 'penombre') return "dans la pénombre"; else if (etat == 'chef') return "est un leader"; let etext = etat; if (etat.endsWith('e')) { - etext = etat.substring(0, etat.length - 1) + '\xE9'; + etext = etat.substring(0, etat.length - 1) + 'é'; } if (perso === undefined) return etext; return etext + eForFemale(perso); @@ -17326,7 +17353,7 @@ var COFantasy = COFantasy || function() { function computeAttackDice(d, maxDmg, options) { if (isNaN(d) || d < 0) { - error("D\xE9 d'attaque incorrect", d); + error("Dé d'attaque incorrect", d); return 0; } let attDice = d; @@ -17385,7 +17412,7 @@ var COFantasy = COFantasy || function() { if (attCarBonus < 1) attCarBonus = ''; else attCarBonus = " +" + attCarBonus; } else { - target.messages.push(nomPerso(target) + " semble immunis\xE9 aux armes ordinaires"); + target.messages.push(nomPerso(target) + " semble immunisé aux armes ordinaires"); attNbDicesCible = 0; attCarBonus = ''; attDMBonus = ''; @@ -17396,7 +17423,7 @@ var COFantasy = COFantasy || function() { return addOrigin(attaquant.name, attNbDicesCible + symbde + attDiceCible + attCarBonus + attDMBonus); } - //retourne le mod de la caract\xE9ristique x, undefined si ce n'en est pas une + //retourne le mod de la caractéristique x, undefined si ce n'en est pas une function computeCarValue(perso, x) { switch (x) { case '@{FOR}': @@ -17470,7 +17497,7 @@ var COFantasy = COFantasy || function() { } sides = sides.split('|'); if (side < 0 || side >= sides.length) { - error("Le token de " + nomPerso(perso) + " n'a pas de face num\xE9ro " + side, sides); + error("Le token de " + nomPerso(perso) + " n'a pas de face numéro " + side, sides); return; } let oldSide = token.get('currentSide'); @@ -17482,44 +17509,44 @@ var COFantasy = COFantasy || function() { return oldSide; } - //Met un effet temporaire sur target. L'effet temporaire est sp\xE9cifi\xE9 dans ef + //Met un effet temporaire sur target. L'effet temporaire est spécifié dans ef // - effet : le nom de l'effet - // - whisper : true si on doit chuchoter l'effet, undefined si on n'affiche pas (mais dans ce cas, target.messages doit \xEAtre d\xE9fini) - // - duree : true si c'est un effet \xE0 dur\xE9e en tours - // - effetIndetermine : true si l'effet a une dur\xE9e ind\xE9termin\xE9e (pas combat) - // - accumuleDuree : si la dur\xE9e peut s'accumuler - // - typeDmg : le type de d\xE9g\xE2ts associ\xE9 \xE0 l'effet, si pertinent + // - whisper : true si on doit chuchoter l'effet, undefined si on n'affiche pas (mais dans ce cas, target.messages doit être défini) + // - duree : true si c'est un effet à durée en tours + // - effetIndetermine : true si l'effet a une durée indéterminée (pas combat) + // - accumuleDuree : si la durée peut s'accumuler + // - typeDmg : le type de dégâts associé à l'effet, si pertinent // - message : la structure de messages (venant de messageEffetTemp ou autre) - // - dm : l'effet fait des d\xE9g\xE2ts + // - dm : l'effet fait des dégâts // - visible : l'effet est visible - // - prejudiciable : l'effet est pr\xE9judiciable (et donc cible de d\xE9livrance) - // - statusMarker : marker associ\xE9 \xE0 l'effet + // - prejudiciable : l'effet est préjudiciable (et donc cible de délivrance) + // - statusMarker : marker associé à l'effet // - pasDeMessageDActivation : pour ne pas afficher le message d'activation - // - image : lien d'une image \xE0 afficher - // - valeur : valeur associ\xE9e \xE0 l'effet - // - valeurMax : champ max de l'attribut valeur associ\xE9 \xE0 l'effet - // - saveParTour : caract\xE9ristiques du save par tour, si besoin. - // - saveActifParTour : caract\xE9ristiques du save actif par tour, si besoin. - // - attaquant : la personne \xE0 l'origine de l'effet - // - options : des options \xE0 mettre dans l'attribut d'options - // - tokenSide : change le c\xF4t\xE9 du token \xE0 cette face + // - image : lien d'une image à afficher + // - valeur : valeur associée à l'effet + // - valeurMax : champ max de l'attribut valeur associé à l'effet + // - saveParTour : caractéristiques du save par tour, si besoin. + // - saveActifParTour : caractéristiques du save actif par tour, si besoin. + // - attaquant : la personne à l'origine de l'effet + // - options : des options à mettre dans l'attribut d'options + // - tokenSide : change le côté du token à cette face function setEffetTemporaire(target, ef, duree, evt, options) { if (ef.effet == 'dedoublement') { if (attributeAsBool(target, 'dedouble') || attributeAsBool(target, 'dedoublement')) { if (ef.whisper !== undefined) { - whisperChar(target.charId, "a d\xE9j\xE0 \xE9t\xE9 d\xE9doubl\xE9 pendant ce combat"); + whisperChar(target.charId, "a déjà été dédoublé pendant ce combat"); } else { - target.messages.push(nomPerso(target) + " a d\xE9j\xE0 \xE9t\xE9 d\xE9doubl\xE9 pendant ce combat"); + target.messages.push(nomPerso(target) + " a déjà été dédoublé pendant ce combat"); } return; } let dedoubleMsg = - "Un double translucide de " + nomPerso(target) + " appara\xEEt."; + "Un double translucide de " + nomPerso(target) + " apparaît."; if (ef.attaquant) { dedoubleMsg += " Il est aux ordres de " + nomPerso(ef.attaquant); } - if (stateCOF.options.affichage.val.duree_effets.val) dedoubleMsg += " (" + duree + " tour" + ((duree>1)?'s':'') +")"; + if (stateCOF.options.affichage.val.duree_effets.val) dedoubleMsg += " (" + duree + " tour" + ((duree > 1) ? 's' : '') + ")"; if (ef.whisper !== undefined) { if (ef.whisper === true) { whisperChar(target.charId, dedoubleMsg); @@ -17542,12 +17569,12 @@ var COFantasy = COFantasy || function() { if (estImmuniseAEffet(target, ef.effet)) { if (ef.whisper !== undefined) { if (ef.whisper === true) { - whisperChar(target.charId, "ne peut pas \xEAtre affect\xE9 par l'effet de " + ef.effet); + whisperChar(target.charId, "ne peut pas être affecté par l'effet de " + ef.effet); } else { - sendChar(target.charId, ef.whisper + "ne peut pas \xEAtre affect\xE9 par l'effet de " + ef.effet); + sendChar(target.charId, ef.whisper + "ne peut pas être affecté par l'effet de " + ef.effet); } } else { - target.messages.push(nomPerso(target) + " ne peut pas \xEAtre affect\xE9 par l'effet de " + ef.effet); + target.messages.push(nomPerso(target) + " ne peut pas être affecté par l'effet de " + ef.effet); } return; } @@ -17595,7 +17622,7 @@ var COFantasy = COFantasy || function() { accumuleAttr.set('current', duree + ',' + dureeAccumulee); } } - return; //Pas besoin de r\xE9appliquer, effet toujours en cours + return; //Pas besoin de réappliquer, effet toujours en cours } } let targetMsg = ''; @@ -17659,7 +17686,7 @@ var COFantasy = COFantasy || function() { setState(target, 'invisible', true, evt); break; case 'aspectDuDemon': - //On retire l'autre aspect du N\xE9cromancien si il est pr\xE9sent + //On retire l'autre aspect du Nécromancien si il est présent finDEffetDeNom(target, "aspectDeLaSuccube", evt); break; case 'aspectDeLaSuccube': @@ -17750,10 +17777,10 @@ var COFantasy = COFantasy || function() { } } - // Applique toutes les options de preDmg d\xE9j\xE0 s\xE9lectionn\xE9es - // Retourne vrai si l'option "continuer" a d\xE9j\xE0 \xE9t\xE9 choisie + // Applique toutes les options de preDmg déjà sélectionnées + // Retourne vrai si l'option "continuer" a déjà été choisie function resolvePreDmgOptions(attaquant, ciblesTouchees, echecCritique, attackLabel, weaponStats, d20roll, display, options, evt, explications, pageId, cibles) { - //Sauvegarde de l'\xE9tat pour pouvoir relancer au niveau de cette fonction + //Sauvegarde de l'état pour pouvoir relancer au niveau de cette fonction evt.action.currentOptions = options; evt.action.echecCritique = echecCritique; evt.action.attackLabel = attackLabel; @@ -17818,7 +17845,7 @@ var COFantasy = COFantasy || function() { if (preDmgToken.evitementGenerique && preDmgToken.evitementGenerique.length > 0) { let nbEvitementsGenerique = preDmgToken.evitementGenerique.length; let finaliseTargetPreDmg = function(msg, generalMsg) { - if (generalMsg !== '' && !continuer && !termineCible) { // rerolls uniquement si pas termin\xE9 + if (generalMsg !== '' && !continuer && !termineCible) { // rerolls uniquement si pas terminé explications.push(msg + generalMsg); } else { cible.messages.push(msg); @@ -17849,7 +17876,7 @@ var COFantasy = COFantasy || function() { }); if (regardPetrifiant && attributeAsBool(attaquant, 'detournerLeRegard') && getIntValeurOfEffet(attaquant, 'detournerLeRegard', 2) > 4) { - sendPerso(attaquant, "aper\xE7oit " + nomPerso(regardPetrifiant) + " \xE0 travers ses paupi\xE8res !"); + sendPerso(attaquant, "aperçoit " + nomPerso(regardPetrifiant) + " à travers ses paupières !"); let seuil = predicateAsInt(regardPetrifiant, 'regardPetrifiant', 0, 16) - 4; let commande = '!cof-effet petrifie --save CON ' + seuil + ' --lanceur ' + regardPetrifiant.token.id + ' --target ' + attaquant.token.id; @@ -17903,7 +17930,7 @@ var COFantasy = COFantasy || function() { let source = drains.find(function(d) { let sa = d.split(':'); if (sa.length != 2) { - log("Drain de sang mal form\xE9 : " + drains); + log("Drain de sang mal formé : " + drains); return false; } return attr.some(function(a) { @@ -17945,7 +17972,7 @@ var COFantasy = COFantasy || function() { }); let attackerTokName = nomPerso(attaquant); if (ciblesTouchees.length === 0 || options.test || options.feinte) { - //\xC9valuation finale pour le cas o\xF9 l'attaque a rat\xE9 + //Évaluation finale pour le cas où l'attaque a raté evalITE(attaquant, undefined, d20roll, options, 1, evt, explications, options, function() { if (options.attrArmeDeJet) { if (options.retourneEnMain) { @@ -17963,7 +17990,7 @@ var COFantasy = COFantasy || function() { options.attrArmeDeJet.attribute.set('current', options.attrArmeDeJet.restant + 1); explications.push(attackerTokName + " rattrape " + weaponStats.name); } else { - explications.push("Rat\xE9 ! Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " \xE0 " + attackerTokName); + explications.push("Raté ! Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " à " + attackerTokName); if (options.attrArmeDeJet.restant === 0) { degainerArmeLancee(attaquant, attackLabel, evt); } @@ -17975,7 +18002,7 @@ var COFantasy = COFantasy || function() { options.attrArmeDeJet.attribute.set('current', options.attrArmeDeJet.restant + 1); explications.push(weaponStats.name + " retourne dans la main de son lanceur"); } else { - explications.push("Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " \xE0 " + attackerTokName); + explications.push("Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " à " + attackerTokName); if (options.attrArmeDeJet.restant === 0) { degainerArmeLancee(attaquant, attackLabel, evt); } @@ -17988,12 +18015,12 @@ var COFantasy = COFantasy || function() { const attackingCharId = attaquant.charId; const attackingToken = attaquant.token; options.attaquant = attaquant; - //Les d\xE9g\xE2ts - //D\xE9g\xE2ts insrits sur la ligne de l'arme + //Les dégâts + //Dégâts insrits sur la ligne de l'arme let mainDmgType = options.type || 'normal'; let attNbDices = weaponStats.attNbDices; if (isNaN(attNbDices) || attNbDices < 0) { - error("D\xE9s de l'attaque incorrect", attNbDices); + error("Dés de l'attaque incorrect", attNbDices); return; } if (attNbDices) { @@ -18010,7 +18037,7 @@ var COFantasy = COFantasy || function() { } } } - // Les autres modifications aux d\xE9g\xE2ts qui ne d\xE9pendent pas de la cible + // Les autres modifications aux dégâts qui ne dépendent pas de la cible let attDMBonusCommun = ''; if (options.armeMagiquePlus) { attDMBonusCommun += " + " + options.armeMagiquePlus; @@ -18083,7 +18110,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '1' + options.d6, }); - explications.push("M\xEAme pas mal => +1" + options.d6 + " DM"); + explications.push("Même pas mal => +1" + options.d6 + " DM"); } if (!options.auto && options.attaqueEnPuissance) { attaquant.additionalDmg.push({ @@ -18113,18 +18140,18 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '1' + options.d6 }); - explications.push("Attaque \xE0 outrance => +1d6 DM"); + explications.push("Attaque à outrance => +1d6 DM"); } else { attaquant.additionalDmg.push({ type: mainDmgType, value: '2' + options.d6 }); - explications.push("Attaque \xE0 outrance => +2d6 DM"); + explications.push("Attaque à outrance => +2d6 DM"); } } if (attaquant.bonusCapitaine) attDMBonusCommun += " +" + attaquant.bonusCapitaine; - // Les autres sources de d\xE9g\xE2ts + // Les autres sources de dégâts if (options.distance) { if (options.semonce) { attaquant.additionalDmg.push({ @@ -18141,7 +18168,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(attaquant, 'forceDeGeant')) { let bonusForceDeGeant = getIntValeurOfEffet(attaquant, 'forceDeGeant', 2); attDMBonusCommun += "+" + bonusForceDeGeant; - explications.push("Force de g\xE9ant => +" + bonusForceDeGeant + " aux DM"); + explications.push("Force de géant => +" + bonusForceDeGeant + " aux DM"); } if (options.frappeDuVide) { attaquant.additionalDmg.push({ @@ -18230,7 +18257,7 @@ var COFantasy = COFantasy || function() { explications.push(msgChampion); } ///////////////////////////////////////////////////////////////// - //Tout ce qui d\xE9pend de la cible + //Tout ce qui dépend de la cible let ciblesCount = ciblesTouchees.length; //Pour l'asynchronie let attaquesEnTraitrePossibles = {}; let finCibles = function() { @@ -18247,7 +18274,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, expl, 80); }); if (target.osBrises) { - addLineToFramedDisplay(display, nomPerso(target) + " a des os bris\xE9s "); + addLineToFramedDisplay(display, nomPerso(target) + " a des os brisés "); setTokenAttr(target, 'osBrises', true, evt); } }); @@ -18256,15 +18283,15 @@ var COFantasy = COFantasy || function() { let voleur = persoOfId(vid); if (voleur === undefined) continue; if (capaciteDisponible(voleur, 'attaqueEnTraitre')) { - displayAttaqueOpportunite(vid, attaquesEnTraitrePossibles[vid], "en tra\xEEtre", 'Attaques en traitre', '--decrLimitePredicatParTour attaqueEnTraitre'); + displayAttaqueOpportunite(vid, attaquesEnTraitrePossibles[vid], "en traître", 'Attaques en traitre', '--decrLimitePredicatParTour attaqueEnTraitre'); } } } }; - //Le lien \xE9pique (+1d6 DM si les 2 attaquent la m\xEAme cible + //Le lien épique (+1d6 DM si les 2 attaquent la même cible let attaqueParLienEpique = new Set(); if (options.lienEpique) { - //On cherche les autres personnages avec le m\xEAme lien \xE9pique + //On cherche les autres personnages avec le même lien épique let allChars = findObjs({ type: 'character' }); @@ -18281,7 +18308,7 @@ var COFantasy = COFantasy || function() { }); } ciblesTouchees.forEach(function(target) { - //l'\xE9valuation finale des conditions quand on sait si l'attaque a touch\xE9. + //l'évaluation finale des conditions quand on sait si l'attaque a touché. evalITE(attaquant, target, d20roll, options, 1, evt, explications, options, function() { target.attaquant = attaquant; if (options.attrArmeDeJet) { @@ -18289,7 +18316,7 @@ var COFantasy = COFantasy || function() { options.attrArmeDeJet.attribute.set('current', options.attrArmeDeJet.restant + 1); explications.push(weaponStats.name + " retourne dans la main de son lanceur"); } else { - explications.push("Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " \xE0 " + attackerTokName); + explications.push("Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " à " + attackerTokName); if (options.attrArmeDeJet.restant === 0) { degainerArmeLancee(attaquant, attackLabel, evt); } @@ -18298,7 +18325,7 @@ var COFantasy = COFantasy || function() { } if (options.enveloppe !== undefined) { if (options.enveloppe.type == 'etreinte' && attributeAsBool(target, 'armureDEau')) { - target.messages.push("L'armure d'eau emp\xEAche " + nomPerso(target) + " d'\xEAtre \xE9treint"); + target.messages.push("L'armure d'eau empêche " + nomPerso(target) + " d'être étreint"); } else { let ligneEnveloppe = nomPerso(attaquant) + " peut "; let commandeEnvelopper = @@ -18306,7 +18333,7 @@ var COFantasy = COFantasy || function() { options.enveloppe.difficulte + ' ' + options.enveloppe.type + ' ' + options.enveloppe.expression; let verbeEnv = 'envelopper'; - if (options.enveloppe.type == 'etreinte') verbeEnv = '\xE9treindre'; + if (options.enveloppe.type == 'etreinte') verbeEnv = 'étreindre'; ligneEnveloppe += boutonSimple(commandeEnvelopper, verbeEnv); ligneEnveloppe += nomPerso(target); target.messages.push(ligneEnveloppe); @@ -18314,7 +18341,7 @@ var COFantasy = COFantasy || function() { } if (options.agripper) { if (attributeAsBool(target, 'armureDEau')) { - target.messages.push("L'armure d'eau emp\xEAche " + nomPerso(target) + " d'\xEAtre aggrip\xE9"); + target.messages.push("L'armure d'eau empêche " + nomPerso(target) + " d'être aggripé"); } else { let immobilise = estAussiGrandQue(attaquant, target); setTokenAttr(attaquant, 'agrippe', idName(target), evt); @@ -18322,7 +18349,7 @@ var COFantasy = COFantasy || function() { maxVal: immobilise }); if (immobilise) setState(target, 'immobilise', true, evt); - target.messages.push("est agripp\xE9"); + target.messages.push("est agrippé"); } } if (options.devorer) { @@ -18331,13 +18358,13 @@ var COFantasy = COFantasy || function() { let cmdAttaqueGratuite = '!cof-attack ' + attaquant.token.id + ' ' + target.token.id + ' ' + attackLabel; target.messages.push(boutonSimple(cmdAttaqueGratuite, 'Attaque gratuite')); } else { - target.messages.push(nomPerso(attaquant) + " a droit \xE0 une attaque gratuite contre " + nomPerso(target)); + target.messages.push(nomPerso(attaquant) + " a droit à une attaque gratuite contre " + nomPerso(target)); } let attackerForce = valAttribute(attaquant, 'FOR', 'force'); let targetForce = valAttribute(target, 'FOR', 'force'); if (targetForce <= attackerForce) { if (attributeAsBool(target, 'armureDEau')) { - target.messages.push("L'armure d'eau emp\xEAche " + nomPerso(target) + " d'\xEAtre saisi"); + target.messages.push("L'armure d'eau empêche " + nomPerso(target) + " d'être saisi"); } else { setState(target, 'renverse', true, evt); setState(target, 'immobilise', true, evt); @@ -18347,7 +18374,7 @@ var COFantasy = COFantasy || function() { } } if (options.attaqueViolente) { - target.messages.push(nomPerso(attaquant) + " fait une attaque violente. Jet de force oppos\xE9 pour voir si " + nomPerso(target) + " se fait projeter"); + target.messages.push(nomPerso(attaquant) + " fait une attaque violente. Jet de force opposé pour voir si " + nomPerso(target) + " se fait projeter"); target.effets.push({ attaqueViolente: true, save: true @@ -18356,25 +18383,25 @@ var COFantasy = COFantasy || function() { if (options.ecraser) { target.messages.push(nomPerso(attaquant) + " saisit " + nomPerso(target) + " entre ses bras puissants"); if (options.ecraser === true) { - error("Il faudrait pr\xE9ciser un label pour \xE9craser", options.ecraser); + error("Il faudrait préciser un label pour écraser", options.ecraser); } else { let cmdEcraser = '!cof-attack ' + attaquant.token.id + ' ' + target.token.id + ' ' + options.ecraser; - target.messages.push("et l'" + boutonSimple(cmdEcraser, '\xE9crase') + "."); + target.messages.push("et l'" + boutonSimple(cmdEcraser, 'écrase') + "."); } if (attributeAsBool(target, 'armureDEau')) { - target.messages.push("L'armure d'eau emp\xEAche " + nomPerso(target) + " d'\xEAtre saisi"); + target.messages.push("L'armure d'eau empêche " + nomPerso(target) + " d'être saisi"); } else { setTokenAttr(attaquant, 'ecrase', idName(target), evt); setTokenAttr(target, 'estEcrasePar', idName(attaquant), evt); } } if (options.saisirEtBroyer) { - target.messages.push(nomPerso(attaquant) + " soul\xE8ve " + nomPerso(target) + " gesticulant" + eForFemale(target)); + target.messages.push(nomPerso(attaquant) + " soulève " + nomPerso(target) + " gesticulant" + eForFemale(target)); if (attackLabel) { let cmdAttaqueGratuiteSaisi = '!cof-attack ' + attaquant.token.id + ' ' + target.token.id + ' ' + attackLabel + ' --bonusAttaque 5'; target.messages.push(boutonSimple(cmdAttaqueGratuiteSaisi, 'Attaque gratuite')); } else { - target.messages.push(nomPerso(attaquant) + " a droit \xE0 une attaque gratuite contre " + nomPerso(target)); + target.messages.push(nomPerso(attaquant) + " a droit à une attaque gratuite contre " + nomPerso(target)); } if (valAttribute(target, 'FOR', 'force') < valAttribute(attaquant, 'FOR', 'force')) { options.rolls = options.rolls || []; @@ -18391,7 +18418,7 @@ var COFantasy = COFantasy || function() { type: 'normal', value: Math.floor(distanceSaisiProjete.val) }); - target.messages.push(nomPerso(target) + " est projet\xE9" + eForFemale(target) + " sur " + distanceSaisiProjete.roll + " m\xE8tres"); + target.messages.push(nomPerso(target) + " est projeté" + eForFemale(target) + " sur " + distanceSaisiProjete.roll + " mètres"); } } if (options.projection && taillePersonnage(attaquant, 4) > taillePersonnage(target, 4)) { @@ -18425,10 +18452,10 @@ var COFantasy = COFantasy || function() { type: 'normal', value: dmgProjection }); - target.messages.push(nomPerso(target) + " est projet\xE9 sur " + distanceProjetee + " m\xE8tres"); + target.messages.push(nomPerso(target) + " est projeté sur " + distanceProjetee + " mètres"); } if (options.gober && taillePersonnage(attaquant, 4) > taillePersonnage(target, 4)) { - //On utilise la liste d'effets pour pouvoir g\xE9rer les jets asynchrones + //On utilise la liste d'effets pour pouvoir gérer les jets asynchrones target.effets.push({ gober: true, save: true @@ -18443,14 +18470,14 @@ var COFantasy = COFantasy || function() { type: 'normal', value: '2d6' }); - target.messages.push("\xC9ventration => +2d6 DM"); + target.messages.push("Éventration => +2d6 DM"); } } else { setTokenAttr(attaquant, 'limiteParTour_eventrationReussie', target.token.id, evt); } } let attDMBonus = attDMBonusCommun; - //Les modificateurs de d\xE9g\xE2ts qui d\xE9pendent de la cible + //Les modificateurs de dégâts qui dépendent de la cible if (target.tempDmg) { let forceTarg = modCarac(target, 'force'); if (forceTarg < 0) { @@ -18462,7 +18489,7 @@ var COFantasy = COFantasy || function() { if (options.pressionMortelle || target.pressionMortelle) { let pMortelle = tokenAttribute(target, 'pressionMortelle'); if (pMortelle.length === 0) { - sendPerso(attaquant, "essaie une pression mortelle, mais aucun point vital de " + nomPerso(target) + " n'a encore \xE9t\xE9 affect\xE9"); + sendPerso(attaquant, "essaie une pression mortelle, mais aucun point vital de " + nomPerso(target) + " n'a encore été affecté"); ciblesCount--; return; } @@ -18475,7 +18502,7 @@ var COFantasy = COFantasy || function() { let modDex = modCarac(attaquant, 'dexterite'); if (target.distance <= 5 * modDex) { attDMBonus += " + " + tirPrecis; - target.messages.push("Tir pr\xE9cis : +" + tirPrecis + " DM"); + target.messages.push("Tir précis : +" + tirPrecis + " DM"); } } } @@ -18483,7 +18510,7 @@ var COFantasy = COFantasy || function() { if (target.sournoise) sournoise += target.sournoise; if (target.critique && sournoise === 0 && predicateAsBool(attaquant, 'botteSecrete')) { sournoise = predicateAsInt(attaquant, 'attaqueSournoise', 1); - target.messages.push("Botte secr\xE8te !"); + target.messages.push("Botte secrète !"); } if (sournoise) { let limiteSournoisesParTour = predicateAsInt(attaquant, 'sournoisesParTour', 1); @@ -18493,7 +18520,7 @@ var COFantasy = COFantasy || function() { } else { setTokenAttr(attaquant, 'limiteParTour_sournoises', nbSournoises - 1, evt); if (predicateAsBool(target, 'immuniteAuxSournoises')) { - target.messages.push(nomPerso(target) + " est immunis\xE9" + eForFemale(target) + " aux attaques sournoises"); + target.messages.push(nomPerso(target) + " est immunisé" + eForFemale(target) + " aux attaques sournoises"); } else { if (options.ouvertureMortelle) { target.messages.push("Ouverture mortelle => + 2 x " + sournoise + options.d6 + " DM"); @@ -18503,13 +18530,13 @@ var COFantasy = COFantasy || function() { } let valueSournoise = sournoise + options.d6; if (predicateAsBool(target, 'armureProtection') && ficheAttributeAsBool(target, 'defarmureon', false)) { - target.messages.push("L'armure de protection de " + nomPerso(target) + " r\xE9duit l'attaque sournoise"); + target.messages.push("L'armure de protection de " + nomPerso(target) + " réduit l'attaque sournoise"); valueSournoise = "ceil(" + valueSournoise + "/2)"; } else if (predicateAsBool(target, 'bouclierProtection') && ficheAttributeAsInt(target, 'defbouclieron', 0)) { - target.messages.push("Le bouclier de protection de " + nomPerso(target) + " r\xE9duit l'attaque sournoise"); + target.messages.push("Le bouclier de protection de " + nomPerso(target) + " réduit l'attaque sournoise"); valueSournoise = "ceil(" + valueSournoise + "/2)"; } else if (predicateAsBool(target, 'anneauProtection')) { - target.messages.push("L'anneau de protection de " + nomPerso(target) + " r\xE9duit l'attaque sournoise"); + target.messages.push("L'anneau de protection de " + nomPerso(target) + " réduit l'attaque sournoise"); valueSournoise = "ceil(" + valueSournoise + "/2)"; } target.additionalDmg.push({ @@ -18537,7 +18564,7 @@ var COFantasy = COFantasy || function() { } if (predicateAsBool(attaquant, 'chasseurDeSorciere') && predicateAsBool(target, 'necromancien')) { attDMBonus += "+2"; - target.messages.push("Chasseur de sorci\xE8re => +2 en DM"); + target.messages.push("Chasseur de sorcière => +2 en DM"); } if (target.ennemiJure) { target.additionalDmg.push({ @@ -18592,7 +18619,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '1' + options.d6 }); - target.messages.push("Lien \xE9pique => + 1" + options.d6 + " DM"); + target.messages.push("Lien épique => + 1" + options.d6 + " DM"); } if (target.feinte) { let value = target.feinte + options.d6; @@ -18616,7 +18643,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '2d6' }); - target.messages.push("Cible \xE9norme => +2d6 DM"); + target.messages.push("Cible énorme => +2d6 DM"); } } if (options.contact && weaponStats.deuxMains && targetTaille > 4) { @@ -18626,18 +18653,18 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '1d6' }); - target.messages.push("Arme tenue \xE0 2 mains => +1d6 DM"); + target.messages.push("Arme tenue à 2 mains => +1d6 DM"); } else if (targetTaille > 5) { target.additionalDmg.push({ type: mainDmgType, value: '2d6' }); - target.messages.push("Arme tenue \xE0 2 mains et cible \xE9norme => +2d6 DM"); + target.messages.push("Arme tenue à 2 mains et cible énorme => +2d6 DM"); } } if (predicateAsBool(attaquant, 'grosMonstreGrosseArme')) { options.puissant = true; - target.messages.push("Gros Monstre, grosse arme => d\xE9g\xE2ts de base augment\xE9s"); + target.messages.push("Gros Monstre, grosse arme => dégâts de base augmentés"); } } if (attributeAsBool(target, 'hemorragie') && !options.sortilege && !options.armeNaturelle) { @@ -18647,7 +18674,7 @@ var COFantasy = COFantasy || function() { value: '1d6', drainDeSang: sourceDrain }); - target.messages.push("H\xE9morragie => +1d6 DM"); + target.messages.push("Hémorragie => +1d6 DM"); } if (!options.pasDeDmg) { let loupParmiLesLoups = predicateAsInt(attaquant, 'loupParmiLesLoups', 0); @@ -18668,7 +18695,7 @@ var COFantasy = COFantasy || function() { }); target.messages.push("Laissez-le moi ! => +1d6 DM"); } - //Bonus aux DMs dus au d\xE9fi samoura\xEF + //Bonus aux DMs dus au défi samouraï let defiSamouraiAttr = tokenAttribute(attaquant, 'defiSamourai'); if (defiSamouraiAttr.length > 0) { defiSamouraiAttr = defiSamouraiAttr[0]; @@ -18689,7 +18716,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: bonusDefi }); - target.messages.push(attackerTokName + " b\xE9n\xE9ficie d'un bonus de +" + bonusDefi + " aux DMs contre " + nomPerso(target)); + target.messages.push(attackerTokName + " bénéficie d'un bonus de +" + bonusDefi + " aux DMs contre " + nomPerso(target)); } } if (options.vicieux) { @@ -18722,7 +18749,7 @@ var COFantasy = COFantasy || function() { } //Additional damage let additionalDmg = attaquant.additionalDmg.concat(target.additionalDmg); - //On enl\xE8ve les DM qui ne passent pas les conditions + //On enlève les DM qui ne passent pas les conditions additionalDmg = additionalDmg.filter(function(dmSpec) { if (dmSpec.conditions === undefined) return true; return dmSpec.conditions.every(function(cond) { @@ -18773,7 +18800,7 @@ var COFantasy = COFantasy || function() { mainDmgRollExpr += " + " + dmSpec.value; return false; }); - // On ajoute le jet pour les d\xE9g\xE2ts de critiques suppl\xE9mentaires + // On ajoute le jet pour les dégâts de critiques supplémentaires if (target.critique && options.additionalCritDmg) { options.additionalCritDmg.forEach(function(dmSpec) { extraDmgRollExpr += " [[" + dmSpec.value + "]]"; @@ -18790,9 +18817,9 @@ var COFantasy = COFantasy || function() { value: mainDmgRollExpr }; // toEvaluateDmg inlines - // 0 : roll de d\xE9g\xE2ts principaux - // 1+ : les rolls de d\xE9g\xE2ts suppl\xE9mentaires - // 1+nb d\xE9g\xE2ts suppl\xE9mentaires + : rolls de d\xE9g\xE2ts critiques + // 0 : roll de dégâts principaux + // 1+ : les rolls de dégâts supplémentaires + // 1+nb dégâts supplémentaires + : rolls de dégâts critiques let toEvaluateDmg = "[[" + mainDmgRollExpr + "]]" + extraDmgRollExpr; sendChat('', toEvaluateDmg, function(resDmg) { let rollsDmg = target.rollsDmg || resDmg[0]; @@ -18814,8 +18841,8 @@ var COFantasy = COFantasy || function() { dmSpec.total = dmSpec.total || rRoll.results.total; let addDmType = dmSpec.type || 'normal'; dmSpec.display = dmSpec.display || buildinline(rRoll, addDmType, options.magique); - } else { //l'expression de DM additionel est mal form\xE9e - error("Expression de d\xE9g\xE2ts de critiques mal form\xE9e : " + options.additionalCritDmg[i].value, options.additionalCritDmg[i]); + } else { //l'expression de DM additionel est mal formée + error("Expression de dégâts de critiques mal formée : " + options.additionalCritDmg[i].value, options.additionalCritDmg[i]); } }); if (target.additionalCritDmg.length === 0) delete target.additionalCritDmg; @@ -18828,28 +18855,28 @@ var COFantasy = COFantasy || function() { dmSpec.total = dmSpec.total || rRoll.results.total; let addDmType = dmSpec.type; dmSpec.display = dmSpec.display || buildinline(rRoll, addDmType, options.magique); - } else { //l'expression de DM additionel est mal form\xE9e - error("Expression de d\xE9g\xE2ts suppl\xE9mentaires mal form\xE9e : " + additionalDmg[i].value, additionalDmg[i]); + } else { //l'expression de DM additionel est mal formée + error("Expression de dégâts supplémentaires mal formée : " + additionalDmg[i].value, additionalDmg[i]); } }); if (options.expertDuCombatDMSpec) { correctAdditionalDmg.push(options.expertDuCombatDMSpec); } additionalDmg = correctAdditionalDmg; - if (target.touche) { //Devrait \xEAtre inutile ? + if (target.touche) { //Devrait être inutile ? if (options.tirDeBarrage) - target.messages.push("Tir de barrage : undo si la cible d\xE9cide de ne pas bouger"); + target.messages.push("Tir de barrage : undo si la cible décide de ne pas bouger"); if (options.pointsVitaux) - target.messages.push(attackerTokName + " vise des points vitaux mais ne semble pas faire de d\xE9g\xE2ts"); + target.messages.push(attackerTokName + " vise des points vitaux mais ne semble pas faire de dégâts"); if (options.pressionMortelle || target.pressionMortelle) { removeTokenAttr(target, 'pressionMortelle', evt); - target.messages.push(attackerTokName + " lib\xE8re la pression des points vitaux, l'effet est d\xE9vastateur !"); + target.messages.push(attackerTokName + " libère la pression des points vitaux, l'effet est dévastateur !"); spawnFx(target.token.get('left'), target.token.get('top'), 'bomb-death', pageId); } - if (options.pasDeDmg === undefined) { //si l'attaque fait des DM, possibilit\xE9 d'attaque en tra\xEEtre + if (options.pasDeDmg === undefined) { //si l'attaque fait des DM, possibilité d'attaque en traître if (attaquant.alliesAvecAttaqueEnTraitre === undefined) { attaquant.alliesAvecAttaqueEnTraitre = []; - //On cherche tous les alli\xE9s ayant l'attaque en traitre + //On cherche tous les alliés ayant l'attaque en traitre const allies = alliesParPerso[attaquant.charId] || new Set(); allies.forEach(function(ci) { if (!charPredicateAsBool(ci, 'attaqueEnTraitre')) return; @@ -18882,7 +18909,7 @@ var COFantasy = COFantasy || function() { } }); } - // change l'\xE9tat de la cible, si sp\xE9cifi\xE9 + // change l'état de la cible, si spécifié if (target.enflamme) { let enflammePuissance = 1; if (options.puissant) enflammePuissance = 2; @@ -18912,7 +18939,7 @@ var COFantasy = COFantasy || function() { } // Draw effect, if any if (options.fx) { - //Pour les cones, on fait un seul effet, car c'est bien g\xE9r\xE9. + //Pour les cones, on fait un seul effet, car c'est bien géré. if (!options.aoe || options.aoe.type != 'cone') { let tokenOrigine = attackingToken; if (options.origineDeLAttaque) @@ -18932,29 +18959,10 @@ var COFantasy = COFantasy || function() { spawnFx(target.token.get('left'), target.token.get('top'), options.targetFx, pageId); } target.rollsDmg = rollsDmg; - let affaiblissements = options.affaiblissementsCarac; - if (target.affaiblissementsCarac) { - if (affaiblissements) - affaiblissements = affaiblissements.concat(target.affaiblissementsCarac); - else affaiblissements = target.affaiblissementsCarac; - } - if (affaiblissements) { - let expliquer = function(s) { - target.messages.push(s); - }; - affaiblissements.forEach(function(aff) { - let carac = aff.carac; - if (carac == 'random') { - let id = 'affaiblissement' + aff.val + '_' + target.token.id; - carac = randomCaracForId(id, options); - } - affaiblirCaracPerso(target, carac, aff.val, expliquer, evt); - }); - } // Compte le nombre de saves pour la synchronisation - // (On ne compte pas les psave, g\xE9r\xE9s dans dealDamage) + // (On ne compte pas les psave, gérés dans dealDamage) let saves = 0; - //ajoute les \xE9tats sans save \xE0 la cible + //ajoute les états sans save à la cible let etats = options.etats; if (target.etats) { if (etats) etats = etats.concat(target.etats); @@ -18983,7 +18991,7 @@ var COFantasy = COFantasy || function() { } if (ce.typeDmg && immuniseAuType(target, ce.typeDmg, attaquant)) { if (!target['msgImmunite_' + ce.typeDmg]) { - target.messages.push(nomPerso(target) + " ne semble pas affect\xE9" + eForFemale(target) + " par " + stringOfType(ce.typeDmg)); + target.messages.push(nomPerso(target) + " ne semble pas affecté" + eForFemale(target) + " par " + stringOfType(ce.typeDmg)); target['msgImmunite_' + ce.typeDmg] = true; } return; @@ -18992,7 +19000,7 @@ var COFantasy = COFantasy || function() { setState(target, ce.etat, true, evt); let msgEtat; if (ce.etat == 'mort') - msgEtat = 'tu\xE9' + eForFemale(target); + msgEtat = 'tué' + eForFemale(target); else msgEtat = stringOfEtat(ce.etat, target); target.messages.push(nomPerso(target) + " est " + msgEtat + " par l'attaque"); @@ -19009,14 +19017,14 @@ var COFantasy = COFantasy || function() { } else { if (ce.condition.type == "moins") { target.messages.push( - "Gr\xE2ce \xE0 sa " + ce.condition.text + ", " + nomPerso(target) + + "Grâce à sa " + ce.condition.text + ", " + nomPerso(target) + " n'est pas " + stringOfEtat(ce.etat, target)); } } }); } let savesEffets = 0; - // Ajoute les effets sans save \xE0 la cible + // Ajoute les effets sans save à la cible let effets = options.effets; if (target.effets) { if (effets) effets = effets.concat(target.effets); @@ -19050,7 +19058,7 @@ var COFantasy = COFantasy || function() { (estElfe(target) || (predicateAsInt(target, 'voieDeLArchange', 1) > 2 && attributeAsBool(target, 'formeDAnge'))) ) { - target.messages.push(nomPerso(target) + " est immunis\xE9 \xE0 la paralysie des goules"); + target.messages.push(nomPerso(target) + " est immunisé à la paralysie des goules"); return; } if (ef.effet == 'affaibliTemp' && estMortVivant(attaquant) && predicateAsInt(target, 'voieDeLArchange', 1) > 2 && attributeAsBool(target, 'formeDAnge')) { @@ -19064,7 +19072,7 @@ var COFantasy = COFantasy || function() { } if (ef.typeDmg && immuniseAuType(target, ef.typeDmg, attaquant)) { if (!target['msgImmunite_' + ef.typeDmg]) { - target.messages.push(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(ef.typeDmg)); + target.messages.push(nomPerso(target) + " ne semble pas affecté par " + stringOfType(ef.typeDmg)); target['msgImmunite_' + ef.typeDmg] = true; } return; @@ -19073,17 +19081,43 @@ var COFantasy = COFantasy || function() { setEffetTemporaire(target, ef, ef.duree, evt, options); }); } - // Tout ce qui se passe apr\xE8s les saves (autres que saves de diminution des dmg + //Les affaiblissements + let saveAffaiblissements = 0; + let affaiblissements = options.affaiblissementsCarac; + if (target.affaiblissementsCarac) { + if (affaiblissements) + affaiblissements = affaiblissements.concat(target.affaiblissementsCarac); + else affaiblissements = target.affaiblissementsCarac; + } + if (affaiblissements) { + let expliquer = function(s) { + target.messages.push(s); + }; + affaiblissements.forEach(function(aff) { + if (aff.save) { + saves++; + saveAffaiblissements++; + return; + } + let carac = aff.carac; + if (carac == 'random') { + let id = 'affaiblissement' + aff.val + '_' + target.token.id; + carac = randomCaracForId(id, options); + } + affaiblirCaracPerso(target, carac, aff.val, expliquer, evt); + }); + } + // Tout ce qui se passe après les saves (autres que saves de diminution des dmg let afterSaves = function() { if (saves > 0) return; //On n'a pas encore fait tous les saves if (target.utiliseRuneProtection) { target.messages.push(nomPerso(target) + " utilise sa Rune de Protection pour annuler les dommages"); addToAttributeAsInt(target, 'limiteParCombat_runeForgesort_protection', 1, -1, evt); - // Pas de d\xE9g\xE2ts, donc pas d'appel \xE0 dealDamage + // Pas de dégâts, donc pas d'appel à dealDamage finCibles(); } else if (options.pasDeDmg || (additionalDmg.length === 0 && mainDmgRoll.total === 0 && attNbDices === 0)) { - // Pas de d\xE9g\xE2ts, donc pas d'appel \xE0 dealDamage + // Pas de dégâts, donc pas d'appel à dealDamage finCibles(); } else { dealDamage(target, mainDmgRoll, additionalDmg, evt, target.critique, @@ -19094,12 +19128,12 @@ var COFantasy = COFantasy || function() { if (suce === 0) { setTokenAttr(attaquant, 'bufDEF', -3, evt); target.messages.push( - attackerTokName + " s'agrippe \xE0 " + nomPerso(target) + - " et commence \xE0 lui sucer le sang"); + attackerTokName + " s'agrippe à " + nomPerso(target) + + " et commence à lui sucer le sang"); } if (suce + dmg >= 6) { target.messages.push( - "Repus, " + attackerTokName + " se d\xE9tache et s'envole"); + "Repus, " + attackerTokName + " se détache et s'envole"); target.messages.push(nomPerso(target) + " se sent un peu faible..."); setState(target, 'affaibli', true, evt); let defbuf = attributeAsInt(attaquant, 'bufDEF', 0); @@ -19112,7 +19146,7 @@ var COFantasy = COFantasy || function() { setTokenAttr(attaquant, 'strigeSuce', suce + dmg, evt); if (suce > 0) target.messages.push( - attackerTokName + " continue \xE0 sucer le sang de " + nomPerso(target)); + attackerTokName + " continue à sucer le sang de " + nomPerso(target)); } } if (dmgDrain || (dmg > 0 && (options.vampirise || target.vampirise))) { @@ -19142,7 +19176,7 @@ var COFantasy = COFantasy || function() { if ((estMortVivant(attaquant) && predicateAsInt(target, 'voieDeLArchange', 1) > 2 && attributeAsBool(target, 'formeDAnge')) || (predicateAsBool(attaquant, 'vampire') && predicateAsBool(target, 'immuniteAbsorptionVampire')) ) { - target.messages.push(nomPerso(target) + "n'est pas affect\xE9" + eForFemale(target) + " par l'absorption d'\xE9nergie"); + target.messages.push(nomPerso(target) + "n'est pas affecté" + eForFemale(target) + " par l'absorption d'énergie"); } else { soigneToken(attaquant, absorptionEnergie, evt, function(soins) { target.messages.push( @@ -19166,7 +19200,7 @@ var COFantasy = COFantasy || function() { target.dmgMessage = "DM : "; if (ficheAttributeAsBool(attaquant, 'jets_caches', false)) { target.dmgMessage += dmg; - sendChat('COF', "/w GM Jet cach\xE9 de dommages : " + dmgDisplay); + sendChat('COF', "/w GM Jet caché de dommages : " + dmgDisplay); } else { target.dmgMessage += dmgDisplay; } @@ -19215,7 +19249,7 @@ var COFantasy = COFantasy || function() { target.messages, function(dmgDisplay, dmg, dmgDrain) { let dmgMsg = - "D\xE9charge \xE9lectrique sur " + attackerTokName + " : " + + "Décharge électrique sur " + attackerTokName + " : " + dmgDisplay; target.messages.push(dmgMsg); finCibles(); @@ -19262,7 +19296,7 @@ var COFantasy = COFantasy || function() { target.messages, function(dmgDisplay, dmg, dmgDrain) { let dmgMsg = - "" + attackerTokName + " est glac\xE9 : " + + "" + attackerTokName + " est glacé : " + dmgDisplay + " DM"; target.messages.push(dmgMsg); finCibles(); @@ -19326,17 +19360,17 @@ var COFantasy = COFantasy || function() { let expliquer = function(msg) { target.messages.push(msg); }; - //Ajoute les \xE9tats avec save \xE0 la cible + //Ajoute les états avec save à la cible let etatsAvecSave = function() { - if (savesEffets > 0) return; //On n'a pas encore fini avec les effets + if (savesEffets > 0 || saveAffaiblissements > 0) return; //On n'a pas encore fini avec les effets et les affaiblissements if (etats && saves > 0) { etats.forEach(function(ce, index) { if (ce.save) { if (testCondition(ce.condition, attaquant, [target], d20roll, options)) { - let msgPour = " pour r\xE9sister \xE0 un effet"; + let msgPour = " pour résister à un effet"; let msgEtat; if (ce.etat == 'mort') - msgEtat = 'tu\xE9' + eForFemale(target); + msgEtat = 'tué' + eForFemale(target); else msgEtat = stringOfEtat(ce.etat, target); let msgRate = ", " + nomPerso(target) + " est " + msgEtat + " par l'attaque"; @@ -19371,7 +19405,7 @@ var COFantasy = COFantasy || function() { } else { if (ce.condition.type == "moins") { target.messages.push( - "Gr\xE2ce \xE0 sa " + ce.condition.text + ", " + nomPerso(target) + + "Grâce à sa " + ce.condition.text + ", " + nomPerso(target) + " n'est pas " + stringOfEtat(ce.etat, target)); } saves--; @@ -19381,8 +19415,9 @@ var COFantasy = COFantasy || function() { }); } else afterSaves(); }; - // Ajoute les effets avec save \xE0 la cible + // Ajoute les effets avec save à la cible let effetsAvecSave = function() { + if (saveAffaiblissements > 0) return; //On n'a pas encore fini avec les affaiblissements if (effets && savesEffets > 0) { effets.forEach(function(ef, index) { if (ef.save) { @@ -19392,13 +19427,13 @@ var COFantasy = COFantasy || function() { options, target.messages, evt, function(resultat, crit, rt1, rt2) { if (resultat == 2) { - target.messages.push(nomPerso(target) + " est enti\xE8rement aval\xE9 par " + attackerTokName); + target.messages.push(nomPerso(target) + " est entièrement avalé par " + attackerTokName); setTokenAttr(attaquant, 'aGobe', idName(target), evt); setTokenAttr(target, 'estGobePar', idName(attaquant), evt); moveTokenWithUndo(target.token, attaquant.token.get('left'), attaquant.token.get('top'), evt); } else { if (resultat === 0) diminueMalediction(attaquant, evt); - target.messages.push(nomPerso(target) + " n'est pas aval\xE9."); + target.messages.push(nomPerso(target) + " n'est pas avalé."); } saves--; savesEffets--; @@ -19411,14 +19446,14 @@ var COFantasy = COFantasy || function() { function(resultat, crit, rt1, rt2) { if (resultat == 2) { let distance = rollDePlus(6); - target.messages.push(nomPerso(target) + " est projet\xE9" + eForFemale(target) + " \xE0 " + - distance.roll + " m\xE8tres et tombe au sol"); + target.messages.push(nomPerso(target) + " est projeté" + eForFemale(target) + " à " + + distance.roll + " mètres et tombe au sol"); setState(target, 'renverse', true, evt); if (attackLabel) { let cmdAttaqueGratuite = '!cof-attack ' + attaquant.token.id + ' ' + target.token.id + ' ' + attackLabel; target.messages.push(boutonSimple(cmdAttaqueGratuite, 'Attaque gratuite')); } else { - target.messages.push(nomPerso(attaquant) + " a droit \xE0 une attaque gratuite contre " + nomPerso(target)); + target.messages.push(nomPerso(attaquant) + " a droit à une attaque gratuite contre " + nomPerso(target)); } } else { if (resultat === 0) diminueMalediction(attaquant, evt); @@ -19431,7 +19466,7 @@ var COFantasy = COFantasy || function() { } else { if (ef.typeDmg && immuniseAuType(target, ef.typeDmg, attaquant)) { if (!target['msgImmunite_' + ef.typeDmg]) { - target.messages.push(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(ef.typeDmg)); + target.messages.push(nomPerso(target) + " ne semble pas affecté par " + stringOfType(ef.typeDmg)); target['msgImmunite_' + ef.typeDmg] = true; } saves--; @@ -19441,7 +19476,7 @@ var COFantasy = COFantasy || function() { } let msgPour = " pour "; if (ef.msgSave) msgPour += ef.msgSave; - else msgPour += "r\xE9sister \xE0 un effet"; + else msgPour += "résister à un effet"; let msgRate = ", " + nomPerso(target) + " "; if (ef.duree && ef.message) { msgRate += messageActivation(target, ef.message); @@ -19472,7 +19507,7 @@ var COFantasy = COFantasy || function() { if (reussite && duree && ef.save.demiDuree) { reussite = false; duree = Math.ceil(duree / 2); - if (stateCOF.options.affichage.val.duree_effets.val) expliquer("La dur\xE9e est r\xE9duite \xE0 " + duree + " tours"); + if (stateCOF.options.affichage.val.duree_effets.val) expliquer("La durée est réduite à " + duree + " tours"); } if (!reussite) { ef.attaquant = attaquant; @@ -19494,15 +19529,15 @@ var COFantasy = COFantasy || function() { options, target.messages, evt, function(resultat, crit, rt1, rt2) { if (resultat == 2) { - target.messages.push(nomPerso(target) + " est pi\xE9tin\xE9 par " + attackerTokName + ", dommages doubl\xE9s"); + target.messages.push(nomPerso(target) + " est piétiné par " + attackerTokName + ", dommages doublés"); setState(target, 'renverse', true, evt); target.dmgCoef = (target.dmgCoef || 0) + 1; target.touche++; if (target.percute) { - target.messages.push(nomPerso(target) + " est projet\xE9 \xE0 " + + target.messages.push(nomPerso(target) + " est projeté à " + rollDePlus(6, { bonus: 1 - }).roll + " m\xE8tres"); + }).roll + " mètres"); effets = effets || []; effets.push({ effet: 'etourdiTemp', @@ -19521,19 +19556,56 @@ var COFantasy = COFantasy || function() { } } else { if (resultat === 0) diminueMalediction(attaquant, evt); - target.messages.push(nomPerso(target) + " n'est pas pi\xE9tin\xE9."); + target.messages.push(nomPerso(target) + " n'est pas piétiné."); } effetsAvecSave(); }); } else effetsAvecSave(); }; - // Peut faire peur \xE0 la cible + let affaiblissementsAvecSave = function() { + if (affaiblissements && saveAffaiblissements > 0) { + let expliquer = function(s) { + target.messages.push(s); + }; + affaiblissements.forEach(function(aff) { + if (!aff.save) { + return; + } + let carac = aff.carac; + if (carac == 'random') { + let id = 'affaiblissement' + aff.val + '_' + target.token.id; + carac = randomCaracForId(id, options); + } + let saveOpts = { + msgPour: " pour résister à un affaiblissement de " + carac, + msgRate: ", raté.", + attaquant, + rolls: options.rolls, + sortilege: options.sortilege, + chanceRollId: options.chanceRollId, + type: options.type, + necromancie: estNecromancie(options), + }; + let saveId = 'affaiblissement' + carac + "_" + target.token.id; + save(aff.save, target, saveId, expliquer, saveOpts, evt, + function(reussite, rollText) { + if (!reussite) { + affaiblirCaracPerso(target, carac, aff.val, expliquer, evt); + } + saves--; + saveAffaiblissements--; + effetPietinement(); + }); + }); + } else effetPietinement(); + }; + // Peut faire peur à la cible if (options.peur) { peurOneToken(target, options.peur.seuil, options.peur.duree, { resisteAvecForce: true - }, target.messages, evt, effetPietinement); - } else effetPietinement(); + }, target.messages, evt, affaiblissementsAvecSave); + } else affaiblissementsAvecSave(); } else { evt.succes = false; finCibles(); @@ -19556,12 +19628,12 @@ var COFantasy = COFantasy || function() { let msg; switch (d12roll) { case 1: - msg = "\xC9chec total : "; + msg = "Échec total : "; if (estMag) { - msg += "le lanceur de sort perd le contr\xF4le de la magie qu'il canalise et subit 1d4 dommages en retour par rang du sort lanc\xE9. "; + msg += "le lanceur de sort perd le contrôle de la magie qu'il canalise et subit 1d4 dommages en retour par rang du sort lancé. "; msg += boutonCritique("!cof-dmg ?{Rang du sort}d4 --ignoreRD"); } else { - msg += "l'attaquant se blesse lui-m\xEAme et s'inflige la moiti\xE9 des d\xE9g\xE2ts de son attaque. L'attaquant ne peut plus attaquer ce tour. "; + msg += "l'attaquant se blesse lui-même et s'inflige la moitié des dégâts de son attaque. L'attaquant ne peut plus attaquer ce tour. "; msg += boutonCritique("!cof-bouton-echec-total " + evt.id); } return msg; @@ -19575,38 +19647,38 @@ var COFantasy = COFantasy || function() { } else { difficulte = 12; } - msg = "Bouscul\xE9 (FOR) : l'attaquant est d\xE9s\xE9quilibr\xE9 par son attaque "; + msg = "Bousculé (FOR) : l'attaquant est déséquilibré par son attaque "; msg += boutonCritique("!cof-set-state renverse true --save FOR " + difficulte); return msg; case 3: if (avecArme) { - msg = "Maladresse (DEX) : l'attaquant laisse \xE9chapper son arme qui tombe hors de port\xE9e imm\xE9diate."; + msg = "Maladresse (DEX) : l'attaquant laisse échapper son arme qui tombe hors de portée immédiate."; msg += boutonCritique("!cof-degainer --save DEX 12"); return msg; } - msg = "D\xE9s\xE9quilibr\xE9 (DEX) : l'attaquant est Ralenti pendant 3 tours."; + msg = "Déséquilibré (DEX) : l'attaquant est Ralenti pendant 3 tours."; msg += boutonCritique("!cof-effet-temp ralentiTemp 3 --save DEX 12"); return msg; case 4: - msg = "Coup de mou (CON) : l'attaquant est affaibli pendant 3 tours, ou jusqu'\xE0 ce qu'il consacre un tour ou 1 PR pour se r\xE9tablir."; + msg = "Coup de mou (CON) : l'attaquant est affaibli pendant 3 tours, ou jusqu'à ce qu'il consacre un tour ou 1 PR pour se rétablir."; msg += boutonCritique("!cof-effet-temp affaibliTemp 3 --save CON 12"); return msg; case 5: if (estCac) { - msg = "Erreur tactique (INT) : le personnage provoque une attaque (gratuite) d\x2019un adversaire \xE0 son contact."; + msg = "Erreur tactique (INT) : le personnage provoque une attaque (gratuite) d’un adversaire à son contact."; msg += boutonCritique("!cof-jet INT 12"); } else if (estMag) { - msg = "Aveugl\xE9 (INT) : le personnage ne contr\xF4le pas sa puissance et une partie de celle-ci \xE9met un flash qui l'aveugle temporairement."; + msg = "Aveuglé (INT) : le personnage ne contrôle pas sa puissance et une partie de celle-ci émet un flash qui l'aveugle temporairement."; msg += boutonCritique("!cof-effet-temp aveugleTemp 3 --save INT 12 --saveParTour CON 12"); } else { - //TODO : Impl\xE9menter un bouton "mauvais calcul" r\xE9alisant une attaque automatique sur un des Obstacle - msg = "Mauvais calcul (INT) : le personnage a une chance de toucher une autre cible sur la trajectoire de son tir. D\xE9terminer la cible au hasard et relancer une attaque sur cette nouvelle cible."; + //TODO : Implémenter un bouton "mauvais calcul" réalisant une attaque automatique sur un des Obstacle + msg = "Mauvais calcul (INT) : le personnage a une chance de toucher une autre cible sur la trajectoire de son tir. Déterminer la cible au hasard et relancer une attaque sur cette nouvelle cible."; msg += boutonCritique("!cof-jet INT 12"); } return msg; case 6: if (estCac) { - msg = "Expos\xE9 (SAG) : l'adversaire dispose d'un bonus de +10 \xE0 la touche pendant un round."; + msg = "Exposé (SAG) : l'adversaire dispose d'un bonus de +10 à la touche pendant un round."; cibles.forEach(function(cible) { msg += boutonCritique("!cof-effet-temp expose 1 --valeur " + cible.token.id + " --save SAG 12"); }); @@ -19616,11 +19688,11 @@ var COFantasy = COFantasy || function() { } return msg; case 7: - msg = "Ridicule (CHA) : le personnage fait un faux mouvement \xE0 la fois douloureux et ridicule, il subit l\x2019\xE9tat \xE9tourdi pendant un round pour reprendre contenance. "; + msg = "Ridicule (CHA) : le personnage fait un faux mouvement à la fois douloureux et ridicule, il subit l’état étourdi pendant un round pour reprendre contenance. "; msg += boutonCritique("!cof-effet-temp etourdiTemp 1 --save CHA 12"); return msg; case 8: - msg = "Inconfort : Une pi\xE8ce d\x2019armure bouge et elle devient plus g\xEAnante que protectrice. Malus en DEF et en attaque pour le reste du combat => Cuir : -1, Maille : -2, Plaque -3. "; + msg = "Inconfort : Une pièce d’armure bouge et elle devient plus gênante que protectrice. Malus en DEF et en attaque pour le reste du combat => Cuir : -1, Maille : -2, Plaque -3. "; msg += boutonCritique("!cof-effet-combat inconfort --valeur ?{Malus ?|-1,1|-2,2|-3,3} --save CHA 12"); return msg; default: @@ -19630,16 +19702,17 @@ var COFantasy = COFantasy || function() { function montrerResultatsAttaque(msg) { if (stateCOF.currentAttackDisplay) { - sendChat('', endFramedDisplay(stateCOF.currentAttackDisplay)); + sendFramedDisplay(stateCOF.currentAttackDisplay); stateCOF.currentAttackDisplay = undefined; if (stateCOF.afterDisplay) { - stateCOF.afterDisplay.forEach(function(d) { + let ad = stateCOF.afterDisplay; + stateCOF.afterDisplay = undefined; //on efface avant au cas où le script crash + ad.forEach(function(d) { sendPerso(d.destinataire, d.msg, true); }); - stateCOF.afterDisplay = undefined; } } else { - sendPlayer(msg, "Pas de r\xE9sultat d'attaque \xE0 montrer"); + sendPlayer(msg, "Pas de résultat d'attaque à montrer"); } } @@ -19660,41 +19733,42 @@ var COFantasy = COFantasy || function() { }; addLineToFramedDisplay(display, boutonSimple('!cof-montrer-resultats-attaque', "Montrer aux joueurs")); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } } if (options === undefined || !options.secret) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else { let playerIds = getPlayerIds(perso); playerIds.forEach(function(playerid) { addFramedHeader(display, playerid, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); autres.forEach(function(target) { let addPlayers = getPlayerIds(target); addPlayers.forEach(function(nid) { if (!playerIds.includes(nid)) { playerIds.push(nid); addFramedHeader(display, nid, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }); }); } if (stateCOF.afterDisplay) { - stateCOF.afterDisplay.forEach(function(d) { + let ad = stateCOF.afterDisplay; + stateCOF.afterDisplay = undefined; + ad.forEach(function(d) { sendPerso(d.destinataire, d.msg, true); }); - stateCOF.afterDisplay = undefined; } } //Affichage final d'une attaque - // attaquant est optionnel, mais si il est pr\xE9sent, cibles doit \xEAtre un tableau et options un objet + // attaquant est optionnel, mais si il est présent, cibles doit être un tableau et options un objet function finaliseDisplay(display, explications, evt, attaquant, cibles, options, echecCritique) { echecCritique = echecCritique || false; explications.forEach(function(expl) { @@ -19722,7 +19796,7 @@ var COFantasy = COFantasy || function() { line += "
" + boutonSimple( "!cof-devier-les-coups " + evt.id + ' --target ' + target.token.id, - "d\xE9vier les coups"); + "dévier les coups"); nbBoutons++; } if (preDmgToken.paradeDeProjectiles) { @@ -19763,7 +19837,7 @@ var COFantasy = COFantasy || function() { } if (preDmgToken.resistanceALaMagieBarbare && preDmgToken.resistanceALaMagieBarbare !== 'reroll') { action = "!cof-resister-a-la-magie " + target.token.id + ' ' + evt.id; - line += "
" + boutonSimple(action, "tenter de r\xE9sister \xE0 la magie"); + line += "
" + boutonSimple(action, "tenter de résister à la magie"); nbBoutons++; } if (preDmgToken.cercleDeProtection && preDmgToken.cercleDeProtectionDe && @@ -19782,7 +19856,7 @@ var COFantasy = COFantasy || function() { } if (preDmgToken.chairACanon) { preDmgToken.chairACanon.forEach(function(tok) { - line += "
" + boutonSimple("!cof-chair-a-canon " + target.token.id + ' ' + tok.id + ' ' + evt.id, "utiliser " + tok.get('name') + " comme chair \xE0 canon"); + line += "
" + boutonSimple("!cof-chair-a-canon " + target.token.id + ' ' + tok.id + ' ' + evt.id, "utiliser " + tok.get('name') + " comme chair à canon"); nbBoutons++; }); } @@ -19846,9 +19920,9 @@ var COFantasy = COFantasy || function() { if (pc > 0 && !echecCritique) { addLineToFramedDisplay(display, boutonSimple("!cof-bouton-chance " + evt.id, "Chance") + " (reste " + pc + " PC)"); } - if (attributeAsBool(perso, 'runeForgesort_\xE9nergie') && - attributeAsInt(perso, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0) { - addLineToFramedDisplay(display, boutonSimple("!cof-bouton-rune-energie " + evt.id, "Rune d'\xE9nergie")); + if (attributeAsBool(perso, 'runeForgesort_énergie') && + attributeAsInt(perso, 'limiteParCombat_runeForgesort_énergie', 1) > 0) { + addLineToFramedDisplay(display, boutonSimple("!cof-bouton-rune-energie " + evt.id, "Rune d'énergie")); } if (capaciteDisponible(perso, 'petitVeinard', 'combat')) { addLineToFramedDisplay(display, boutonSimple("!cof-bouton-petit-veinard " + evt.id, "Petit veinard")); @@ -19879,7 +19953,7 @@ var COFantasy = COFantasy || function() { boutonSimple("!cof-bouton-pousser-kiai " + evt.id, "Kiai")); } if (capaciteDisponible(perso, 'petitVeinard', 'combat')) { - addLineToFramedDisplay(display, boutonSimple("!cof-bouton-petit-veinard " + evt.id, "Petit veinard") + " pour relancer un d\xE9"); + addLineToFramedDisplay(display, boutonSimple("!cof-bouton-petit-veinard " + evt.id, "Petit veinard") + " pour relancer un dé"); } } if (options && options.contact && cibles && attaquant && @@ -19913,7 +19987,7 @@ var COFantasy = COFantasy || function() { attaquant.ennemisAuContact = tokensEnnemis; } if (attaquant.ennemisAuContact.length > 0) { - let msgEnchainement = nomPerso(attaquant) + " a droit \xE0 une attaque au contact gratuite contre "; + let msgEnchainement = nomPerso(attaquant) + " a droit à une attaque au contact gratuite contre "; let sep = ""; let armeEnMain = tokenAttribute(attaquant, 'armeEnMain'); let act; @@ -20037,7 +20111,7 @@ var COFantasy = COFantasy || function() { } sendPerso(attaquant, "Plus de cible sur laquelle ricocher et trop loin pour un retour en main", true); } - } else { //on a rat\xE9, il faut remettre le rounMarker \xE0 sa place + } else { //on a raté, il faut remettre le rounMarker à sa place if (stateCOF.options.affichage.val.init_dynamique.val) { threadSync++; activateRoundMarker(threadSync, attaquant.token); @@ -20056,7 +20130,7 @@ var COFantasy = COFantasy || function() { } } - // RD sp\xE9cifique au type + // RD spécifique au type function typeRD(rd, dmgType) { if (dmgType === undefined || dmgType == 'normal') return 0; return (rd[dmgType] || 0); @@ -20067,7 +20141,7 @@ var COFantasy = COFantasy || function() { let proba1 = probaSucces(de, seuil, 1); return 1 - (1 - proba1) * (1 - proba1); } - if (seuil < 2) seuil = 2; // 1 est toujours un \xE9chec + if (seuil < 2) seuil = 2; // 1 est toujours un échec else if (seuil > 20) seuil = 20; return ((de - seuil) + 1) / de; } @@ -20137,23 +20211,43 @@ var COFantasy = COFantasy || function() { return carac1; } - //s repr\xE9sente le save, avec une carac, une carac2 optionnelle et un seuil + function dansAuraDeProfanation(perso) { + if (perso.dansAuraDeProfanation !== undefined) + return perso.dansAuraDeProfanation; + let pageId = perso.token.get('pageid'); + let tokens = findObjs({ + _type: 'graphic', + _subtype: 'token', + layer: 'objects', + _pageid: pageId + }); + let res = tokens.some(function(token) { + let p = persoOfToken(token); + if (!p) return false; + if (distanceCombat(perso.token, token, pageId) > 6) return false; + if (getState(p, 'mort')) return false; + return predicateAsBool(p, 'auraDeProfanation'); + }); + perso.dansAuraDeProfanation = res; + return res; + } + //s représente le save, avec une carac, une carac2 optionnelle et un seuil //expliquer est une fonction qui prend en argument un string et le publie // options peut contenir les champs : - // - msgPour : message d'explication \xE0 afficher avant le jet - // - msgReussite : message \xE0 afficher en cas de r\xE9ussite - // - msgRate : message \xE0 afficher si l'action rate - // - silencieuxSiPasAffecte: ne rien afficher pour les cibles immunis\xE9es - // - regard: l'attaque vient d'un regard, on peut d\xE9tourner les yeux + // - msgPour : message d'explication à afficher avant le jet + // - msgReussite : message à afficher en cas de réussite + // - msgRate : message à afficher si l'action rate + // - silencieuxSiPasAffecte: ne rien afficher pour les cibles immunisées + // - regard: l'attaque vient d'un regard, on peut détourner les yeux // - attaquant : le {charId, token} de l'attaquant contre lequel le save se fait (si il y en a un) - // - type : le type de d\xE9g\xE2ts contre lequel on fait le save + // - type : le type de dégâts contre lequel on fait le save // - hideSaveTitle : cache le titre du save // - bonus : bonus au jet de save // s peut contenir: - // - carac : la caract\xE9ristique \xE0 utiliser pour le save - // - carac2 : caract\xE9ristique alternative - // - seuil : la difficult\xE9 du jet de sauvegarde - // - contact : la difficult\xE9 si la cible est au contact de options.attaquant + // - carac : la caractéristique à utiliser pour le save + // - carac2 : caractéristique alternative + // - seuil : la difficulté du jet de sauvegarde + // - contact : la difficulté si la cible est au contact de options.attaquant // - fauchage // - entrave (pour les action qui immobilisent, ralentissent ou paralysent) // - necromancie @@ -20161,7 +20255,7 @@ var COFantasy = COFantasy || function() { function save(s, target, saveId, expliquer, options, evt, afterSave) { if (options.type && immuniseAuType(target, options.type, options.attaquant)) { if (!target['msgImmunite_' + options.type] && !options.silencieuxSiPasAffecte) { - expliquer(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(options.type)); + expliquer(nomPerso(target) + " ne semble pas affecté par " + stringOfType(options.type)); target['msgImmunite_' + options.type] = true; } afterSave(true, ''); @@ -20177,7 +20271,7 @@ var COFantasy = COFantasy || function() { } if (predicateAsBool(target, 'vegetatif')) { if (!options.silencieuxSiPasAffecte) - expliquer(nomPerso(target) + " est une cr\xE9ature v\xE9g\xE9tative."); + expliquer(nomPerso(target) + " est une créature végétative."); afterSave(true, ''); return; } @@ -20192,12 +20286,12 @@ var COFantasy = COFantasy || function() { } if (s.fauchage) { if (s.fauchage <= taillePersonnage(target, 4)) { - expliquer(nomPerso(target) + " est trop grand pour \xEAtre fauch\xE9."); + expliquer(nomPerso(target) + " est trop grand pour être fauché."); afterSave(true, ''); return; } if (predicateAsBool(target, 'inderacinable')) { - expliquer(nomPerso(target) + " est ind\xE9racinable."); + expliquer(nomPerso(target) + " est indéracinable."); afterSave(true, ''); return; } @@ -20206,7 +20300,7 @@ var COFantasy = COFantasy || function() { if (getState(target, 'mort') || getState(target, 'assomme') || getState(target, 'paralyse') || getState(target, 'endormi')) { if (!options.silencieuxSiPasAffecte) - expliquer(nomPerso(target) + " n'est pas en \xE9tat d'\xE9viter l'effet."); + expliquer(nomPerso(target) + " n'est pas en état d'éviter l'effet."); afterSave(false, ''); } } @@ -20220,23 +20314,23 @@ var COFantasy = COFantasy || function() { } if (s.entrave && predicateAsBool(target, 'actionLibre')) { bonus += 5; - expliquer("Action libre => +5 pour r\xE9sister aux entraves"); + expliquer("Action libre => +5 pour résister aux entraves"); } if (options.necromancie && attributeAsBool(target, 'sangDeLArbreCoeur')) { bonus += 5; - expliquer("Sang de l'Arbre-Coeur => +5 pour r\xE9sister \xE0 la n\xE9cromancie"); + expliquer("Sang de l'Arbre-Coeur => +5 pour résister à la nécromancie"); } if (options.type == 'poison') { if (predicateAsBool(target, 'liberateurDAnathazerin')) { bonus += 2; - expliquer("Lib\xE9rateur d'Anathazer\xEFn => +2 pour r\xE9sister au poison"); + expliquer("Libérateur d'Anathazerïn => +2 pour résister au poison"); } if (predicateAsBool(target, 'peauDEcorceAvancee') && attributeAsBool(target, 'peauDEcorce')) { let bonusPeau = getIntValeurOfEffet(target, 'peauDEcorce', 2); if (bonusPeau == 2 && predicateAsInt(target, 'voieDesForets', 0) > 3) bonusPeau = 4; bonus += bonusPeau; - expliquer("Peau d'\xE9corce am\xE9lior\xE9e => +" + bonusPeau + " pour r\xE9sister au poison"); + expliquer("Peau d'écorce améliorée => +" + bonusPeau + " pour résister au poison"); } } let bonusAttrs = []; @@ -20255,13 +20349,13 @@ var COFantasy = COFantasy || function() { switch (getIntValeurOfEffet(target, 'detournerLeRegard', 2)) { case 1: seuil -= 3; - expliquer("d\xE9tourne un peu le regard => -3 \xE0 la difficult\xE9"); + expliquer("détourne un peu le regard => -3 à la difficulté"); break; case 2: case 3: case 4: seuil -= 6; - expliquer("d\xE9tourne le regard => -6 \xE0 la difficult\xE9"); + expliquer("détourne le regard => -6 à la difficulté"); break; default: expliquer(nomPerso(target) + " ferme les yeux"); @@ -20271,7 +20365,7 @@ var COFantasy = COFantasy || function() { } } let carac = s.carac; - //Cas o\xF9 le save peut se faire au choix parmis 2 caracs + //Cas où le save peut se faire au choix parmis 2 caracs if (s.carac2) { carac = meilleureCarac(carac, s.carac2, target, seuil); } @@ -20288,6 +20382,14 @@ var COFantasy = COFantasy || function() { } if (options.energiePositive) { bonusPreds.push('bonusSaveContre_positif'); + //Recherche de token avec aura de profanation + if (dansAuraDeProfanation(target)) { + bonus += 3; + expliquer("Aura de profanation => +3 au save"); + } + } else if (estMortVivant(target) && dansAuraDeProfanation(target)) { + bonus += 1; + expliquer("Aura de profanation => +1 au save"); } if (!options.hideSaveTitle) { let title = " Jet " + deCarac(carac) + " " + seuil; @@ -20313,11 +20415,11 @@ var COFantasy = COFantasy || function() { smsg += '">' + tr.texte + ''; } if (tr.reussite) { - smsg += " => r\xE9ussite"; + smsg += " => réussite"; if (options.msgReussite) smsg += options.msgReussite; smsg += tr.modifiers; } else { - smsg += " => \xE9chec"; + smsg += " => échec"; if (options.msgRate) smsg += options.msgRate; smsg += tr.rerolls + tr.modifiers; } @@ -20348,7 +20450,7 @@ var COFantasy = COFantasy || function() { return; } if ((sav.carac == 'CON' || sav.carac2 == 'CON') && estNonVivant(target)) { - expliquer("Les cr\xE9atures non-vivantes sont immnunis\xE9es aux attaques qui demandent un test de constitution"); + expliquer("Les créatures non-vivantes sont immnunisées aux attaques qui demandent un test de constitution"); afterSave({ succes: true, dmgDisplay: '0', @@ -20368,8 +20470,8 @@ var COFantasy = COFantasy || function() { return; } let saveOpts = { - msgPour: " pour r\xE9duire les d\xE9g\xE2ts", - msgReussite: ", d\xE9g\xE2ts divis\xE9s par 2", + msgPour: " pour réduire les dégâts", + msgReussite: ", dégâts divisés par 2", attaquant: ps.attaquant, rolls: ps.rolls, chanceRollId: ps.chanceRollId, @@ -20377,8 +20479,8 @@ var COFantasy = COFantasy || function() { energiePositive: ps.energiePositive }; if (totalSave) { - saveOpts.msgPour = " pour \xE9viter les d\xE9g\xE2ts"; - saveOpts.msgReussite = ", d\xE9g\xE2ts \xE9vit\xE9s"; + saveOpts.msgPour = " pour éviter les dégâts"; + saveOpts.msgReussite = ", dégâts évités"; } let saveId = 'parseSave_' + target.token.id; save(sav, target, saveId, expliquer, saveOpts, evt, @@ -20437,7 +20539,7 @@ var COFantasy = COFantasy || function() { if (r === '') return; let rds; let index = r.indexOf(':'); - if (index > 0) { //RD \xE0 un type particulier + if (index > 0) { //RD à un type particulier let type = r.substring(0, index); if (type == 'rdt' || type == 'sauf') return; if (type == 'magie') type = 'magique'; @@ -20448,7 +20550,7 @@ var COFantasy = COFantasy || function() { return; } index = r.indexOf('/'); - if (index > 0) { //RD sauf \xE0 des types + if (index > 0) { //RD sauf à des types rds = parseInt(r.substring(0, index)); if (isNaN(rds) || rds === 0) return; let sauf = r.substring(index + 1); @@ -20523,7 +20625,7 @@ var COFantasy = COFantasy || function() { case 'acide': return "l'acide"; case 'electrique': - return "l'\xE9lectricit\xE9"; + return "l'électricité"; case 'soniqe': return "le son"; case 'maladie': @@ -20540,7 +20642,7 @@ var COFantasy = COFantasy || function() { case 'FOR': return "la force"; case 'DEX': - return "la dext\xE9rit\xE9"; + return "la dextérité"; case 'CON': return "la constitution"; case 'INT': @@ -20566,7 +20668,7 @@ var COFantasy = COFantasy || function() { (predicateAsBool(target, 'protectionDMZone') || predicateAsBool(target, 'protectionDMZone_' + dmgType))) { divide(); - expliquer(nomPerso(target) + " est prot\xE9g\xE9 contre les d\xE9g\xE2ts de zone"); + expliquer(nomPerso(target) + " est protégé contre les dégâts de zone"); } if (predicateOrAttributeAsBool(target, 'resistanceA_' + dmgType) || predicateAsBool(target, 'diviseEffet_' + dmgType)) { divide(); @@ -20618,7 +20720,7 @@ var COFantasy = COFantasy || function() { divide(); } if (options.vampirise && predicateOrAttributeAsBool(target, 'controleSanguin')) { - expliquer(nomPerso(target) + " contr\xF4le parfaitement son sang"); + expliquer(nomPerso(target) + " contrôle parfaitement son sang"); divide(); } } @@ -20628,9 +20730,9 @@ var COFantasy = COFantasy || function() { return options.aoe && !options.sortilege && options.aoe.type == 'cone' && options.attaquant && estDraconique(options.attaquant); } - //On a d\xE9termin\xE9 les DM du type principal(possiblement apr\xE8s save des dmgExtra, maintenant on applique les r\xE9sistances, puis on ajoute les DM d'autres types + //On a déterminé les DM du type principal(possiblement après save des dmgExtra, maintenant on applique les résistances, puis on ajoute les DM d'autres types function dealDamageAfterDmgExtra(target, mainDmgType, dmgTotal, dmgDisplay, showTotal, dmgParType, dmgExtra, crit, options, evt, expliquer, displayRes) { - if (options.pointsVitaux && dmgTotal > 0) { //d\xE9g\xE2ts retard\xE9s pour une pression mortelle + if (options.pointsVitaux && dmgTotal > 0) { //dégâts retardés pour une pression mortelle let pMortelle = tokenAttribute(target, 'pressionMortelle'); let dmgPMort = dmgTotal; let numberPMort = 1; @@ -20655,7 +20757,7 @@ var COFantasy = COFantasy || function() { } if (dmgTotal > 0 && immuniseAuType(target, mainDmgType, options.attaquant)) { if (expliquer && !target['msgImmunite_' + mainDmgType]) { - expliquer(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(mainDmgType)); + expliquer(nomPerso(target) + " ne semble pas affecté par " + stringOfType(mainDmgType)); target['msgImmunite_' + mainDmgType] = true; } dmgTotal = 0; @@ -20668,6 +20770,8 @@ var COFantasy = COFantasy || function() { if (options.tranchant && rd.tranchant) rdMain += rd.tranchant; if (options.percant && rd.percant) rdMain += rd.percant; if (options.contondant && rd.contondant) rdMain += rd.contondant; + } else if ((mainDmgType == 'poison' || mainDmgType == 'feu' || mainDmgType == 'froid') && !options.magique && rd.nature && !dmgNaturel(options)) { + rdMain += rd.nature; } if (options.asphyxie) rdMain += rd.asphyxie; if (rd.drain && (options.vampirise || target.vampirise) && mainDmgType != 'drain') { @@ -20762,13 +20866,13 @@ var COFantasy = COFantasy || function() { else dmSuivis[tv] = 0; }); }); - // Autres sources de d\xE9g\xE2ts + // Autres sources de dégâts // On compte d'abord les autres sources, pour la synchronisation let count = 0; for (let dt in dmgParType) { if (immuniseAuType(target, dt, options.attaquant)) { if (expliquer && !target['msgImmunite_' + dt]) { - expliquer(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(dt)); + expliquer(nomPerso(target) + " ne semble pas affecté par " + stringOfType(dt)); target['msgImmunite_' + dt] = true; } delete dmgParType[dt]; @@ -20780,7 +20884,7 @@ var COFantasy = COFantasy || function() { if (dmgType == mainDmgType) { count -= dmgParType[dmgType].length; if (count === 0) dealDamageAfterOthers(target, crit, options, evt, expliquer, displayRes, dmgTotal, dmgDisplay, showTotal, dmSuivis); - return; //type principal d\xE9j\xE0 g\xE9r\xE9 + return; //type principal déjà géré } showTotal = true; let dm = 0; @@ -20822,6 +20926,8 @@ var COFantasy = COFantasy || function() { if (options.tranchant && rd.tranchant) rdl += rd.tranchant; if (options.percant && rd.percant) rdl += rd.percant; if (options.contondant && rd.contondant) rdl += rd.contondant; + } else if ((dmgType == 'poison' || dmgType == 'feu' || dmgType == 'froid') && !options.magique && rd.nature && !dmgNaturel(options)) { + rdl += rd.nature; } if (target.ignoreMoitieRD) rdl = parseInt(rdl / 2); if (target.ignoreRD) { @@ -20898,15 +21004,15 @@ var COFantasy = COFantasy || function() { } } - //Appel\xE9 quand on met \xE0 0 PV + //Appelé quand on met à 0 PV function mort(personnage, expliquer, evt) { - if (getState(personnage, 'mort')) return; //d\xE9j\xE0 mort + if (getState(personnage, 'mort')) return; //déjà mort if (predicateAsBool(personnage, 'energieDeLaMort')) { let duree = rollDePlus(6, { bonus: 5 }); - sendChat('', '/w GM ' + nomPerso(personnage) + ' r\xE9appara\xEEtra dans ' + duree.roll + ' tours.'); - let effet = 'messageRetarde(r\xE9apparition)'; + sendChat('', '/w GM ' + nomPerso(personnage) + ' réapparaîtra dans ' + duree.roll + ' tours.'); + let effet = 'messageRetarde(réapparition)'; setAttrDuree(personnage, effet, duree.val - 1, evt); setToken(personnage.token, 'layer', 'gmlayer', evt); if (personnage.attaquant) { @@ -20922,9 +21028,9 @@ var COFantasy = COFantasy || function() { let explications = []; dealDamage(personnage.attaquant, dmg, [], evt, false, {}, explications, function(dmgDisplay, dmgFinal, dmgDrain) { - setTokenAttr(personnage, effet + 'Valeur', nomPerso(personnage) + " r\xE9apparait avec " + dmgFinal + " PV en plus.", evt); + setTokenAttr(personnage, effet + 'Valeur', nomPerso(personnage) + " réapparait avec " + dmgFinal + " PV en plus.", evt); let attName = nomPerso(personnage); - let msg = "se transforme en brume noire qui traverse " + attName + " de part en part avant de dispara\xEEtre dans une paroi en poussant un hululement inhumain. le froid de la mort inflige " + dmgDisplay + " DM \xE0 " + attName; + let msg = "se transforme en brume noire qui traverse " + attName + " de part en part avant de disparaître dans une paroi en poussant un hululement inhumain. le froid de la mort inflige " + dmgDisplay + " DM à " + attName; if (expliquer) { expliquer(nomPerso(personnage) + ' ' + msg); } else { @@ -20979,11 +21085,11 @@ var COFantasy = COFantasy || function() { switch (charRace) { case 'insecte': case 'ankheg': - case 'araign\xE9e': + case 'araignée': case 'araignee': - case 'gu\xEApe': + case 'guêpe': case 'libellule': - case 'scarab\xE9e': + case 'scarabée': case 'scorpion': case 'strige': return true; @@ -20992,8 +21098,8 @@ var COFantasy = COFantasy || function() { } } - // retourne les nombre de PR restant, undefined si les PR ne sont pas d\xE9finis - // current, max, et si d\xE9fini, attribut + // retourne les nombre de PR restant, undefined si les PR ne sont pas définis + // current, max, et si défini, attribut function pointsDeRecuperation(perso) { if (!ficheAttributeAsBool(perso, 'option_pr', true)) return; let attrPR = charAttribute(perso.charId, 'pr', { @@ -21027,7 +21133,7 @@ var COFantasy = COFantasy || function() { }; } - // pr doit \xEAtre d\xE9fini, et pr.current > 0 + // pr doit être défini, et pr.current > 0 function enleverPointDeRecuperation(perso, pr, evt) { evt.attributes = evt.attributes || []; let attrPR; @@ -21075,18 +21181,18 @@ var COFantasy = COFantasy || function() { let pr = pointsDeRecuperation(target); if (!pr) return; if (pr.current > 0) { - expliquer("Les d\xE9g\xE2ts sont si importants que " + nomPerso(target) + " perd 1 PR"); + expliquer("Les dégâts sont si importants que " + nomPerso(target) + " perd 1 PR"); enleverPointDeRecuperation(target, pr, evt); } else if (getState(target, 'blesse')) { if (getState(target, 'mort')) { - expliquer("Avec la blessure grave, c'est vraiment la fin, " + nomPerso(target) + " ne se rel\xE8vera plus..."); + expliquer("Avec la blessure grave, c'est vraiment la fin, " + nomPerso(target) + " ne se relèvera plus..."); } else { - expliquer("Les d\xE9g\xE2ts sont trop importants, et " + nomPerso(target) + " s'effondre"); + expliquer("Les dégâts sont trop importants, et " + nomPerso(target) + " s'effondre"); mort(target, expliquer, evt); } } else { setState(target, 'blesse', true, evt); - expliquer("Les d\xE9g\xE2ts occasionnent une blessure grave !"); + expliquer("Les dégâts occasionnent une blessure grave !"); } } } @@ -21121,7 +21227,7 @@ var COFantasy = COFantasy || function() { attrs[0].set('current', newCur); } - function finDEffetDeNom(perso, effet, evt, options) { //Supprime l'effet si pr\xE9sent + function finDEffetDeNom(perso, effet, evt, options) { //Supprime l'effet si présent let attrs = tokenAttribute(perso, effet); if (attrs.length === 0) return; attrs = attrs[0]; @@ -21143,9 +21249,9 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(args[2]); if (evt === undefined) { - error("Impossible de trouver l'\xE9v\xE9nement qui a caus\xE9 la mort", args); + error("Impossible de trouver l'événement qui a causé la mort", args); evt = { - type: "Mettre \xE0 0 PV" + type: "Mettre à 0 PV" }; addEvent(evt); } @@ -21165,13 +21271,13 @@ var COFantasy = COFantasy || function() { } updateCurrentBar(target, 1, 0, evt); if (predicateAsBool(target, 'baroudHonneur')) { - let msgBarroud = nomPerso(target) + " devrait \xEAtre mort"; + let msgBarroud = nomPerso(target) + " devrait être mort"; msgBarroud += eForFemale(target) + ", mais "; - msgBarroud += onGenre(target, 'il', 'elle') + " continue \xE0 se battre !"; + msgBarroud += onGenre(target, 'il', 'elle') + " continue à se battre !"; expliquer(msgBarroud); setTokenAttr(target, 'baroudHonneurActif', true, evt); } else if (predicateAsBool(target, 'increvable') && attributeAsInt(target, 'limiteParCombat__increvable', predicateAsInt(target, 'increvable', 1)) > 0) { - let msgIncrevable = nomPerso(target) + " devrait \xEAtre mort"; + let msgIncrevable = nomPerso(target) + " devrait être mort"; msgIncrevable += eForFemale(target) + ", mais "; msgIncrevable += onGenre(target, 'il', 'elle') + " est increvable !"; expliquer(msgIncrevable); @@ -21180,25 +21286,25 @@ var COFantasy = COFantasy || function() { setTokenAttr(target, 'increvableActif', true, evt); } else if ((attributeAsBool(target, 'enrage') || predicateAsBool(target, 'durACuire')) && !attributeAsBool(target, 'aAgiAZeroPV')) { - let msgAgitZ = nomPerso(target) + " devrait \xEAtre mort"; + let msgAgitZ = nomPerso(target) + " devrait être mort"; msgAgitZ += eForFemale(target) + ", mais "; - msgAgitZ += onGenre(target, 'il', 'elle') + " continue \xE0 se battre !"; + msgAgitZ += onGenre(target, 'il', 'elle') + " continue à se battre !"; expliquer(msgAgitZ); if (!attributeAsBool(target, 'agitAZeroPV')) setAttrDuree(target, 'agitAZeroPV', 1, evt); } else if (predicateAsBool(target, 'nAbandonneJamais')) { if (attributeAsBool(target, 'mortMaisNAbandonnePas')) { - expliquer(nomPerso(target) + " est dans un \xE9tat lamentable, mais continue \xE0 bouger. Il faudrait une action limit\xE9e pour le r\xE9duire en miettes."); + expliquer(nomPerso(target) + " est dans un état lamentable, mais continue à bouger. Il faudrait une action limitée pour le réduire en miettes."); } else { - expliquer(nomPerso(target) + " est pratiquement d\xE9truit, mais continue \xE0 bouger !"); + expliquer(nomPerso(target) + " est pratiquement détruit, mais continue à bouger !"); setTokenAttr(target, 'mortMaisNAbandonnePas', true, evt); setState(target, 'ralenti', true, evt); } } else if (predicateAsBool(target, 'exsangue') && !attributeAsBool(target, 'etatExsangue')) { let msg; if (expliquer) { - expliquer(nomPerso(target) + " continue \xE0 agir malgr\xE9 son \xE9tat"); - } else msg = "continue \xE0 agir malgr\xE9 son \xE9tat"; + expliquer(nomPerso(target) + " continue à agir malgré son état"); + } else msg = "continue à agir malgré son état"; setTokenAttr(target, 'etatExsangue', true, evt, { msg }); @@ -21217,7 +21323,7 @@ var COFantasy = COFantasy || function() { let defierLaMort = charAttributeAsInt(target, 'defierLaMort', 10); let rollId = 'defierLaMort_' + target.token.id; let saveOpts = { - msgPour: " pour d\xE9fier la mort", + msgPour: " pour défier la mort", msgReussite: ", conserve 1 PV", rolls: options.rolls, chanceRollId: options.chanceRollId @@ -21239,7 +21345,7 @@ var COFantasy = COFantasy || function() { } postBarUpdateForDealDamage(target, dmgTotal, pvPerdus, bar1, tempDmg, dmgDisplay, showTotal, dmDrains, displayRes, evt, expliquer); }); - //On arr\xEAte l\xE0, car tout le reste est fait dans la continuation du save. + //On arrête là, car tout le reste est fait dans la continuation du save. return; } mettreAZeroPV(target, pvMax, evt, expliquer); @@ -21287,7 +21393,7 @@ var COFantasy = COFantasy || function() { if (rd > 0 && !options.aoe && options.attaquant && predicateAsBool(options.attaquant, 'ventreMou')) { let taille = taillePersonnage(target, 4); if (taille > 4) { - if (target.messages) target.messages.push("Ventre mou => L'attaque ignore la RD d\xFBe \xE0 la taille"); + if (target.messages) target.messages.push("Ventre mou => L'attaque ignore la RD dûe à la taille"); rd -= 3 * (taille - 4); if (taille > 6) rd--; if (rd < 0) rd = 0; @@ -21308,7 +21414,7 @@ var COFantasy = COFantasy || function() { else if (attributeAsBool(target, 'petrifie')) rd += 20; if (attributeAsBool(target, 'mutationSilhouetteMassive')) rd += 3; if (crit) { - let rdCrit = predicateAsInt(target, 'RD_critique', 0); //pour la compatibilit\xE9 + let rdCrit = predicateAsInt(target, 'RD_critique', 0); //pour la compatibilité if (ficheAttributeAsBool(target, 'casque_on', false)) rdCrit += ficheAttributeAsInt(target, 'casque_rd', 0); rd += rdCrit; @@ -21341,7 +21447,7 @@ var COFantasy = COFantasy || function() { } if (target.extraRDBouclier) { rd += target.extraRDBouclier; - expliquer(nomPerso(target) + " d\xE9vie le coup avec son bouclier"); + expliquer(nomPerso(target) + " dévie le coup avec son bouclier"); } if (target.ignoreTouteRD) rd = 0; else if (target.ignoreMoitieRD) rd = parseInt(rd / 2); @@ -21362,17 +21468,17 @@ var COFantasy = COFantasy || function() { if (dmgTotal <= rd) expliquer("La rune de protection absorbe tous les dommages"); else expliquer("La rune de protection encaisse " + target.utiliseRuneProtectionMax + " dommages"); } - //RD PeauDePierre \xE0 prendre en compte en dernier + //RD PeauDePierre à prendre en compte en dernier if (!target.defautCuirasse && !target.ignoreTouteRD && rd < dmgTotal && attributeAsBool(target, 'peauDePierreMag')) { let peauDePierreMagValeur = tokenAttribute(target, 'peauDePierreMagValeur'); if (peauDePierreMagValeur.length === 0) { - error("compteur de Peau de Pierre non trouv\xE9", target); + error("compteur de Peau de Pierre non trouvé", target); } else { peauDePierreMagValeur = peauDePierreMagValeur[0]; let rdPeauDePierreMax = parseInt(peauDePierreMagValeur.get('current')); let peauDePierreAbsorbe = parseInt(peauDePierreMagValeur.get('max')); if (isNaN(rdPeauDePierreMax) || isNaN(peauDePierreAbsorbe) || rdPeauDePierreMax < 1 || peauDePierreAbsorbe < 1) { - error("compteur de Peau de Pierre mal form\xE9", peauDePierreMagValeur); + error("compteur de Peau de Pierre mal formé", peauDePierreMagValeur); finDEffetDeNom(target, "peauDePierreMag", evt); } else { let rdPeauDePierreMag = rdPeauDePierreMax; @@ -21425,7 +21531,7 @@ var COFantasy = COFantasy || function() { }); } if (predicateAsBool(target, 'commandant')) { - //On cherche si il y a au moins 4 cr\xE9atures sous ses ordres \xE0 moins de 10 m + //On cherche si il y a au moins 4 créatures sous ses ordres à moins de 10 m let pageId = target.token.get('pageid'); let tokens = findObjs({ @@ -21482,7 +21588,7 @@ var COFantasy = COFantasy || function() { options.memePasMal += dmgTotal; dmgTotal = 0; } - expliquer("M\xEAme pas mal : ignore " + options.memePasMal + " PVs et peut enrager"); + expliquer("Même pas mal : ignore " + options.memePasMal + " PVs et peut enrager"); let mpm = attributeAsInt(target, 'memePasMalIgnore', 0); setTokenAttr(target, 'memePasMalIgnore', mpm + options.memePasMal, evt); setAttrDuree(target, 'memePasMalBonus', 3, evt); @@ -21542,7 +21648,7 @@ var COFantasy = COFantasy || function() { showTotal = true; dmgTotal = 1; if (dmSuivis.drain && dmSuivis.drain > 0) dmSuivis.drain = 1; - expliquer("La nu\xE9e est constitu\xE9e de tr\xE8s nombreuses cibles, l'attaque ne lui fait qu'1 DM"); + expliquer("La nuée est constituée de très nombreuses cibles, l'attaque ne lui fait qu'1 DM"); } if (options.attaquant && options.arme && dmgTotal > 0 && predicateAsBool(options.attaquant, 'blessureSanglante') && @@ -21568,9 +21674,9 @@ var COFantasy = COFantasy || function() { }; let sujet = onGenre(target, 'il', 'elle'); let saveOpts = { - msgPour: " pour se lib\xE9rer de la domination", - msgReussite: ", " + sujet + " se lib\xE8re de la domination", - msgRate: ", " + sujet + " reste sous domination malgr\xE9 les d\xE9g\xE2ts", + msgPour: " pour se libérer de la domination", + msgReussite: ", " + sujet + " se libère de la domination", + msgRate: ", " + sujet + " reste sous domination malgré les dégâts", rolls: options.rolls, chanceRollId: options.chanceRollId }; @@ -21596,7 +21702,7 @@ var COFantasy = COFantasy || function() { } enlevePVStatueDeBois(target, pvPerdus, evt); } else { - //On enl\xE8ve les points de vie + //On enlève les points de vie let pvTemporaires = attributeAsInt(target, 'PVTemporaires', 0); if (bar1 > 0 && bar1 + pvTemporaires <= dmgTotal && predicateAsBool(target, 'instinctDeSurvieHumain')) { @@ -21611,7 +21717,7 @@ var COFantasy = COFantasy || function() { dmgDisplay += " / 2"; showTotal = true; } - expliquer("L'instinct de survie aide \xE0 r\xE9duire une attaque fatale"); + expliquer("L'instinct de survie aide à réduire une attaque fatale"); } pvPerdus = dmgTotal; if (pvTemporaires > 0) { @@ -21626,18 +21732,18 @@ var COFantasy = COFantasy || function() { } else { bar1 = bar1 - dmgTotal; } - if (crit) { //Vuln\xE9rabilit\xE9 aux critiues + if (crit) { //Vulnérabilité aux critiues let vulnerableCritique = predicateAsInt(target, 'vulnerableCritique', 0); if (vulnerableCritique > 0) { if (randomInteger(100) <= vulnerableCritique) { - expliquer("Le coup critique le fait voler en \xE9clats"); + expliquer("Le coup critique le fait voler en éclats"); if (bar1 > 0) { dmgTotal += bar1; pvPerdus += bar1; bar1 = 0; } } else { - expliquer("Le coup critique fait vibrer l'adversaire, mais il r\xE9siste."); + expliquer("Le coup critique fait vibrer l'adversaire, mais il résiste."); } } } @@ -21645,7 +21751,7 @@ var COFantasy = COFantasy || function() { predicateAsBool(target, 'peutEnrager') && !attributeAsBool(target, 'enrage')) { setTokenAttr(target, 'enrage', true, evt); - expliquer(nomPerso(target) + " devient enrag\xE9" + eForFemale(target) + "."); + expliquer(nomPerso(target) + " devient enragé" + eForFemale(target) + "."); finDEffetDeNom(target, 'apeureTemp', evt); finDEffetDeNom(target, 'peurEtourdi', evt); setState(target, 'apeure', false, evt); @@ -21690,7 +21796,7 @@ var COFantasy = COFantasy || function() { if (bar1 <= 0) { if (predicateAsBool(target, 'sergent') && !attributeAsBool(target, 'attributDeCombat_sergentUtilise')) { - expliquer(nomPerso(target) + " \xE9vite l'attaque in-extremis"); + expliquer(nomPerso(target) + " évite l'attaque in-extremis"); setTokenAttr(target, 'attributDeCombat_sergentUtilise', true, evt); pvPerdus = 0; } else if (target.attackRoll && @@ -21713,8 +21819,8 @@ var COFantasy = COFantasy || function() { } else { weaponStatsIncrevable = enMain; } - } else { //attaque \xE0 distance - weaponStatsIncrevable.name = "Attaque \xE0 distance"; + } else { //attaque à distance + weaponStatsIncrevable.name = "Attaque à distance"; weaponStatsIncrevable.attSkill = '@{ATKTIR}'; } let optionsIncrevable = {...options @@ -21733,7 +21839,7 @@ var COFantasy = COFantasy || function() { } } else if (getState(target, 'immobilise')) { dice = 12; - expliquer(nomPerso(target) + " immobilis\xE9 => D12 au lieu de D20 en Attaque"); + expliquer(nomPerso(target) + " immobilisé => D12 au lieu de D20 en Attaque"); } else if (attributeAsBool(target, 'mortMaisNAbandonnePas')) { dice = 12; expliquer(nomPerso(target) + " mort mais n'abandonne pas => D12 au lieu de D20 en Attaque"); @@ -21771,12 +21877,12 @@ var COFantasy = COFantasy || function() { let msgIncrevable = "Increvable : " + nomPerso(target) + " fait " + attRollValue; //TODO: afficher les explications de calcul des bonus d'attaque ? if (attackRollAttaquant < target.attackRoll) { - expliquer(msgIncrevable + " < " + target.attackRoll + " => \xE9chec "); + expliquer(msgIncrevable + " < " + target.attackRoll + " => échec "); prendreUnCoupMortel(target, dmgTotal, pvPerdus, bar1, pvmax, tempDmg, dmgDisplay, showTotal, dmSuivis.drain, displayRes, options, evt, expliquer); return; } - //L'attaque est \xE9vit\xE9e - expliquer(msgIncrevable + " > " + target.attackRoll + " => l'attaque est \xE9vit\xE9e ! "); + //L'attaque est évitée + expliquer(msgIncrevable + " > " + target.attackRoll + " => l'attaque est évitée ! "); postBarUpdateForDealDamage(target, dmgTotal, 0, bar1, tempDmg, dmgDisplay, showTotal, dmSuivis.drain, displayRes, evt, expliquer); }); @@ -21798,7 +21904,7 @@ var COFantasy = COFantasy || function() { } function postBarUpdateForDealDamage(target, dmgTotal, pvPerdus, bar1, tempDmg, dmgDisplay, showTotal, dmDrains, displayRes, evt, expliquer) { - if (bar1 > 0 && tempDmg >= bar1) { //assomm\xE9 + if (bar1 > 0 && tempDmg >= bar1) { //assommé setState(target, 'assomme', true, evt); } let attrsLienDeSang = tokenAttribute(target, "lienDeSangVers"); @@ -21812,7 +21918,7 @@ var COFantasy = COFantasy || function() { }; let personnageLie = persoOfId(attrsLienDeSang[0].get("current")); if (personnageLie) { - expliquer("Le lien de sang inflige " + lienDuSangDmg + " d\xE9g\xE2ts \xE0 " + personnageLie.token.get("name")); + expliquer("Le lien de sang inflige " + lienDuSangDmg + " dégâts à " + personnageLie.token.get("name")); dealDamage(personnageLie, r, [], evt, false); } } @@ -22012,8 +22118,8 @@ var COFantasy = COFantasy || function() { return toEvaluate.replace(/@{/g, "@{" + name + "|"); } - // Retourne le diam\xE8tre d'un disque inscrit dans un carr\xE9 de surface - // \xE9quivalente \xE0 celle du token + // Retourne le diamètre d'un disque inscrit dans un carré de surface + // équivalente à celle du token function tokenSizeAsCircle(token) { const surface = token.get('width') * token.get('height'); return Math.sqrt(surface); @@ -22074,11 +22180,11 @@ var COFantasy = COFantasy || function() { let pt1 = pointOfToken(tok1); let pt2 = pointOfToken(tok2); let distToTrajectory = distancePixTokenSegment(obj, pt1, pt2); - // On mod\xE9lise le token comme un disque + // On modélise le token comme un disque let rayonObj = tokenSizeAsCircle(obj) / 2; if (distToTrajectory > rayonObj) return; liste_obstacles.push(obj.get("name")); - // On calcule un malus proportionnel \xE0 l'arc \xE0 traverser + // On calcule un malus proportionnel à l'arc à traverser // Pour l'instant, malus = 1 si distance = PIX_PER_UNIT let longueurArc = 2 * Math.sqrt(rayonObj * rayonObj - distToTrajectory * distToTrajectory); let mToken = longueurArc / PIX_PER_UNIT; @@ -22093,7 +22199,7 @@ var COFantasy = COFantasy || function() { else mObstacle = Math.round(mObstacle); let res = mPortee + mObstacle; if (mObstacle > 0) { - log("Obstacle" + ((liste_obstacles.length > 1) ? "s" : "") + " trouv\xE9 : " + liste_obstacles.join(', ')); + log("Obstacle" + ((liste_obstacles.length > 1) ? "s" : "") + " trouvé : " + liste_obstacles.join(', ')); let msgObstacles = 'Obstacle' + ((liste_obstacles.length > 1) ? 's' : '') + ' sur le trajet => -' + mObstacle + ' en Attaque
'; if (liste_obstacles.length > 0) msgObstacles += '' + liste_obstacles.join(', ') + ''; @@ -22123,12 +22229,12 @@ var COFantasy = COFantasy || function() { }); } - // Fait foo sur tous les tokens repr\xE9sentant charId, ayant l'effet donn\xE9, et correspondant au nom d'attribut. Pour le cas o\xF9 le token doit \xEAtre li\xE9 au personnage, on ne prend qu'un seul token, sauf si les options indiquent autrement (soit option.tousLesTokens, soit une fonction options.filterAffected) + // Fait foo sur tous les tokens représentant charId, ayant l'effet donné, et correspondant au nom d'attribut. Pour le cas où le token doit être lié au personnage, on ne prend qu'un seul token, sauf si les options indiquent autrement (soit option.tousLesTokens, soit une fonction options.filterAffected) // Ne fonctionne correctement que pour les attributs sans _ function iterTokensOfAttribute(charId, pageId, attrName, attrNameComplet, foo, options) { options = options || {}; - let total = 1; //Nombre de tokens affect\xE9s, pour g\xE9rer l'asynchronie si besoin - if (attrNameComplet == attrName) { //token li\xE9 au character + let total = 1; //Nombre de tokens affectés, pour gérer l'asynchronie si besoin + if (attrNameComplet == attrName) { //token lié au character let tokens; if (pageId) { tokens = @@ -22173,7 +22279,7 @@ var COFantasy = COFantasy || function() { if (options.filterAffected(tok)) foo(tok, total); }); } else foo(tokens[0], 1); - } else { //token non li\xE9 au character + } else { //token non lié au character let tokenName = attrNameComplet.substring(attrNameComplet.indexOf('_') + 1); let tNames; if (pageId) { @@ -22220,7 +22326,7 @@ var COFantasy = COFantasy || function() { let character = getObj('character', charId); let charName = "d'id " + charId; if (character) charName = character.get('name'); - error("Attention, il y a plusieurs tokens nomm\xE9s " + tokenName, total); + error("Attention, il y a plusieurs tokens nommés " + tokenName, total); log(" tokens instances du personnage " + charName, total); } } @@ -22251,7 +22357,7 @@ var COFantasy = COFantasy || function() { token.set('showplayers_aura2', true); } else { let status = ''; - // Cas des tokens personnalis\xE9s + // Cas des tokens personnalisés if (statusForInitEnemy && statusForInitAlly) { // ennemi => rouge status = statusForInitEnemy; @@ -22264,7 +22370,7 @@ var COFantasy = COFantasy || function() { } } - //Ne rajoute pas evt \xE0 l'historique + //Ne rajoute pas evt à l'historique function setActiveToken(combat, tokenId, evt) { let pageId; if (combat) pageId = combat.pageId; @@ -22309,10 +22415,10 @@ var COFantasy = COFantasy || function() { if (tokenId) { let perso = persoOfId(tokenId, tokenId); if (perso) { - //On remet \xE0 0 la liste des cibles attaqu\xE9es par le personnage + //On remet à 0 la liste des cibles attaquées par le personnage removeDernieresCiblesAttaquees(perso, evt); let token = perso.token; - // personnage li\xE9 au Token + // personnage lié au Token affectToken(token, 'statusmarkers', token.get('statusmarkers'), evt); affectToken(token, 'aura2_radius', token.get('aura2_radius'), evt); affectToken(token, 'aura2_color', token.get('aura2_color'), evt); @@ -22329,7 +22435,7 @@ var COFantasy = COFantasy || function() { onGenre(perso, 'Il', 'Elle') + " ne fait rien ce tour"); removeTokenFlagAura(token); } else { - //Trouver la cr\xE9ature la plus proche + //Trouver la créature la plus proche let closestToken; pageId = token.get('pageid'); let toksOnPage = findObjs({ @@ -22374,7 +22480,7 @@ var COFantasy = COFantasy || function() { } } } - //On enl\xE8ve aussi les \xE9tats qui ne durent qu'un tour + //On enlève aussi les états qui ne durent qu'un tour let defenseTotale = tokenAttribute(perso, 'defenseTotale'); if (defenseTotale.length > 0) { defenseTotale = defenseTotale[0]; @@ -22402,7 +22508,7 @@ var COFantasy = COFantasy || function() { const charId = a.get('characterid'); let m = parseInt(a.get('max')); if (isNaN(m) || m < 0) { - error("Erreur dans les quantit\xE9s d'arme de jet", a); + error("Erreur dans les quantités d'arme de jet", a); a.remove(); return; } @@ -22415,7 +22521,7 @@ var COFantasy = COFantasy || function() { }); if (!msgAffiche.has(charId)) { msgAffiche.add(charId); - whisperChar(charId, "r\xE9cup\xE8re ses armes de jet"); + whisperChar(charId, "récupère ses armes de jet"); } a.set('current', m); } @@ -22432,7 +22538,7 @@ var COFantasy = COFantasy || function() { const charId = a.get('characterid'); let m = parseInt(a.get('max')); if (isNaN(m) || m < 0) { - error("Erreur dans les quantit\xE9s de munitions", a); + error("Erreur dans les quantités de munitions", a); a.remove(); return; } @@ -22445,7 +22551,7 @@ var COFantasy = COFantasy || function() { }); if (!msgAffiche.has(charId)) { msgAffiche.add(charId); - whisperChar(charId, "r\xE9cup\xE8re ses munitions"); + whisperChar(charId, "récupère ses munitions"); } a.set('current', m); } @@ -22458,10 +22564,10 @@ var COFantasy = COFantasy || function() { let combat = stateCOF.combat; if (!combat) { log("Pas en combat"); - sendChat("GM", "/w GM Le combat est d\xE9j\xE0 termin\xE9"); + sendChat("GM", "/w GM Le combat est déjà terminé"); return; } - sendChat("GM", "Le combat est termin\xE9"); + sendChat("GM", "Le combat est terminé"); let evt = { type: 'fin_combat', initiativepage: Campaign().get('initiativepage'), @@ -22512,18 +22618,18 @@ var COFantasy = COFantasy || function() { attrs = removeAllAttributes('meneurDHommesCible', evt, attrs); attrs = removeAllAttributes('energieImpie', evt, attrs); // Autres attributs - // On r\xE9cup\xE8re les munitions r\xE9cup\xE9rables - resetAttr(attrs, 'munition', evt, "r\xE9cup\xE8re ses munitions"); //obsol\xE8te depuis mars 2023. + // On récupère les munitions récupérables + resetAttr(attrs, 'munition', evt, "récupère ses munitions"); //obsolète depuis mars 2023. recupererMunitions(attrs, evt); recupererArmesDeJet(attrs, evt); - //Utilisation automatique de second souffle, si pas utilis\xE9 + //Utilisation automatique de second souffle, si pas utilisé let tokens = findObjs({ // Les tokens sur la page du combat _type: 'graphic', _subtype: 'token', _pageid: combat.pageId, }); - let persosDuCombat = []; //peupl\xE9 la premi\xE8re fois qu'on regarde les tokens - let persoParCharId = {}; //Pour ne garder qu'un jeu de pr\xE9dicat par charId + let persosDuCombat = []; //peuplé la première fois qu'on regarde les tokens + let persoParCharId = {}; //Pour ne garder qu'un jeu de prédicat par charId tokens.forEach(function(token) { let charId = token.get('represents'); if (charId === '' || charId === undefined) return; @@ -22550,11 +22656,11 @@ var COFantasy = COFantasy || function() { let jetSoins = rollDePlus(10, { bonus: bonus }); - let msg = ' reprend son souffle et r\xE9cup\xE8re '; + let msg = ' reprend son souffle et récupère '; let soins = jetSoins.val; if (pv + soins > pvDebut) { soins = pvDebut - pv; - msg += soins + " PV (le jet \xE9tait " + jetSoins.roll + ")"; + msg += soins + " PV (le jet était " + jetSoins.roll + ")"; } else { msg += jetSoins.roll + " PVs"; } @@ -22565,11 +22671,11 @@ var COFantasy = COFantasy || function() { }); attrs = removeAllAttributes('secondSouffleUtilise', evt, attrs); attrs = removeAllAttributes('PVsDebutCombat', evt, attrs); - // On diminue l'\xE9bri\xE9t\xE9 des personnages sous vapeurs \xE9thyliques + // On diminue l'ébriété des personnages sous vapeurs éthyliques allAttributesNamed(attrs, 'vapeursEthyliques').forEach(function(attr) { let veCharId = attr.get('characterid'); if (veCharId === undefined || veCharId === '') { - error("Attribut sans personnage associ\xE9", attr); + error("Attribut sans personnage associé", attr); return; } iterTokensOfAttribute(veCharId, combat.pageId, @@ -22580,7 +22686,7 @@ var COFantasy = COFantasy || function() { token: tok }; removeTokenAttr(perso, 'niveauEbriete', evt, { - msg: "d\xE9sao\xFBle" + msg: "désaoûle" }); }); }); @@ -22592,7 +22698,7 @@ var COFantasy = COFantasy || function() { degainerArme(perso, '', evt); } }); - // On remet en main l'arme par d\xE9faut si elle est pr\xE9cis\xE9e + // On remet en main l'arme par défaut si elle est précisée persosDuCombat.forEach(function(perso) { if (!isActive(perso)) return; let persoTest = persoParCharId[perso.charId]; @@ -22630,7 +22736,7 @@ var COFantasy = COFantasy || function() { ilds.forEach(function(ild) { let douleur = parseInt(ild.get('current')); if (isNaN(douleur)) { - error("La douleur ignor\xE9e n'est pas un nombre", douleur); + error("La douleur ignorée n'est pas un nombre", douleur); return; } let charId = ild.get('characterid'); @@ -22654,7 +22760,7 @@ var COFantasy = COFantasy || function() { pvAttr = pvAttr[0]; let pv = parseInt(pvAttr.get('current')); if (isNaN(pv)) { - error("PV mal form\xE9s ", pvAttr); + error("PV mal formés ", pvAttr); return; } evt.attributes.push({ @@ -22665,13 +22771,13 @@ var COFantasy = COFantasy || function() { if (newPv < 0) newPv = 0; pvAttr.set('current', newPv); if (pv > 0 && newPv === 0) { - sendChar(charId, "s'\xE9croule. Il semble sans vie. La douleur qu'il avait ignor\xE9e l'a finalement rattrap\xE9...", true); + sendChar(charId, "s'écroule. Il semble sans vie. La douleur qu'il avait ignorée l'a finalement rattrapé...", true); } else { let tempDmg = ficheAttributeAsInt(charId, 'DMTEMP', 0); if (pv > tempDmg && newPv <= tempDmg) { - sendChar(charId, "s'\xE9croule, assomm\xE9. La douleur qu'il avait ignor\xE9e l'a finalement rattrap\xE9...", true); + sendChar(charId, "s'écroule, assommé. La douleur qu'il avait ignorée l'a finalement rattrapé...", true); } else { - sendChar(charId, "subit le contrecoup de la douleur qu'il avait ignor\xE9e", true); + sendChar(charId, "subit le contrecoup de la douleur qu'il avait ignorée", true); } } } else { // ignorer la douleur d'un token @@ -22683,11 +22789,11 @@ var COFantasy = COFantasy || function() { name: tokName }); if (tokensIld.length === 0) { - error("Pas de token nomm\xE9 " + tokName + " qui aurait ignor\xE9 la douleur", ild); + error("Pas de token nommé " + tokName + " qui aurait ignoré la douleur", ild); return; } if (tokensIld.length > 1) { - sendChar(charId, "a plusieurs tokens nomm\xE9s " + tokName + ". Un seul d'entre eux subira l'effet d'ignorer la douleur", true); + sendChar(charId, "a plusieurs tokens nommés " + tokName + ". Un seul d'entre eux subira l'effet d'ignorer la douleur", true); } let tokPv = parseInt(tokensIld[0].get('bar1_value')); let tokNewPv = tokPv - douleur; @@ -22714,7 +22820,7 @@ var COFantasy = COFantasy || function() { } //Attributs qu'on veut enlever en dernier let removedLaterAttrs = []; - // fin des effets temporaires (dur\xE9e en tours, ou dur\xE9e = combat) + // fin des effets temporaires (durée en tours, ou durée = combat) attrs.forEach(function(obj) { let attrName = obj.get('name'); let charId = obj.get('characterid'); @@ -22768,7 +22874,7 @@ var COFantasy = COFantasy || function() { }, { tousLesTokens: true }); - //Pas besoin de d\xE9truire l'attribut, ce sera fait plus loin + //Pas besoin de détruire l'attribut, ce sera fait plus loin } evt.deletedAttributes.push(obj); obj.remove(); @@ -22831,7 +22937,7 @@ var COFantasy = COFantasy || function() { } //Asynchrone - // ne rajoute pas evt \xE0 l'historique + // ne rajoute pas evt à l'historique function soinsEcuyers(ecuyers, manquePV, playerId, evt) { ecuyers.forEach(function(ec) { const ecuyer = ec.perso; @@ -22841,11 +22947,11 @@ var COFantasy = COFantasy || function() { name: ecuyerDe }); if (charChevalier.length === 0) { - error("Pas de chevalier " + ecuyerDe + " pour l'\xE9cuyer " + nomPerso(ecuyer), ec); + error("Pas de chevalier " + ecuyerDe + " pour l'écuyer " + nomPerso(ecuyer), ec); return; } if (charChevalier.length > 1) { - error("Plusieurs personnages nomm\xE9s " + ecuyerDe + ". Attention aux ambiguit\xE9s."); + error("Plusieurs personnages nommés " + ecuyerDe + ". Attention aux ambiguités."); } charChevalier = charChevalier[0].id; let maxASoigner = modCarac(charChevalier, 'charisme') + 1; @@ -22869,17 +22975,17 @@ var COFantasy = COFantasy || function() { } alliesASoigner.push(cible); } - }); //fin de d\xE9termination des cibles + }); //fin de détermination des cibles if (chevalier === undefined && monture === undefined && - (maxASoigner < 1 || alliesASoigner.length === 0)) { //Personne \xE0 soigner + (maxASoigner < 1 || alliesASoigner.length === 0)) { //Personne à soigner return; } - //TODO: utiliser l'id d'un player qui contr\xF4le le chevalier - let display = startFramedDisplay(playerId, "Services d'\xE9cuyer", ecuyer); + //TODO: utiliser l'id d'un player qui contrôle le chevalier + let display = startFramedDisplay(playerId, "Services d'écuyer", ecuyer); let finSoin = function() { nbCibles--; if (nbCibles === 0) { - if (display) sendChat("", endFramedDisplay(display)); + if (display) sendFramedDisplay(display); } }; let soigneUneCible = function(c) { @@ -22891,17 +22997,17 @@ var COFantasy = COFantasy || function() { if (c.token.id == ecuyer.token.id) { msgSoin = 'se soigne de '; } else { - msgSoin = nomPerso(c) + " r\xE9cup\xE8re "; + msgSoin = nomPerso(c) + " récupère "; } if (s < soins) - msgSoin += s + " PV. (Le r\xE9sultat du jet \xE9tait " + soinTxt + ")"; + msgSoin += s + " PV. (Le résultat du jet était " + soinTxt + ")"; else msgSoin += soinTxt + " PV."; addLineToFramedDisplay(display, msgSoin); }; soigneToken(c, soins, evt, printTrue); finSoin(); }); //fin du sendChat - }; // fin de d\xE9finition de soigneCible + }; // fin de définition de soigneCible let peutToutSoigner = (alliesASoigner.length <= maxASoigner); if (peutToutSoigner) nbCibles += alliesASoigner.length; else if (maxASoigner > 0) nbCibles++; //pour ne pas finir avant d'imprimer les boutons @@ -22921,7 +23027,7 @@ var COFantasy = COFantasy || function() { }); finSoin(); } - }); //fin iteration sur les \xE9cuyers + }); //fin iteration sur les écuyers } function parseOptions(msg) { @@ -22929,7 +23035,7 @@ var COFantasy = COFantasy || function() { if (msg.selected && msg.selected.length > 0) { let firstSelected = getObj('graphic', msg.selected[0]._id); if (firstSelected === undefined) { - error("Un token s\xE9lectionn\xE9 n'est pas trouv\xE9 en interne", msg.selected); + error("Un token sélectionné n'est pas trouvé en interne", msg.selected); return; } pageId = firstSelected.get('pageid'); @@ -22963,7 +23069,7 @@ var COFantasy = COFantasy || function() { break; case 'lanceur': if (cmd.length < 2) { - error("Il faut pr\xE9ciser l'id ou le nom du lanceur", arg); + error("Il faut préciser l'id ou le nom du lanceur", arg); return; } options.lanceur = persoOfId(cmd[1], cmd[1], pageId); @@ -23011,7 +23117,7 @@ var COFantasy = COFantasy || function() { cout = parseInt(cmd[1]); } if (isNaN(cout) || cout < 0) { - error("Co\xFBt en mana incorrect", cmd); + error("Coût en mana incorrect", cmd); return; } options.mana = options.mana || 0; @@ -23026,7 +23132,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { cout = parseInt(cmd[1]); if (isNaN(cout) || cout < 0) { - error("Le co\xFBt de la magie rapide n'est pas un entier positif", cmd); + error("Le coût de la magie rapide n'est pas un entier positif", cmd); cout = 1; } } @@ -23045,19 +23151,19 @@ var COFantasy = COFantasy || function() { } let rang = parseInt(cmd[1]); if (isNaN(rang) || rang < 1) { - error("Le rang doit \xEAtre un nombre positif"); + error("Le rang doit être un nombre positif"); return; } options.rang = rang; break; case 'limiteParJour': if (cmd.length < 2) { - error("Il manque la limite journali\xE8re", cmd); + error("Il manque la limite journalière", cmd); return; } let limiteParJour = parseInt(cmd[1]); if (isNaN(limiteParJour) || limiteParJour < 1) { - error("La limite journali\xE8re doit \xEAtre un nombre positif", cmd); + error("La limite journalière doit être un nombre positif", cmd); return; } options.limiteParJour = limiteParJour; @@ -23068,24 +23174,24 @@ var COFantasy = COFantasy || function() { return; case 'depasseLimite': if (cmd.length < 2) { - error("Il manque le co\xFBt en mana pour depasser la limite", cmd); + error("Il manque le coût en mana pour depasser la limite", cmd); return; } let depasse = parseInt(cmd[1]); if (isNaN(depasse) || depasse < 1) { - error("Le co\xFBt de d\xE9passement doit \xEAtre un nombre positif", cmd); + error("Le coût de dépassement doit être un nombre positif", cmd); return; } options.depasseLimite = depasse; return; case 'limiteSoinsParJour': if (cmd.length < 2) { - error("Il manque la limite de soins journali\xE8re", cmd); + error("Il manque la limite de soins journalière", cmd); return; } let limiteSoinsParJour = parseInt(cmd[1]); if (isNaN(limiteSoinsParJour) || limiteSoinsParJour < 1) { - error("La limite de soins journali\xE8re doit \xEAtre un nombre positif", cmd); + error("La limite de soins journalière doit être un nombre positif", cmd); return; } options.limiteSoinsParJour = limiteSoinsParJour; @@ -23096,12 +23202,12 @@ var COFantasy = COFantasy || function() { return; case 'limiteCibleParJour': if (cmd.length < 2) { - error("Il manque la limite journali\xE8re", cmd); + error("Il manque la limite journalière", cmd); return; } let limiteCibleParJour = parseInt(cmd[1]); if (isNaN(limiteCibleParJour) || limiteCibleParJour < 1) { - error("La limite journali\xE8re doit \xEAtre un nombre positif", cmd); + error("La limite journalière doit être un nombre positif", cmd); return; } options.limiteCibleParJour = limiteCibleParJour; @@ -23117,7 +23223,7 @@ var COFantasy = COFantasy || function() { } let limiteParCombat = parseInt(cmd[1]); if (isNaN(limiteParCombat) || limiteParCombat < 1) { - error("La limite par combat doit \xEAtre un nombre positif", cmd); + error("La limite par combat doit être un nombre positif", cmd); return; } options.limiteParCombat = limiteParCombat; @@ -23128,16 +23234,16 @@ var COFantasy = COFantasy || function() { return; case 'tempsRecharge': if (cmd.length < 3) { - error("Il manque un argument \xE0 l'option --tempsRecharge", cmd); + error("Il manque un argument à l'option --tempsRecharge", cmd); return; } if (!estEffetTemp(cmd[1])) { - error("Le premier argument de l'option --tempsRecharge doit \xEAtre un effet temporaire r\xE9pertori\xE9", cmd); + error("Le premier argument de l'option --tempsRecharge doit être un effet temporaire répertorié", cmd); return; } let tr = parseInt(cmd[2]); if (isNaN(tr)) { - error("Le deuxi\xE8me argument de l'option --tempsRecharge doit \xEAtre un nombre", cmd); + error("Le deuxième argument de l'option --tempsRecharge doit être un nombre", cmd); return; } options.tempsRecharge = { @@ -23162,7 +23268,7 @@ var COFantasy = COFantasy || function() { portee = parseInt(cmd[1]); } if (isNaN(portee) || portee < 0) { - error("Port\xE9e incorrecte", cmd); + error("Portée incorrecte", cmd); return; } options.portee = portee; @@ -23185,21 +23291,21 @@ var COFantasy = COFantasy || function() { return; case 'decrAttribute': if (cmd.length < 2) { - error("Erreur interne d'une commande g\xE9n\xE9r\xE9e par bouton", opts); + error("Erreur interne d'une commande générée par bouton", opts); return; } let attr = getObj('attribute', cmd[1]); if (attr === undefined && options.lanceur) { attr = tokenAttribute(options.lanceur, cmd[1]); if (attr.length === 0) { - log("Attribut \xE0 changer perdu"); + log("Attribut à changer perdu"); log(cmd); return; } attr = attr[0]; } if (attr === undefined) { - log("Attribut \xE0 changer perdu"); + log("Attribut à changer perdu"); log(cmd); return; } @@ -23250,14 +23356,14 @@ var COFantasy = COFantasy || function() { break; case "classeEffet": if (cmd.length < 2) { - sendChat("COF", "Il manque un argument \xE0 l'option --classeEffet"); + sendChat("COF", "Il manque un argument à l'option --classeEffet"); return; } options.classeEffet = cmd[1]; return; case 'message': if (cmd.length < 2) { - error("Il manque le message apr\xE8s --message", cmd); + error("Il manque le message après --message", cmd); return; } options.messages = options.messages || []; @@ -23265,7 +23371,7 @@ var COFantasy = COFantasy || function() { return; case 'messageMJ': if (cmd.length < 2) { - error("Il manque le message apr\xE8s --messageMJ", cmd); + error("Il manque le message après --messageMJ", cmd); return; } options.messagesMJ = options.messagesMJ || []; @@ -23273,14 +23379,14 @@ var COFantasy = COFantasy || function() { return; case 'image': if (cmd.length < 2) { - error("Il manque le nom de l'imageapr\xE8s --image", cmd); + error("Il manque le nom de l'imageaprès --image", cmd); return; } options.image = cmd[1].replace(':', ':'); return; case 'son': if (cmd.length < 2) { - error("Il manque le nom du son apr\xE8s --son", cmd); + error("Il manque le nom du son après --son", cmd); return; } options.son = cmd.slice(1).join(' '); @@ -23306,7 +23412,7 @@ var COFantasy = COFantasy || function() { return; case 'etat': if (cmd.length < 2) { - error("Il manque le nom de l'\xE9tat et sa valeur apr\xE8s --etat", cmd); + error("Il manque le nom de l'état et sa valeur après --etat", cmd); return; } options.etats = options.etats || {}; @@ -23326,7 +23432,7 @@ var COFantasy = COFantasy || function() { case 'dm': let t = cmd[0]; if (options[t]) { - error(t + " d\xE9j\xE0 d\xE9fini", opts); + error(t + " déjà défini", opts); return; } if (cmd.length < 2) { @@ -23349,7 +23455,7 @@ var COFantasy = COFantasy || function() { } else { let base = parseInt(cmd[1]); if (isNaN(base)) { - error("L'argument de --magieEnArmure doit \xEAtre un nombre ou mana", cmd); + error("L'argument de --magieEnArmure doit être un nombre ou mana", cmd); return; } options.magieEnArmure = { @@ -23362,12 +23468,12 @@ var COFantasy = COFantasy || function() { return; case 'tokenSide': if (cmd.length < 2) { - error("Il faut pr\xE9ciser le cot\xE9 de token \xE0 utiliser", cmd); + error("Il faut préciser le coté de token à utiliser", cmd); return; } let side = parseInt(cmd[1]); if (isNaN(side) || side < 0) { - error("Le cot\xE9 de token doit \xEAtre un nombre positif", cmd); + error("Le coté de token doit être un nombre positif", cmd); return; } options.tokenSide = side; @@ -23379,11 +23485,11 @@ var COFantasy = COFantasy || function() { return options; } - //Si il y a des effets \xE0 dur\xE9e ind\xE9termin\xE9es, les rappeler au MJ, avec un bouton pour facilement y mettre fin si n\xE9cessaire + //Si il y a des effets à durée indéterminées, les rappeler au MJ, avec un bouton pour facilement y mettre fin si nécessaire function proposerFinEffetsIndetermines() { - //On commence par les \xE9tats globaux + //On commence par les états globaux if (stateCOF.tenebresMagiques) { - sendPlayer('GM', boutonSimple("!cof-tenebres-magiques fin", "Mettre fin") + "aux t\xE9n\xE8bres magiques ?"); + sendPlayer('GM', boutonSimple("!cof-tenebres-magiques fin", "Mettre fin") + "aux ténèbres magiques ?"); } if (stateCOF.effetAuD20) { for (let ev in stateCOF.effetAuD20) { @@ -23399,7 +23505,7 @@ var COFantasy = COFantasy || function() { estEffetIndetermine(name); }); if (attrs.length === 0) return; - const display = startFramedDisplay(undefined, "Effets \xE0 dur\xE9e ind\xE9termin\xE9e actifs", undefined, { + const display = startFramedDisplay(undefined, "Effets à durée indéterminée actifs", undefined, { chuchote: 'gm' }); let attrsParPerso = {}; @@ -23463,7 +23569,7 @@ var COFantasy = COFantasy || function() { } attrsParPerso[charId].effets.push(ef); return; - } // on a un attribut de token non li\xE9 + } // on a un attribut de token non lié let pn = attrName.indexOf('_'); if (pn < 1) return; ef.nom = attrName.substring(0, pn - 1); @@ -23517,11 +23623,11 @@ var COFantasy = COFantasy || function() { }); addLineToFramedDisplay(display, line); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } - // Remise \xE0 z\xE9ro de toutes les limites journali\xE8res - // N'ajoute pas evt \xE0 l'historique + // Remise à zéro de toutes les limites journalières + // N'ajoute pas evt à l'historique function jour(persos, evt, options) { let attrs; attrs = removeAllAttributes('pressionMortelle', evt); @@ -23535,14 +23641,14 @@ var COFantasy = COFantasy || function() { attrs = removeAllAttributes('immunise24HA', evt, attrs); attrs = removeAllAttributes('testsRatesDuTour', evt, attrs); attrs = removeAllAttributes('pointsDeViolence', evt, attrs); - //Les \xE9lixirs + //Les élixirs attrs = removeAllAttributes('elixirsACreer', evt, attrs); attrs = proposerRenouveauElixirs(evt, attrs, options); //Les runes attrs = proposerRenouveauRunes(evt, attrs, options); - //Les plantes m\xE9dicinales - attrs = removeAllAttributes('dose_Plante m\xE9dicinale', evt, attrs); - attrs = removeConsommables('Plante m\xE9dicinale', evt, attrs); + //Les plantes médicinales + attrs = removeAllAttributes('dose_Plante médicinale', evt, attrs); + attrs = removeConsommables('Plante médicinale', evt, attrs); //La perte de substance persos.forEach(function(perso) { if (predicateAsBool(perso, 'perteDeSubstance')) { @@ -23550,8 +23656,8 @@ var COFantasy = COFantasy || function() { let msg = nomPerso(perso) + " a maintenant " + perteDeSubstance; msg += " jour" + ((perteDeSubstance > 1) ? 's' : '') + " de perte de substance.
"; if (!predicateAsBool(perso, 'ancreInvincible')) { - msg += " Demander un jet de CHA difficult\xE9 " + perteDeSubstance; - msg += " ou " + onGenre(perso, 'il', 'elle') + " dispara\xEEt pendant "; + msg += " Demander un jet de CHA difficulté " + perteDeSubstance; + msg += " ou " + onGenre(perso, 'il', 'elle') + " disparaît pendant "; let nj = rollDePlus(6); msg += nj.roll + " heure" + ((nj.val > 1) ? 's' : '') + '.'; } @@ -23584,13 +23690,13 @@ var COFantasy = COFantasy || function() { let attrName = attr.get('name'); let carac = attr.get('current'); if (!isCarac(carac)) { - error("Save par jour " + attrName + " mal form\xE9", carac); + error("Save par jour " + attrName + " mal formé", carac); finalize(); return; } let seuil = parseInt(attr.get('max')); if (isNaN(seuil)) { - error("Save par jour " + attrName + " mal form\xE9", seuil); + error("Save par jour " + attrName + " mal formé", seuil); finalize(); return; } @@ -23622,7 +23728,7 @@ var COFantasy = COFantasy || function() { name: attrName }); if (attrEffet === undefined || attrEffet.length === 0) { - error("Save sans effet associ\xE9 " + attrName, attr); + error("Save sans effet associé " + attrName, attr); findObjs({ _type: 'attribute', _characterid: charId, @@ -23641,11 +23747,11 @@ var COFantasy = COFantasy || function() { let sujet = onGenre(perso, 'il', 'elle'); let met = messageEffetIndetermine[effetC]; if (met === undefined) met = { - fin: "r\xE9siste \xE0 l'effet", + fin: "résiste à l'effet", actf: "reste sous l'emprise de l'effet" }; let saveOpts = { - msgPour: " pour ne plus \xEAtre sous l'effet " + effetC, + msgPour: " pour ne plus être sous l'effet " + effetC, msgReussite: ", " + sujet + ' ' + messageFin(perso, met), msgRate: ", " + sujet + ' ' + messageActif(perso, met), rolls: options.rolls, @@ -23676,7 +23782,7 @@ var COFantasy = COFantasy || function() { }); //fin boucle attrSave } - //La caract\xE9ristique sans affaiblissement + //La caractéristique sans affaiblissement function caracNormale(perso, carac) { let res = ficheAttributeAsInt(perso, carac, 10); if (!persoEstPNJ(perso)) return res; @@ -23712,7 +23818,7 @@ var COFantasy = COFantasy || function() { attributeAsInt(perso, 'affaiblissementde' + carac, 0); } - //N'ajoute pas evt \xE0 l'historique + //N'ajoute pas evt à l'historique function diminueAffaiblissement(perso, carac, valeur, evt, malus) { if (valeur < 1) return; let nomAttr = 'affaiblissementde' + carac; @@ -23740,7 +23846,7 @@ var COFantasy = COFantasy || function() { } let pvMaxNormaux = attributeAsInt(perso, 'pvMaxNormaux', 0); if (pvMaxNormaux < pvmax) { - error("Les PV max sont inf\xE9rieurs \xE0 la valeur normale", pvMaxNormaux); + error("Les PV max sont inférieurs à la valeur normale", pvMaxNormaux); return; } if (valeur == malus || (valeur == malus - 1 && caracNormale(perso, 'consititution') % 2 == 1)) { @@ -23767,7 +23873,7 @@ var COFantasy = COFantasy || function() { } } } else if (valeur == malus) { - //Au cas o\xF9, on v\xE9rifie le pv max + //Au cas où, on vérifie le pv max let pvMaxNormaux = attributeAsInt(perso, 'pvMaxNormaux', 0); if (pvMaxNormaux > 0) { let pvmax = parseInt(perso.token.get("bar1_max")); @@ -23825,7 +23931,7 @@ var COFantasy = COFantasy || function() { let speaksAs = player.get('speakingas'); if (speaksAs !== '') fromMsg = speaksAs; } - sendChat(fromMsg, "Un nouveau jour se l\xE8ve"); + sendChat(fromMsg, "Un nouveau jour se lève"); if (stateCOF.combat) sortirDuCombat(); jour(persos, evt, options); if (options.repos) { @@ -23842,8 +23948,8 @@ var COFantasy = COFantasy || function() { if (msg.content.includes(' --reposLong')) reposLong = true; getSelected(msg, function(selection, playerId) { if (selection.length === 0) { - sendPlayer(msg, "!cof-recuperer sans s\xE9lection de tokens", playerId); - log("!cof-recuperer requiert des tokens s\xE9lectionn\xE9s"); + sendPlayer(msg, "!cof-recuperer sans sélection de tokens", playerId); + log("!cof-recuperer requiert des tokens sélectionnés"); return; } let persos = []; @@ -23871,8 +23977,8 @@ var COFantasy = COFantasy || function() { let allCaracs = ['force', 'dexterite', 'constitution', 'intelligence', 'sagesse', 'charisme']; - //Asynchrone (jets de d\xE9s) - // ne rajoute pas evt \xE0 l'historique + //Asynchrone (jets de dés) + // ne rajoute pas evt à l'historique function recuperation(persos, reposLong, playerId, evt, options) { options = options || {}; let manquePV = []; @@ -23919,7 +24025,7 @@ var COFantasy = COFantasy || function() { let hasMana = false; let dmTemp = bar2; let estMook = token.get('bar1_link') === ''; - if (manaAttr.length > 0) { // R\xE9cup\xE9ration des points de mana + if (manaAttr.length > 0) { // Récupération des points de mana let manaMax = parseInt(manaAttr[0].get('max')); hasMana = !isNaN(manaMax) && manaMax > 0; if (hasMana) { @@ -23930,7 +24036,7 @@ var COFantasy = COFantasy || function() { } } } - if (!isNaN(dmTemp) && dmTemp > 0) { // r\xE9cup\xE9ration de DM temp + if (!isNaN(dmTemp) && dmTemp > 0) { // récupération de DM temp if (reposLong) dmTemp = 0; else dmTemp = Math.max(0, dmTemp - 10); if (hasMana) { @@ -23946,18 +24052,18 @@ var COFantasy = COFantasy || function() { return; } if (bar1 >= pvmax && !reposLong) { - //Plus rien \xE0 faire si pas un repos long + //Plus rien à faire si pas un repos long sendPerso(perso, "n'a pas besoin de repos"); finalize(); return; } if (reposLong) { - //R\xE9cup\xE9ration des affaiblissements de carac si repos long + //Récupération des affaiblissements de carac si repos long allCaracs.forEach(function(carac) { let malus = attributeAsInt(perso, 'affaiblissementde' + carac, 0); if (malus > 0) { diminueAffaiblissement(perso, carac, 1, evt, malus); - sendPerso(perso, "r\xE9cup\xE8re un point " + deCarac(carac)); + sendPerso(perso, "récupère un point " + deCarac(carac)); } }); if (bar1 >= pvmax && (!pr || pr.current == pr.max)) { @@ -23965,19 +24071,19 @@ var COFantasy = COFantasy || function() { return; } if (bar1 < pvmax && predicateAsBool(perso, 'montureMagique')) { - //La monture magique r\xE9cup\xE8re tous ses PV durant la nuit + //La monture magique récupère tous ses PV durant la nuit updateCurrentBar(perso, 1, pvmax, evt); - sendPerso(perso, "r\xE9cup\xE8re tous ses PV"); + sendPerso(perso, "récupère tous ses PV"); finalize(); return; } } - //La r\xE9cup\xE9ration de PV ou de PR + //La récupération de PV ou de PR let dVie = ficheAttributeAsInt(perso, "DV", 0); if (dVie < 4) { if (bar1 < pvmax) manquePV.push(perso); finalize(); - return; //Si pas de d\xE9 de vie, alors pas de PR. + return; //Si pas de dé de vie, alors pas de PR. } if (limiteRessources(perso, options, 'repos', 'repos', evt)) { if (bar1 < pvmax) manquePV.push(perso); @@ -23985,18 +24091,18 @@ var COFantasy = COFantasy || function() { return; } let message; - if (reposLong && pr && pr.current < pr.max) { // on r\xE9cup\xE8re un PR + if (reposLong && pr && pr.current < pr.max) { // on récupère un PR //Sauf si on a une blessure gave if (getState(perso, 'blesse')) { - let testId = 'gu\xE9rir_blessure_' + perso.token.id; + let testId = 'guérir_blessure_' + perso.token.id; testCaracteristique(perso, 'CON', 8, testId, options, evt, function(tr) { - sendPerso(perso, "fait un jet de CON pour gu\xE9rir de sa blessure"); + sendPerso(perso, "fait un jet de CON pour guérir de sa blessure"); let m = "/direct " + onGenre(perso, 'Il', 'Elle') + " fait " + tr.texte; if (tr.reussite) { - sendChar(charId, m + "≥ 8, son \xE9tat s'am\xE9liore nettement." + tr.modifiers, true); + sendChar(charId, m + "≥ 8, son état s'améliore nettement." + tr.modifiers, true); setState(perso, 'blesse', false, evt); } else { - let msgRate = m + "< 8, son \xE9tat reste pr\xE9occupant." + tr.rerolls + tr.modifiers; + let msgRate = m + "< 8, son état reste préoccupant." + tr.rerolls + tr.modifiers; sendChar(charId, msgRate, true); } finalize(); @@ -24005,25 +24111,25 @@ var COFantasy = COFantasy || function() { } let affAttr = rajouterPointDeRecuperation(perso, evt, pr); if (affAttr === undefined) { - error("Pas de point de r\xE9cup\xE9ration \xE0 rajouter et pourtant pas au max", token); + error("Pas de point de récupération à rajouter et pourtant pas au max", token); finalize(); return; } message = - "Au cours de la nuit, les points de r\xE9cup\xE9ration de " + nomPerso(perso) + - " passent de " + (pr.current - 1) + " \xE0 " + pr.current; + "Au cours de la nuit, les points de récupération de " + nomPerso(perso) + + " passent de " + (pr.current - 1) + " à " + pr.current; sendChar(charId, message, true); if (bar1 < pvmax) manquePV.push(perso); finalize(); return; } if (!reposLong && pr) { - if (pr.current === 0) { //pas possible de r\xE9cup\xE9rer - message = " a besoin d'une nuit compl\xE8te pour r\xE9cup\xE9rer"; + if (pr.current === 0) { //pas possible de récupérer + message = " a besoin d'une nuit complète pour récupérer"; sendPerso(perso, message); finalize(); return; - } else { //d\xE9pense d'un PR + } else { //dépense d'un PR enleverPointDeRecuperation(perso, pr, evt); pr.current--; } @@ -24058,10 +24164,10 @@ var COFantasy = COFantasy || function() { if (reposLong) { message = "Au cours de la nuit, "; } else { - message = "Apr\xE8s 5 minutes de repos, "; + message = "Après 5 minutes de repos, "; } - message += "r\xE9cup\xE8re " + buildinline(roll) + "+" + bonus + " PV."; - if (pr) message += " Il lui reste " + pr.current + " points de r\xE9cup\xE9ration"; + message += "récupère " + buildinline(roll) + "+" + bonus + " PV."; + if (pr) message += " Il lui reste " + pr.current + " points de récupération"; sendPerso(perso, message); finalize(); }); @@ -24088,8 +24194,8 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected, playerId) { if (selected === undefined) { - sendPlayer(msg, "!cof-recharger sans s\xE9lection de tokens", playerId); - log("!cof-recharger requiert des tokens s\xE9lectionn\xE9s"); + sendPlayer(msg, "!cof-recharger sans sélection de tokens", playerId); + log("!cof-recharger requiert des tokens sélectionnés"); return; } iterSelected(selected, function(perso) { @@ -24116,7 +24222,7 @@ var COFantasy = COFantasy || function() { attrs = attrs[0]; currentCharge = parseInt(attrs.get('current')); if (isNaN(currentCharge)) { - error("charge mal form\xE9e", attrs); + error("charge mal formée", attrs); currentCharge = 0; } } @@ -24138,7 +24244,7 @@ var COFantasy = COFantasy || function() { } else attrGrenaille = attrGrenaille[0]; currentChargeGrenaille = parseInt(attrGrenaille.get('current')); if (isNaN(currentChargeGrenaille)) { - error("charge de grenaille mal form\xE9e", attrGrenaille); + error("charge de grenaille mal formée", attrGrenaille); return; } if (currentChargeGrenaille > currentCharge) currentChargeGrenaille = currentCharge; @@ -24171,7 +24277,7 @@ var COFantasy = COFantasy || function() { } else attrGrenaille = attrGrenaille[0]; currentChargeGrenaille = parseInt(attrGrenaille.get('current')); if (isNaN(currentChargeGrenaille)) { - error("charge de grenaille mal form\xE9e", attrGrenaille); + error("charge de grenaille mal formée", attrGrenaille); return; } if (currentChargeGrenaille < currentCharge) { @@ -24187,7 +24293,7 @@ var COFantasy = COFantasy || function() { attrGrenaille = attrGrenaille[0]; currentChargeGrenaille = parseInt(attrGrenaille.get('current')); if (isNaN(currentChargeGrenaille)) { - error("charge de grenaille mal form\xE9e", attrGrenaille); + error("charge de grenaille mal formée", attrGrenaille); return; } if (currentChargeGrenaille > 0) { @@ -24202,9 +24308,9 @@ var COFantasy = COFantasy || function() { } } if (maxCharge == 1) { - sendPerso(perso, arme.name + " est d\xE9j\xE0 charg\xE9"); + sendPerso(perso, arme.name + " est déjà chargé"); } else { - sendPerso(perso, "a d\xE9j\xE0 tous ses " + arme.name + " charg\xE9s"); + sendPerso(perso, "a déjà tous ses " + arme.name + " chargés"); } }); }); @@ -24220,12 +24326,12 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let action = evt.action; if (!action) { - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); return; } let perso = evt.personnage; @@ -24233,7 +24339,7 @@ var COFantasy = COFantasy || function() { if (args.length > 2) { let roll = action.rolls[args[2]]; if (roll === undefined) { - error("Erreur interne du bouton de chance : roll non identifi\xE9", args); + error("Erreur interne du bouton de chance : roll non identifié", args); return; } if (roll.token === undefined) { @@ -24244,7 +24350,7 @@ var COFantasy = COFantasy || function() { rollId = args[2]; } if (perso === undefined) { - error("Erreur interne du bouton de chance : l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton de chance : l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24253,7 +24359,7 @@ var COFantasy = COFantasy || function() { } let chance = pointsDeChance(perso); if (chance <= 0) { - sendPerso(perso, "n'a plus de point de chance \xE0 d\xE9penser..."); + sendPerso(perso, "n'a plus de point de chance à dépenser..."); return; } let evtChance = { @@ -24263,7 +24369,7 @@ var COFantasy = COFantasy || function() { chance--; undoEvent(evt); setFicheAttr(perso, 'pc', chance, evtChance, { - msg: " a d\xE9pens\xE9 un point de chance. Il lui en reste " + chance + msg: " a dépensé un point de chance. Il lui en reste " + chance }); action.options = action.options || {}; if (rollId) { @@ -24273,7 +24379,7 @@ var COFantasy = COFantasy || function() { action.options.chance = (action.options.chance + 10) || 10; } if (!redoEvent(evt, action, perso)) - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); addEvent(evtChance); } @@ -24286,19 +24392,19 @@ var COFantasy = COFantasy || function() { } const evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let perso = evt.personnage; let rollId; if (args.length > 2) { if (!evt.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let roll = evt.action.rolls[args[2]]; if (roll === undefined) { - error("Erreur interne du bouton de chance : roll non identifi\xE9", args); + error("Erreur interne du bouton de chance : roll non identifié", args); return; } if (roll.token === undefined) { @@ -24309,7 +24415,7 @@ var COFantasy = COFantasy || function() { rollId = args[2]; } if (perso === undefined) { - error("Erreur interne du bouton de prouesse : l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton de prouesse : l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24345,7 +24451,7 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evtProuesse, false, {}, explications, function(dmgDisplay, dmg) { - sendPerso(perso, "r\xE9alise une prouesse et perd " + dmgDisplay + " PV"); + sendPerso(perso, "réalise une prouesse et perd " + dmgDisplay + " PV"); explications.forEach(function(expl) { sendPerso(perso, expl); }); @@ -24359,7 +24465,7 @@ var COFantasy = COFantasy || function() { } if (redoEvent(evt, action, perso)) return; } - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); } //!cof-pacte-sanglant [evt.id] [3|5] [rollId] @@ -24371,7 +24477,7 @@ var COFantasy = COFantasy || function() { } const evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let bonus = parseInt(args[2]); @@ -24383,12 +24489,12 @@ var COFantasy = COFantasy || function() { let rollId; if (args.length > 3) { if (!evt.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let roll = evt.action.rolls[args[3]]; if (roll === undefined) { - error("Erreur interne du bouton de pacte sanglant : roll non identifi\xE9", args); + error("Erreur interne du bouton de pacte sanglant : roll non identifié", args); return; } if (roll.token === undefined) { @@ -24399,7 +24505,7 @@ var COFantasy = COFantasy || function() { rollId = args[3]; } if (perso === undefined) { - error("Erreur interne du bouton de pacte sanglant : l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton de pacte sanglant : l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24408,7 +24514,7 @@ var COFantasy = COFantasy || function() { } let valPacteSanglant = predicateAsInt(perso, 'pacteSanglant', 0); if (valPacteSanglant < bonus) { - sendPerso(perso, "ne peut pas faire \xE7a !"); + sendPerso(perso, "ne peut pas faire ça !"); return; } let action = evt.action; @@ -24437,7 +24543,7 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evtPacteSanglant, false, {}, explications, function(dmgDisplay, dmg) { - sendPerso(perso, "r\xE9alise un Pacte sanglant et perd " + dmgDisplay + " PV"); + sendPerso(perso, "réalise un Pacte sanglant et perd " + dmgDisplay + " PV"); explications.forEach(function(expl) { sendPerso(perso, expl); }); @@ -24450,7 +24556,7 @@ var COFantasy = COFantasy || function() { } if (redoEvent(evt, action, perso)) return; } - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); } //!cof-pacte-sanglant [evt.id] [3|5] [targetId] @@ -24462,11 +24568,11 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } if (!evt.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let bonus = parseInt(args[2]); @@ -24476,7 +24582,7 @@ var COFantasy = COFantasy || function() { } let perso = persoOfId([args[3]]); if (perso === undefined) { - error("Erreur interne du bouton de pacte sanglant (DEF) : pas de cible trouv\xE9e", args); + error("Erreur interne du bouton de pacte sanglant (DEF) : pas de cible trouvée", args); return; } if (!peutController(msg, perso)) { @@ -24485,7 +24591,7 @@ var COFantasy = COFantasy || function() { } let valPacteSanglant = predicateAsInt(perso, 'pacteSanglant', 0); if (valPacteSanglant < bonus) { - sendPerso(perso, "ne peut pas faire \xE7a !"); + sendPerso(perso, "ne peut pas faire ça !"); return; } let action = evt.action; @@ -24513,7 +24619,7 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evtPacteSanglant, false, {}, explications, function(dmgDisplay, dmg) { - sendPerso(perso, "r\xE9alise un Pacte sanglant et perd " + dmgDisplay + " PV"); + sendPerso(perso, "réalise un Pacte sanglant et perd " + dmgDisplay + " PV"); explications.forEach(function(expl) { sendPerso(perso, expl); }); @@ -24522,7 +24628,7 @@ var COFantasy = COFantasy || function() { options.pacteSanglantDef[perso.token.id] = (options.pacteSanglantDef[perso.token.id] + bonus) || bonus; if (redoEvent(evt, action, perso)) return; } - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); } //!cof-tour-force [evt.id] [rollId] @@ -24534,19 +24640,19 @@ var COFantasy = COFantasy || function() { } const evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let perso = evt.personnage; let rollId; if (args.length > 2) { if (!evt.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let roll = evt.action.rolls[args[2]]; if (roll === undefined) { - error("Erreur interne du bouton de tour de force : roll non identifi\xE9", args); + error("Erreur interne du bouton de tour de force : roll non identifié", args); return; } if (roll.token === undefined) { @@ -24557,7 +24663,7 @@ var COFantasy = COFantasy || function() { rollId = args[2]; } if (perso === undefined) { - error("Erreur interne du bouton de tour de force : l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton de tour de force : l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24566,7 +24672,7 @@ var COFantasy = COFantasy || function() { } let attrTourDeForce = predicateAsBool(perso, 'tourDeForce'); if (!attrTourDeForce) { - sendPerso(perso, "ne peut pas faire \xE7a !"); + sendPerso(perso, "ne peut pas faire ça !"); return; } let action = evt.action; @@ -24593,7 +24699,7 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evtTourDeForce, false, {}, explications, function(dmgDisplay, dmg) { - sendPerso(perso, "r\xE9alise un Tour de force et perd " + dmgDisplay + " PV"); + sendPerso(perso, "réalise un Tour de force et perd " + dmgDisplay + " PV"); explications.forEach(function(expl) { sendPerso(perso, expl); }); @@ -24606,7 +24712,7 @@ var COFantasy = COFantasy || function() { } if (redoEvent(evt, action, perso)) return; } - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); } //Renvoie true si redo possible, false sinon @@ -24665,7 +24771,7 @@ var COFantasy = COFantasy || function() { action.testINT, action.infosAdditionelles, options); return true; case 'enveloppement': - case '\xE9treinte': + case 'étreinte': doEnveloppement(action.attaquant, action.cible, action.difficulte, action.type, action.exprDM, options); return true; case 'injonction': @@ -24757,12 +24863,12 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let perso = evt.personnage; if (perso === undefined) { - error("Erreur interne du bouton d'\xE9chec total: l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton d'échec total: l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24771,14 +24877,14 @@ var COFantasy = COFantasy || function() { } let action = evt.action; if (!action || evt.type != "Attaque") { - error("Erreur interne du bouton d'\xE9chec total: l'\xE9v\xE8nement n'est pas une attaque", evt); + error("Erreur interne du bouton d'échec total: l'évènement n'est pas une attaque", evt); return; } let evtEchecTotal = { type: 'echecTotal' }; addEvent(evtEchecTotal); - // Attaquer avec les m\xEAmes options, vider redo et preDmg \xE9ventuels + // Attaquer avec les mêmes options, vider redo et preDmg éventuels let options = action.options; options.auto = true; options.echecTotal = true; @@ -24800,11 +24906,11 @@ var COFantasy = COFantasy || function() { if (limiteRessources(perso, { limiteParCombat: rangExpertDuCombat * 2, limiteParTour: limiteParTour - }, "expertDuCombat", "a atteint sa limite de d\xE9 d'expert du combat", evt)) { + }, "expertDuCombat", "a atteint sa limite de dé d'expert du combat", evt)) { addEvent(evt); return false; } - sendPerso(perso, "utilise un d\xE9 d'expert du combat"); + sendPerso(perso, "utilise un dé d'expert du combat"); return true; } @@ -24813,19 +24919,19 @@ var COFantasy = COFantasy || function() { //!cof-expert-combat-dm function expertDuCombat(msg) { if (!stateCOF.combat) { - sendPlayer(msg, "On ne peut utiliser les d\xE9s d'expert du combat qu'en combat"); + sendPlayer(msg, "On ne peut utiliser les dés d'expert du combat qu'en combat"); return; } let cmd = msg.content.split(' '); let evtARefaire; const evt = { - type: "D\xE9 d'expert du combat (touche)", + type: "Dé d'expert du combat (touche)", attributes: [] }; - if (cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 1) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; @@ -24835,7 +24941,7 @@ var COFantasy = COFantasy || function() { return; } if (perso === undefined) { - error("Erreur interne du bouton expert de combat : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton expert de combat : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -24851,11 +24957,11 @@ var COFantasy = COFantasy || function() { else if (cmd[0].includes("-dm")) action.options.expertDuCombatDM = action.options.expertDuCombatDM + 1 || 1; if (!redoEvent(evtARefaire, action, perso)) - error("Type d'\xE9v\xE8nement pas support\xE9 par le bouton Rune d'Energie", evt); - } else { //Juste pour v\xE9rifier l'attribut et le diminuer + error("Type d'évènement pas supporté par le bouton Rune d'Energie", evt); + } else { //Juste pour vérifier l'attribut et le diminuer getSelected(msg, function(selection) { if (selection.length === 0) { - sendPlayer(msg, 'Pas de token s\xE9lectionn\xE9 pour !cof-bouton-expert-combat-touche'); + sendPlayer(msg, 'Pas de token sélectionné pour !cof-bouton-expert-combat-touche'); return; } iterSelected(selection, function(perso) { @@ -24875,17 +24981,17 @@ var COFantasy = COFantasy || function() { } let evtARefaire = findEvent(args[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let action = evtARefaire.action; if (action === undefined) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let perso = persoOfId([args[2]]); if (perso === undefined) { - error("Erreur interne du bouton d'expert du combat (DEF) : pas de cible trouv\xE9e", args); + error("Erreur interne du bouton d'expert du combat (DEF) : pas de cible trouvée", args); return; } if (!peutController(msg, perso)) { @@ -24906,37 +25012,37 @@ var COFantasy = COFantasy || function() { } function persoUtiliseRuneEnergie(perso, evt) { - let attr = tokenAttribute(perso, 'runeForgesort_\xE9nergie'); + let attr = tokenAttribute(perso, 'runeForgesort_énergie'); if (attr.length < 1 || attr[0].get('current') < 1) { - sendPerso(perso, "n'a pas de rune d'\xE9nergie"); + sendPerso(perso, "n'a pas de rune d'énergie"); return false; } if (limiteRessources(perso, { limiteParCombat: 1 - }, "runeForgesort_\xE9nergie", "a d\xE9j\xE0 utilis\xE9 sa rune d'\xE9nergie durant ce combat", evt)) { + }, "runeForgesort_énergie", "a déjà utilisé sa rune d'énergie durant ce combat", evt)) { addEvent(evt); return false; } - sendPerso(perso, "utilise sa rune d'\xE9nergie pour relancer un d20 sur un test d'attaque, de FOR, DEX ou CON"); + sendPerso(perso, "utilise sa rune d'énergie pour relancer un d20 sur un test d'attaque, de FOR, DEX ou CON"); return true; } //!cof-bouton-rune-energie function runeEnergie(msg) { if (!stateCOF.combat) { - sendPlayer(msg, "On ne peut utiliser les runes d'\xE9nergie qu'en combat"); + sendPlayer(msg, "On ne peut utiliser les runes d'énergie qu'en combat"); return; } let cmd = msg.content.split(' '); let evtARefaire; const evt = { - type: "Rune d'\xE9nergie", + type: "Rune d'énergie", attributes: [] }; - if (cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 1) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; @@ -24949,7 +25055,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 2) { let roll = action.rolls[cmd[2]]; if (roll === undefined) { - error("Erreur interne du bouton de chance : roll non identifi\xE9", cmd); + error("Erreur interne du bouton de chance : roll non identifié", cmd); return; } if (roll.token === undefined) { @@ -24961,7 +25067,7 @@ var COFantasy = COFantasy || function() { evt.rollId = rollId; } if (perso === undefined) { - error("Erreur interne du bouton de rune d'\xE9nergie : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton de rune d'énergie : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -24970,7 +25076,7 @@ var COFantasy = COFantasy || function() { } let carac = action.caracteristque; if (carac == 'SAG' || carac == 'INT' || carac == 'CHA') { - sendPerso(perso, "ne peut pas utiliser la rune d'\xE9nergie pour un test " + deCarac(carac)); + sendPerso(perso, "ne peut pas utiliser la rune d'énergie pour un test " + deCarac(carac)); return; } if (!persoUtiliseRuneEnergie(perso, evt)) return; @@ -24979,11 +25085,11 @@ var COFantasy = COFantasy || function() { if (rollId) delete action.rolls[rollId]; else if (action.rolls && action.rolls.attack) delete action.rolls.attack; if (!redoEvent(evtARefaire, action, perso)) - error("Type d'\xE9v\xE8nement pas support\xE9 par le bouton Rune d'Energie", evt); - } else { //Juste pour v\xE9rifier l'attribut et le diminuer + error("Type d'évènement pas supporté par le bouton Rune d'Energie", evt); + } else { //Juste pour vérifier l'attribut et le diminuer getSelected(msg, function(selection) { if (selection.length === 0) { - sendPlayer(msg, 'Pas de token s\xE9lectionn\xE9 pour !cof-rune-energie'); + sendPlayer(msg, 'Pas de token sélectionné pour !cof-rune-energie'); return; } iterSelected(selection, function(perso) { @@ -24998,7 +25104,7 @@ var COFantasy = COFantasy || function() { let attrName = permanent ? 'runeDePuissance' + labelArme : "runeForgesort_puissance(" + labelArme + ")"; let arme = getAttackName(labelArme, perso); if (arme === undefined) { - error(perso.tokNname + " n'a pas d'arme associ\xE9e au label " + labelArme, perso); + error(perso.tokNname + " n'a pas d'arme associée au label " + labelArme, perso); return false; } if (!permanent && tokenAttribute(perso, attrName).length === 0) { @@ -25007,7 +25113,7 @@ var COFantasy = COFantasy || function() { } if (limiteRessources(perso, { limiteParCombat: 1 - }, attrName, "a d\xE9j\xE0 utilis\xE9 sa rune de puissance durant ce combat", evt)) { + }, attrName, "a déjà utilisé sa rune de puissance durant ce combat", evt)) { addEvent(evt); return false; } @@ -25024,7 +25130,7 @@ var COFantasy = COFantasy || function() { } let cmd = msg.content.split(' '); if (cmd.length < 2) { - error("Il faut sp\xE9cifier le label de l'arme sur laquelle la rune de puissance est inscrite", cmd); + error("Il faut spécifier le label de l'arme sur laquelle la rune de puissance est inscrite", cmd); return; } let labelArme = cmd[1]; @@ -25033,15 +25139,15 @@ var COFantasy = COFantasy || function() { type: "Rune de puissance", attributes: [] }; - if (cmd.length > 2) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 2) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[2]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; if (perso === undefined) { - error("Erreur interne du bouton de rune de puissance : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton de rune de puissance : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -25074,10 +25180,10 @@ var COFantasy = COFantasy || function() { default: return; } - } else { //Juste pour v\xE9rifier l'attribut et le diminuer + } else { //Juste pour vérifier l'attribut et le diminuer getSelected(msg, function(selection, playerId) { if (selection.length === 0) { - sendPlayer(msg, 'Pas de token s\xE9lectionn\xE9 pour !cof-rune-puissance', playerId); + sendPlayer(msg, 'Pas de token sélectionné pour !cof-rune-puissance', playerId); return; } iterSelected(selection, function(perso) { @@ -25101,12 +25207,12 @@ var COFantasy = COFantasy || function() { } let evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; if (perso === undefined) { - error("Erreur interne du bouton de kiai : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton de kiai : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -25148,7 +25254,7 @@ var COFantasy = COFantasy || function() { } } - //Devrait \xEAtre appel\xE9 seulement depuis un bouton + //Devrait être appelé seulement depuis un bouton //!cof-esquive-fatale evtid target_id function doEsquiveFatale(msg) { let cmd = msg.content.split(' '); @@ -25158,12 +25264,12 @@ var COFantasy = COFantasy || function() { attributes: [] }; if (cmd.length < 3) { - error("Il manque des arguments \xE0 !cof-esquive-fatale", cmd); + error("Il manque des arguments à !cof-esquive-fatale", cmd); return; } evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'attaque est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'attaque est trop ancienne ou a été annulée", cmd); return; } let action = evtARefaire.action; @@ -25173,7 +25279,7 @@ var COFantasy = COFantasy || function() { } let perso = action.cibles[0]; if (perso === undefined) { - error("Erreur interne du bouton de 'esquive fatale : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton de 'esquive fatale : l'évenement n'a pas de personnage", evtARefaire); return; } let adversaire = persoOfId(cmd[2]); @@ -25192,7 +25298,7 @@ var COFantasy = COFantasy || function() { } let ennemisAuContact = perso.ennemisAuContact; if (ennemisAuContact === undefined) { - error("Ennemis au contact non d\xE9finis", perso); + error("Ennemis au contact non définis", perso); } else { let i = ennemisAuContact.find(function(tok) { return (tok.id == adversaire.token.id); @@ -25206,12 +25312,12 @@ var COFantasy = COFantasy || function() { sendPlayer(msg, "pas le droit d'utiliser ce bouton"); return; } - let testEsquiveFatale = testLimiteUtilisationsCapa(perso, 'esquiveFatale', 'combat', "a d\xE9j\xE0 fait une esquive fatale durant ce combat", "ne sait pas faire d'esquive fatale"); + let testEsquiveFatale = testLimiteUtilisationsCapa(perso, 'esquiveFatale', 'combat', "a déjà fait une esquive fatale durant ce combat", "ne sait pas faire d'esquive fatale"); if (testEsquiveFatale === undefined) { return; } utiliseCapacite(perso, testEsquiveFatale, evt); - //On va refaire compl\xE8tement l'attaque + //On va refaire complètement l'attaque undoEvent(evtARefaire); addEvent(evt); adversaire.msgEsquiveFatale = nomPerso(perso) + " esquive l'attaque qui touche " + nomPerso(adversaire); @@ -25221,21 +25327,21 @@ var COFantasy = COFantasy || function() { redoEvent(evtARefaire, action); } - //Soit juste !cof-intercepter (en s\xE9lectionnant le chevalier) + //Soit juste !cof-intercepter (en sélectionnant le chevalier) //Soit depuis un bouton !cof-intercepter evtid cibleid function intercepter(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } let fromEvtId; if (cmd.length > 1) { fromEvtId = cmd[1]; //Appel depuis le bouton if (cmd.length < 3) { - error("Bouton d'interception mal form\xE9", cmd); + error("Bouton d'interception mal formé", cmd); return; } } @@ -25243,10 +25349,10 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(chevalier) { let character = getObj('character', chevalier.charId); if (character === undefined) { - error("L'argument de !cof-intercepter n'est pas une id de token valide (personnage non d\xE9fini)", msg.content); + error("L'argument de !cof-intercepter n'est pas une id de token valide (personnage non défini)", msg.content); return; } - let test = testLimiteUtilisationsCapa(chevalier, 'intercepter', 'tour', "a d\xE9j\xE0 intercept\xE9 une attaque ce tour", "ne sait pas utiliser intercepter les attaques"); + let test = testLimiteUtilisationsCapa(chevalier, 'intercepter', 'tour', "a déjà intercepté une attaque ce tour", "ne sait pas utiliser intercepter les attaques"); if (test === undefined) { return; } @@ -25254,7 +25360,7 @@ var COFantasy = COFantasy || function() { let attaque; let originalTarget; let evtARefaire; - if (fromEvtId) { //On a utilis\xE9 un bouton + if (fromEvtId) { //On a utilisé un bouton if (!peutController(msg, chevalier)) { sendPlayer(msg, "pas le droit d'utiliser ce bouton"); return; @@ -25288,15 +25394,15 @@ var COFantasy = COFantasy || function() { attaque = evtARefaire.action; } if (attaque === undefined) { - sendPlayer(msg, "La derni\xE8re action trouv\xE9e n'est pas une attaque, impossible d'intercepter"); + sendPlayer(msg, "La dernière action trouvée n'est pas une attaque, impossible d'intercepter"); return; } if (attaque.cibles.length === 0) { - sendPlayer(msg, "la derni\xE8re attaque n'a touch\xE9 aucune cible, impossible d'intercepter"); + sendPlayer(msg, "la dernière attaque n'a touché aucune cible, impossible d'intercepter"); return; } if (attaque.cibles.length > 1) { - sendPlayer(msg, "la derni\xE8re attaque a touch\xE9 plus d'une cible, impossible d'intercepter"); + sendPlayer(msg, "la dernière attaque a touché plus d'une cible, impossible d'intercepter"); return; } originalTarget = attaque.cibles[0]; @@ -25323,19 +25429,19 @@ var COFantasy = COFantasy || function() { }); } - //simplement prendre les DM \xE0 la place d'un autre + //simplement prendre les DM à la place d'un autre function interposer(msg) { getSelected(msg, function(selected, playerId) { iterSelected(selected, function(cible) { let charId = cible.charId; let character = getObj('character', charId); if (character === undefined) { - error("L'argument de !cof-interposer n'est pas une id de token valide (personnage non d\xE9fini)", msg.content); + error("L'argument de !cof-interposer n'est pas une id de token valide (personnage non défini)", msg.content); return; } cible.name = character.get('name'); //TODO: utile ? if (attributeAsBool(cible, 'interposer')) { - sendPerso(cible, " a d\xE9j\xE0 intercept\xE9 une attaque ce tour"); + sendPerso(cible, " a déjà intercepté une attaque ce tour"); return; } let attaque; @@ -25344,20 +25450,20 @@ var COFantasy = COFantasy || function() { attaque = lastAct.action; } if (attaque === undefined) { - sendPlayer(msg, "la derni\xE8re action trouv\xE9e n'est pas une attaque, impossible d'intercepter"); + sendPlayer(msg, "la dernière action trouvée n'est pas une attaque, impossible d'intercepter"); return; } if (attaque.cibles.length === 0) { - sendPlayer(msg, "la derni\xE8re attaque n'a touch\xE9 aucune cible, impossible de s'interposer"); + sendPlayer(msg, "la dernière attaque n'a touché aucune cible, impossible de s'interposer"); return; } if (attaque.cibles.length > 1) { - sendPlayer(msg, "la derni\xE8re attaque a touch\xE9 plus d'une cible, impossible de s'interposer en utilisant le script"); + sendPlayer(msg, "la dernière attaque a touché plus d'une cible, impossible de s'interposer en utilisant le script"); return; } let target = attaque.cibles[0]; if (target === undefined) { - error("Le token de la derni\xE8re attaque est ind\xE9fini", attaque); + error("Le token de la dernière attaque est indéfini", attaque); return; } let targetName = nomPerso(target); @@ -25374,7 +25480,7 @@ var COFantasy = COFantasy || function() { let pvApres = target.token.get('bar1_value'); // On annule l'ancienne action undoEvent(); - // On calcule ensuite les pv perdus, et on les applique au d\xE9fenseur + // On calcule ensuite les pv perdus, et on les applique au défenseur let pvPerdus = target.token.get('bar1_value') - pvApres; // Puis on refait en changeant la cible let options = attaque.options; @@ -25392,7 +25498,7 @@ var COFantasy = COFantasy || function() { getSelected(msg, function(selected, playerId) { iterSelected(selected, function(cible) { if (attributeAsBool(cible, 'exemplaire')) { - sendPerso(cible, " a d\xE9j\xE0 montr\xE9 l'exemple \xE0 ce tour"); + sendPerso(cible, " a déjà montré l'exemple à ce tour"); return; } let attaque; @@ -25403,20 +25509,20 @@ var COFantasy = COFantasy || function() { } } if (attaque === undefined) { - sendPlayer(msg, "la derni\xE8re action trouv\xE9e n'est pas une attaque rat\xE9e, impossible de montrer l'exemple", + sendPlayer(msg, "la dernière action trouvée n'est pas une attaque ratée, impossible de montrer l'exemple", playerId); return; } let attackerName = nomPerso(attaque.attaquant); if (attackerName === undefined) { - error("Le token de la derni\xE8re attaque est ind\xE9fini", attaque); + error("Le token de la dernière attaque est indéfini", attaque); return; } const evt = { type: "Montrer l'exemple" }; setTokenAttr(cible, 'exemplaire', true, evt, { - msg: "montre l'exemple \xE0 " + attackerName + msg: "montre l'exemple à " + attackerName }); // On annule l'ancienne action undoEvent(); @@ -25439,16 +25545,16 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2 || (cmd[1] != "rate" && cmd[1] != "touche")) { - error("Il manque l'option rate ou touche \xE0 Intervention Divine", msg); + error("Il manque l'option rate ou touche à Intervention Divine", msg); return; } getSelected(msg, function(selected) { iterSelected(selected, function(pretre) { - let testIntervention = testLimiteUtilisationsCapa(pretre, 'interventionDivine', 'combat', "a d\xE9j\xE0 fait une intervention divine ce combat", "ne sait pas faire d'intervention divine"); + let testIntervention = testLimiteUtilisationsCapa(pretre, 'interventionDivine', 'combat', "a déjà fait une intervention divine ce combat", "ne sait pas faire d'intervention divine"); if (testIntervention === undefined) { return; } @@ -25486,9 +25592,9 @@ var COFantasy = COFantasy || function() { }); } - //!cof-petit-veinard (avec un token s\xE9lectionn\xE9) + //!cof-petit-veinard (avec un token sélectionné) //!cof-bouton-petit-veinard evtid - //sans argument, diminue juste l'attribut, sinon relance l'\xE9v\xE9nement + //sans argument, diminue juste l'attribut, sinon relance l'événement function petitVeinard(msg) { if (!stateCOF.combat) { sendPlayer(msg, "On ne peut utiliser petit veinard qu'en combat"); @@ -25498,7 +25604,7 @@ var COFantasy = COFantasy || function() { if (msgOptions === undefined) return; let cmd = msgOptions.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } let evtARefaire; @@ -25506,22 +25612,22 @@ var COFantasy = COFantasy || function() { type: "Petit veinard", attributes: [] }; - if (cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 1) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; let rollId; if (cmd.length > 2) { if (!evtARefaire.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", msg.content); + error("Le dernier évènement n'est pas une action", msg.content); return; } let roll = evtARefaire.action.rolls[cmd[2]]; if (roll === undefined) { - error("Erreur interne du bouton de chance : roll non identifi\xE9", msg.content); + error("Erreur interne du bouton de chance : roll non identifié", msg.content); return; } if (roll.token === undefined) { @@ -25532,7 +25638,7 @@ var COFantasy = COFantasy || function() { rollId = cmd[2]; } if (perso === undefined) { - error("Erreur interne du bouton petit veinard : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton petit veinard : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -25544,7 +25650,7 @@ var COFantasy = COFantasy || function() { error("Impossible de relancer l'action", evtARefaire); return; } - let testPetitVeinard = testLimiteUtilisationsCapa(perso, 'petitVeinard', 'combat', "a d\xE9j\xE0 tent\xE9 sa chance pour ce combat", "n'est pas un petit veinard"); + let testPetitVeinard = testLimiteUtilisationsCapa(perso, 'petitVeinard', 'combat', "a déjà tenté sa chance pour ce combat", "n'est pas un petit veinard"); if (testPetitVeinard === undefined) { return; } @@ -25554,19 +25660,19 @@ var COFantasy = COFantasy || function() { if (rollId) delete action.rolls[rollId]; else if (action.rolls && action.rolls.attack) delete action.rolls.attack; if (!redoEvent(evtARefaire, action, perso)) - error("Type d'\xE9v\xE8nement pas support\xE9 par le bouton Petit Veinard", evt); - } else { //Juste pour v\xE9rifier l'attribut et le diminuer + error("Type d'évènement pas supporté par le bouton Petit Veinard", evt); + } else { //Juste pour vérifier l'attribut et le diminuer getSelected(msg, function(selection, playerId) { if (selection.length === 0) { - sendPlayer(msg, 'Pas de token s\xE9lectionn\xE9 pour !cof-petit-veinard', playerId); + sendPlayer(msg, 'Pas de token sélectionné pour !cof-petit-veinard', playerId); return; } iterSelected(selection, function(perso) { - let testPetitVeinard = testLimiteUtilisationsCapa(perso, 'petitVeinard', 'combat', "a d\xE9j\xE0 tent\xE9 sa chance pour ce combat", "n'est pas un petit veinard"); + let testPetitVeinard = testLimiteUtilisationsCapa(perso, 'petitVeinard', 'combat', "a déjà tenté sa chance pour ce combat", "n'est pas un petit veinard"); if (testPetitVeinard === undefined) { return; } - sendPerso(perso, "peut relancer un d\xE9"); + sendPerso(perso, "peut relancer un dé"); utiliseCapacite(perso, testPetitVeinard, evt); }); //fin iterSelected addEvent(evt); @@ -25579,7 +25685,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } let testSurprise; @@ -25591,8 +25697,8 @@ var COFantasy = COFantasy || function() { let ciblesSelectionnees; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "!cof-surprise sans s\xE9lection de token", playerId); - log("!cof-surprise requiert de s\xE9lectionner des tokens"); + sendPlayer(msg, "!cof-surprise sans sélection de token", playerId); + log("!cof-surprise requiert de sélectionner des tokens"); return; } ciblesSelectionnees = selected; @@ -25606,7 +25712,7 @@ var COFantasy = COFantasy || function() { if (cibles.length > 0) { doSurprise(cibles, testSurprise, ciblesSelectionnees, options); } else { - error("Pas de cible valable s\xE9lectionn\xE9e pour la surprise", msg.content); + error("Pas de cible valable sélectionnée pour la surprise", msg.content); } } @@ -25629,12 +25735,12 @@ var COFantasy = COFantasy || function() { if (testSurprise === undefined) { display = startFramedDisplay(options.playerId, "Surprise !"); } else { - display = startFramedDisplay(options.playerId, "Test de surprise difficult\xE9 " + testSurprise); + display = startFramedDisplay(options.playerId, "Test de surprise difficulté " + testSurprise); } let tokensToProcess = cibles.length; let sendEvent = function() { if (tokensToProcess == 1) { - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } tokensToProcess--; }; @@ -25650,12 +25756,12 @@ var COFantasy = COFantasy || function() { if (compagnonPresent(perso, 'surveillance')) { bonusSurprise += 5; setTokenAttr(perso, 'bonusInitEmbuscade', 5, evt); - bonusMessages.push(name + " garde un temps d'avance gr\xE2ce \xE0 son compagnon animal : +5"); + bonusMessages.push(name + " garde un temps d'avance grâce à son compagnon animal : +5"); initPerso(perso, evt, true); } if (attributeAsBool(perso, 'sixiemeSens')) { bonusSurprise += 5; - bonusMessages.push(name + " a un sixi\xE8me sens : +5"); + bonusMessages.push(name + " a un sixième sens : +5"); } if (testSurprise !== undefined) { let testId = 'surprise_' + perso.token.id; @@ -25668,9 +25774,9 @@ var COFantasy = COFantasy || function() { testCaracteristique(perso, 'SAG', testSurprise, testId, optionsTest, evt, function(tr, explications) { let result; - if (tr.reussite) result = "r\xE9ussi." + tr.modifiers; + if (tr.reussite) result = "réussi." + tr.modifiers; else { - result = "rat\xE9, " + name + " est surpris"; + result = "raté, " + name + " est surpris"; result += eForFemale(perso); result += tr.rerolls + tr.modifiers; setState(perso, 'surpris', true, evt); @@ -25693,7 +25799,7 @@ var COFantasy = COFantasy || function() { }); } - function interchangeable(attackingToken, target, pageId) { //d\xE9termine si il y a assez de tokens + function interchangeable(attackingToken, target, pageId) { //détermine si il y a assez de tokens let token = target.token; let res = { result: false, @@ -25721,7 +25827,7 @@ var COFantasy = COFantasy || function() { let d = distanceCombat(attackingToken, tok); return (d === 0); }); - } else { // cible \xE0 distance, on garde celles au contact de la cible + } else { // cible à distance, on garde celles au contact de la cible res.targets = tokens.filter(function(tok) { let d = distanceCombat(token, tok); return (d === 0); @@ -25758,8 +25864,8 @@ var COFantasy = COFantasy || function() { }, nombre: 0 }; - // Appel\xE9 uniquement apr\xE8s le "ready" et lorsqu'on modifie un handout (fonctionne apr\xE8s l'ajout et la destruction d'un handout) - // Du coup, alliesParPerso est toujours \xE0 jour + // Appelé uniquement après le "ready" et lorsqu'on modifie un handout (fonctionne après l'ajout et la destruction d'un handout) + // Du coup, alliesParPerso est toujours à jour function changeHandout(hand, prev) { if (prev && prev.name && prev.name.startsWith("Equipe ")) { const handouts = findObjs({ @@ -25772,7 +25878,7 @@ var COFantasy = COFantasy || function() { } } - //pour se d\xE9barasser des balises html + //pour se débarasser des balises html // et avoir un tableau de lignes function linesOfNote(note) { note = note.trim(); @@ -25797,7 +25903,7 @@ var COFantasy = COFantasy || function() { return c.get('name').trim() == name; }); if (charsWithName.length === 0) { - log(name + " dans l'\xE9quipe " + nomEquipe + " est inconnu"); + log(name + " dans l'équipe " + nomEquipe + " est inconnu"); return; } if (charsWithName.length > 1) { @@ -25806,7 +25912,7 @@ var COFantasy = COFantasy || function() { }); if (nonArch.length > 0) charsWithName = nonArch; if (charsWithName.length > 1) { - log(name + " dans l'\xE9quipe " + nomEquipe + " est en double"); + log(name + " dans l'équipe " + nomEquipe + " est en double"); } } charsWithName.forEach(function(character) { @@ -25834,7 +25940,7 @@ var COFantasy = COFantasy || function() { //On ajoute les familiers }); }); //end hand.get('notes') - } else if (handName == 'Comp\xE9tences' || handName == 'Competences') { + } else if (handName == 'Compétences' || handName == 'Competences') { listeCompetences = { FOR: { list: [], @@ -25863,23 +25969,23 @@ var COFantasy = COFantasy || function() { nombre: 0 }; hand.get('notes', function(note) { // asynchronous - var carac; //La carac dont on sp\xE9cifie les comp\xE9tences actuellement - var lignes = linesOfNote(note); + let carac; //La carac dont on spécifie les compétences actuellement + let lignes = linesOfNote(note); lignes.forEach(function(ligne) { ligne = ligne.trim(); - var header = ligne.split(':'); + let header = ligne.split(':'); if (header.length > 1) { - var c = header.shift().trim().toUpperCase(); + let c = header.shift().trim().toUpperCase(); if (!isCarac(c)) return; carac = c; ligne = header.join(':').trim(); } if (ligne.length === 0) return; if (carac === undefined) { - error("Comp\xE9tences sans caract\xE9ristique associ\xE9e", note); + error("Compétences sans caractéristique associée", note); return; } - var comps = ligne.split(/, |\/| /); + let comps = ligne.split(/, |\/| /); comps.forEach(function(comp) { if (comp.length === 0) return; comp = comp.replace(/_/g, ' '); @@ -25912,7 +26018,7 @@ var COFantasy = COFantasy || function() { } //options peut contenir: - // - ligneOptions : une cha\xEEne de caract\xE8res \xE0 ajouter aux attaques + // - ligneOptions : une chaîne de caractères à ajouter aux attaques // - target : l'id de la cible des attaques // - nePasAfficherArmes : quand on affiche plus tard l'arme en main function listeAttaquesVisibles(perso, options) { @@ -25920,7 +26026,7 @@ var COFantasy = COFantasy || function() { let ligneOptions = options.ligneOptions || ''; let target = options.target || '@{target|token_id}'; let ligne = ''; - //Cherche toutes les attaques \xE0 afficher + //Cherche toutes les attaques à afficher let attaques = listAllAttacks(perso); let attaquesTriees = []; let attaquesNonTriees = {}; @@ -25928,7 +26034,7 @@ var COFantasy = COFantasy || function() { let att = attaques[attLabel]; if (fieldAsInt(att, 'armeactionvisible', 1) === 0) continue; if (options.nePasAfficherArmes && estArme(att)) continue; - //V\xE9rification que des options n'emp\xEAchent pas l'utilisation de l'attaque + //Vérification que des options n'empêchent pas l'utilisation de l'attaque let attackOptions = ' ' + fieldAsString(att, 'armeoptions', ''); if (actionImpossible(perso, attackOptions.split(' --'), attLabel)) continue; //On regarde aussi si c'est une arme de jet @@ -25947,14 +26053,14 @@ var COFantasy = COFantasy || function() { for (let label in attaquesNonTriees) { ligne += attaquesNonTriees[label] + '
'; } - //On ajoute aussi les lancers de feu gr\xE9geois, si il y en a - let attrFeuxGregeois = tokenAttribute(perso, 'elixir_feu_gr\xE9geois'); + //On ajoute aussi les lancers de feu grégeois, si il y en a + let attrFeuxGregeois = tokenAttribute(perso, 'elixir_feu_grégeois'); if (attrFeuxGregeois.length > 0) { attrFeuxGregeois = attrFeuxGregeois[0]; let feuxGregeois = parseInt(attrFeuxGregeois.get('current')); if (feuxGregeois > 0) { let command = attrFeuxGregeois.get('max').trim(); - ligne += bouton(command, 'Feu gr\xE9geois', perso, { + ligne += bouton(command, 'Feu grégeois', perso, { ressource: attrFeuxGregeois }); ligne += " (reste " + feuxGregeois + ")
"; @@ -26017,13 +26123,13 @@ var COFantasy = COFantasy || function() { return res; } - //Si listActions est fourni, \xE7a peut faire r\xE9f\xE9rence \xE0 une ability + //Si listActions est fourni, ça peut faire référence à une ability //dont le nom commence et termine par #, contenant une liste d'actions - //\xE0 afficher - //sinon, fait r\xE9f\xE9rence \xE0 une des listes d'action de la fiche + //à afficher + //sinon, fait référence à une des listes d'action de la fiche function turnAction(perso, playerId, listActions) { const pageId = perso.token.get('pageid'); - // Toutes les Abilities du personnage li\xE9 au Token + // Toutes les Abilities du personnage lié au Token const abilities = findObjs({ _type: 'ability', _characterid: perso.charId, @@ -26050,7 +26156,7 @@ var COFantasy = COFantasy || function() { if (actionsDuTour === 0) { if (!isActive(perso)) { if (!getState(perso, 'surpris') || !compagnonPresent(perso, 'surveillance')) { - sendPerso(perso, "ne peut pas agir \xE0 ce tour"); + sendPerso(perso, "ne peut pas agir à ce tour"); return true; } } @@ -26066,23 +26172,24 @@ var COFantasy = COFantasy || function() { } } } - //actionDuTour peut \xEAtre undefined, pour la liste par d\xE9faut + //actionDuTour peut être undefined, pour la liste par défaut let actionsAAfficher; let ligne = ''; let command = ''; if (actionsParDefaut && !stateCOF.chargeFantastique && attributeAsBool(perso, 'hate')) { - ligne += "Effet de h\xE2te : une action d'attaque ou de mouvement en plus
"; + ligne += "Effet de hâte : une action d'attaque ou de mouvement en plus
"; } if (actionsParDefaut && !stateCOF.chargeFantastique && attributeAsBool(perso, 'reactionViolente')) { - ligne += "Crise de folie : doit attaquer la personne qui l'a provoqu\xE9 et ceux qui l'en emp\xEAchent.
"; + ligne += "Crise de folie : doit attaquer la personne qui l'a provoqué et ceux qui l'en empêchent.
"; ligne += boutonSimple('!cof-fin-reaction-violente ' + perso.token.id, "Prendre sur soi"); } - //Les d\xE9g\xE2ts aux personnages envelopp\xE9s par perso + //Les dégâts aux personnages enveloppés par perso let attrs_enveloppe = tokenAttribute(perso, 'enveloppe'); attrs_enveloppe.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); if (cible === undefined) { - error("Attribut d'enveloppe mal form\xE9 ou obsol\xE8te", a.get('current')); + error("Attribut d'enveloppe mal formé ou obsolète", a.get('current')); + a.remove(); return; } let enveloppeDM = a.get('max'); @@ -26095,21 +26202,37 @@ var COFantasy = COFantasy || function() { command = abEnveloppe.get('action').trim(); command = replaceAction(command, perso); command = command.replace(new RegExp(escapeRegExp('@{target|token_id}'), 'g'), cible.token.id); - ligne += bouton(command, "Infliger DMS \xE0 " + nomPerso(cible), perso) + '
'; + ligne += bouton(command, "Infliger DMS à " + nomPerso(cible), perso) + '
'; } } else if (enveloppeDM.startsWith('label ')) { actionsAAfficher = true; command = '!cof-attack ' + perso.token.id + ' ' + cible.token.id + ' ' + enveloppeDM.substring(6) + ' --auto --acide --effet paralyseTemp [[2d6]] --save CON 15'; - ligne += bouton(command, "Infliger DMs \xE0 " + nomPerso(cible), perso) + '
'; + ligne += bouton(command, "Infliger DMs à " + nomPerso(cible), perso) + '
'; } else if (enveloppeDM.startsWith('etreinte ')) { actionsAAfficher = true; enveloppeDM = enveloppeDM.substring(9); - command = '!cof-attack ' + perso.token.id + ' ' + cible.token.id + ' --dm ' + enveloppeDM + ' --auto --nom \xE9treinte '; - ligne += bouton(command, "Infliger DMs \xE0 " + nomPerso(cible), perso) + '
'; + command = '!cof-attack ' + perso.token.id + ' ' + cible.token.id + ' --dm ' + enveloppeDM + ' --auto --nom étreinte '; + ligne += bouton(command, "Infliger DMs à " + nomPerso(cible), perso) + '
'; } //else pas reconnu - //On ajoute aussi un bouton pour lib\xE9rer + //On ajoute aussi un bouton pour libérer command = '!cof-echapper-enveloppement libere --target ' + cible.token.id; - ligne += boutonSimple(command, "Lib\xE9rer " + nomPerso(cible)) + '
'; + ligne += boutonSimple(command, "Libérer " + nomPerso(cible)) + '
'; + }); + //Bouton pour libérer une personne qu'on agrippe + let attrs_agrippe = tokenAttribute(perso, 'agrippe'); + attrs_agrippe = + attrs_agrippe.concat( + tokenAttribute(perso, 'etreinteImmole'), + tokenAttribute(perso, 'etreinteScorpionSur'), + tokenAttribute(perso, 'devore')); + attrs_agrippe.forEach(function(a) { + let cible = persoOfIdName(a.get('current'), pageId); + if (cible === undefined) { + a.remove(); + return; + } + command = '!cof-liberer-agrippe ' + cible.token.id + ' libere'; + ligne += boutonSimple(command, "Libérer " + nomPerso(cible)) + '
'; }); let gobePar; let attrGobePar = tokenAttribute(perso, 'estGobePar'); @@ -26122,18 +26245,18 @@ var COFantasy = COFantasy || function() { if (!gobePar && attributeAsBool(perso, 'enveloppePar')) { actionsAAfficher = true; command = '!cof-echapper-enveloppement --target ' + perso.token.id; - ligne += boutonSimple(command, 'Se lib\xE9rer') + '
'; + ligne += boutonSimple(command, 'Se libérer') + '
'; } else if (getState(perso, 'enseveli')) { actionsAAfficher = true; ligne += boutonSaveState(perso, 'enseveli') + '
'; } else if (!gobePar && attributeAsBool(perso, 'etreinteScorpionPar')) { actionsAAfficher = true; command = '!cof-liberer-agrippe ' + perso.token.id; - ligne += boutonSimple(command, 'Se lib\xE9rer') + "de l'\xE9treinte du scorpion
"; + ligne += boutonSimple(command, 'Se libérer') + "de l'étreinte du scorpion
"; } else if (!gobePar && attributeAsBool(perso, 'estEcrasePar')) { actionsAAfficher = true; command = '!cof-liberer-ecrase ' + perso.token.id; - ligne += boutonSimple(command, 'Se lib\xE9rer') + "de l'\xE9treinte
"; + ligne += boutonSimple(command, 'Se libérer') + "de l'étreinte
"; } else { //On affiche les actions normales if (stateCOF.combat && stateCOF.combat.armeesDesMorts && !gobePar) { let combattreArmee = false; @@ -26141,7 +26264,7 @@ var COFantasy = COFantasy || function() { if (aid == perso.token.id) continue; let persoArmee = stateCOF.combat.armeesDesMorts[aid]; if (!persoArmee || !persoArmee.token) { - error("Erreur dans l'arm\xE9e des morts", stateCOF.combat.armeesDesMorts); + error("Erreur dans l'armée des morts", stateCOF.combat.armeesDesMorts); delete stateCOF.combat.armeesDesMorts[aid]; continue; } @@ -26163,12 +26286,12 @@ var COFantasy = COFantasy || function() { if (!gobePar && (attributeAsBool(perso, 'estAgrippePar') || attributeAsBool(perso, 'estDevorePar'))) { actionsAAfficher = true; command = '!cof-liberer-agrippe ' + perso.token.id; - ligne += bouton(command, 'Se lib\xE9rer', perso) + '(action de mvt)
'; + ligne += bouton(command, 'Se libérer', perso) + '(action de mvt)
'; } if (!gobePar && attributeAsBool(perso, 'etreinteImmolePar')) { actionsAAfficher = true; command = '!cof-liberer-agrippe ' + perso.token.id; - ligne += bouton(command, 'Se lib\xE9rer', perso) + ' (action limit\xE9e)
'; + ligne += bouton(command, 'Se libérer', perso) + ' (action limitée)
'; } //Actions pour les saves actifs let attrs = findObjs({ @@ -26207,7 +26330,7 @@ var COFantasy = COFantasy || function() { let cible = persoOfIdName(a.get('current')); if (cible) { let commande = "!cof-attack " + perso.token.id + ' ' + cible.token.id + ' ' + ecraser; - ligne += boutonSimple(commande, '\xC9craser') + ' ' + nomPerso(cible) + '
'; + ligne += boutonSimple(commande, 'Écraser') + ' ' + nomPerso(cible) + '
'; } else { a.remove(); } @@ -26236,7 +26359,7 @@ var COFantasy = COFantasy || function() { c = command + " Morsure --toucher " + atk + " --dm 1d6+" + force; ligne += bouton(c, 'Morsure', perso) + '
'; } - //On cherche si il y a une arm\xE9e conjur\xE9e \xE0 attaquer + //On cherche si il y a une armée conjurée à attaquer let attrs_armee = findObjs({ _type: 'attribute', @@ -26271,42 +26394,42 @@ var COFantasy = COFantasy || function() { if (allies.has(perso.charId)) return; allTokens.forEach(function(t) { if (t.get('represents') == aacid) { - //teste si dans un carr\xE9 de 20 m de cot\xE9 autour de l'arm\xE9e. + //teste si dans un carré de 20 m de coté autour de l'armée. let tx = t.get('left'); let ty = t.get('top'); if (tx < pxp && tx > pxm && ty < pyp && ty > pym) { command = '!cof-attack ' + perso.token.id + ' ' + t.id + - " Attaque de l'arm\xE9e --dm " + + " Attaque de l'armée --dm " + (ficheAttributeAsInt(perso, 'niveau', 1) + 1) + " --auto --attaqueArmeeConjuree --allonge 20"; - ligne += bouton(command, "Attaque de l'arm\xE9e", perso) + '
'; + ligne += bouton(command, "Attaque de l'armée", perso) + '
'; } } }); }); } - //Les soins pour les \xE9l\xE9mentaires + //Les soins pour les élémentaires if (predicateAsBool(perso, 'corpsElementaire')) { command = '!cof-soin 5'; - ligne += bouton(command, "R\xE9g\xE9n\xE9ration", perso) + " si source \xE9l\xE9mentaire proche
"; + ligne += bouton(command, "Régénération", perso) + " si source élémentaire proche
"; } - //Regard p\xE9trifiant + //Regard pétrifiant let regardPetrifiant = predicateAsInt(perso, 'regardPetrifiant', 0, 16); if (regardPetrifiant) { let c = '!cof-effet petrifie --lanceur ' + perso.token.id + ' --target @{target|token_id} --regard --save CON '; - ligne += boutonSimple(c + (regardPetrifiant - 4), "Regard p\xE9trifiant") + + ligne += boutonSimple(c + (regardPetrifiant - 4), "Regard pétrifiant") + boutonSimple(c + regardPetrifiant, "(inconscient)") + '
'; } - //Violence cibl\xE9e + //Violence ciblée if (predicateAsBool(perso, 'violenceCiblee') && !attributeAsBool(perso, 'reactionViolente')) { let pointsDeViolence = attributeAsInt(perso, 'pointsDeViolence', 0); if (pointsDeViolence > 0) { let attr = tokenAttribute(perso, 'pointsDeViolence')[0]; command = "!cof-effet-temp reactionViolente [[1d4]] --decrAttribute " + attr.id + " --target " + perso.token.id; - ligne += boutonSimple(command, 'Violence cibl\xE9e') + '
'; + ligne += boutonSimple(command, 'Violence ciblée') + '
'; } } - //Les attaques de la fiche \xE0 afficher dans la liste d'actions + //Les attaques de la fiche à afficher dans la liste d'actions const montrerAttaques = ficheAttributeAsInt(perso, 'montrerattaques', 1); const afficherAttaquesFiche = actionsParDefaut || @@ -26319,7 +26442,7 @@ var COFantasy = COFantasy || function() { attackOptions.nePasAfficherArmes = true; ligne += listeAttaquesVisibles(perso, attackOptions); } - //L'arme en main et d\xE9gainer, si besoin + //L'arme en main et dégainer, si besoin if (montrerArmeEnMain && armesAutorisees) { let { listeAttaques, @@ -26350,7 +26473,7 @@ var COFantasy = COFantasy || function() { else nomCommande += ' (1M)'; } if (attributeAsBool(perso, 'paradeCroisee')) { - //On conna\xEEtra vraiment l'arme au moment de faire l'attaque + //On connaîtra vraiment l'arme au moment de faire l'attaque command += '-1'; if (labelArmeGauche && listeAttaques[labelArmeGauche]) { @@ -26372,11 +26495,11 @@ var COFantasy = COFantasy || function() { if (perso.armeGauche) { ligneArmeGauche = bouton("!cof-attack @{selected|token_id} @{target|token_id} " + labelArmeGauche, perso.armeGauche.name, perso); } - //Maintenant on propose de d\xE9gainer + //Maintenant on propose de dégainer if (armeVisible) { let degainer = "!cof-degainer ?{Arme?|"; let armeADegainer; - //Prise en compte des pr\xE9dicats pour ce qu'on veut voir en premier + //Prise en compte des prédicats pour ce qu'on veut voir en premier let i = 1; let labelsVus = new Set(); while (true) { @@ -26390,12 +26513,12 @@ var COFantasy = COFantasy || function() { if (label == labelArmePrincipale || labelGauche == labelArmeGauche) continue; let arme = armes[label]; if (arme === undefined) { - error("Impossible de trouver l'arme de label " + label + " mentionn\xE9e dans le pr\xE9dicat actionDegainer" + (i - 1), armes); + error("Impossible de trouver l'arme de label " + label + " mentionnée dans le prédicat actionDegainer" + (i - 1), armes); continue; } let armeGauche = armes[labelGauche]; if (armeGauche === undefined) { - error("Impossible de trouver l'arme de label " + labelGauche + " mentionn\xE9e dans le pr\xE9dicat actionDegainer" + (i - 1), armes); + error("Impossible de trouver l'arme de label " + labelGauche + " mentionnée dans le prédicat actionDegainer" + (i - 1), armes); continue; } degainer += arme.armenom + " et " + armeGauche.armenom + "," + label + ' ' + labelGauche + "|"; @@ -26409,7 +26532,7 @@ var COFantasy = COFantasy || function() { if (labels == labelArmePrincipale || labels == labelArmeGauche) continue; let arme = armes[labels]; if (arme === undefined) { - error("Impossible de trouver l'arme de label " + labels + " mentionn\xE9e dans le pr\xE9dicat actionDegainer" + (i - 1), armes); + error("Impossible de trouver l'arme de label " + labels + " mentionnée dans le prédicat actionDegainer" + (i - 1), armes); continue; } labelsVus.add(labels); @@ -26461,7 +26584,7 @@ var COFantasy = COFantasy || function() { else degainer += "son arme"; degainer += ",&#32;}"; } else if (armeADegainer.unique) { - //Dans ce cas, pas de choix, juste une arme \xE0 d\xE9gainer + //Dans ce cas, pas de choix, juste une arme à dégainer degainer = '!cof-degainer ' + armeADegainer.label; } else { degainer = degainer.substr(0, degainer.length - 1) + '}'; @@ -26470,7 +26593,7 @@ var COFantasy = COFantasy || function() { if (ligneArmePrincipale) ligneArmePrincipale += bouton(degainer, ';', perso); else - ligneArmePrincipale = bouton(degainer, 'D\xE9gainer', perso); + ligneArmePrincipale = bouton(degainer, 'Dégainer', perso); if (armeADegainer.unique && !labelArmePrincipale && !labelArmeGauche) ligneArmePrincipale += armeADegainer.nom; } else { @@ -26497,22 +26620,22 @@ var COFantasy = COFantasy || function() { ligne += bouton(command, 'Second souffle', perso) + '
'; } } - //Changement de phase pour intangibilit\xE9 avec changement de phase + //Changement de phase pour intangibilité avec changement de phase if (attributeAsBool(perso, 'intangiblePuissant')) { if (attributeAsInt(perso, 'intangibleValeur', 1)) { command = "!cof-set-attribute intangibleValeur 0 --target " + perso.token.id + " --message redevient tangible"; ligne += boutonSimple(command, "Redevenir tangible") + '
'; } else { - command = "!cof-set-attribute intangibleValeur 1 --target " + perso.token.id + " --message devient l\xE9g\xE8rement translucide"; + command = "!cof-set-attribute intangibleValeur 1 --target " + perso.token.id + " --message devient légèrement translucide"; ligne += boutonSimple(command, "Redevenir intangible") + '
'; } } if (attributeAsBool(perso, 'intangibleInvisiblePuissant')) { if (attributeAsInt(perso, 'intangibleInvisibleValeur', 1)) { - command = "!cof-set-attribute intangibleInvisibleValeur 0 --etat invisible false --target " + perso.token.id + " --message r\xE9appara\xEEt"; + command = "!cof-set-attribute intangibleInvisibleValeur 0 --etat invisible false --target " + perso.token.id + " --message réapparaît"; ligne += boutonSimple(command, "Redevenir tangible") + '
'; } else { - command = "!cof-set-attribute intangibleInvisibleValeur 1 --etat invisible true --target " + perso.token.id + " --message dispara\xEEt"; + command = "!cof-set-attribute intangibleInvisibleValeur 1 --etat invisible true --target " + perso.token.id + " --message disparaît"; ligne += boutonSimple(command, "Redevenir intangible") + '
'; } } @@ -26540,7 +26663,7 @@ var COFantasy = COFantasy || function() { if (caracDM > 0) command += '+' + caracDM; else if (caracDM < 0) command += caracDM; command += "--energie --magique --limiteParTour 1 runeIsulys --effet affaibli 1"; - ligne += bouton(command, "Rayon d'\xE9nergie", perso) + '
'; + ligne += bouton(command, "Rayon d'énergie", perso) + '
'; } command = "!cof-gerer-runes-mortes " + perso.token.id; ligne += boutonSimple(command, "Gestion des runes mortes") + '
'; @@ -26550,8 +26673,8 @@ var COFantasy = COFantasy || function() { command = "!cof-attendre ?{Nouvelle initiative}"; ligne += bouton(command, 'Attendre', perso) + '
'; if (!gobePar && !charAttributeAsBool(perso, 'armeeConjuree')) { - command = "!cof-action-defensive ?{Action d\xE9fensive|simple|totale}"; - ligne += bouton(command, 'Se d\xE9fendre', perso) + '
'; + command = "!cof-action-defensive ?{Action défensive|simple|totale}"; + ligne += bouton(command, 'Se défendre', perso) + '
'; let manoeuvreDuelliste = predicateAsBool(perso, 'manoeuvreDuelliste'); if (manoeuvreDuelliste) { command = "!cof-manoeuvre @{selected|token_id} @{target|token_id} ?{Manoeuvre?|bloquer|desarmer|renverser|tenirADistance|repousser}"; @@ -26577,9 +26700,9 @@ var COFantasy = COFantasy || function() { } } if (actionsAAfficher) { - // on envoie la liste aux joueurs qui g\xE8rent le personnage dont le token est li\xE9 + // on envoie la liste aux joueurs qui gèrent le personnage dont le token est lié let lastPlayerid; - // on r\xE9cup\xE8re les players_ids qui controllent le Token + // on récupère les players_ids qui controllent le Token let playerIds; if (playerId) playerIds = [playerId]; else playerIds = getPlayerIds(perso); @@ -26587,7 +26710,7 @@ var COFantasy = COFantasy || function() { lastPlayerid = playerid; let display = startFramedDisplay(playerid, title, perso, opt_display); addLineToFramedDisplay(display, ligne); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); // En prime, on l'envoie au MJ, si besoin let envoieAuMJ = playerIds.length === 0; @@ -26598,9 +26721,9 @@ var COFantasy = COFantasy || function() { } if (envoieAuMJ) { opt_display.chuchote = 'gm'; - var display = startFramedDisplay(lastPlayerid, title, perso, opt_display); + const display = startFramedDisplay(lastPlayerid, title, perso, opt_display); addLineToFramedDisplay(display, ligne); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } return actionsAAfficher; @@ -26620,7 +26743,7 @@ var COFantasy = COFantasy || function() { let actions = turnAction(perso, playerId, liste); if (!actions) { let l = liste || ''; - sendPerso(perso, "n'a pas de liste d'actions " + l + " d\xE9finie"); + sendPerso(perso, "n'a pas de liste d'actions " + l + " définie"); } }); }); @@ -26709,7 +26832,7 @@ var COFantasy = COFantasy || function() { return res; } - //ne rajoute pas evt \xE0 l'historique + //ne rajoute pas evt à l'historique function setTurnOrder(to, evt) { if (to.pasAgi.length > 0) { to.pasAgi.sort(function(a, b) { @@ -26717,8 +26840,8 @@ var COFantasy = COFantasy || function() { if (b.id == "-1") return -1; if (a.pr < b.pr) return 1; if (b.pr < a.pr) return -1; - // Priorit\xE9 aux joueurs - // Premier crit\xE8re : la barre de PV des joueurs est li\xE9e + // Priorité aux joueurs + // Premier critère : la barre de PV des joueurs est liée let tokenA = getObj('graphic', a.id); if (tokenA === undefined) return 1; let tokenB = getObj('graphic', b.id); @@ -26728,7 +26851,7 @@ var COFantasy = COFantasy || function() { return 1; } if (tokenB.get('bar1_link') === '') return -1; - // Deuxi\xE8me crit\xE8re : les joueurs ont un DV + // Deuxième critère : les joueurs ont un DV let charIdA = tokenA.get('represents'); if (charIdA === '') return 1; let charIdB = tokenB.get('represents'); @@ -26748,7 +26871,7 @@ var COFantasy = COFantasy || function() { return 1; } if (dvB === 0) return -1; - //Entre joueurs, priorit\xE9 \xE0 la plus grosse sagesse + //Entre joueurs, priorité à la plus grosse sagesse let sagA = caracCourante(persoA, 'sagesse'); let sagB = caracCourante(persoB, 'sagesse'); if (sagA < sagB) return 1; @@ -26770,17 +26893,17 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected) { if (selected === undefined || selected.length === 0) { - error("La fonction !cof-attendre : rien \xE0 faire, pas de token selectionn\xE9", msg); + error("La fonction !cof-attendre : rien à faire, pas de token selectionné", msg); return; } let cmd = msg.content.split(' '); if (cmd.length < 2) { - error("Attendre jusqu'\xE0 quelle initiative ?", cmd); + error("Attendre jusqu'à quelle initiative ?", cmd); return; } let newInit = parseInt(cmd[1]); if (isNaN(newInit) || newInit < 1) { - error("On ne peut attendre que jusqu'\xE0 une initiative de 1", cmd); + error("On ne peut attendre que jusqu'à une initiative de 1", cmd); newInit = 1; } let evt = { @@ -26795,7 +26918,7 @@ var COFantasy = COFantasy || function() { return (elt.id == token.id); }); if (tokenPos == -1) { // token ne peut plus agir - sendPerso(perso, " a d\xE9j\xE0 agit ce tour"); + sendPerso(perso, " a déjà agit ce tour"); return; } if (newInit < to.pasAgi[tokenPos].pr) { @@ -26803,7 +26926,7 @@ var COFantasy = COFantasy || function() { sendPerso(perso, " attend un peu avant d'agir..."); updateNextInit(perso); } else { - sendPerso(perso, " a d\xE9j\xE0 une initiative inf\xE9rieure \xE0 " + newInit); + sendPerso(perso, " a déjà une initiative inférieure à " + newInit); } }); setTurnOrder(to, evt); @@ -26811,22 +26934,22 @@ var COFantasy = COFantasy || function() { }); } - // Affiche des informations sur le personnage s\xE9lectionn\xE9 + // Affiche des informations sur le personnage sélectionné function statut(msg) { getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Dans !cof-statut : rien \xE0 faire, pas de token selectionn\xE9", msg); + error("Dans !cof-statut : rien à faire, pas de token selectionné", msg); return; } iterSelected(selected, function(perso) { - //Au cas o\xF9 + //Au cas où unlockToken(perso); const token = perso.token; const charId = perso.charId; const name = nomPerso(perso); let lie = true; if (token.get('bar1_link') === '') lie = false; - const display = startFramedDisplay(playerId, "\xC9tat de " + name, perso, { + const display = startFramedDisplay(playerId, "État de " + name, perso, { chuchote: true }); const estPNJ = persoEstPNJ(perso); @@ -26846,7 +26969,7 @@ var COFantasy = COFantasy || function() { hasMana = !isNaN(manaMax) && manaMax > 0; } let dmTemp = parseInt(token.get('bar2_value')); - if (hasMana) { //ne peut pas \xEAtre un PNJ + if (hasMana) { //ne peut pas être un PNJ if (lie) { dmTemp = ficheAttributeAsInt(perso, 'DMTEMP', 0); } else { @@ -26865,7 +26988,7 @@ var COFantasy = COFantasy || function() { } let douleurIgnoree = attributeAsInt(perso, 'douleurIgnoree', 0); if (douleurIgnoree > 0) { - line = "a ignor\xE9 " + douleurIgnoree + " pv dans ce combat."; + line = "a ignoré " + douleurIgnoree + " pv dans ce combat."; addLineToFramedDisplay(display, line); } let aDV = ficheAttributeAsInt(perso, 'DV', 0); @@ -26873,7 +26996,7 @@ var COFantasy = COFantasy || function() { let pr = pointsDeRecuperation(perso); if (pr) { line = - "Points de r\xE9cup\xE9ration : " + pr.current + " / " + pr.max; + "Points de récupération : " + pr.current + " / " + pr.max; addLineToFramedDisplay(display, line); } if (ficheAttributeAsInt(perso, 'option_pc', 1)) { @@ -26919,7 +27042,7 @@ var COFantasy = COFantasy || function() { if (att.armespec && predicateOfRaw(att.armespec).charge) { let charge = attributeAsInt(perso, 'charge_' + armeLabel, 0); if (charge === 0) { - line = nomArme + " n'est pas charg\xE9"; + line = nomArme + " n'est pas chargé"; } else { let na = fullAttributeName(perso, 'chargeGrenaille_' + armeLabel); let grenaille = attrsChar.find(function(a) { @@ -26930,7 +27053,7 @@ var COFantasy = COFantasy || function() { if (isNaN(grenaille) || grenaille < 0) grenaille = 0; } else grenaille = 0; if (charge == 1) { - line = nomArme + " est charg\xE9"; + line = nomArme + " est chargé"; if (grenaille) line += " de grenaille"; } else if (charge > 1) { line = nomArme + " contient encore " + charge + " charges"; @@ -26945,7 +27068,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, line); } else if (armeEnMain == armeLabel) { if (armeEnMainGauche == armeLabel) { - addLineToFramedDisplay(display, "tient " + nomArme + " \xE0 2 mains."); + addLineToFramedDisplay(display, "tient " + nomArme + " à 2 mains."); } else { addLineToFramedDisplay(display, "tient " + nomArme + " en main."); } @@ -26963,8 +27086,8 @@ var COFantasy = COFantasy || function() { if (attrEnveloppe.length > 0) { let cube = persoOfIdName(attrEnveloppe[0].get('current')); if (cube) { - let actE = "est envelopp\xE9 dans "; - if ((attrEnveloppe[0].get('max') + '').startsWith('etreinte')) actE = "est prisonnier de l'\xE9treinte de "; + let actE = "est enveloppé dans "; + if ((attrEnveloppe[0].get('max') + '').startsWith('etreinte')) actE = "est prisonnier de l'étreinte de "; addLineToFramedDisplay(display, actE + cube.tokName); } } @@ -26975,7 +27098,7 @@ var COFantasy = COFantasy || function() { let defenseMontree; let bufDef = attributeAsInt(perso, 'bufDEF', 0); if (bufDef > 0) { - addLineToFramedDisplay(display, "D\xE9fense temporairement modifi\xE9e de " + bufDef + " (DEF " + defense + ")"); + addLineToFramedDisplay(display, "Défense temporairement modifiée de " + bufDef + " (DEF " + defense + ")"); defenseMontree = true; } for (let etat in cof_states) { @@ -26995,22 +27118,22 @@ var COFantasy = COFantasy || function() { let possedeArmure = ficheAttributeAsInt(perso, 'defarmure', 0) > 0; if (possedeArmure) addLineToFramedDisplay(display, "Ne porte pas son armure"); if (predicateAsInt(perso, 'vetementsSacres', 0) > 0) { - if (possedeArmure) addLineToFramedDisplay(display, " mais b\xE9n\xE9ficie de ses v\xEAtements sacr\xE9s (DEF " + defense + ")"); - else addLineToFramedDisplay(display, "porte des v\xEAtements sacr\xE9s (DEF " + defense + ")"); + if (possedeArmure) addLineToFramedDisplay(display, " mais bénéficie de ses vêtements sacrés (DEF " + defense + ")"); + else addLineToFramedDisplay(display, "porte des vêtements sacrés (DEF " + defense + ")"); defenseMontree = true; } if (predicateAsInt(perso, 'armureDeVent', 0) > 0) { - if (possedeArmure) addLineToFramedDisplay(display, " mais b\xE9n\xE9ficie de son armure de vent (DEF " + defense + ")"); - else addLineToFramedDisplay(display, "b\xE9n\xE9ficie de son armure de vent (DEF " + defense + ")"); + if (possedeArmure) addLineToFramedDisplay(display, " mais bénéficie de son armure de vent (DEF " + defense + ")"); + else addLineToFramedDisplay(display, "bénéficie de son armure de vent (DEF " + defense + ")"); defenseMontree = true; } } if (ficheAttributeAsInt(perso, 'defbouclieron', 0) === 0 && - ficheAttributeAsInt(perso, 'defbouclier', 0)) + ficheAttributeAsBool(perso, 'defbouclier', false)) addLineToFramedDisplay(display, "Ne porte pas son bouclier"); if (ficheAttributeAsInt(perso, 'casque_rd', 0)) { if (ficheAttributeAsBool(perso, 'casque_on', false)) { - let b = boutonSimple('!cof-set-attribute casque_on false --message enl\xE8ve son casque --target ' + perso.token.id, "l'enlever"); + let b = boutonSimple('!cof-set-attribute casque_on false --message enlève son casque --target ' + perso.token.id, "l'enlever"); addLineToFramedDisplay(display, "Porte son casque :" + b); } else { let b = boutonSimple('!cof-set-attribute casque_on true --message met son casque --target ' + perso.token.id, "le mettre"); @@ -27042,7 +27165,7 @@ var COFantasy = COFantasy || function() { if (stateCOF.options.affichage.val.duree_effets.val || playerIsGM(playerId)) { let effetVal = attr.get('current'); if (parseInt(effetVal)) { - explEffetMsg += " (" + effetVal + " tour" + ((effetVal>1)?'s':'') + ")"; + explEffetMsg += " (" + effetVal + " tour" + ((effetVal > 1) ? 's' : '') + ")"; } else { explEffetMsg += " (tour final)"; } @@ -27067,7 +27190,7 @@ var COFantasy = COFantasy || function() { } let perteDeSubstance = parseInt(attr.get('current')); if (isNaN(perteDeSubstance) || perteDeSubstance < 1) { - error("Attribut de perte de substance mal form\xE9", attr); + error("Attribut de perte de substance mal formé", attr); return; } if (playerIsGM(playerId)) { @@ -27076,21 +27199,21 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, m); } if (perteDeSubstance < 3) { - addLineToFramedDisplay(display, "Dans le noir, on peut distinguer les lumi\xE8res vives au travers de son corps"); + addLineToFramedDisplay(display, "Dans le noir, on peut distinguer les lumières vives au travers de son corps"); } else if (perteDeSubstance < 5) { - addLineToFramedDisplay(display, "Le soleil diffuse \xE0 travers le corps \xE0 contre-jour"); + addLineToFramedDisplay(display, "Le soleil diffuse à travers le corps à contre-jour"); } else if (perteDeSubstance < 7) { - addLineToFramedDisplay(display, "On peut distinguer les objets \xE0 travers ses mains, et sa couleur s'estompe"); + addLineToFramedDisplay(display, "On peut distinguer les objets à travers ses mains, et sa couleur s'estompe"); } else if (perteDeSubstance < 10) { addLineToFramedDisplay(display, "Est translucide comme une eau sale"); } else if (perteDeSubstance < 15) { addLineToFramedDisplay(display, "Est aussi transparent que de l'eau et n'a plus faim ni soif"); } else { - addLineToFramedDisplay(display, "A perdu sa substance : impossible de tenir un objet et possibilit\xE9 de passer \xE0 travers des obstacles"); + addLineToFramedDisplay(display, "A perdu sa substance : impossible de tenir un objet et possibilité de passer à travers des obstacles"); } } }); - //ancienne version de munitions, obsol\xE8te depuis mars 2023 + //ancienne version de munitions, obsolète depuis mars 2023 allAttributesNamed(attrsChar, 'munition').forEach(function(attr) { let attrName = attr.get('name'); let underscore = attrName.indexOf('_'); @@ -27105,7 +27228,7 @@ var COFantasy = COFantasy || function() { let postureMsg = "a une posture "; switch (posture.substr(-3, 3)) { case 'DEF': - postureMsg += "d\xE9fensive"; + postureMsg += "défensive"; break; case 'ATT': postureMsg += "offensive"; @@ -27118,10 +27241,10 @@ var COFantasy = COFantasy || function() { postureMsg += " mais "; switch (posture.substr(0, 3)) { case 'DEF': - postureMsg += "risqu\xE9e"; + postureMsg += "risquée"; break; case 'ATT': - postureMsg += "moins pr\xE9cise"; + postureMsg += "moins précise"; break; case 'DM_': postureMsg += "moins puissante"; @@ -27132,7 +27255,7 @@ var COFantasy = COFantasy || function() { } let attaqueAOutrance = attributeAsInt(perso, 'attaqueAOutrance', 0); if (attaqueAOutrance) { - let attaqueAOutranceMsg = "attaque \xE0 outrance "; + let attaqueAOutranceMsg = "attaque à outrance "; switch (attaqueAOutrance) { case 2: attaqueAOutranceMsg += "(-2 DEF, +1D6 DM)"; @@ -27153,10 +27276,10 @@ var COFantasy = COFantasy || function() { if (soinsLegers < rangSoin) { soinsRestants = rangSoin - soinsLegers; if (soinsRestants > 1) soins = 's'; - msgSoins = "peut encore faire " + soinsRestants + " soin" + soins + " l\xE9ger" + soins; + msgSoins = "peut encore faire " + soinsRestants + " soin" + soins + " léger" + soins; addLineToFramedDisplay(display, msgSoins); } else { - addLineToFramedDisplay(display, "ne peut plus faire de soin l\xE9ger aujourd'hui"); + addLineToFramedDisplay(display, "ne peut plus faire de soin léger aujourd'hui"); } if (rangSoin > 1) { let soinsModeres = attributeAsInt(perso, 'soinsModeres', 0); @@ -27164,18 +27287,18 @@ var COFantasy = COFantasy || function() { soinsRestants = rangSoin - soinsModeres; if (soinsRestants > 1) soins = 's'; else soins = ''; - msgSoins = "peut encore faire " + soinsRestants + " soin" + soins + " mod\xE9r\xE9" + soins; + msgSoins = "peut encore faire " + soinsRestants + " soin" + soins + " modéré" + soins; addLineToFramedDisplay(display, msgSoins); } else { - addLineToFramedDisplay(display, "ne peut plus faire de soin mod\xE9r\xE9 aujourd'hui"); + addLineToFramedDisplay(display, "ne peut plus faire de soin modéré aujourd'hui"); } } if (rangSoin > 3) { - let soinsGuerison = attributeAsInt(perso, 'limiteParJour_gu\xE9rison', 1); + let soinsGuerison = attributeAsInt(perso, 'limiteParJour_guérison', 1); if (soinsGuerison > 0) { - addLineToFramedDisplay(display, "peut encore faire " + soinsGuerison + " gu\xE9rison" + (soinsGuerison > 1 ? 's' : '') + " aujourd'hui"); + addLineToFramedDisplay(display, "peut encore faire " + soinsGuerison + " guérison" + (soinsGuerison > 1 ? 's' : '') + " aujourd'hui"); } else { - addLineToFramedDisplay(display, "ne peut plus faire de gu\xE9rison aujourd'hui"); + addLineToFramedDisplay(display, "ne peut plus faire de guérison aujourd'hui"); } } } @@ -27185,7 +27308,7 @@ var COFantasy = COFantasy || function() { } let bonusCouvert = attributeAsInt(perso, 'bonusCouvert'); if (bonusCouvert) { - addLineToFramedDisplay(display, "est \xE0 couvert (+" + bonusCouvert + " DEF)"); + addLineToFramedDisplay(display, "est à couvert (+" + bonusCouvert + " DEF)"); } if (!defenseMontree) { let defenseAffichee = 10; @@ -27198,7 +27321,7 @@ var COFantasy = COFantasy || function() { defenseAffichee += modCarac(perso, 'dexterite'); } if (defense != defenseAffichee) - addLineToFramedDisplay(display, "D\xE9fense actuelle : " + defense); + addLineToFramedDisplay(display, "Défense actuelle : " + defense); } let predicatExpertDuCombat = predicateAsInt(perso, "expertDuCombat", 0); if (stateCOF.combat && predicatExpertDuCombat > 0) { @@ -27210,11 +27333,11 @@ var COFantasy = COFantasy || function() { else nbDesExpertDuCombat_tour_max = 1; let nbDesExpertDuCombat_tour = Math.min(nbDesExpertDuCombat_combat, attributeAsInt(perso, "limiteParTour_expertDuCombat", nbDesExpertDuCombat_tour_max)); - addLineToFramedDisplay(display, "D\xE9s d'expertise du combat :
" + + addLineToFramedDisplay(display, "Dés d'expertise du combat :
" + "Tour : " + nbDesExpertDuCombat_tour + "/" + nbDesExpertDuCombat_tour_max + "
" + "Combat : " + nbDesExpertDuCombat_combat + "/" + nbDesExpertDuCombat_combat_max + "
"); } - //Affaiblissements de caract\xE9ristiques + //Affaiblissements de caractéristiques allCaracs.forEach(function(carac) { let malus = attributeAsInt(perso, 'affaiblissementde' + carac, 0); if (malus > 0) { @@ -27223,7 +27346,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, ligne); } }); - //Violence cibl\xE9e + //Violence ciblée if (predicateAsBool(perso, 'violenceCiblee')) { let pointsDeViolence = attributeAsInt(perso, 'pointsDeViolence', 0); if (pointsDeViolence > 0) { @@ -27231,7 +27354,7 @@ var COFantasy = COFantasy || function() { } } if (attributeAsBool(perso, 'lumiere')) { - addLineToFramedDisplay(display, "\xE9claire ou fait de la lumi\xE8re"); + addLineToFramedDisplay(display, "éclaire ou fait de la lumière"); } let autresAttributs = predicatesNamed(perso, 'attributsDeStatut'); autresAttributs.forEach(function(attr) { @@ -27248,12 +27371,12 @@ var COFantasy = COFantasy || function() { }); }); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); //fin du iterSelected }); } - //retourne l'id du suivant si le token actuel \xE9tait en t\xEAte de liste + //retourne l'id du suivant si le token actuel était en tête de liste function removeFromTurnTracker(perso, evt) { removeDernieresCiblesAttaquees(perso, evt); let tokenId = perso.token.id; @@ -27337,14 +27460,14 @@ var COFantasy = COFantasy || function() { } if (buf === 0) return; let message = ""; - if (buf > 0) message = "voit sa d\xE9fense augmenter"; - else message = "voit sa d\xE9fense baisser"; + if (buf > 0) message = "voit sa défense augmenter"; + else message = "voit sa défense baisser"; let evt = { type: 'other' }; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof--buf-def", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof--buf-def", playerId); } iterSelected(selected, function(perso) { setTokenAttr(perso, 'bufDEF', buf, evt, { @@ -27353,7 +27476,7 @@ var COFantasy = COFantasy || function() { setToken(perso.token, 'status_blue', buf, evt); }); if (evt.attributes.length === 0) { - error("Pas de cible valide s\xE9lectionn\xE9e pour !cod-buf-def", msg); + error("Pas de cible valide sélectionnée pour !cod-buf-def", msg); return; } addEvent(evt); @@ -27366,11 +27489,11 @@ var COFantasy = COFantasy || function() { }; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof-remove-buf-def", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof-remove-buf-def", playerId); } iterSelected(selected, function(perso) { removeTokenAttr(perso, 'bufDEF', evt, { - msg: "retrouve sa d\xE9fense normale" + msg: "retrouve sa défense normale" }); setToken(perso.token, 'status_blue', false, evt); }); @@ -27437,16 +27560,18 @@ var COFantasy = COFantasy || function() { options.nature = true; return; case 'vampirise': - var vampirise = 100; - if (opt.length > 1) { - vampirise = parseInt(opt[1]); - if (isNaN(vampirise)) { - error("Il faut un pourcentage entier comme argument \xE0 --vampirise", opt); - vampirise = 100; + { + let vampirise = 100; + if (opt.length > 1) { + vampirise = parseInt(opt[1]); + if (isNaN(vampirise)) { + error("Il faut un pourcentage entier comme argument à --vampirise", opt); + vampirise = 100; + } } + options.vampirise = vampirise; + return; } - options.vampirise = vampirise; - return; case "ignoreRD": if (opt.length < 2) { options.ignoreTouteRD = true; @@ -27454,7 +27579,7 @@ var COFantasy = COFantasy || function() { } options.ignoreRD = parseInt(opt[1]); if (isNaN(options.ignoreRD) || options.ignoreRD < 1) { - log("Pas un nombre positif apr\xE8s --ignoreRD, interpr\xE9t\xE9 comme ignore toute la RD"); + log("Pas un nombre positif après --ignoreRD, interprété comme ignore toute la RD"); options.ignoreRD = undefined; options.ignoreTouteRD = true; } @@ -27462,7 +27587,7 @@ var COFantasy = COFantasy || function() { case 'attaquant': { if (opt.length < 2) { - error("Manque l'id de l'attaquant, option ignor\xE9e", optArgs); + error("Manque l'id de l'attaquant, option ignorée", optArgs); return; } const attaquant = persoOfId(opt[1]); @@ -27470,12 +27595,12 @@ var COFantasy = COFantasy || function() { options.attaquant = attaquant; return; } - error("Attaquant non trouv\xE9", opt); + error("Attaquant non trouvé", opt); return; } case 'titre': if (opt.length < 2) { - error("Il manque le message apr\xE8s --message", text); + error("Il manque le message après --message", text); return; } options.titre = opt.slice(1).join(' '); @@ -27490,13 +27615,13 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("cof-dmg prend les d\xE9gats en argument, avant les options", + error("cof-dmg prend les dégats en argument, avant les options", msg.content); return; } getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "pas de cible trouv\xE9e, action annul\xE9e", playerId); + sendPlayer(msg, "pas de cible trouvée, action annulée", playerId); return; } options.aoe = true; @@ -27507,7 +27632,7 @@ var COFantasy = COFantasy || function() { }); cibles = enleveDoublonsPartagePV(cibles); if (options.return) return; - //L'expression \xE0 lancer est tout ce qui est entre le premier blanc et le premier -- + //L'expression à lancer est tout ce qui est entre le premier blanc et le premier -- let debutDmgRollExpr = msg.content.indexOf(' ') + 1; let dmgRollExpr = msg.content.substring(debutDmgRollExpr); let finDmgRollExpr = msg.content.indexOf(' --'); @@ -27549,7 +27674,7 @@ var COFantasy = COFantasy || function() { addEvent(evt); } evt.action = { - titre: "D\xE9g\xE2ts", + titre: "Dégâts", playerId: playerId, playerName: playerName, cibles: cibles, @@ -27557,12 +27682,12 @@ var COFantasy = COFantasy || function() { options: options }; if (options.lanceur && limiteRessources(options.lanceur, options, 'dmg', 'dmg', evt)) return; - let action = "D\xE9g\xE2ts. "; + let action = "Dégâts. "; if (options.titre) action += options.titre + "
"; if (options.partialSave) { action += - " Jet de " + options.partialSave.carac + " difficult\xE9 " + options.partialSave.seuil + - " pour r\xE9duire les d\xE9g\xE2ts"; + " Jet de " + options.partialSave.carac + " difficulté " + options.partialSave.seuil + + " pour réduire les dégâts"; } let display = startFramedDisplay(playerId, action); let tokensToProcess = cibles.length; @@ -27570,9 +27695,9 @@ var COFantasy = COFantasy || function() { let finalDisplay = function() { if (tokensToProcess == 1) { if (someDmgDone) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else { - sendPlayer(playerName, "Aucune cible valide n'a \xE9t\xE9 s\xE9lection\xE9e"); + sendPlayer(playerName, "Aucune cible valide n'a été sélectionée"); } } tokensToProcess--; @@ -27585,7 +27710,7 @@ var COFantasy = COFantasy || function() { dmg.total = dmg.roll.inlinerolls[dmgRollNumber].results.total; dmg.display = buildinline(dmg.roll.inlinerolls[dmgRollNumber], dmg.type, options.magique); cibles.forEach(function(perso) { - if (getState(perso, 'mort')) { //pas de d\xE9g\xE2ts aux morts + if (getState(perso, 'mort')) { //pas de dégâts aux morts finalDisplay(); return; } @@ -27600,16 +27725,16 @@ var COFantasy = COFantasy || function() { dealDamage(perso, dmg, [], evt, false, options, explications, function(dmgDisplay, dmgFinal) { someDmgDone = true; addLineToFramedDisplay(display, - name + " re\xE7oit " + dmgDisplay + " DM"); + name + " reçoit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); finalDisplay(); }); }); //fin forEach - }); //fin du jet de d\xE9s + }); //fin du jet de dés } catch (rollError) { - error("Jet " + dmg.value + " mal form\xE9", dmg); + error("Jet " + dmg.value + " mal formé", dmg); } } @@ -27631,12 +27756,12 @@ var COFantasy = COFantasy || function() { if (valeur == 'false' || valeur == '0' || valeur == 'non' || valeur == 'no') valeur = false; if (valeur == 'true' || valeur == 'oui' || valeur == 'yes') valeur = true; if (!_.has(cof_states, etat)) { - error("Le premier argument de !cof-set-state n'est pas un \xE9tat valide", cmd); + error("Le premier argument de !cof-set-state n'est pas un état valide", cmd); return; } if (isCarac(cmd[2])) { if (cmd.length < 4) { - error("Il manque la difficult\xE9 du jet de sauvegarde.", cmd); + error("Il manque la difficulté du jet de sauvegarde.", cmd); return; } valeur = true; @@ -27649,7 +27774,7 @@ var COFantasy = COFantasy || function() { } else { options.saveActifParTour.difficulte = parseInt(cmd[3]); if (isNaN(options.saveActifParTour.difficulte)) { - error("Difficult\xE9 du jet de sauvegarde incorrecte", cmd); + error("Difficulté du jet de sauvegarde incorrecte", cmd); return; } } @@ -27657,12 +27782,12 @@ var COFantasy = COFantasy || function() { let cibles = []; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - error("Pas de cible pour le changement d'\xE9tat", msg); + error("Pas de cible pour le changement d'état", msg); return; } iterSelected(selected, function(perso) { if (options.seulementVivant && estNonVivant(perso)) { - sendPlayer(msg, "cet effet n'affecte que les cr\xE9atures vivantes", playerId); + sendPlayer(msg, "cet effet n'affecte que les créatures vivantes", playerId); return; } switch (etat) { @@ -27762,8 +27887,8 @@ var COFantasy = COFantasy || function() { }; if (options.save) { let saveOpts = { - msgPour: " pour r\xE9sister \xE0 l'effet " + stringOfEtat(etat), - msgRate: ", rat\xE9.", + msgPour: " pour résister à l'effet " + stringOfEtat(etat), + msgRate: ", raté.", rolls: options.rolls, chanceRollId: options.chanceRollId, type: options.type @@ -27786,7 +27911,7 @@ var COFantasy = COFantasy || function() { function textOfSaveState(etat, perso) { switch (etat) { case 'immobilise': - return "se lib\xE9rer"; + return "se libérer"; case 'aveugle': return "retrouver la vue"; case 'etourdi': @@ -27796,13 +27921,13 @@ var COFantasy = COFantasy || function() { case 'renverse': return "se relever"; case 'endormi': - return "se r\xE9veiller"; + return "se réveiller"; case 'apeure': return "retrouver du courage"; case 'enseveli': return "sortir de terre"; default: - return "ne plus \xEAtre " + stringOfEtat(etat, perso); + return "ne plus être " + stringOfEtat(etat, perso); } } @@ -27811,7 +27936,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 4 || !_.has(cof_states, cmd[1])) { - error("Param\xE8tres de !cof-save-state incorrects", cmd); + error("Paramètres de !cof-save-state incorrects", cmd); return; } let etat = cmd[1]; @@ -27822,17 +27947,17 @@ var COFantasy = COFantasy || function() { carac2 = carac.substring(3, 6); carac = carac.substring(0, 3); if (!isCarac(carac) || !isCarac(carac)) { - error("Param\xE8tres de !cof-save-state incorrects", cmd); + error("Paramètres de !cof-save-state incorrects", cmd); return; } } else { - error("Param\xE8tres de !cof-save-state incorrects", cmd); + error("Paramètres de !cof-save-state incorrects", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Pas de token s\xE9lectionn\xE9", msg.content); + error("Pas de token sélectionné", msg.content); return; } let pageId = options.pageId; @@ -27855,7 +27980,7 @@ var COFantasy = COFantasy || function() { } else { let seuil = parseInt(cmd[3]); if (isNaN(seuil)) { - error("La difficult\xE9 n'est pas un nombre", cmd); + error("La difficulté n'est pas un nombre", cmd); return; } iterSelected(selected, function(perso) { @@ -27904,7 +28029,7 @@ var COFantasy = COFantasy || function() { explications.forEach(function(e) { addLineToFramedDisplay(display, e); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); } else { let testId = 'saveState_' + carac + seuil; @@ -27933,13 +28058,13 @@ var COFantasy = COFantasy || function() { } //!cof-save-effet token_id attr_id - // o\xF9 attr_id est l'id de l'attribut de save + // où attr_id est l'id de l'attribut de save function parseSaveEffet(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 3) { - error("Param\xE8tres de !cof-save-effet incorrects", cmd); + error("Paramètres de !cof-save-effet incorrects", cmd); return; } let perso = persoOfId(cmd[1]); @@ -27957,7 +28082,7 @@ var COFantasy = COFantasy || function() { let effetC = attrName.substring(0, indexSave); let effetTemp = estEffetTemp(effetC); if (!effetTemp && !estEffetCombat(effetC)) { - error("Impossible de trouver l'effet correspondant \xE0 " + effetC, attrName); + error("Impossible de trouver l'effet correspondant à " + effetC, attrName); return; } attrName = effetC + attrName.substr(indexSave + 16); @@ -27967,19 +28092,19 @@ var COFantasy = COFantasy || function() { let msgPour = " pour "; if (met.msgSave) msgPour += met.msgSave; else { - msgPour += "ne plus \xEAtre sous l'effet de "; + msgPour += "ne plus être sous l'effet de "; if (effetC.startsWith('dotGen(')) msgPour += effetC.substring(7, effetC.indexOf(')')); else msgPour += effetC; } let carac = attr.get('current'); if (!isCarac(carac)) { - error("Save par tour " + attrName + " mal form\xE9", carac); + error("Save par tour " + attrName + " mal formé", carac); return; } let seuil = parseInt(attr.get('max')); if (isNaN(seuil)) { - error("Save par tour " + attrName + " mal form\xE9", seuil); + error("Save par tour " + attrName + " mal formé", seuil); return; } let attrEffet = findObjs({ @@ -28051,7 +28176,7 @@ var COFantasy = COFantasy || function() { explications.forEach(function(e) { addLineToFramedDisplay(display, e); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); if (reussite) { let eff = effetC; if (estEffetTemp(effetC)) eff = effetTempOfAttribute(attrEffet); @@ -28080,7 +28205,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("commande non form\xE9e", msg.content); + error("commande non formée", msg.content); return; } let armeLabel = ''; @@ -28093,7 +28218,7 @@ var COFantasy = COFantasy || function() { let personnages = []; getSelected(msg, function(selected) { if (selected === undefined || selected.length === 0) { - error("Qui doit d\xE9gainer ?", msg); + error("Qui doit dégainer ?", msg); return; } iterSelected(selected, function(perso) { @@ -28118,14 +28243,14 @@ var COFantasy = COFantasy || function() { persos.forEach(function(perso) { function afterSave() { let nomArme = degainerArme(perso, labelArme, evt, options); - if (nomArme) sendPerso(perso, "a d\xE9j\xE0 " + nomArme + " en main"); + if (nomArme) sendPerso(perso, "a déjà " + nomArme + " en main"); else if (options.montreActions && persos.length === 1) turnAction(perso); } if (options.save) { let saveOpts = { msgPour: " pour garder son arme en main", - msgRate: ", rat\xE9.", + msgRate: ", raté.", rolls: options.rolls, chanceRollId: options.chanceRollId }; @@ -28147,7 +28272,7 @@ var COFantasy = COFantasy || function() { function echangeInit(msg) { let combat = stateCOF.combat; if (!combat) { - error("\xC9change d'intiative en dehors du combat", msg); + error("Échange d'intiative en dehors du combat", msg); return; } let options = parseOptions(msg); @@ -28172,7 +28297,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3) { attackBonus = parseInt(cmd[3]); if (isNaN(attackBonus)) { - error("Le troisi\xE8me argument n'est pas un nombre", cmd[3]); + error("Le troisième argument n'est pas un nombre", cmd[3]); return; } } @@ -28187,23 +28312,23 @@ var COFantasy = COFantasy || function() { return (t.id == perso2.token.id); }); if (tourTok1 < 0) { - sendPerso(perso1, "a d\xE9j\xE0 agit, pas moyen d'\xE9changer son initiative"); + sendPerso(perso1, "a déjà agit, pas moyen d'échanger son initiative"); return; } if (tourTok2 < 0) { - sendPerso(perso2, "a d\xE9j\xE0 agit, pas moyen d'\xE9changer son initiative"); + sendPerso(perso2, "a déjà agit, pas moyen d'échanger son initiative"); return; } let pr1 = to.pasAgi[tourTok1].pr; let pr2 = to.pasAgi[tourTok2].pr; if (pr1 == pr2) { - sendPerso(perso1, "a la m\xEAme initiative que " + nomPerso(perso2)); + sendPerso(perso1, "a la même initiative que " + nomPerso(perso2)); return; } if (pr1 > pr2) { if (attackBonus) { setTokenAttr(perso1, 'actionConcertee', attackBonus, evt, { - msg: "gagne un bonus de " + attackBonus + " \xE0 ses attaques et en DEF pour ce tour" + msg: "gagne un bonus de " + attackBonus + " à ses attaques et en DEF pour ce tour" }); } setActiveToken(combat, perso2.token.id, evt); @@ -28242,7 +28367,7 @@ var COFantasy = COFantasy || function() { return arg == '--secret'; }); setTokenAttr(perso1, 'aCouvert', 1, evt, { - msg: "reste \xE0 couvert", + msg: "reste à couvert", maxVal: init, secret: secret }); @@ -28255,9 +28380,9 @@ var COFantasy = COFantasy || function() { } if (perso2.token.id == perso1.token.id) { if (secret) { - whisperChar(perso1.charId, "s'est cibl\xE9 " + onGenre(perso1, 'lui', 'elle') + "-m\xEAme, il est donc le seul \xE0 couvert"); + whisperChar(perso1.charId, "s'est ciblé " + onGenre(perso1, 'lui', 'elle') + "-même, il est donc le seul à couvert"); } else { - sendPerso(perso1, "s'est cibl\xE9 " + onGenre(perso1, 'lui', 'elle') + "-m\xEAme, il est donc le seul \xE0 couvert"); + sendPerso(perso1, "s'est ciblé " + onGenre(perso1, 'lui', 'elle') + "-même, il est donc le seul à couvert"); } addEvent(evt); return; @@ -28265,13 +28390,13 @@ var COFantasy = COFantasy || function() { let d = distanceCombat(perso1.token, perso2.token); if (d > 0) { if (secret) { - whisperChar(perso2.charId, "est trop \xE9loign\xE9 de " + nomPerso(perso1) + " pour rester \xE0 couvert avec lui"); + whisperChar(perso2.charId, "est trop éloigné de " + nomPerso(perso1) + " pour rester à couvert avec lui"); } else { - sendPerso(perso2, "est trop \xE9loign\xE9 de " + nomPerso(perso1) + " pour rester \xE0 couvert avec lui"); + sendPerso(perso2, "est trop éloigné de " + nomPerso(perso1) + " pour rester à couvert avec lui"); } } else { setTokenAttr(perso2, 'aCouvert', 1, evt, { - msg: "suit " + nomPerso(perso1) + " et reste \xE0 couvert", + msg: "suit " + nomPerso(perso1) + " et reste à couvert", maxVal: init, secret: secret }); @@ -28302,20 +28427,20 @@ var COFantasy = COFantasy || function() { effet += 'Temp'; } if (effet == 'forgeron' || effet == 'armeEnflammee' || effet == 'armeGlacee') { - //Compl\xE9ter description de l'effet + //Compléter description de l'effet if (!lanceur) { error("Pas de lanceur pour " + effet, msg.content); return; } let armeActuelle = tokenAttribute(lanceur, 'armeEnMain'); if (armeActuelle.length === 0) { - whisperChar(charId, "Pas d'arme en main, impossible de savoir \xE0 quoi appliquer " + effet); + whisperChar(charId, "Pas d'arme en main, impossible de savoir à quoi appliquer " + effet); return; } let labelArme = armeActuelle[0].get('current'); effet = effet + '(' + labelArme + ')'; } else if (!estEffetTemp(effet)) { - error(effet + " n'est pas un effet temporaire r\xE9pertori\xE9", msg.content); + error(effet + " n'est pas un effet temporaire répertorié", msg.content); return; } if (lanceur && options.mana !== undefined && attributeAsBool(lanceur, 'frappeDesArcanes')) { @@ -28336,7 +28461,7 @@ var COFantasy = COFantasy || function() { if (options.puissantDuree || options.tempeteDeManaDuree) duree = duree * 2; getSelected(msg, function(selected, playerId, aoe) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour l'effet", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour l'effet", playerId); return; } options.aoe = aoe; @@ -28355,7 +28480,7 @@ var COFantasy = COFantasy || function() { } if (lanceur && options.tempeteDeMana) { if (duree > 0 && options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, dm: mEffet.dm, @@ -28369,7 +28494,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPlayer(msg, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayer(msg, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } if (selected.length == 1 && options.tempeteDeMana.altruiste) { selected[0]._id = options.tempeteDeMana.altruiste.token.id; @@ -28389,7 +28514,7 @@ var COFantasy = COFantasy || function() { } if ((mEffet.seulementVivant || options.seulementVivant) && estNonVivant(perso)) { - sendPlayer(msg, "cet effet n'affecte que les cr\xE9atures vivantes", playerId); + sendPlayer(msg, "cet effet n'affecte que les créatures vivantes", playerId); return; } if (predicateAsBool(perso, 'liberteDAction') && @@ -28431,7 +28556,7 @@ var COFantasy = COFantasy || function() { }, options); } - //Si display est d\xE9fini, l'envoie dans le chat \xE0 la fin de l'appel + //Si display est défini, l'envoie dans le chat à la fin de l'appel function activerEffetTemporaire(lanceur, cibles, effet, mEffet, duree, options, evt, whisper, explications, display) { let ef = { effet: effet, @@ -28466,7 +28591,7 @@ var COFantasy = COFantasy || function() { explications.forEach(function(e) { addLineToFramedDisplay(display, e); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else { explications.forEach(function(e) { sendChat('', e); @@ -28487,7 +28612,7 @@ var COFantasy = COFantasy || function() { ressource = "limiteParJour_" + ressource; let utilisations = attributeAsInt(perso, ressource, options.limiteCibleParJour); if (utilisations === 0) { - expliquer("ne peut plus b\xE9n\xE9ficier de " + effet + " aujourd'hui"); + expliquer("ne peut plus bénéficier de " + effet + " aujourd'hui"); return; } setTokenAttr(perso, ressource, utilisations - 1, evt); @@ -28512,7 +28637,7 @@ var COFantasy = COFantasy || function() { height: diametre, layer: 'map', isDrawing: true, - name: 'Prison v\xE9g\xE9tale', + name: 'Prison végétale', gmnotes: 'terrainDifficile:disque ' + Math.floor(diametre) }); if (t) { @@ -28531,7 +28656,7 @@ var COFantasy = COFantasy || function() { setEffetTemporaire(perso, ef, d, evt, options); if (!renew) { if (effet.startsWith('forgeron(')) { - //Il faut d\xE9gainer l'arme si elle n'est pas en main, et ajouter une lumi\xE8re + //Il faut dégainer l'arme si elle n'est pas en main, et ajouter une lumière let labelArmeForgeron = effet.substring(9, effet.indexOf(')')); degainerArme(perso, labelArmeForgeron, evt); let feu = getIntValeurOfEffet(perso, effet, 1, 'voieDuMetal'); @@ -28590,14 +28715,14 @@ var COFantasy = COFantasy || function() { else sendPerso(perso, s); }; if (options.type && immuniseAuType(perso, options.type, lanceur)) { - expliquer("ne semble pas affect\xE9 par " + stringOfType(options.type)); + expliquer("ne semble pas affecté par " + stringOfType(options.type)); finalize(); return; } if (options.save) { let saveOpts = { - msgPour: options.save.msgPour || " pour r\xE9sister \xE0 l'effet " + effet, - msgRate: ", rat\xE9.", + msgPour: options.save.msgPour || " pour résister à l'effet " + effet, + msgRate: ", raté.", attaquant: lanceur, rolls: options.rolls, chanceRollId: options.chanceRollId, @@ -28614,7 +28739,7 @@ var COFantasy = COFantasy || function() { } if (reussite) { if (effet == 'reactionViolente' && predicateAsBool(perso, 'violenceCiblee')) { - expliquer("r\xE9siste \xE0 la provocation, mais emmagasine de la violence"); + expliquer("résiste à la provocation, mais emmagasine de la violence"); addToAttributeAsInt(perso, 'pointsDeViolence', 0, 1, evt); } finalize(); @@ -28636,7 +28761,7 @@ var COFantasy = COFantasy || function() { return (2 * magieEnArmure < defa + ma); } - //options doit \xEAtre d\xE9fini + //options doit être défini function effetTemporaire(playerId, cibles, effet, mEffet, duree, options) { const evt = { type: 'effetTemp', @@ -28683,15 +28808,15 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, line); activerEffetTemporaire(lanceur, cibles, effet, mEffet, duree, options, evt, whisper, explications, display); } else { - line += '< ' + difficulte + ", le sort est rat\xE9"; + line += '< ' + difficulte + ", le sort est raté"; addLineToFramedDisplay(display, line); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }); } else { activerEffetTemporaire(lanceur, cibles, effet, mEffet, duree, options, evt, whisper, explications); } - } else { //On met fin \xE0 l'effet + } else { //On met fin à l'effet explications.forEach(function(e) { sendChat('', e); }); @@ -28730,7 +28855,7 @@ var COFantasy = COFantasy || function() { case 'oui': case 'Oui': case 'true': - case 'd\xE9but': + case 'début': case 'debut': valeur = true; activer = true; @@ -28769,7 +28894,7 @@ var COFantasy = COFantasy || function() { } let effet = cmd[1]; if (!estEffetCombat(effet)) { - error(effet + " n'est pas un effet de combat r\xE9pertori\xE9", msg.content); + error(effet + " n'est pas un effet de combat répertorié", msg.content); return; } const evt = { @@ -28795,7 +28920,7 @@ var COFantasy = COFantasy || function() { } } if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour l'effet", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour l'effet", playerId); return; } if (lanceur === undefined) { @@ -28810,7 +28935,7 @@ var COFantasy = COFantasy || function() { } if (lanceur && options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, dm: messageEffetCombat[effet].dm, @@ -28823,7 +28948,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(lanceur, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort", options.secret); + sendPerso(lanceur, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort", options.secret); } if (selected.length == 1 && options.tempeteDeMana.altruiste) { selected[0]._id = options.tempeteDeMana.altruiste.token.id; @@ -28895,7 +29020,7 @@ var COFantasy = COFantasy || function() { setTokenAttr(perso, effet + 'TokenSide', oldSide, evt); } }); - } else { //on d\xE9sactive + } else { //on désactive iterSelected(selected, function(perso) { let actMsg = messageFin(perso, mEffet) + extraImg; removeTokenAttr(perso, effet, evt, { @@ -28977,7 +29102,7 @@ var COFantasy = COFantasy || function() { effetCombat(msg); return; } - error(effet + " n'est pas un effet r\xE9pertori\xE9", msg.content); + error(effet + " n'est pas un effet répertorié", msg.content); return; } let av = activeOuValeur(cmd, options); @@ -28991,7 +29116,7 @@ var COFantasy = COFantasy || function() { if (lanceur) charId = lanceur.charId; getSelected(msg, function(selected, playerId, aoe) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour l'effet", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour l'effet", playerId); return; } if (lanceur === undefined) { @@ -29009,7 +29134,7 @@ var COFantasy = COFantasy || function() { } if (lanceur && options.tempeteDeMana) { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPlayer(msg, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayer(msg, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } if (selected.length == 1 && options.tempeteDeMana.altruiste) { selected[0]._id = options.tempeteDeMana.altruiste.token.id; @@ -29038,12 +29163,12 @@ var COFantasy = COFantasy || function() { } if (activer === undefined) { if (cibles.length > 1) { - sendPlayer(msg, "On ne peut s\xE9lectionner qu'un token si on ne pr\xE9cise pas si il faut activer ou d\xE9sactiver l'effet"); + sendPlayer(msg, "On ne peut sélectionner qu'un token si on ne précise pas si il faut activer ou désactiver l'effet"); return; } let perso = persoOfId(selected[0]._id); if (!perso) { - error("Token s\xE9lectionn\xE9 non valide", selected); + error("Token sélectionné non valide", selected); return; } activer = !attributeAsBool(perso, effet); @@ -29067,7 +29192,7 @@ var COFantasy = COFantasy || function() { normalToken = JSON.parse(normalToken); let nw = normalToken.width; let nh = normalToken.height; - //Rien \xE0 faire si le token occupe d\xE9j\xE0 une case + //Rien à faire si le token occupe déjà une case if (nw >= PIX_PER_UNIT || nh >= PIX_PER_UNIT) return; setTokenAttr(perso, 'tailleDeTokenNormale', nw, evt, { maxVal: nh @@ -29101,7 +29226,7 @@ var COFantasy = COFantasy || function() { let nw = parseInt(attr.get('current')); let nh = parseInt(attr.get('max')); if (isNaN(nw) || isNaN(nh)) { - error("La taille de token sauvegard\xE9e n'est pas correcte", attr); + error("La taille de token sauvegardée n'est pas correcte", attr); attr.remove(); } let character = getObj('character', perso.charId); @@ -29246,11 +29371,11 @@ var COFantasy = COFantasy || function() { if (!msgPour) { msgPour = " pour "; if (mEffet.msgSave) msgPour += mEffet.msgSave; - else msgPour += "r\xE9sister \xE0 l'effet " + effet; + else msgPour += "résister à l'effet " + effet; } let saveOpts = { msgPour, - msgRate: ", rat\xE9.", + msgRate: ", raté.", silencieuxSiPasAffecte: options.silencieuxSiPasAffecte, attaquant: lanceur, rolls: options.rolls, @@ -29328,7 +29453,7 @@ var COFantasy = COFantasy || function() { let classeEffet = cmd[1]; getSelected(msg, function(selected) { if (selected === undefined || selected.length === 0) { - error("Pas de cible s\xE9lectionn\xE9e pour la fin d'une classe d'effets", msg); + error("Pas de cible sélectionnée pour la fin d'une classe d'effets", msg); return; } const evt = { @@ -29366,16 +29491,16 @@ var COFantasy = COFantasy || function() { predicateAsBool(target, 'sansEsprit') || attributeAsBool(target, 'enrage') || predicateAsBool(target, 'liberteDAction')) { - messages.push(targetName + " est insensible \xE0 la peur !"); + messages.push(targetName + " est insensible à la peur !"); callback(); return; } if (options.immuniseSiResiste && attributeAsBool(target, options.immuniseSiResiste)) { - messages.push(targetName + " a d\xE9j\xE0 r\xE9sist\xE9 \xE0 cet effet, " + onGenre(target, 'il', 'elle') + " n'y est plus sensible"); + messages.push(targetName + " a déjà résisté à cet effet, " + onGenre(target, 'il', 'elle') + " n'y est plus sensible"); callback(); return; } - let carac = 'SAG'; //carac pour r\xE9sister + let carac = 'SAG'; //carac pour résister if (options.resisteAvecForce) carac = meilleureCarac('SAG', 'FOR', target, difficulte); //chercher si un partenaire a sansPeur pour appliquer le bonus @@ -29387,7 +29512,7 @@ var COFantasy = COFantasy || function() { let allTokens; allies.forEach(function(cid) { if (charPredicateAsBool(cid, 'sansPeur')) { - //On cherche si l'alli\xE9 est pr\xE9sent sur la m\xEAme page + //On cherche si l'allié est présent sur la même page allTokens = allTokens || findObjs({ _type: "graphic", @@ -29406,7 +29531,7 @@ var COFantasy = COFantasy || function() { charId: cid, token: alliePresent }; - msgAllieSansPeur = nomPerso(allie) + " a donn\xE9 +" + bonusAllie + " au jet"; + msgAllieSansPeur = nomPerso(allie) + " a donné +" + bonusAllie + " au jet"; } } } @@ -29422,7 +29547,7 @@ var COFantasy = COFantasy || function() { let line = targetName + " fait " + tr.texte; let sujet = onGenre(target, 'il', 'elle'); if (tr.reussite) { - line += ", " + sujet + " r\xE9siste \xE0 la peur." + tr.modifiers; + line += ", " + sujet + " résiste à la peur." + tr.modifiers; if (options.immuniseSiResiste) setTokenAttr(target, options.immuniseSiResiste, true, evt); } else { @@ -29430,14 +29555,18 @@ var COFantasy = COFantasy || function() { let effet = 'apeureTemp'; let etat = 'apeure'; if (options.etourdi) { - line += "s'enfuit ou reste recroquevill\xE9" + eForFemale(target) + " sur place"; + line += "s'enfuit ou reste recroquevillé" + eForFemale(target) + " sur place"; effet = 'peurEtourdi'; } else if (options.ralenti) { line += "est ralenti" + eForFemale(target); effet = 'ralentiTemp'; etat = 'ralenti'; + } else if (options.paralyse) { + line += "est paralysé" + eForFemale(target); + effet = 'paralyseTemp'; + etat = 'paralyse'; } else if (options.secoue && !attributeAsBool(target, 'secoue')) { - line += "est secou\xE9" + eForFemale(target); + line += "est secoué" + eForFemale(target); effet = 'secoue'; etat = false; } else { @@ -29467,12 +29596,12 @@ var COFantasy = COFantasy || function() { let pageId = getPageId(playerId); let difficulte = parseInt(cmd[1]); if (isNaN(difficulte)) { - error("Le premier argument de !cof-peur, la difficult\xE9 du test de r\xE9sistance, n'est pas un nombre", cmd); + error("Le premier argument de !cof-peur, la difficulté du test de résistance, n'est pas un nombre", cmd); return; } - let duree = parseDice(cmd[2], "dur\xE9e de peur"); + let duree = parseDice(cmd[2], "durée de peur"); if (!dePositif(duree)) { - error("Le second argument de !cof-peur, la dur\xE9e, n'est pas un nombre positif", cmd); + error("Le second argument de !cof-peur, la durée, n'est pas un nombre positif", cmd); return; } let options = {}; @@ -29487,16 +29616,17 @@ var COFantasy = COFantasy || function() { case 'ralenti': case 'effroi': case 'secoue': + case 'paralyse': options[optCmd[0]] = true; return; case 'portee': if (optCmd.length < 2) { - error("Il manque l'argument de port\xE9e", optArgs); + error("Il manque l'argument de portée", optArgs); return; } options.portee = parseInt(optCmd[1]); if (isNaN(options.portee) || options.portee < 0) { - error("La port\xE9e n'est pas un nombre positif", optCmd); + error("La portée n'est pas un nombre positif", optCmd); delete options.portee; } return; @@ -29529,7 +29659,7 @@ var COFantasy = COFantasy || function() { let cibles = []; getSelected(msg, function(selected) { if (selected === undefined || selected.length === 0) { - error("Pas de cible s\xE9lectionn\xE9e pour la peur", msg); + error("Pas de cible sélectionnée pour la peur", msg); return; } iterSelected(selected, function(perso) { @@ -29546,7 +29676,7 @@ var COFantasy = COFantasy || function() { if (cibles.length > 0) { doPeur(cibles, difficulte, options); } else { - error("Aucune cible valable \xE0 port\xE9e de l'effet de Peur", msg); + error("Aucune cible valable à portée de l'effet de Peur", msg); } } @@ -29566,14 +29696,14 @@ var COFantasy = COFantasy || function() { if (options.titre) action += options.titre; else if (options.effroi) action += "est vraiment effrayant" + eForFemale(options.lanceur); - else action = "Capacit\xE9 : Sort de peur"; + else action = "Capacité : Effet de peur"; } else if (options.titre) action = options.titre; let messages = []; entrerEnCombat(options.lanceur, cibles, messages, evt); let display = startFramedDisplay(options.playerId, action, options.lanceur); let jet = " Jet de SAG "; if (options.resisteAvecForce) jet += "ou FOR "; - jet += "difficult\xE9 " + difficulte; + jet += "difficulté " + difficulte; addLineToFramedDisplay(display, jet, 80); let counter = cibles.length; let finalDisplay = function() { @@ -29587,7 +29717,7 @@ var COFantasy = COFantasy || function() { } } if (counter < 1) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }; cibles.forEach(function(perso) { @@ -29600,7 +29730,7 @@ var COFantasy = COFantasy || function() { if (options === undefined || options.cmd === undefined) return; let cmd = options.cmd; if (cmd.length < 3) { - error("Il faut au moins 2 arguments \xE0 !cof-attaque-magique", cmd); + error("Il faut au moins 2 arguments à !cof-attaque-magique", cmd); return; } let attaquant = persoOfId(cmd[1], cmd[1]); @@ -29634,13 +29764,13 @@ var COFantasy = COFantasy || function() { } } - // callback est seulement appel\xE9 si on fait le test - // evt est facultatif ; si absent, en cr\xE9e un nouveau g\xE9n\xE9rique et l'ajoute \xE0 l'historique + // callback est seulement appelé si on fait le test + // evt est facultatif ; si absent, en crée un nouveau générique et l'ajoute à l'historique function attaqueMagiqueOpposee(playerId, attaquant, cible, options, callback, evt) { if (options.attaqueMentale) { if (predicateAsBool(cible, 'sansEsprit') || predicateAsBool(cible, 'vegetatif')) { sendPerso(attaquant, " est sans esprit, " + onGenre(cible, 'il', 'elle') + - " est immunis\xE9" + onGenre(cible, '', 'e') + " aux attaques mentales."); + " est immunisé" + onGenre(cible, '', 'e') + " aux attaques mentales."); return; } else if (predicateAsBool(cible, 'liberteDAction')) { sendPerso(cible, "reste libre de ses actions !"); @@ -29720,7 +29850,7 @@ var COFantasy = COFantasy || function() { let attackRoll2 = d20roll2 + att2Skill; if (options.chanceRollId && options.chanceRollId.roll2) attackRoll2 += options.chanceRollId.roll2; - let action = "Attaque magique oppos\xE9e"; + let action = "Attaque magique opposée"; let reussi; if (d20roll1 == 1) { if (d20roll2 == 1) reussi = (attackRoll1 >= attackRoll2); @@ -29773,15 +29903,15 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, line); if (reussi) { diminueMalediction(cible, evt); - addLineToFramedDisplay(display, "Attaque r\xE9ussie !"); + addLineToFramedDisplay(display, "Attaque réussie !"); } else { diminueMalediction(attaquant, evt); - addLineToFramedDisplay(display, "L'attaque \xE9choue."); + addLineToFramedDisplay(display, "L'attaque échoue."); } explications.forEach(explication => addLineToFramedDisplay(display, explication, 80)); if (callback) callback(display, reussi); else { - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }); } @@ -29802,17 +29932,17 @@ var COFantasy = COFantasy || function() { function(display, reussi) { if (reussi) { if (attributeAsBool(cible, 'immunise24HA_injonction')) { - addLineToFramedDisplay(display, nomPerso(cible) + " a d\xE9j\xE0 r\xE9sist\xE9 \xE0 une injonction aujourd'hui, c'est sans effet"); + addLineToFramedDisplay(display, nomPerso(cible) + " a déjà résisté à une injonction aujourd'hui, c'est sans effet"); } else if (predicateAsBool(cible, 'liberteDAction')) { addLineToFramedDisplay(display, nomPerso(cible) + " reste libre de ses actions !"); } else { - addLineToFramedDisplay(display, nomPerso(cible) + " ob\xE9it \xE0 l'injonction"); + addLineToFramedDisplay(display, nomPerso(cible) + " obéit à l'injonction"); } - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } else { setTokenAttr(cible, 'immunise24HA_injonction', true, evt); - addLineToFramedDisplay(display, nomPerso(cible) + " n'ob\xE9it pas \xE0 l'injonction"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " n'obéit pas à l'injonction"); + sendFramedDisplay(display); } }, evt); } @@ -29832,13 +29962,13 @@ var COFantasy = COFantasy || function() { function(display, reussi) { if (reussi) { if (estNonVivant(cible)) { - addLineToFramedDisplay(display, nomPerso(cible) + " n'est pas une cr\xE9ature vivante, il ne peut croire \xE0 sa mort"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " n'est pas une créature vivante, il ne peut croire à sa mort"); + sendFramedDisplay(display); return; } if (attributeAsBool(cible, 'limiteParJour_tueurFantasmagorique')) { - addLineToFramedDisplay(display, nomPerso(cible) + " a d\xE9j\xE0 \xE9t\xE9 victime d'un tueur fantasmagorique aujourd'hui, c'est sans effet"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " a déjà été victime d'un tueur fantasmagorique aujourd'hui, c'est sans effet"); + sendFramedDisplay(display); return; } setTokenAttr(cible, 'limiteParJour_tueurFantasmagorique', true, evt); @@ -29856,7 +29986,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, message, 80); }; const saveOpts = { - msgPour: " pour r\xE9sister au tueur fantasmagorique", + msgPour: " pour résister au tueur fantasmagorique", attaquant: attaquant, rolls: options.rolls, chanceRollId: options.chanceRollId, @@ -29866,18 +29996,18 @@ var COFantasy = COFantasy || function() { save(s, cible, saveId, expliquer, saveOpts, evt, function(reussiteSave, texte) { if (reussiteSave) { - addLineToFramedDisplay(display, nomPerso(cible) + " perd l'\xE9quilibre et tombe par terre"); + addLineToFramedDisplay(display, nomPerso(cible) + " perd l'équilibre et tombe par terre"); setState(cible, 'renverse', true, evt); - } else { //save rat\xE9 - addLineToFramedDisplay(display, nomPerso(cible) + " succombe \xE0 ses pires terreurs"); + } else { //save raté + addLineToFramedDisplay(display, nomPerso(cible) + " succombe à ses pires terreurs"); updateCurrentBar(cible, 1, 0, evt); setState(cible, 'mort', true, evt); } - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); } else { setTokenAttr(cible, 'limiteParJour_tueurFantasmagorique', true, evt); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }, evt); } @@ -29897,8 +30027,8 @@ var COFantasy = COFantasy || function() { function(display, reussi) { if (reussi) { if (attributeAsBool(cible, 'limiteParJour_enkystementLointain')) { - addLineToFramedDisplay(display, nomPerso(cible) + " a d\xE9j\xE0 \xE9t\xE9 victime d'un enkystement lointain aujourd'hui, c'est sans effet"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " a déjà été victime d'un enkystement lointain aujourd'hui, c'est sans effet"); + sendFramedDisplay(display); return; } setTokenAttr(cible, 'limiteParJour_enkystementLointain', true, evt); @@ -29908,19 +30038,19 @@ var COFantasy = COFantasy || function() { val, roll } = rollDePlus(20); - let message = nomPerso(cible) + " est t\xE9l\xE9port\xE9" + eForFemale(cible) + " \xE0 une distance de "; + let message = nomPerso(cible) + " est téléporté" + eForFemale(cible) + " à une distance de "; if (niveauCible < niveauAttaquant / 2) { - message += (val * 100) + " kilom\xE8tres."; + message += (val * 100) + " kilomètres."; } else if (niveauCible < niveauAttaquant) { - message += roll + " kilom\xE8tre" + (val > 1) ? 's' : ''; + message += roll + " kilomètre" + (val > 1) ? 's' : ''; } else { - message += (val * 10) + " m\xE8tres."; + message += (val * 10) + " mètres."; } addLineToFramedDisplay(display, message); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } else { //Dans ce cas, pas victime, donc on permet d'autre tentatives - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }, evt); } @@ -29930,7 +30060,7 @@ var COFantasy = COFantasy || function() { if (options === undefined || options.cmd === undefined) return; const cmd = options.cmd; if (cmd.length < 3) { - error("Il faut au moins 2 arguments \xE0 !cof-injonction-mortelle", cmd); + error("Il faut au moins 2 arguments à !cof-injonction-mortelle", cmd); return; } let attaquant = persoOfId(cmd[1], cmd[1]); @@ -29949,7 +30079,7 @@ var COFantasy = COFantasy || function() { } function injonctionMortelle(playerId, attaquant, cible, options) { - var evt = { + const evt = { type: 'injonctionMortelle', action: { titre: "Injonction Mortelle", @@ -29967,19 +30097,19 @@ var COFantasy = COFantasy || function() { }); explications.forEach(msg => addLineToFramedDisplay(display, msg, 80)); if (attributeAsBool(cible, 'injonctionMortelle')) { - addLineToFramedDisplay(display, nomPerso(cible) + " a d\xE9j\xE0 \xE9t\xE9 victime d'une injonction mortelle ce combat, c'est sans effet"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " a déjà été victime d'une injonction mortelle ce combat, c'est sans effet"); + sendFramedDisplay(display); return; } if (predicateAsBool(cible, 'liberteDAction')) { addLineToFramedDisplay(display, nomPerso(cible) + " reste libre de ses actions !"); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); return; } setTokenAttr(cible, 'injonctionMortelle', true, evt); let saveOpts = { - msgPour: " pour r\xE9sister \xE0 l'injonction mortelle", - msgRate: ", rat\xE9.", + msgPour: " pour résister à l'injonction mortelle", + msgRate: ", raté.", attaquant: attaquant, rolls: options.rolls, chanceRollId: options.chanceRollId, @@ -30012,47 +30142,47 @@ var COFantasy = COFantasy || function() { cible.attaquant = attaquant; dealDamage(cible, dmg, [], evt, false, options, explicationsDmg, function(dmgDisplay, dmgFinal) { addLineToFramedDisplay(display, - name + " re\xE7oit " + dmgDisplay + " DM"); + name + " reçoit " + dmgDisplay + " DM"); explicationsDmg.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); }); } else { addLineToFramedDisplay(display, nomPerso(cible) + " meurt sous l'injonction mortelle !", 80); updateCurrentBar(cible, 1, 0, evt); setState(cible, 'mort', true, evt); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }); } function parseSommeil(msg) { //sort de sommeil - var options = parseOptions(msg); + const options = parseOptions(msg); if (options === undefined) return; - var args = options.cmd; + const args = options.cmd; if (args.length < 2) { error("La fonction !cof-sommeil a besoin du nom ou de l'id du lanceur de sort", args); return; } - var lanceur = persoOfId(args[1], args[1]); + const lanceur = persoOfId(args[1], args[1]); if (lanceur === undefined) { - error("Aucun personnage nomm\xE9 " + args[1], args); + error("Aucun personnage nommé " + args[1], args); return; } - var casterCharId = lanceur.charId; - var casterChar = getObj('character', casterCharId); + const casterCharId = lanceur.charId; + const casterChar = getObj('character', casterCharId); if (casterChar === undefined) { error("Fiche de personnage manquante"); return; } getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lectionn\xE9e pour le sort de sommeil", playerId); + sendPlayer(msg, "Pas de cible sélectionnée pour le sort de sommeil", playerId); return; } - var cibles = []; + let cibles = []; iterSelected(selected, function(perso) { cibles.push(perso); }); @@ -30063,14 +30193,14 @@ var COFantasy = COFantasy || function() { } function doSommeil(lanceur, cibles, options, ciblesSansSave, ciblesAvecSave) { - var evt = { + const evt = { type: 'sommeil', action: { - lanceur: lanceur, - cibles: cibles, - ciblesSansSave: ciblesSansSave, - ciblesAvecSave: ciblesAvecSave, - options: options + lanceur, + cibles, + ciblesSansSave, + ciblesAvecSave, + options } }; addEvent(evt); @@ -30089,14 +30219,14 @@ var COFantasy = COFantasy || function() { let rollD6 = evt.action.rolls[rollD6Id] || rolls.inlinerolls[d6RollNumber]; evt.action.rolls[rollD6Id] = rollD6; let nbTargetsMax = rollD6.results.total + cha; - let action = "Capacit\xE9 : Sort de sommeil (max " + nbTargetsMax + " cibles)"; + let action = "Capacité : Sort de sommeil (max " + nbTargetsMax + " cibles)"; let display = startFramedDisplay(options.playerId, action, lanceur); let attMag = rolls.inlinerolls[attMagRollNumber].results.total; let targetsWithSave = []; let targetsWithoutSave = []; cibles.forEach(function(perso) { - if (estNonVivant(perso) || predicateAsBool(perso, 'immunite_endormi')) { //le sort de sommeil n'affecte que les cr\xE9atures vivantes - addLineToFramedDisplay(display, nomPerso(perso) + " n'est pas affect\xE9 par le sommeil"); + if (estNonVivant(perso) || predicateAsBool(perso, 'immunite_endormi')) { //le sort de sommeil n'affecte que les créatures vivantes + addLineToFramedDisplay(display, nomPerso(perso) + " n'est pas affecté par le sommeil"); return; } if (predicateAsBool(perso, "liberteDAction")) { @@ -30105,7 +30235,7 @@ var COFantasy = COFantasy || function() { } let pv = perso.token.get('bar1_max'); if (pv > 2 * attMag) { - let line = nomPerso(perso) + " a trop de PV pour \xEAtre affect\xE9 par le sort"; + let line = nomPerso(perso) + " a trop de PV pour être affecté par le sort"; addLineToFramedDisplay(display, line); } else if (pv > attMag) { targetsWithSave.push(perso); @@ -30113,13 +30243,13 @@ var COFantasy = COFantasy || function() { targetsWithoutSave.push(perso); } }); - var ciblesSansSave; + let ciblesSansSave; if (evt.action.ciblesSansSave) { ciblesSansSave = evt.action.ciblesSansSave; nbTargetsMax -= ciblesSansSave.length; } else { ciblesSansSave = []; - var i, r; + let i, r; if (targetsWithoutSave.length > nbTargetsMax) { i = 0; //position to decide while (nbTargetsMax > 0) { @@ -30140,16 +30270,16 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, nomPerso(t) + " s'endort"); }); if (nbTargetsMax > 0 && targetsWithSave.length > 0) { - var ciblesAvecSave; + let ciblesAvecSave; if (evt.action.ciblesAvecSave) { ciblesAvecSave = evt.action.ciblesAvecSave; nbTargetsMax -= ciblesAvecSave.length; } else { ciblesAvecSave = []; if (targetsWithSave.length > nbTargetsMax) { - var j = 0; + let j = 0; while (nbTargetsMax > 0) { - var ra = randomInteger(nbTargetsMax) + j; + let ra = randomInteger(nbTargetsMax) + j; ciblesAvecSave.push(targetsWithSave[ra]); targetsWithSave[ra] = targetsWithSave[j]; j++; @@ -30160,21 +30290,21 @@ var COFantasy = COFantasy || function() { nbTargetsMax -= ciblesAvecSave.length; } } - var seuil = 10 + cha; - var tokensToProcess = ciblesAvecSave.length; - var finalize = function() { + let seuil = 10 + cha; + let tokensToProcess = ciblesAvecSave.length; + let finalize = function() { if (tokensToProcess == 1) { - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } tokensToProcess--; }; evt.action.ciblesAvecSave = ciblesAvecSave; ciblesAvecSave.forEach(function(perso) { - var testId = 'resisteSommeil_' + perso.token.id; + let testId = 'resisteSommeil_' + perso.token.id; testCaracteristique(perso, 'SAG', seuil, testId, options, evt, function(tr) { - var line = "Jet de r\xE9sistance de " + nomPerso(perso) + ": " + tr.texte; - var sujet = onGenre(perso, 'il', 'elle'); + let line = "Jet de résistance de " + nomPerso(perso) + ": " + tr.texte; + let sujet = onGenre(perso, 'il', 'elle'); if (tr.reussite) { line += ">=" + seuil + ", " + sujet + " ne s'endort pas." + tr.modifiers; } else { @@ -30186,22 +30316,23 @@ var COFantasy = COFantasy || function() { }); }); } else { // all targets are without save - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }); } //!cof-attaque-magique-contre-pv {selected|token_id} {target|token_id} + // deprecated function attaqueMagiqueContrePV(msg) { - var options = parseOptions(msg); + const options = parseOptions(msg); if (options === undefined || options.cmd === undefined) return; - var cmd = options.cmd; + let cmd = options.cmd; if (cmd.length < 3) { - error("Il faut au moins 2 arguments \xE0 !cof-attaque-magique-contre-pv", cmd); + error("Il faut au moins 2 arguments à !cof-attaque-magique-contre-pv", cmd); return; } - var attaquant = persoOfId(cmd[1], cmd[1]); - var cible = persoOfId(cmd[2], cmd[2]); + let attaquant = persoOfId(cmd[1], cmd[1]); + let cible = persoOfId(cmd[2], cmd[2]); if (attaquant === undefined || cible === undefined) { error("Arguments de !cof-attaque-magique-contre-pv incorrects", cmd); return; @@ -30224,7 +30355,7 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); if (limiteRessources(attaquant, options, 'attaque magique', "l'attaque magique", evt)) return; - var attaquantChar = getObj('character', attaquant.charId); + let attaquantChar = getObj('character', attaquant.charId); if (attaquantChar === undefined) { error("Fiche de l'attaquant introuvable"); return; @@ -30250,58 +30381,58 @@ var COFantasy = COFantasy || function() { effetAuD20(attaquant, d20roll); let attSkill = rolls.inlinerolls[attSkillNumber].results.total; if (estAffaibli(attaquant) && predicateAsBool(attaquant, 'insensibleAffaibli')) attSkill -= 2; - var attackRoll = d20roll + attSkill; + let attackRoll = d20roll + attSkill; let line = nomPerso(attaquant) + " fait " + buildinline(rolls.inlinerolls[attRollNumber]); if (attSkill > 0) line += "+" + attSkill + " = " + attackRoll; else if (attSkill < 0) line += attSkill + " = " + attackRoll; addLineToFramedDisplay(display, line); - var reussi; + let reussi; if (d20roll == 1) reussi = false; else if (d20roll == 20) reussi = true; else reussi = (attackRoll >= pvMax); if (reussi) { - addLineToFramedDisplay(display, "Attaque r\xE9ussie !"); + addLineToFramedDisplay(display, "Attaque réussi !"); } else { diminueMalediction(attaquant, evt); - addLineToFramedDisplay(display, "L'attaque \xE9choue."); + addLineToFramedDisplay(display, "L'attaque échoue."); } - sendChat("", endFramedDisplay(display)); - }); //Fin du jet de d\xE9s pour l'attaque + sendFramedDisplay(display); + }); //Fin du jet de dés pour l'attaque } function transeGuerison(msg) { if (stateCOF.combat) { - sendPlayer(msg, "Pas possible de m\xE9diter en combat"); + sendPlayer(msg, "Pas possible de méditer en combat"); return; } - var options = parseOptions(msg); + const options = parseOptions(msg); if (options === undefined) return; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lectionn\xE9e pour la transe de gu\xE9rison", playerId); + sendPlayer(msg, "Pas de cible sélectionnée pour la transe de guérison", playerId); return; } - var evt = { - type: "Transe de gu\xE9rison", + const evt = { + type: "Transe de guérison", }; iterSelected(selected, function(perso) { - var token = perso.token; - if (attributeAsBool(perso, 'transeDeGu\xE9rison')) { - sendPerso(perso, "a d\xE9j\xE0 m\xE9dit\xE9 depuis le dernier combat"); + let token = perso.token; + if (attributeAsBool(perso, 'transeDeGuérison')) { + sendPerso(perso, "a déjà médité depuis le dernier combat"); return; } - var bar1 = parseInt(token.get("bar1_value")); - var pvmax = parseInt(token.get("bar1_max")); + let bar1 = parseInt(token.get("bar1_value")); + let pvmax = parseInt(token.get("bar1_max")); if (isNaN(bar1) || isNaN(pvmax)) return; if (bar1 >= pvmax) { - sendPerso(perso, "n'a pas besoin de m\xE9diter"); + sendPerso(perso, "n'a pas besoin de méditer"); return; } - var sagMod = modCarac(perso, 'sagesse'); - var niveau = ficheAttributeAsInt(perso, 'niveau', 1); - var soin = niveau + sagMod; + let sagMod = modCarac(perso, 'sagesse'); + let niveau = ficheAttributeAsInt(perso, 'niveau', 1); + let soin = niveau + sagMod; if (soin < 0) soin = 0; if (bar1 === 0) { if (attributeAsBool(perso, 'etatExsangue')) { @@ -30316,8 +30447,8 @@ var COFantasy = COFantasy || function() { bar1 = pvmax; } updateCurrentBar(perso, 1, bar1, evt); - setTokenAttr(perso, 'transeDeGu\xE9rison', true, evt); - sendPerso(perso, "entre en m\xE9ditation pendant 10 minutes et r\xE9cup\xE8re " + soin + " points de vie."); + setTokenAttr(perso, 'transeDeGuérison', true, evt); + sendPerso(perso, "entre en méditation pendant 10 minutes et récupère " + soin + " points de vie."); }); addEvent(evt); }); @@ -30332,7 +30463,7 @@ var COFantasy = COFantasy || function() { } function estFee(perso) { - if (predicateAsBool(perso, 'f\xE9e')) return true; + if (predicateAsBool(perso, 'fée')) return true; if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); perso.race = perso.race.toLowerCase(); @@ -30342,7 +30473,7 @@ var COFantasy = COFantasy || function() { case 'licorne': case 'farfadet': case 'fee': - case 'f\xE9e': + case 'fée': case 'pixie': case 'lutin': return true; @@ -30352,14 +30483,14 @@ var COFantasy = COFantasy || function() { } function estDemon(perso) { - if (predicateAsBool(perso, 'd\xE9mon')) return true; + if (predicateAsBool(perso, 'démon')) return true; if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); perso.race = perso.race.toLowerCase(); } if (perso.race === '') return false; switch (perso.race) { - case 'd\xE9mon': + case 'démon': case 'demon': case 'balor': case 'marilith': @@ -30411,14 +30542,14 @@ var COFantasy = COFantasy || function() { } function estGeant(perso) { - if (predicateAsBool(perso, 'g\xE9ant')) return true; + if (predicateAsBool(perso, 'géant')) return true; if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); perso.race = perso.race.toLowerCase(); } if (perso.race === '') return false; switch (perso.race) { - case 'g\xE9ant': + case 'géant': case 'geant': case 'ogre': case 'troll': @@ -30484,7 +30615,7 @@ var COFantasy = COFantasy || function() { return false; } - //Vrai pour les insectes et araign\xE9es + //Vrai pour les insectes et araignées function estInsecte(perso) { if (predicateAsBool(perso, 'insecte')) return true; if (perso.profil === undefined) { @@ -30492,7 +30623,7 @@ var COFantasy = COFantasy || function() { perso.profil = perso.profil.toLowerCase(); } if (perso.profil == 'insecte') return true; - if (perso.profil == 'araign\xE9e') return true; + if (perso.profil == 'araignée') return true; if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); perso.race = perso.race.toLowerCase(); @@ -30501,7 +30632,7 @@ var COFantasy = COFantasy || function() { if (perso.race.includes('elf') && perso.race.includes('noir')) return true; switch (perso.race) { case 'ankheg': - case 'araign\xE9e': + case 'araignée': case 'araignee': case 'insecte': return true; @@ -30526,18 +30657,18 @@ var COFantasy = COFantasy || function() { case 'drow': case 'haut elfe': case 'halfelin': - case 'g\xE9ant': + case 'géant': case 'geant': case 'ange': case 'barghest': - case 'd\xE9mon': + case 'démon': case 'doppleganger': case 'dryade': case 'gnoll': case 'gobelin': case 'gobelours': case 'hobegobelin': - case 'homme-l\xE9zard': + case 'homme-lézard': case 'kobold': case 'nymphe': case 'ogre': @@ -30559,25 +30690,25 @@ var COFantasy = COFantasy || function() { if (perso.race === '') return false; switch (perso.race) { case 'ankheg': - case 'araign\xE9e': + case 'araignée': case 'araignee': case 'basilic': - case 'b\xE9hir': + case 'béhir': case 'behir': case 'bulette': case 'bison': case 'centaure': case 'cheval': case 'chien': - case 'chim\xE8re': + case 'chimère': case 'chimere': case 'cockatrice': case 'crocodile': case 'dragon': case 'drider': - case 'el\xE9phant': + case 'eléphant': case 'elephant': - case '\xE9l\xE9phant': + case 'éléphant': case 'mammouth': case 'griffon': case 'hipogriffe': @@ -30590,13 +30721,13 @@ var COFantasy = COFantasy || function() { case 'manticore': case 'ours': case 'panthere': - case 'panth\xE8re': + case 'panthère': case 'pegase': - case 'p\xE9gase': + case 'pégase': case 'pieuvre': case 'rat': case 'rhinoceros': - case 'rhinoc\xE9ros': + case 'rhinocéros': case 'sanglier': case 'taureau': case 'tigre': @@ -30628,7 +30759,7 @@ var COFantasy = COFantasy || function() { case 'animal': case 'aigle': case 'araignee': - case 'araign\xE9e': + case 'araignée': case 'basilic': case 'bulette': case 'bison': @@ -30638,8 +30769,8 @@ var COFantasy = COFantasy || function() { case 'chien': case 'crocodile': case 'dinosaure': - case '\xE9l\xE9phant': - case 'el\xE9phant': + case 'éléphant': + case 'eléphant': case 'elephant': case 'gorille': case 'griffon': @@ -30652,11 +30783,11 @@ var COFantasy = COFantasy || function() { case 'manticore': case 'ours': case 'ours-hibou': - case 'panth\xE8re': + case 'panthère': case 'pegase': - case 'p\xE9gase': + case 'pégase': case 'pieuvre': - case 'rhinoc\xE9ros': + case 'rhinocéros': case 'roc': case 'sanglier': case 'serpent': @@ -30676,7 +30807,7 @@ var COFantasy = COFantasy || function() { switch (perso.race) { case 'squelette': case 'zombie': - case '\xE9l\xE9mentaire': + case 'élémentaire': case 'momie': return true; default: @@ -30697,7 +30828,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd.length < 2) { - error("Il faut au moins un argument \xE0 !cof-soin", cmd); + error("Il faut au moins un argument à !cof-soin", cmd); return; } let soigneur = options.lanceur; @@ -30705,7 +30836,7 @@ var COFantasy = COFantasy || function() { let cible; let argSoin; if (cmd.length > 4) { - error("Trop d'arguments \xE0 !cof-soin", cmd); + error("Trop d'arguments à !cof-soin", cmd); } if (cmd.length > 2) { //cof-soin lanceur [cible] montant if (soigneur === undefined) { @@ -30719,7 +30850,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3) { // on a la cible en argument cible = persoOfId(cmd[2], cmd[2], pageId); if (cible === undefined) { - error("Le deuxi\xE8me argument n'est pas un token valide: " + msg.content, cmd[2]); + error("Le deuxième argument n'est pas un token valide: " + msg.content, cmd[2]); return; } argSoin = cmd[3]; @@ -30730,7 +30861,7 @@ var COFantasy = COFantasy || function() { argSoin = cmd[1]; } if (soigneur === undefined && (options.mana || (options.portee !== undefined) || options.limiteParJour || options.limiteParCombat || options.dose || options.limiteSoinsParJour)) { - error("Il faut pr\xE9ciser un soigneur pour ces options d'effet", options); + error("Il faut préciser un soigneur pour ces options d'effet", options); return; } let charId; @@ -30748,11 +30879,11 @@ var COFantasy = COFantasy || function() { if (options.tempeteDeManaIntense) nbDes += options.tempeteDeManaIntense; switch (argSoin) { case 'leger': - effet += ' l\xE9gers'; + effet += ' légers'; if (options.dose === undefined && options.limiteParJour === undefined) options.limiteAttribut = { nom: 'soinsLegers', - message: "ne peut plus lancer de sort de soins l\xE9gers aujourd'hui", + message: "ne peut plus lancer de sort de soins légers aujourd'hui", limite: rangSoin }; let bonusLeger = niveau + predicateAsInt(soigneur, 'voieDuGuerisseur', 0); @@ -30764,11 +30895,11 @@ var COFantasy = COFantasy || function() { if (options.portee === undefined) options.portee = 0; break; case 'modere': - effet += ' mod\xE9r\xE9s'; + effet += ' modérés'; if (options.dose === undefined && options.limiteParJour === undefined) options.limiteAttribut = { nom: 'soinsModeres', - message: "ne peut plus lancer de sort de soins mod\xE9r\xE9ss aujourd'hui", + message: "ne peut plus lancer de sort de soins modéréss aujourd'hui", limite: rangSoin }; if (options.portee === undefined) options.portee = 0; @@ -30822,7 +30953,7 @@ var COFantasy = COFantasy || function() { if (options.dose === undefined && options.limiteParJour === undefined) options.limiteAttribut = { nom: 'attributDeCombat_soinsDeGroupe', - message: " a d\xE9j\xE0 fait un soin de groupe durant ce combat", + message: " a déjà fait un soin de groupe durant ce combat", limite: 1 }; if (options.puissant) soins = "[[1d10"; @@ -30841,14 +30972,14 @@ var COFantasy = COFantasy || function() { case 'secondSouffle': { if (!stateCOF.combat) { - whisperChar(charId, " ne peut pas utiliser la capacit\xE9 second souffle en dehors des combats"); + whisperChar(charId, " ne peut pas utiliser la capacité second souffle en dehors des combats"); return; } effet = "second souffle"; if (options.dose === undefined && options.limiteParJour === undefined) options.limiteAttribut = { nom: 'secondSouffleUtilise', - message: " a d\xE9j\xE0 repris son souffle durant ce combat", + message: " a déjà repris son souffle durant ce combat", limite: 1 }; soins = "[[1d10+"; @@ -30858,8 +30989,8 @@ var COFantasy = COFantasy || function() { soins += "]]"; cible = soigneur; options.recuperation = true; - if (bonus == -1 || bonus > 0) { //Il y a un pr\xE9dicat second souffle - //On limite les soins \xE0 ce qui a \xE9t\xE9 perdu dans ce combat + if (bonus == -1 || bonus > 0) { //Il y a un prédicat second souffle + //On limite les soins à ce qui a été perdu dans ce combat const pvDebut = attributeAsInt(soigneur, 'PVsDebutCombat', 0); let pv = parseInt(soigneur.token.get('bar1_value')); if (isNaN(pv)) return; @@ -30908,7 +31039,7 @@ var COFantasy = COFantasy || function() { const playerId = getPlayerIdFromMsg(msg); if (options.tempeteDeMana && soigneur) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options const optMana = { mana: options.mana, rang: options.rang, @@ -30920,7 +31051,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(soigneur, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPerso(soigneur, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -30929,7 +31060,7 @@ var COFantasy = COFantasy || function() { soins = res[0].inlinerolls[0].results.total; let soinTxt = buildinline(res[0].inlinerolls[0], 'normal', true); if (soins <= 0) { - sendChar(charId, "ne r\xE9ussit pas \xE0 soigner (total de soins " + soinTxt + ")", true); + sendChar(charId, "ne réussit pas à soigner (total de soins " + soinTxt + ")", true); return; } const evt = { @@ -30962,7 +31093,7 @@ var COFantasy = COFantasy || function() { if (nbCibles > 1) { display = startFramedDisplay(playerId, effet, soigneur); } else if (nbCibles === 0) { - sendChar(charId, "personne \xE0 soigner", true); + sendChar(charId, "personne à soigner", true); return; } iterSelected(selected, callback); @@ -30979,7 +31110,7 @@ var COFantasy = COFantasy || function() { else sendChar(charId, message, true); }); } - if (display) sendChat("", endFramedDisplay(display)); + if (display) sendFramedDisplay(display); if (ressourceLimiteSoinsParJour) { whisperChar(charId, "peut encore soigner de " + attributeAsInt(soigneur, ressourceLimiteSoinsParJour, options.limiteSoinsParJour) + " PV aujourd'hui."); } @@ -31008,7 +31139,7 @@ var COFantasy = COFantasy || function() { let utilisations = attributeAsInt(cible, ressourceLimiteCibleParJour, options.limiteCibleParJour); if (utilisations === 0) { - sendPerso(cible, "ne peut plus b\xE9n\xE9ficier de " + effet + " aujourd'hui"); + sendPerso(cible, "ne peut plus bénéficier de " + effet + " aujourd'hui"); finSoin(); return; } @@ -31044,11 +31175,11 @@ var COFantasy = COFantasy || function() { return; } if (display) { - addLineToFramedDisplay(display, "R\xE9sultat des d\xE9s : " + soinTxt); + addLineToFramedDisplay(display, "Résultat des dés : " + soinTxt); } if (msg.content.includes(' --sacrifierPV')) { //paie autant de PV que soins if (soigneur === undefined) { - error("Il faut pr\xE9ciser qui est le soigneur pour utiliser l'option --sacrifierPV", msg.content); + error("Il faut préciser qui est le soigneur pour utiliser l'option --sacrifierPV", msg.content); soinImpossible = true; display = undefined; finSoin(); @@ -31083,7 +31214,7 @@ var COFantasy = COFantasy || function() { let pv = parseInt(cible.token.get('bar1_value')); if (isNaN(pv) || pv > 0) { let sort = (souffleDeVie > 0) ? "souffle de vie" : "premiers soins"; - let m = nomPerso(cible) + " n'est pas \xE0 0 PV, impossible d'utiliser " + sort + " pour " + onGenre(cible, 'lui', 'elle'); + let m = nomPerso(cible) + " n'est pas à 0 PV, impossible d'utiliser " + sort + " pour " + onGenre(cible, 'lui', 'elle'); if (display) addLineToFramedDisplay(display, m); else sendChar(charId, m, true); finSoin(); @@ -31103,7 +31234,7 @@ var COFantasy = COFantasy || function() { } } if (tropTard) { - let m = nomPerso(cible) + " est \xE0 0 PV depuis plus de 2 tours, impossible d'utiliser le souffle de vie pour " + onGenre(cible, 'lui', 'elle'); + let m = nomPerso(cible) + " est à 0 PV depuis plus de 2 tours, impossible d'utiliser le souffle de vie pour " + onGenre(cible, 'lui', 'elle'); if (display) addLineToFramedDisplay(display, m); else sendChar(charId, m, true); finSoin(); @@ -31127,7 +31258,7 @@ var COFantasy = COFantasy || function() { if (display) { addLineToFramedDisplay(display, "" + nomCible + " : pas besoin de soins."); } else { - var maxMsg = "n'a pas besoin de "; + let maxMsg = "n'a pas besoin de "; if (options.recuperation) { maxMsg = "se reposer"; charId = soigneur.charId; @@ -31137,7 +31268,7 @@ var COFantasy = COFantasy || function() { } else { maxMsg += "soigner " + nomCible; } - sendChar(charId, maxMsg + ". " + Sujet + " est d\xE9j\xE0 au maximum de PV", true); + sendChar(charId, maxMsg + ". " + Sujet + " est déjà au maximum de PV", true); } }; let extraImg = afficheOptionImage(options); @@ -31157,9 +31288,9 @@ var COFantasy = COFantasy || function() { msgSoin = 'soigne ' + nomCible; } msgSoin += " de "; - if (options.recuperation) msgSoin = "r\xE9cup\xE8re "; + if (options.recuperation) msgSoin = "récupère "; if (limiteSoinsAtteinte || s != soins) - msgSoin += s + " PV. (Le r\xE9sultat du jet \xE9tait " + soinTxt + ")"; + msgSoin += s + " PV. (Le résultat du jet était " + soinTxt + ")"; else msgSoin += soinTxt + " PV."; msgSoin += extraImg; sendChar(charId, msgSoin, true); @@ -31168,7 +31299,7 @@ var COFantasy = COFantasy || function() { let callTrueFinal = printTrue; if (msg.content.includes(' --transfer')) { //paie avec ses PV if (soigneur === undefined) { - error("Il faut pr\xE9ciser qui est le soigneur pour utiliser l'option --transfer", msg.content); + error("Il faut préciser qui est le soigneur pour utiliser l'option --transfer", msg.content); soinImpossible = true; finSoin(); return; @@ -31194,11 +31325,11 @@ var COFantasy = COFantasy || function() { }; } if (options.fx) { - var p1e = { + let p1e = { x: soigneur.token.get('left'), y: soigneur.token.get('top'), }; - var p2e = { + let p2e = { x: cible.token.get('left'), y: cible.token.get('top'), }; @@ -31211,15 +31342,15 @@ var COFantasy = COFantasy || function() { soigneToken(cible, soins, evt, callTrueFinal, callMax, options); finSoin(); }); //fin de iterCibles - }); //fin du sendChat du jet de d\xE9s + }); //fin du sendChat du jet de dés } catch (e) { if (soins) { log(msg.content); - log("L'expression des soins \xE9tait " + soins + ", et il y a eu une erreur durant son \xE9valuation"); + log("L'expression des soins était " + soins + ", et il y a eu une erreur durant son évaluation"); if (argSoin) { - error("L'expression des soins (" + argSoin + ") n'est pas bien form\xE9e", msg.content); + error("L'expression des soins (" + argSoin + ") n'est pas bien formée", msg.content); } else { - error("Erreur pendant l'\xE9valuation de l'expression des soins. Plus d'informations dans le log", msg); + error("Erreur pendant l'évaluation de l'expression des soins. Plus d'informations dans le log", msg); } } else { error("Erreur pendant les soins ", msg.content); @@ -31263,7 +31394,7 @@ var COFantasy = COFantasy || function() { } function ajouterConsommable(perso, nom, nb, action, evt) { - if (perso.token.get('bar1_link') === '') { //Perso non li\xE9, on utilise un attribut + if (perso.token.get('bar1_link') === '') { //Perso non lié, on utilise un attribut let attrName = 'dose_' + nom; let attr = tokenAttribute(perso, attrName); if (attr.length > 0) { @@ -31285,7 +31416,7 @@ var COFantasy = COFantasy || function() { maxVal: action }); } - } else { //On va mettre les consommables dans l'\xE9quipement + } else { //On va mettre les consommables dans l'équipement let attributes = findObjs({ _type: 'attribute', _characterid: perso.charId @@ -31335,7 +31466,7 @@ var COFantasy = COFantasy || function() { }); return true; }); - // si le consommable n'a pas \xE9t\xE9 trouv\xE9, on le cr\xE9e avec une valeur de nb + // si le consommable n'a pas été trouvé, on le crée avec une valeur de nb if (!found) { let pref = 'repeating_equipement_' + generateRowID() + '_'; let attre = createObj("attribute", { @@ -31370,12 +31501,12 @@ var COFantasy = COFantasy || function() { } function parseNatureNourriciere(msg) { - var options = parseOptions(msg); + const options = parseOptions(msg); getSelected(msg, function(selected) { iterSelected(selected, function(lanceur) { - var voieDeLaSurvie = predicateAsInt(lanceur, 'voieDeLaSurvie', 0); + let voieDeLaSurvie = predicateAsInt(lanceur, 'voieDeLaSurvie', 0); if (voieDeLaSurvie < 1) { - sendPerso(lanceur, " ne conna\xEEt pas la Voie de la Survie ?"); + sendPerso(lanceur, " ne connaît pas la Voie de la Survie ?"); } doNatureNourriciere(lanceur, options); }); @@ -31392,34 +31523,34 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - var voieDeLaSurvie = predicateAsInt(perso, 'voieDeLaSurvie', 0); - var trouveBaies = predicateAsBool(perso, 'natureNourriciereBaies'); + let voieDeLaSurvie = predicateAsInt(perso, 'voieDeLaSurvie', 0); + let trouveBaies = predicateAsBool(perso, 'natureNourriciereBaies'); if (options.rolls && options.rolls.duree) { evt.action.rolls.duree = options.rolls.duree; } else { evt.action.rolls.duree = rollDePlus(6); } - var output = "cherche des herbes. "; + let output = "cherche des herbes. "; if (trouveBaies) output = "cherche des baies. "; - output += "Apr\xE8s " + evt.action.rolls.duree.roll + " heure"; + output += "Après " + evt.action.rolls.duree.roll + " heure"; if (evt.action.rolls.duree.val > 1) output += "s"; output += ", " + onGenre(perso, "il", "elle"); - var testId = 'natureNourriciere'; + const testId = 'natureNourriciere'; testCaracteristique(perso, 'SAG', 10, testId, options, evt, function(tr) { - var post = ""; + let post = ""; if ((tr.reussite && !trouveBaies) || (trouveBaies && !tr.reussite && tr.valeur > 7)) { if (voieDeLaSurvie > 0) { - output += " revient avec " + voieDeLaSurvie + " plantes m\xE9dicinales." + tr.modifiers; - var actionHerbes = "!cof-soin @{selected|token_id} @{selected|token_id} 1d6"; - ajouterConsommable(perso, 'Plante m\xE9dicinale', voieDeLaSurvie, actionHerbes, evt); + output += " revient avec " + voieDeLaSurvie + " plantes médicinales." + tr.modifiers; + let actionHerbes = "!cof-soin @{selected|token_id} @{selected|token_id} 1d6"; + ajouterConsommable(perso, 'Plante médicinale', voieDeLaSurvie, actionHerbes, evt); } else { - output += " revient avec de quoi soigner les bless\xE9s." + tr.modifiers; + output += " revient avec de quoi soigner les blessés." + tr.modifiers; } } else if (tr.reussite && trouveBaies) { - var niveau = ficheAttributeAsInt(perso, 'niveau', 1); - var actionBaies = "!cof-consommer-baie " + niveau + " --limiteParJour 1 baieMagique"; - var nbBaies = voieDeLaSurvie + Math.floor((tr.valeur - 10) / 2); + let niveau = ficheAttributeAsInt(perso, 'niveau', 1); + let actionBaies = "!cof-consommer-baie " + niveau + " --limiteParJour 1 baieMagique"; + let nbBaies = voieDeLaSurvie + Math.floor((tr.valeur - 10) / 2); if (nbBaies === 0) nbBaies = 1; output += " revient avec " + nbBaies + " baies magiques." + tr.modifiers; ajouterConsommable(perso, 'Baie magique', nbBaies, actionBaies, evt); @@ -31437,10 +31568,10 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; let evtARefaire = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } @@ -31448,11 +31579,11 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(chevalier) { let token = chevalier.token; if (attributeAsInt(chevalier, 'douleurIgnoree', 0) > 0) { - sendPerso(chevalier, "a d\xE9j\xE0 ignor\xE9 la doubleur une fois pendant ce combat"); + sendPerso(chevalier, "a déjà ignoré la doubleur une fois pendant ce combat"); return; } if (evtARefaire === undefined || evtARefaire.type === undefined || !evtARefaire.type.startsWith('Attaque')) { - sendPerso(chevalier, "s'y prend trop tard pour ignorer la douleur : la derni\xE8re action n'\xE9tait pas une attaque"); + sendPerso(chevalier, "s'y prend trop tard pour ignorer la douleur : la dernière action n'était pas une attaque"); return; } let aIgnore; @@ -31460,18 +31591,18 @@ var COFantasy = COFantasy || function() { type: 'ignorer la douleur' }; let PVid = token.get('bar1_link'); - if (PVid === '') { //token non li\xE9, effets seulement sur le token. + if (PVid === '') { //token non lié, effets seulement sur le token. if (evtARefaire.affecte) { let affecte = evtARefaire.affectes[token.id]; if (affecte && affecte.prev) { let lastBar1 = affecte.prev.bar1_value; let bar1 = parseInt(token.get('bar1_value')); if (isNaN(lastBar1) || isNaN(bar1) || lastBar1 <= bar1) { - //On regarde la barre 2, peut-\xEAtre qu'il s'agit de DM temporaires + //On regarde la barre 2, peut-être qu'il s'agit de DM temporaires let lastBar2 = affecte.prev.bar2_value; let bar2 = parseInt(token.get('bar2_value')); if (isNaN(lastBar2) || isNaN(bar2) || bar2 <= lastBar2) { - sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la derni\xE8re attaque ne lui ait pas enlev\xE9 de PV"); + sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la dernière attaque ne lui ait pas enlevé de PV"); return; } updateCurrentBar(chevalier, 2, lastBar2, evt); @@ -31484,7 +31615,7 @@ var COFantasy = COFantasy || function() { } } } - } else { // token li\xE9, il faut regarder l'attribut + } else { // token lié, il faut regarder l'attribut let attrPV = evtARefaire.attributes.find(function(attr) { return (attr.attribute.id == PVid); }); @@ -31492,13 +31623,13 @@ var COFantasy = COFantasy || function() { let lastPV = attrPV.current; let newPV = attrPV.attribute.get('current'); if (isNaN(lastPV) || isNaN(newPV) || lastPV <= newPV) { - sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la derni\xE8re attaque ne lui ait pas enlev\xE9 de PV"); + sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la dernière attaque ne lui ait pas enlevé de PV"); return; } updateCurrentBar(chevalier, 1, lastPV, evt); setTokenAttr(chevalier, 'douleurIgnoree', lastPV - newPV, evt); aIgnore = true; - } else { //peut-\xEAtre qu'il s'agit de DM temporaires + } else { //peut-être qu'il s'agit de DM temporaires PVid = token.get('bar2_link'); attrPV = evtARefaire.attributes.find(function(attr) { return (attr.attribute.id == PVid); @@ -31507,7 +31638,7 @@ var COFantasy = COFantasy || function() { let lastDmTemp = attrPV.current; let newDmTemp = attrPV.attribute.get('current'); if (isNaN(lastDmTemp) || isNaN(newDmTemp) || newDmTemp <= lastDmTemp) { - sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la derni\xE8re attaque ne lui ait pas augment\xE9 les DM temporaires"); + sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la dernière attaque ne lui ait pas augmenté les DM temporaires"); return; } updateCurrentBar(chevalier, 2, lastDmTemp, evt); @@ -31517,10 +31648,10 @@ var COFantasy = COFantasy || function() { } } if (aIgnore) { - sendPerso(chevalier, " ignore la douleur de la derni\xE8re attaque"); + sendPerso(chevalier, " ignore la douleur de la dernière attaque"); addEvent(evt); } else { - sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la derni\xE8re attaque ne l'ait pas affect\xE9"); + sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la dernière attaque ne l'ait pas affecté"); } }); }); @@ -31531,7 +31662,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("La fonction !cof-fortifiant attend en argument le rang dans la Voie des \xE9lixirs du cr\xE9ateur", cmd); + error("La fonction !cof-fortifiant attend en argument le rang dans la Voie des élixirs du créateur", cmd); return; } const rang = parseInt(cmd[1]); @@ -31552,9 +31683,9 @@ var COFantasy = COFantasy || function() { }); sendPerso(beneficiaire, " boit un fortifiant"); soigneToken(beneficiaire, soins.val, evt, function(soinsEffectifs) { - let msgSoins = "et est soign\xE9 de "; + let msgSoins = "et est soigné de "; if (soinsEffectifs == soins.val) msgSoins += soins.roll + " PV"; - else msgSoins += soinsEffectifs + " PV (le jet \xE9tait " + soins.roll + ")"; + else msgSoins += soinsEffectifs + " PV (le jet était " + soins.roll + ")"; sendPerso(beneficiaire, msgSoins); }); // Finalement on met l'effet fortifie @@ -31564,7 +31695,7 @@ var COFantasy = COFantasy || function() { } //Appliquer une huile instable sur l'arme de la cible - // Par d\xE9faut, c'est l'arme en main de la cible + // Par défaut, c'est l'arme en main de la cible // TODO: le faire pour les projectiles // !cof-huile-instable @{target|token_id} function huileInstable(msg) { @@ -31613,7 +31744,7 @@ var COFantasy = COFantasy || function() { _id: options.lanceur.token.id }]; } else { - error("Pas de token s\xE9lection\xE9e pour !cof-lancer-sort", cmd); + error("Pas de token sélectionée pour !cof-lancer-sort", cmd); return; } } @@ -31625,7 +31756,7 @@ var COFantasy = COFantasy || function() { let lanceur = options.lanceur; if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, dm: false, @@ -31638,7 +31769,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(lanceur, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPerso(lanceur, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -31651,7 +31782,7 @@ var COFantasy = COFantasy || function() { if (!options.lanceur) { if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options const optMana = { mana: options.mana, dm: false, @@ -31664,7 +31795,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(cible, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPerso(cible, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -31714,11 +31845,11 @@ var COFantasy = COFantasy || function() { sendChat(nomPerso, cmd.join(' ')); } - // Renvoie la dur\xE9e mise \xE0 jour ou undefined si l'action n'est pas possible + // Renvoie la durée mise à jour ou undefined si l'action n'est pas possible function lancerMurDeForce(lanceur, playerId, duree, msg, typeMur, evt, options) { if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, dm: false, @@ -31731,7 +31862,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(lanceur, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPerso(lanceur, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -31754,7 +31885,7 @@ var COFantasy = COFantasy || function() { } //!cof-mur-de-force [opt] [duree] - // opt peut \xEAtre mur, noImage ou vent + // opt peut être mur, noImage ou vent // On peut changer la taille du mur avec l'option --portee. function murDeForce(msg) { let options = parseOptions(msg); @@ -31784,13 +31915,13 @@ var COFantasy = COFantasy || function() { if (cmd.length > 2) { duree = parseInt(cmd[2]); if (isNaN(duree) || duree < 1) { - error("Le deuxi\xE8me argument de !cof-mur-de-force doit \xEAtre une dur\xE9e", cmd); + error("Le deuxième argument de !cof-mur-de-force doit être une durée", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Aucun personnage s\xE9lectionn\xE9 pour lancer le mur de " + typeMur, playerId); + sendPlayer(msg, "Aucun personnage sélectionné pour lancer le mur de " + typeMur, playerId); return; } const evt = { @@ -31843,7 +31974,7 @@ var COFantasy = COFantasy || function() { if (options.puissantDuree || options.tempeteDeManaDuree) duree += duree; setAttrDuree(cible, 'murDeForce', duree, evt); } else { - error("Impossible de cr\xE9er l'image " + options.image, imageFields); + error("Impossible de créer l'image " + options.image, imageFields); } } else { sendPlayerAndGM(msg, playerId, "placer l'image du mur sur la carte"); @@ -31890,7 +32021,7 @@ var COFantasy = COFantasy || function() { } else { capitaine = persoOfId(cmd[1], cmd[1]); if (capitaine === undefined) { - error("Le premier argument de !cof-capitaine doit \xEAtre un token", cmd[1]); + error("Le premier argument de !cof-capitaine doit être un token", cmd[1]); return; } setState(capitaine, 'chef', true, evt); @@ -31898,7 +32029,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 2 && !cmd[2].startsWith('--')) { bonus = parseInt(cmd[2]); if (isNaN(bonus) || bonus < 0) { - error("Le bonus de capitaine (second argument) doit \xEAtre un nombre positif", cmd); + error("Le bonus de capitaine (second argument) doit être un nombre positif", cmd); return; } if (bonus === 0) remove = true; @@ -31907,7 +32038,7 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected) { if (selected.length === 0) { - error("Pas de token s\xE9lectionn\xE9 pour !cof-capitaine"); + error("Pas de token sélectionné pour !cof-capitaine"); return; } iterSelected(selected, function(perso) { @@ -31932,12 +32063,12 @@ var COFantasy = COFantasy || function() { function distribuerBaies(msg) { if (msg.selected === undefined || msg.selected.length != 1) { - error("Pour utiliser !cof-distribuer-baies, il faut s\xE9lectionner un token", msg); + error("Pour utiliser !cof-distribuer-baies, il faut sélectionner un token", msg); return; } let druide = persoOfId(msg.selected[0]._id); if (druide === undefined) { - error("Erreur de s\xE9lection dans !cof-distribuer-baies", msg.selected); + error("Erreur de sélection dans !cof-distribuer-baies", msg.selected); return; } let niveau = ficheAttributeAsInt(druide, 'niveau', 1); @@ -31951,13 +32082,13 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(perso) { let nom = nomPerso(perso); ajouterConsommable(perso, 'Baie magique', 1, mangerBaie, evt); - let line = nom + " re\xE7oit une baie"; + let line = nom + " reçoit une baie"; if (perso.token.id == druide.token.id) line = nom + " en garde une pour " + onGenre(druide, "lui", "elle"); addLineToFramedDisplay(display, line); }); addEvent(evt); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }, { lanceur: druide }); //fin du getSelected @@ -31969,17 +32100,17 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd.length < 2) { - error("Il faut un argument \xE0 !cof-consommer-baie", cmd); + error("Il faut un argument à !cof-consommer-baie", cmd); return; } let baie = parseInt(cmd[1]); if (isNaN(baie) || baie < 0) { - error("L'argument de !cof-consommer-baie doit \xEAtre un nombre positif", cmd); + error("L'argument de !cof-consommer-baie doit être un nombre positif", cmd); return; } getSelected(msg, function(selected, playerId) { if (selected === undefined) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof-consommer-baie", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof-consommer-baie", playerId); return; } const evt = { @@ -31987,21 +32118,21 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); iterSelected(selected, function(perso) { - if (limiteRessources(perso, options, 'baieMagique', "a d\xE9j\xE0 mang\xE9 une baie aujourd'hui. Pas d'effet.", evt)) return; + if (limiteRessources(perso, options, 'baieMagique', "a déjà mangé une baie aujourd'hui. Pas d'effet.", evt)) return; let soins = rollDePlus(6, { bonus: baie }); soigneToken(perso, soins.val, evt, function(soinsEffectifs) { let msgSoins = "mange une baie magique. " + - onGenre(perso, "Il est rassasi\xE9", "Elle est rassasi\xE9e") + - " et r\xE9cup\xE8re "; + onGenre(perso, "Il est rassasié", "Elle est rassasiée") + + " et récupère "; if (soinsEffectifs == soins.val) msgSoins += soins.roll + " points de vie"; - else msgSoins += soinsEffectifs + " PV (le jet \xE9tait " + soins.roll + ")"; + else msgSoins += soinsEffectifs + " PV (le jet était " + soins.roll + ")"; sendPerso(perso, msgSoins); }, function() { - sendPerso(perso, "mange une baie magique. " + onGenre(perso, "Il", "Elle") + " se sent rassasi\xE9" + onGenre(perso, '', 'e') + '.'); + sendPerso(perso, "mange une baie magique. " + onGenre(perso, "Il", "Elle") + " se sent rassasié" + onGenre(perso, '', 'e') + '.'); }); }); }); //fin de getSelected @@ -32021,9 +32152,9 @@ var COFantasy = COFantasy || function() { } } - /* Quand on prot\xE8ge un alli\xE9, on stocke l'idName dans un attribut 'protegerUnAllie', et pour ce token, on met un - * attribut 'protegePar_nom' o\xF9 nom est le nom du token protecteur, et qui contient l'idName du protecteur - * Ces attributs disparaissent \xE0 la fin des combats */ + /* Quand on protège un allié, on stocke l'idName dans un attribut 'protegerUnAllie', et pour ce token, on met un + * attribut 'protegePar_nom' où nom est le nom du token protecteur, et qui contient l'idName du protecteur + * Ces attributs disparaissent à la fin des combats */ function protegerUnAllie(msg) { let args = msg.content.split(' '); if (args.length < 3) { @@ -32040,27 +32171,27 @@ var COFantasy = COFantasy || function() { let pageId = tokenProtecteur.get('pageid'); let target = persoOfId(args[2], args[2], pageId); if (target === undefined) { - error("Le deuxi\xE8me argument n'est pas un token valide: " + msg.content, args[2]); + error("Le deuxième argument n'est pas un token valide: " + msg.content, args[2]); return; } let tokenTarget = target.token; if (tokenTarget.id == tokenProtecteur.id) { - sendPerso(protecteur, "ne peut pas se prot\xE9ger i" + onGenre(protecteur, 'lui', 'elle') + "-m\xEAme"); + sendPerso(protecteur, "ne peut pas se protéger i" + onGenre(protecteur, 'lui', 'elle') + "-même"); return; } const nameTarget = nomPerso(target); const evt = { - type: "Prot\xE9ger un alli\xE9" + type: "Protéger un allié" }; let attrsProtecteur = tokenAttribute(protecteur, 'protegerUnAllie'); let protegePar = 'protegePar_' + nameProtecteur; let other; - if (attrsProtecteur.length > 0) { //On prot\xE8ge d\xE9j\xE0 quelqu'un + if (attrsProtecteur.length > 0) { //On protège déjà quelqu'un let previousTarget = persoOfIdName(attrsProtecteur[0].get('current'), pageId); if (previousTarget) { if (previousTarget.token.id == tokenTarget.id) { - sendPerso(protecteur, "prot\xE8ge d\xE9j\xE0 " + nameTarget); + sendPerso(protecteur, "protège déjà " + nameTarget); return; } if (predicateAsBool(protecteur, 'protegerUnAllieAvance')) { @@ -32068,25 +32199,25 @@ var COFantasy = COFantasy || function() { persoOfIdName(attrsProtecteur[0].get('max'), pageId); if (previousTarget2) { if (previousTarget2.token.id == tokenTarget.id) { - sendPerso(protecteur, "prot\xE8ge d\xE9j\xE0 " + nameTarget); + sendPerso(protecteur, "protège déjà " + nameTarget); return; } removeTokenAttr(previousTarget2, protegePar, evt, { - msg: "n'est plus prot\xE9g\xE9 par " + nameProtecteur + msg: "n'est plus protégé par " + nameProtecteur }); } else { other = attrsProtecteur[0].get('current'); } } removeTokenAttr(previousTarget, protegePar, evt, { - msg: "n'est plus prot\xE9g\xE9 par " + nameProtecteur + msg: "n'est plus protégé par " + nameProtecteur }); } } let distTargetProtecteur = distanceCombat(target.token, protecteur.token, pageId); if (distTargetProtecteur > 0) { sendPerso(protecteur, "est trop loin de " + - nameTarget + " pour le prot\xE9ger"); + nameTarget + " pour le protéger"); return; } if (ficheAttributeAsInt(protecteur, 'defbouclieron', 0) === 0) { @@ -32105,24 +32236,24 @@ var COFantasy = COFantasy || function() { setTokenAttr(protecteur, 'protegerUnAllie', other, evt, opt); } setTokenAttr(target, protegePar, idName(protecteur), evt); - sendPerso(protecteur, "prot\xE8ge " + nameTarget); + sendPerso(protecteur, "protège " + nameTarget); addEvent(evt); } function actionDefensive(msg) { let combat = stateCOF.combat; if (!combat) { - sendPlayer(msg, "Il faut entrer en combat pour se d\xE9fendre"); + sendPlayer(msg, "Il faut entrer en combat pour se défendre"); return; } let cmd = msg.content.split(' '); - let def = 2; //pour une d\xE9fense simple - let defMsg = "pr\xE9f\xE8re se d\xE9fendre pendant ce tour"; + let def = 2; //pour une défense simple + let defMsg = "préfère se défendre pendant ce tour"; if (cmd.length > 1) { switch (cmd[1]) { case 'totale': def = 4; - defMsg = "se consacre enti\xE8rement \xE0 sa d\xE9fense pendant ce tour"; + defMsg = "se consacre entièrement à sa défense pendant ce tour"; break; case 'simple': def = 2; @@ -32132,7 +32263,7 @@ var COFantasy = COFantasy || function() { } } const evt = { - type: "action d\xE9fensive" + type: "action défensive" }; getSelected(msg, function(selected) { initiative(selected, evt); @@ -32160,7 +32291,7 @@ var COFantasy = COFantasy || function() { var pageId = necromancien.token.get('pageid'); var target = persoOfId(args[2], args[2], pageId); if (target === undefined) { - error("Le deuxi\xE8me argument n'est pas un token valide: " + msg.content, args[2]); + error("Le deuxième argument n'est pas un token valide: " + msg.content, args[2]); return; } let name2 = nomPerso(target); @@ -32176,7 +32307,7 @@ var COFantasy = COFantasy || function() { if (dureeStrang.length > 0) { nouvelleDuree = parseInt(dureeStrang[0].get('current')); if (isNaN(nouvelleDuree)) { - log("Dur\xE9e de strangulation n'est pas un nombre"); + log("Durée de strangulation n'est pas un nombre"); log(dureeStrang); nouvelleDuree = 1; } else nouvelleDuree++; @@ -32229,7 +32360,7 @@ var COFantasy = COFantasy || function() { } let duree = parseInt(cmd[3]); if (isNaN(duree) || duree <= 0) { - error("La dur\xE9e doit \xEAtre un nombre positif", cmd); + error("La durée doit être un nombre positif", cmd); return; } let image = options.image || stateCOF.options.images.val.image_ombre.val; @@ -32247,13 +32378,13 @@ var COFantasy = COFantasy || function() { let msgRes = "invoquer une ombre mortelle"; if (limiteRessources(lanceur, options, "Ombre_mortelle", msgRes, evt)) return; copieToken(cible, image, stateCOF.options.images.val.image_ombre.val, "Ombre de " + nomPerso(cible), 'ombreMortelle', duree, pageId, evt); - let msgOmbre = "anime l'ombre de " + cible.tokName + ". Celle-ci commence \xE0 attaquer " + cible.tokName + " !"; + let msgOmbre = "anime l'ombre de " + cible.tokName + ". Celle-ci commence à attaquer " + cible.tokName + " !"; if (options.secret) whisperChar(lanceur.charId, msgOmbre); else sendPerso(lanceur, msgOmbre); addEvent(evt); } - //renvoie l'attribut de l'effet temporaire cr\xE9\xE9 + //renvoie l'attribut de l'effet temporaire créé function copieToken(cible, image1, image2, nom, effet, duree, pageId, evt) { let pv = parseInt(cible.token.get('bar1_value')); if (isNaN(pv)) { @@ -32300,7 +32431,7 @@ var COFantasy = COFantasy || function() { newToken = createObj('graphic', tokenFields); } if (newToken === undefined) { - error("L'image du token s\xE9lectionn\xE9 n'a pas \xE9t\xE9 upload\xE9, et l'image par d\xE9faut n'est pas correcte. Impossible de cr\xE9er un token.", tokenFields); + error("L'image du token sélectionné n'a pas été uploadé, et l'image par défaut n'est pas correcte. Impossible de créer un token.", tokenFields); return; } } @@ -32316,7 +32447,7 @@ var COFantasy = COFantasy || function() { return attr; } - //retourne true si le joueur est effectivement d\xE9plac\xE9 + //retourne true si le joueur est effectivement déplacé function movePlayerToPage(pid, oldPageId, newPageId) { if (getObj('player', pid) === undefined) return; var c = Campaign(); @@ -32374,8 +32505,8 @@ var COFantasy = COFantasy || function() { function escalier(msg) { getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de s\xE9lection de token pour !cof-escalier", playerId); - log("!cof-escalier requiert de s\xE9lectionner des tokens"); + sendPlayer(msg, "Pas de sélection de token pour !cof-escalier", playerId); + log("!cof-escalier requiert de sélectionner des tokens"); return; } let pageId = getObj('graphic', selected[0]._id).get('pageid'); @@ -32459,7 +32590,7 @@ var COFantasy = COFantasy || function() { let left = sortieEscalier.get('left'); let top = sortieEscalier.get('top'); let newPageId = sortieEscalier.get('pageid'); - //D\xE9placement du token + //Déplacement du token if (newPageId == pageId) { token.set('left', left); token.set('top', top); @@ -32467,7 +32598,7 @@ var COFantasy = COFantasy || function() { //On change de carte, il faut donc copier le token var tokenObj = JSON.parse(JSON.stringify(token)); tokenObj._pageid = newPageId; - //On met la taille du token \xE0 jour en fonction des \xE9chelles des cartes. + //On met la taille du token à jour en fonction des échelles des cartes. var ratio = computeScale(pageId) / computeScale(newPageId); if (ratio < 0.9 || ratio > 1.1) { if (ratio < 0.25) ratio = 0.25; @@ -32484,12 +32615,12 @@ var COFantasy = COFantasy || function() { return; } } - //On d\xE9place ensuite le joueur. + //On déplace ensuite le joueur. let character = getObj('character', perso.charId); if (character === undefined) return; let charControlledby = character.get('controlledby'); if (charControlledby === '') { - //Seul le MJ contr\xF4le le personnage + //Seul le MJ contrôle le personnage let players = findObjs({ _type: 'player', online: true @@ -32507,7 +32638,7 @@ var COFantasy = COFantasy || function() { sendPing(left, top, newPageId, pid, true, pid); }); } - //Enfin, on efface le token de d\xE9part si on a chang\xE9 de page + //Enfin, on efface le token de départ si on a changé de page if (newPageId != pageId) token.remove(); return; } @@ -32539,10 +32670,10 @@ var COFantasy = COFantasy || function() { return; } var evt = { - type: "D\xE9faut dans la cuirasse" + type: "Défaut dans la cuirasse" }; setTokenAttr(cible, 'defautDansLaCuirasse_' + nomPerso(tireur), 2, evt); - sendPerso(tireur, "passe le tour \xE0 analyser les points faibles de " + nomPerso(cible)); + sendPerso(tireur, "passe le tour à analyser les points faibles de " + nomPerso(cible)); addEvent(evt); } @@ -32555,12 +32686,12 @@ var COFantasy = COFantasy || function() { var bonus = parseInt(args[1]); var attrDebuf = args[2]; if (attrDebuf != 'DEF' && attrDebuf != 'ATT' && attrDebuf != 'DM') { - error("L'attribut \xE0 d\xE9buffer pour la posture de combat est incorrect", args); + error("L'attribut à débuffer pour la posture de combat est incorrect", args); return; } var attrBuf = args[3]; if (attrBuf != 'DEF' && attrBuf != 'ATT' && attrBuf != 'DM') { - error("L'attribut \xE0 augmenter pour la posture de combat est incorrect", args); + error("L'attribut à augmenter pour la posture de combat est incorrect", args); return; } getSelected(msg, function(selected, playerId) { @@ -32571,7 +32702,7 @@ var COFantasy = COFantasy || function() { } var rang = predicateAsInt(guerrier, "voieDuSoldat", 0); if (rang > 0 && rang < bonus) { - sendPerso(guerrier, "ne peut choisir qu'un bonus inf\xE9rieur \xE0 " + rang + " pour sa posture de combat"); + sendPerso(guerrier, "ne peut choisir qu'un bonus inférieur à " + rang + " pour sa posture de combat"); return; } var evt = { @@ -32586,7 +32717,7 @@ var COFantasy = COFantasy || function() { msg = "prend une posture "; switch (attrBuf) { case 'DEF': - msg += "d\xE9fensive"; + msg += "défensive"; break; case 'ATT': msg += "offensive"; @@ -32599,10 +32730,10 @@ var COFantasy = COFantasy || function() { msg += " mais "; switch (attrDebuf) { case 'DEF': - msg += "risqu\xE9e"; + msg += "risquée"; break; case 'ATT': - msg += "moins pr\xE9cise"; + msg += "moins précise"; break; case 'DM': msg += "moins puissante"; @@ -32626,21 +32757,21 @@ var COFantasy = COFantasy || function() { } let bonus = parseInt(args[1]); if (bonus != 0 && bonus != 2 && bonus != 5) { - error("Le malus de DEF ne peut \xEAtre que 0, 2 ou 5", args); + error("Le malus de DEF ne peut être que 0, 2 ou 5", args); return; } getSelected(msg, function(selected) { iterSelected(selected, function(guerrier) { const evt = { - type: "Attaque \xE0 outrance" + type: "Attaque à outrance" }; if (bonus === 0) { - sendPerso(guerrier, "n'attaque plus \xE0 outrance"); + sendPerso(guerrier, "n'attaque plus à outrance"); removeTokenAttr(guerrier, 'attaqueAOutrance', evt); addEvent(evt); return; } - msg = "attaque \xE0 outrance "; + msg = "attaque à outrance "; switch (bonus) { case 2: msg += "(-2 DEF, +1D6 DM)"; @@ -32662,14 +32793,14 @@ var COFantasy = COFantasy || function() { var options = parseOptions(msg); var cmd = options.cmd; if (cmd < 2) { - error("Il manque un argument \xE0 !cof-tour-de-force", cmd); + error("Il manque un argument à !cof-tour-de-force", cmd); return; } var seuil = parseInt(cmd[1]); getSelected(msg, function(selected, playerId) { iterSelected(selected, function(barbare) { if (isNaN(seuil)) { - sendPlayer(msg, "le seuil de difficult\xE9 du tour de force doit \xEAtre un nombre", playerId); + sendPlayer(msg, "le seuil de difficulté du tour de force doit être un nombre", playerId); return; } doTourDeForce(barbare, seuil, options); @@ -32687,18 +32818,18 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - let action = "Capacit\xE9 : Tour de force"; + let action = "Capacité : Tour de force"; let display = startFramedDisplay(options.playerId, action, perso); let testId = 'tourDeForce'; options.bonus = 10; testCaracteristique(perso, 'FOR', seuil, testId, options, evt, function(tr) { - addLineToFramedDisplay(display, " Jet de force difficult\xE9 " + seuil); + addLineToFramedDisplay(display, " Jet de force difficulté " + seuil); let smsg = nomPerso(perso) + " fait " + tr.texte; if (tr.reussite) { - smsg += " => r\xE9ussite"; + smsg += " => réussite"; } else { - smsg += " => \xE9chec" + tr.rerolls; + smsg += " => échec" + tr.rerolls; } addLineToFramedDisplay(display, smsg); let d4 = options.rolls.tourDeForceDmg || rollDePlus(4); @@ -32712,12 +32843,12 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evt, false, {}, explications, function(dmgDisplay, dmg) { - let dmgMsg = "mais cela lui co\xFBte " + dmgDisplay + " PV"; + let dmgMsg = "mais cela lui coûte " + dmgDisplay + " PV"; addLineToFramedDisplay(display, dmgMsg); explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); } @@ -32736,41 +32867,41 @@ var COFantasy = COFantasy || function() { } } - //!cof-encaisser-un-coup, avec la personne qui encaisse s\xE9lectionn\xE9e + //!cof-encaisser-un-coup, avec la personne qui encaisse sélectionnée function doEncaisserUnCoup(msg) { var optionsEncaisser = parseOptions(msg); if (optionsEncaisser === undefined) return; var cmd = optionsEncaisser.cmd; var evt = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Personne n'est s\xE9lectionn\xE9 pour encaisser un coup", msg); + error("Personne n'est sélectionné pour encaisser un coup", msg); return; } if (evt === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour encaisser un coup"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour encaisser un coup"); return; } if (evt.type != 'Attaque' || evt.succes === false) { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour encaisser le coup d'une action pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour encaisser le coup d'une action précédente"); return; } var action = evt.action; if (action.options.distance) { - sendChat('', "Impossible d'encaisser le dernier coup, ce n'\xE9tait pas une attaque au contact"); + sendChat('', "Impossible d'encaisser le dernier coup, ce n'était pas une attaque au contact"); return; } var toProceed; iterSelected(selected, function(chevalier) { if (!attributeAsBool(chevalier, 'encaisserUnCoup')) { - sendPerso(chevalier, "n'est pas plac\xE9 pour encaisser un coup"); + sendPerso(chevalier, "n'est pas placé pour encaisser un coup"); return; } if (!peutController(msg, chevalier)) { @@ -32781,7 +32912,7 @@ var COFantasy = COFantasy || function() { return (target.token.id === chevalier.token.id); }); if (cible === undefined) { - sendPerso(chevalier, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(chevalier, "n'est pas la cible de la dernière attaque"); return; } action.choices = action.choices || {}; @@ -32804,40 +32935,40 @@ var COFantasy = COFantasy || function() { removePreDmg(options, cible, "encaisserUnCoup"); } - //!cof-devier-les-coups, avec la personne qui encaisse s\xE9lectionn\xE9e + //!cof-devier-les-coups, avec la personne qui encaisse sélectionnée function doDevierLesCoups(msg) { let optionsDevier = parseOptions(msg); if (optionsDevier === undefined) return; let cmd = optionsDevier.cmd; let evt = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Personne n'est s\xE9lectionn\xE9 pour d\xE9vier les coups", msg); + error("Personne n'est sélectionné pour dévier les coups", msg); return; } if (evt === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour d\xE9vier les coups"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour dévier les coups"); return; } if (evt.type != 'Attaque' || evt.succes === false) { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour d\xE9vier les coups d'une action pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour dévier les coups d'une action précédente"); return; } var action = evt.action; if (action.options.distance) { - sendChat('', "Impossible d'encaisser le dernier coup, ce n'\xE9tait pas une attaque au contact"); + sendChat('', "Impossible d'encaisser le dernier coup, ce n'était pas une attaque au contact"); return; } let toProceed; iterSelected(selected, function(perso) { - let testDevierCoups = testLimiteUtilisationsCapa(perso, 'devierLesCoups', 'tour', "ne peut plus d\xE9vier les coups \xE0 ce tour-ci"); + let testDevierCoups = testLimiteUtilisationsCapa(perso, 'devierLesCoups', 'tour', "ne peut plus dévier les coups à ce tour-ci"); if (testDevierCoups === undefined) return; if (!peutController(msg, perso)) { sendPlayer(msg, "pas le droit d'utiliser ce bouton", playerId); @@ -32847,7 +32978,7 @@ var COFantasy = COFantasy || function() { return (target.token.id === perso.token.id); }); if (cible === undefined) { - sendPerso(perso, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(perso, "n'est pas la cible de la dernière attaque"); return; } action.choices = action.choices || {}; @@ -32866,9 +32997,7 @@ var COFantasy = COFantasy || function() { function appliquerDevierLesCoups(cible, test, options, evt) { utiliseCapacite(cible, test, evt); - cible.extraRDBouclier = - ficheAttributeAsInt(cible, 'defbouclier', 0) * - ficheAttributeAsInt(cible, 'defbouclieron', 0); + cible.extraRDBouclier = defenseBouclier(cible); removePreDmg(options, cible, 'devierLesCoups'); } @@ -32878,33 +33007,33 @@ var COFantasy = COFantasy || function() { if (optionsParade === undefined) return; var cmd = optionsParade.cmd; var evt = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Personne n'est s\xE9lectionn\xE9 pour parer le projectile", msg); + error("Personne n'est sélectionné pour parer le projectile", msg); return; } if (evt === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour parer le projectile"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour parer le projectile"); return; } if (evt.type != 'Attaque' || evt.succes === false) { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour parer le projectile d'une action pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour parer le projectile d'une action précédente"); return; } var action = evt.action; if (!action.options.distance) { - sendChat('', "Impossible de parer le projectile, ce n'\xE9tait pas une attaque \xE0 distance"); + sendChat('', "Impossible de parer le projectile, ce n'était pas une attaque à distance"); return; } if (action.options.poudre) { - sendChat('', "Impossible de parer le projectile, il s'agit d'une arme \xE0 poudre"); + sendChat('', "Impossible de parer le projectile, il s'agit d'une arme à poudre"); return; } if (action.cibles.length > 1) { @@ -32925,7 +33054,7 @@ var COFantasy = COFantasy || function() { return (target.token.id === moine.token.id); }); if (cible === undefined) { - sendPerso(moine, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(moine, "n'est pas la cible de la dernière attaque"); return; } action.choices = action.choices || {}; @@ -32950,8 +33079,8 @@ var COFantasy = COFantasy || function() { // asynchrone : on fait les jets du personnage en opposition // options : - // predicat : on utilise un pr\xE9dicat et non un attribut. Peut \xEAtre 'tour' ou 'combat' - // protecteur: c'est un protecteur qui prot\xE8ge la cible (pas compatible avec predicate + // predicat : on utilise un prédicat et non un attribut. Peut être 'tour' ou 'combat' + // protecteur: c'est un protecteur qui protège la cible (pas compatible avec predicate function evitementGenerique(msg, verbe, attributeName, actionName, tente, msgDejaFait, carac, typeAttaque, msgReussite, opt) { let options = parseOptions(msg); if (options === undefined) return; @@ -32966,10 +33095,10 @@ var COFantasy = COFantasy || function() { } let evt; let chance; - if (cmd.length > 2) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 2) { //On relance pour un événement particulier evt = findEvent(cmd[2]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } chance = cmd.length > 3 && cmd[3] == 'chance'; @@ -32977,11 +33106,11 @@ var COFantasy = COFantasy || function() { evt = lastEvent(); } if (evt === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour esquiver"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour esquiver"); return; } if (evt.type != 'Attaque') { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour " + verbe + " l'attaque pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour " + verbe + " l'attaque précédente"); return; } const perso = persoOfId(cmd[1]); @@ -32996,12 +33125,12 @@ var COFantasy = COFantasy || function() { return (target.token.id === perso.token.id); }); if (cible === undefined) { - sendPerso(perso, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(perso, "n'est pas la cible de la dernière attaque"); return; } let attributAVerifier = attributeName; let persoAttribut = perso; - if (opt.protecteur) { // c'est un personnage tiers qui prot\xE8ge la cible + if (opt.protecteur) { // c'est un personnage tiers qui protège la cible let protecteurAttrs = tokenAttribute(perso, attributeName + 'Valeur'); if (protecteurAttrs.length < 1) { error("Erreur interne dans le bouton de protection, protecteur introuvable", cmd); @@ -33048,7 +33177,7 @@ var COFantasy = COFantasy || function() { } else { let curAttribut = parseInt(attribut.get('current')); if (isNaN(curAttribut)) { - error("Resource pour " + actionName + " mal form\xE9e", attribut); + error("Resource pour " + actionName + " mal formée", attribut); return; } if (curAttribut < 1) { @@ -33111,8 +33240,8 @@ var COFantasy = COFantasy || function() { } } else if (testPredicat) { utiliseCapacite(testPredicat.perso, testPredicat, evt); - } else if (attributeName !== undefined) { //ni attribut ni pr\xE9dicat - error("On n'a ni attribut ni pr\xE9dicat pour un \xE9vitement g\xE9n\xE9rique", evitementGen); + } else if (attributeName !== undefined) { //ni attribut ni prédicat + error("On n'a ni attribut ni prédicat pour un évitement générique", evitementGen); return; } let optDice; @@ -33194,17 +33323,17 @@ var COFantasy = COFantasy || function() { onGenre(lanceur, "Il", "elle") + " fait " + msg; var generalMsg = ''; if (totalEvitement < jetAdversaire) { - msg += " => Rat\xE9"; + msg += " => Raté"; var pc = pointsDeChance(lanceur); if (attackRoll.results.total != 1 && pc > 0) { generalMsg += '
' + boutonSimple("!cof-bouton-chance " + evt.id + " " + testId, "Chance") + " (reste " + pc + " PC)"; } - if (stateCOF.combat && attributeAsBool(lanceur, 'runeForgesort_\xE9nergie') && - attributeAsInt(lanceur, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0 && + if (stateCOF.combat && attributeAsBool(lanceur, 'runeForgesort_énergie') && + attributeAsInt(lanceur, 'limiteParCombat_runeForgesort_énergie', 1) > 0 && (carac == 'force' || carac == 'constitution' || carac == 'dexterite')) { - generalMsg += '
' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'\xE9nergie"); + generalMsg += '
' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'énergie"); } if (stateCOF.combat && capaciteDisponible(lanceur, 'petitVeinard', 'combat')) { generalMsg += '
' + boutonSimple("!cof-bouton-petit-veinard " + evt.id + " " + testId, "Petit veinard"); @@ -33214,23 +33343,23 @@ var COFantasy = COFantasy || function() { } else { //Sinon cacher le bouton mais laisser l'option reroll removePreDmg(options, cible, attributeName, 'reroll'); } - } else { //\xC9vitement r\xE9ussi + } else { //Évitement réussi if (opt && cible.critique && (opt.critiqueDevientNormal || (opt.critiqueAnnuleCritique && d20roll != 20))) { cible.critique = false; - msg += " => R\xE9ussi, l'attaque fait des d\xE9g\xE2ts normaux"; + msg += " => Réussi, l'attaque fait des dégâts normaux"; removePreDmg(options, cible, attributeName); } else { cible.touche = false; if (opt.annule) { delete options.preDmg; options.preDmgAnnule = true; - generalMsg += " => R\xE9ussi, " + msgReussite; + generalMsg += " => Réussi, " + msgReussite; } else { action.ciblesTouchees = action.ciblesTouchees.filter(function(c) { return c.token.id != cible.token.id; }); removePreDmg(options, cible); - msg += " => R\xE9ussi, " + msgReussite; + msg += " => Réussi, " + msgReussite; } } } @@ -33249,7 +33378,7 @@ var COFantasy = COFantasy || function() { }; evitementGenerique(msg, "absorber un coup au bouclier", 'absorberUnCoup', "d'absorption de coup au bouclier", "d'absorber un coup au bouclier", - " a d\xE9j\xE0 essay\xE9 d'absorber un coup au bouclier ce tour", 'force', 'contact', "le coup est absorb\xE9 !", { + " a déjà essayé d'absorber un coup au bouclier ce tour", 'force', 'contact', "le coup est absorbé !", { attrAsBool: true, condition, }); @@ -33266,7 +33395,7 @@ var COFantasy = COFantasy || function() { }; evitementGenerique(msg, "absorber un sort au bouclier", 'absorberUnSort', "d'absorption de sort au bouclier", "d'absorber un sort au bouclier", - " a d\xE9j\xE0 essay\xE9 d'absorber un sort au bouclier ce tour", 'sagesse', 'magique', "le sort est absorb\xE9 !", { + " a déjà essayé d'absorber un sort au bouclier ce tour", 'sagesse', 'magique', "le sort est absorbé !", { attrAsBool: true, condition: condition }); @@ -33275,10 +33404,10 @@ var COFantasy = COFantasy || function() { // asynchrone : on fait les jets du barbare en opposition //!cof-resister-a-la-magie id [evtid] [chance] function resisterALaMagie(msg) { - evitementGenerique(msg, 'r\xE9sister \xE0 la magie', 'resistanceALaMagieBarbare', - 'r\xE9sistance \xE0 la magie', "de r\xE9sister \xE0 la magie", - " a d\xE9j\xE0 essay\xE9 de r\xE9sister \xE0 la magie ce tour", - 'sagesse', 'magique', "il r\xE9siste \xE0 la magie !", { + evitementGenerique(msg, 'résister à la magie', 'resistanceALaMagieBarbare', + 'résistance à la magie', "de résister à la magie", + " a déjà essayé de résister à la magie ce tour", + 'sagesse', 'magique', "il résiste à la magie !", { predicat: 'tour' }); } @@ -33288,8 +33417,8 @@ var COFantasy = COFantasy || function() { function cercleDeProtection(msg) { evitementGenerique(msg, 'activer le cercle de protection', 'cercleDeProtection', 'activation du cercle de protection', "de bloquer le sort avec le Cercle de Protection", - " a d\xE9j\xE0 active le Cercle de Protection ce tour", - 'intelligence', 'magique', "le sort est annul\xE9 !", { + " a déjà active le Cercle de Protection ce tour", + 'intelligence', 'magique', "le sort est annulé !", { protecteur: true, annule: true }); @@ -33299,7 +33428,7 @@ var COFantasy = COFantasy || function() { //!cof-esquive-acrobatique id [evtid] [chance] function doEsquiveAcrobatique(msg) { evitementGenerique(msg, 'esquiver', 'esquiveAcrobatique', - 'esquive acrobatique', "une esquive acrobatique", " a d\xE9j\xE0 fait une esquive acrobatique ce tour", 'dexterite', 'distance', "l'attaque est esquiv\xE9e !", { + 'esquive acrobatique', "une esquive acrobatique", " a déjà fait une esquive acrobatique ce tour", 'dexterite', 'distance', "l'attaque est esquivée !", { critiqueDevientNormal: true, predicat: 'tour' }); @@ -33307,12 +33436,12 @@ var COFantasy = COFantasy || function() { function doEsquiveDeLaMagie(msg) { evitementGenerique(msg, 'esquiver', undefined, - "esquive de la magie", "d'esquiver la magie", " a d\xE9j\xE0 fait esquiv\xE9 la magie", 'dexterite', 'esquive', "l'attaque est esquiv\xE9e !", {}); + "esquive de la magie", "d'esquiver la magie", " a déjà fait esquivé la magie", 'dexterite', 'esquive', "l'attaque est esquivée !", {}); } function doEsquiveMagistrale(msg) { evitementGenerique(msg, 'esquiver', 'paradeMagistrale', - 'esquive acrobatique', "une esquive acrobatique", " a d\xE9j\xE0 fait une parade magistrale ce tour", 'dexterite', 'distance', "l'attaque est esquiv\xE9e !", { + 'esquive acrobatique', "une esquive acrobatique", " a déjà fait une parade magistrale ce tour", 'dexterite', 'distance', "l'attaque est esquivée !", { bonusAttaque: -5, critiqueDevientNormal: true, predicat: 'tour' @@ -33321,7 +33450,7 @@ var COFantasy = COFantasy || function() { function doParadeMagistrale(msg) { evitementGenerique(msg, 'parer', 'paradeMagistrale', - 'parade magistrale', "une parade magistrale", " a d\xE9j\xE0 fait une parade magistrale ce tour", 'dexterite', 'distance', "l'attaque est par\xE9e !", { + 'parade magistrale', "une parade magistrale", " a déjà fait une parade magistrale ce tour", 'dexterite', 'distance', "l'attaque est parée !", { arme: true, critiqueDevientNormal: true, predicat: 'tour' @@ -33331,7 +33460,7 @@ var COFantasy = COFantasy || function() { //!cof-parade-au-bouclier function doParadeAuBouclier(msg) { evitementGenerique(msg, 'parer', 'paradeAuBouclier', - 'parade au bouclier', "une parade au bouclier", " a d\xE9j\xE0 fait une parade au bouclier ce tour", 'force', 'contact', "l'attaque est par\xE9e !", { + 'parade au bouclier', "une parade au bouclier", " a déjà fait une parade au bouclier ce tour", 'force', 'contact', "l'attaque est parée !", { armeGauche: true, critiqueAnnuleCritique: true, predicat: 'tour' @@ -33339,7 +33468,7 @@ var COFantasy = COFantasy || function() { } //!cof-chair-a-canon id1 id2 [evt_id] - // id1 est l'id du pnj r\xE9current + // id1 est l'id du pnj récurrent // id2 est l'id du token qui se met devant l'attaque function doChairACanon(msg) { let options = parseOptions(msg); @@ -33350,13 +33479,13 @@ var COFantasy = COFantasy || function() { return; } let evtARefaire; - if (cmd.length > 3) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 3) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[3]); } else { evtARefaire = lastEvent(); } if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let pnjRec = persoOfId(cmd[1]); @@ -33368,7 +33497,7 @@ var COFantasy = COFantasy || function() { sendPlayer(msg, "pas le droit d'utiliser ce bouton"); return; } - let testChairACanon = testLimiteUtilisationsCapa(pnjRec, 'chairACanon', 'tour', "a d\xE9j\xE0 utilis\xE9 un sous-fifre ce tour", "ne sait pas utiliser ses sous-fifres pour se d\xE9fendre"); + let testChairACanon = testLimiteUtilisationsCapa(pnjRec, 'chairACanon', 'tour', "a déjà utilisé un sous-fifre ce tour", "ne sait pas utiliser ses sous-fifres pour se défendre"); if (testChairACanon === undefined) { return; } @@ -33378,11 +33507,11 @@ var COFantasy = COFantasy || function() { return; } if (evtARefaire === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour la chair \xE0 canon"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour la chair à canon"); return; } if (evtARefaire.type != 'Attaque') { - sendChat('', "la derni\xE8re action n'est pas une attaque"); + sendChat('', "la dernière action n'est pas une attaque"); return; } let attaque = evtARefaire.action; @@ -33407,7 +33536,7 @@ var COFantasy = COFantasy || function() { let optionsRedo = attaque.options; optionsRedo.rolls = attaque.rolls; let evt = { - type: "chair \xE0 canon" + type: "chair à canon" }; utiliseCapacite(pnjRec, testChairACanon, evt); undoEvent(evtARefaire); @@ -33416,7 +33545,7 @@ var COFantasy = COFantasy || function() { redoEvent(evtARefaire, attaque); } - // modifie res et le retourne (au cas o\xF9 il ne serait pas donn\xE9) + // modifie res et le retourne (au cas où il ne serait pas donné) function listRollResults(roll, res) { res = res || []; switch (roll.type) { @@ -33431,7 +33560,7 @@ var COFantasy = COFantasy || function() { roll.results.forEach(function(r) { if (r.v) res.push(r.v); else if (r.d) res.push(r.d); - else log("Type de r\xE9sultat de d\xE9 inconnu " + r); + else log("Type de résultat de dé inconnu " + r); }); return res; case 'M': @@ -33452,9 +33581,9 @@ var COFantasy = COFantasy || function() { return res; } - //category est un tableau de string, le premier \xE9l\xE9ment \xE9tant la cat\xE9gorie - //principale, le suivant la sous-cat\xE9gorie, etc - //value peut \xEAtre un nombre, un tableau de nombres, ou un inline roll + //category est un tableau de string, le premier élément étant la catégorie + //principale, le suivant la sous-catégorie, etc + //value peut être un nombre, un tableau de nombres, ou un inline roll function addStatistics(playerId, category, value) { if (stateCOF.statistiques === undefined) return; var stat = stateCOF.statistiques; @@ -33495,7 +33624,7 @@ var COFantasy = COFantasy || function() { nombre: 0, total: 0, }; - if (stats.nombre) { //on peut afficher des r\xE9sultats + if (stats.nombre) { //on peut afficher des résultats res.nombre = stats.nombre; res.total = stats.total; } @@ -33507,7 +33636,7 @@ var COFantasy = COFantasy || function() { res.nombre += catRes.nombre; res.total += catRes.total; } - var msg = "aucun jet cellect\xE9"; + var msg = "aucun jet cellecté"; if (res.nombre > 0) { var moyenne = res.total / res.nombre; msg = res.nombre + " jet" + ((res.nombre > 1) ? "s" : "") + ", moyenne " + moyenne; @@ -33529,8 +33658,8 @@ var COFantasy = COFantasy || function() { if (stats) addLineToFramedDisplay(display, "Statistiques en pause"); else { - addLineToFramedDisplay(display, "Aucune statistique collect\xE9e"); - sendChat("COF", endFramedDisplay(display)); + addLineToFramedDisplay(display, "Aucune statistique collectée"); + sendFramedDisplay(display); return; } } @@ -33563,7 +33692,7 @@ var COFantasy = COFantasy || function() { tot.nombre += catRes.nombre; } addLineToFramedDisplay(display, tot.nombre + " jets au total, dont la somme fait " + tot.total); - sendChat("COF", endFramedDisplay(display)); + sendFramedDisplay(display); } function parseDestructionDesMortsVivants(msg) { @@ -33571,7 +33700,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let args = options.cmd; if (args === undefined || args.length < 2) { - error("Il faut au moins un argument \xE0 !cof-destruction-des-morts-vivants", args); + error("Il faut au moins un argument à !cof-destruction-des-morts-vivants", args); return; } args.shift(); @@ -33584,11 +33713,11 @@ var COFantasy = COFantasy || function() { dm = dm.replace(/\]/g, ']'); getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Il faut s\xE9lectionner le lanceur de la destruction des morts-vivants", playerId); + sendPlayer(msg, "Il faut sélectionner le lanceur de la destruction des morts-vivants", playerId); return; } if (selected.length > 1) { - sendPlayer(msg, "Ne s\xE9lectionner qu'un token \xE0 la fois pour lancer la destruction des mort-vivants.", playerId); + sendPlayer(msg, "Ne sélectionner qu'un token à la fois pour lancer la destruction des mort-vivants.", playerId); return; } let playerName = msg.who; @@ -33596,7 +33725,7 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(lanceur) { if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options var optMana = { mana: options.mana, dm: true, @@ -33608,7 +33737,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -33618,7 +33747,7 @@ var COFantasy = COFantasy || function() { let nbDes = parseInt(findNbDes[1]); dm = dm.replace(findNbDes[0], (nbDes + options.tempeteDeManaIntense) + 'd'); } else { - log("Pas r\xE9ussi \xE0 trouver le nombre de d\xE9s dans " + dm); + log("Pas réussi à trouver le nombre de dés dans " + dm); } } else if (options.puissant) { let findValDes = dm.match(/^([0-9]+d)([0-9]+)/); @@ -33626,7 +33755,7 @@ var COFantasy = COFantasy || function() { let valDes = parseInt(findValDes[2]) + 2; dm = dm.replace(findValDes[0], findValDes[1] + valDes); } else { - log("Pas r\xE9ussi \xE0 trouver le nombre de faces des d\xE9s dans " + dm); + log("Pas réussi à trouver le nombre de faces des dés dans " + dm); } } doDestructionDesMortsVivants(lanceur, playerName, dm, options); @@ -33698,7 +33827,7 @@ var COFantasy = COFantasy || function() { if (!estMortVivant(cible)) return; if (getState(cible, 'mort')) return; if (predicateAsBool(cible, 'immunite_destruction')) { - addLineToFramedDisplay(display, nomPerso(cible) + " ne semble pas affect\xE9 par la destruction des morts-vivants"); + addLineToFramedDisplay(display, nomPerso(cible) + " ne semble pas affecté par la destruction des morts-vivants"); return; } cibles.push(cible); @@ -33706,7 +33835,7 @@ var COFantasy = COFantasy || function() { let nbCibles = cibles.length; if (nbCibles === 0) { addLineToFramedDisplay(display, "Aucun mort-vivant en vue"); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); return; } let expl = []; @@ -33725,7 +33854,7 @@ var COFantasy = COFantasy || function() { let finalDisplay = function() { nbCibles--; if (nbCibles < 1) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }; cibles.forEach(function(perso) { @@ -33745,23 +33874,23 @@ var COFantasy = COFantasy || function() { dmg.display = buildinline(dmg.roll.inlinerolls[dmgRollNumber], dmg.type, optionsDM.magique); dealDamage(perso, dmg, [], evt, false, optionsDM, explications, function(dmgDisplay, dmgFinal) { addLineToFramedDisplay(display, - name + " re\xE7oit " + dmgDisplay + " DM"); + name + " reçoit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); finalDisplay(); }); - }); //fin du jet de d\xE9s + }); //fin du jet de dés } catch (rollError) { - error("Jet " + dm + " mal form\xE9", dm); + error("Jet " + dm + " mal formé", dm); } }); //fin forEach } else { addLineToFramedDisplay(display, msgJet + " < " + difficulte); - let msgRate = nomPerso(lanceur) + " ne r\xE9ussit pas \xE0 invoquer son dieu." + testRes.rerolls + testRes.modifiers; + let msgRate = nomPerso(lanceur) + " ne réussit pas à invoquer son dieu." + testRes.rerolls + testRes.modifiers; addLineToFramedDisplay(display, msgRate); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }); } @@ -33780,7 +33909,7 @@ var COFantasy = COFantasy || function() { let label = cmd[1]; let typePoison = cmd[2]; if (typePoison != 'rapide' && typePoison != 'affaiblissant') { - error("Les seuls type de poison g\xE9r\xE9s sont rapide et affaiblissant, mais pas encore " + typePoison, cmd); + error("Les seuls type de poison gérés sont rapide et affaiblissant, mais pas encore " + typePoison, cmd); } let nomMunition; let estMunition = label.startsWith('munition_'); @@ -33788,7 +33917,7 @@ var COFantasy = COFantasy || function() { let forcePoison = cmd[3]; let savePoison = parseInt(cmd[4]); if (isNaN(savePoison)) { - error("Le dernier argument non optionnel doit \xEAtre la difficult\xE9 du test de CON", cmd); + error("Le dernier argument non optionnel doit être la difficulté du test de CON", cmd); return; } let testINT = 14; @@ -33797,7 +33926,7 @@ var COFantasy = COFantasy || function() { switch (cmd[0]) { case 'testINT': if (cmd.length < 2) { - error("Il faut un argument \xE0 --testINT", cmd); + error("Il faut un argument à --testINT", cmd); return; } testINT = parseInt(cmd[1]); @@ -33845,11 +33974,11 @@ var COFantasy = COFantasy || function() { return; } if (arme.sortilege) { - sendPerso(perso, "imossible d'enduire un sortil\xE8ge de poison", true); + sendPerso(perso, "imossible d'enduire un sortilège de poison", true); return; } if (arme.typeDegats == 'contondant') { - sendPerso(perso, arme.name + " fait des d\xE9g\xE2ts contondants. Est-il vraiment possible de l'empoisonner ?", true); + sendPerso(perso, arme.name + " fait des dégâts contondants. Est-il vraiment possible de l'empoisonner ?", true); } if (arme.armeDeJet) estMunition = true; } @@ -33864,22 +33993,22 @@ var COFantasy = COFantasy || function() { let munitions = listAllMunitions(perso); let m = munitions[nomMunition]; if (m) { - let typeMunition = fieldAsString(m, 'typemunition', 'Fl\xE8che'); + let typeMunition = fieldAsString(m, 'typemunition', 'Flèche'); armeEnduite = fieldAsString(m, 'nommunition', typeMunition); munitionsCourantes = fieldAsInt(m, 'qtemunition', 1); maxMunitions = fieldAsInt(m, 'qtemunition_max', 1); - } else { //ancienne variante, obsol\xE8te depuis mars 2023 + } else { //ancienne variante, obsolète depuis mars 2023 armeEnduite = nomMunition.replace(/_/g, ' '); let attrQte = tokenAttribute(perso, labelArme); if (attrQte.length === 0) { - sendPerso(perso, "n'a pas de munition nomm\xE9e " + nomMunition); + sendPerso(perso, "n'a pas de munition nommée " + nomMunition); return; } attrQte = attrQte[0]; munitionsCourantes = parseInt(attrQte.get('current')); maxMunitions = parseInt(attrQte.get('max')); if (isNaN(munitionsCourantes) || isNaN(maxMunitions)) { - error("Attribut de munitions mal form\xE9", attrQte); + error("Attribut de munitions mal formé", attrQte); return; } } @@ -33893,7 +34022,7 @@ var COFantasy = COFantasy || function() { let infos = attr[0].get('max'); let indexInfos = infos.indexOf(' '); if (indexInfos < 1) { - error("Attribut de poison rapide de munition mal form\xE9 (il faudrait la difficult\xE9 du save + le nombre de munitions empoisonn\xE9es)", infos); + error("Attribut de poison rapide de munition mal formé (il faudrait la difficulté du save + le nombre de munitions empoisonnées)", infos); return; } let oldSave = parseInt(infos.substring(0, indexInfos)); @@ -33902,23 +34031,23 @@ var COFantasy = COFantasy || function() { if (dejaEnduits > 0 && (attr[0].get('current') != typePoison + ' ' + forcePoison || oldSave != savePoison)) { - sendPlayer(msg, "Il y a d\xE9j\xE0 du poison de type " + attr[0].get('current') + "et de save " + oldSave + " sur les munitions " + armeEnduite + ". Le script ne sait pas g\xE9rer diff\xE9rents poisons sur les m\xEAmes munitions.", playerId); + sendPlayer(msg, "Il y a déjà du poison de type " + attr[0].get('current') + "et de save " + oldSave + " sur les munitions " + armeEnduite + ". Le script ne sait pas gérer différents poisons sur les mêmes munitions.", playerId); return; } } infosAdditionelles = savePoison + ' ' + (dejaEnduits + 1); if (dejaEnduits >= maxMunitions) { - sendPlayer(msg, "Toutes les munitions " + armeEnduite + " sont d\xE9j\xE0 enduites de poison", playerId); + sendPlayer(msg, "Toutes les munitions " + armeEnduite + " sont déjà enduites de poison", playerId); return; } } else { armeEnduite = getAttackName(labelArme, perso); if (armeEnduite === undefined) { - error(perso.tokNname + " n'a pas d'arme associ\xE9e au label " + labelArme, cmd); + error(perso.tokNname + " n'a pas d'arme associée au label " + labelArme, cmd); return; } if (attributeAsBool(perso, attribut)) { - sendPlayer(msg, armeEnduite + " est d\xE9j\xE0 enduit de poison.", playerId); + sendPlayer(msg, armeEnduite + " est déjà enduit de poison.", playerId); return; } } @@ -33958,13 +34087,13 @@ var COFantasy = COFantasy || function() { addEvent(evt); if (limiteRessources(perso, options, 'enduirePoison', 'enduire de poison', evt)) return; const display = startFramedDisplay(options.playerId, "Essaie d'enduire " + armeEnduite + " de poison", perso); - //Test d'INT pour savoir si l'action r\xE9ussit. + //Test d'INT pour savoir si l'action réussit. let testId = 'enduireDePoison'; testCaracteristique(perso, 'INT', testINT, testId, options, evt, function(tr) { let jet = "Jet d'INT : " + tr.texte; - if (tr.echecCritique) { //\xE9chec critique - jet += " \xC9chec critique !" + tr.rerolls + tr.modifiers; + if (tr.echecCritique) { //échec critique + jet += " Échec critique !" + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, jet); addLineToFramedDisplay(display, nomPerso(perso) + " s'empoisonne."); sendChat('', "[[" + forcePoison + "]]", function(res) { @@ -33992,8 +34121,8 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, e); }); addLineToFramedDisplay(display, nomPerso(perso) + " subit " + dmgDisplay + " DM"); - sendChat('', endFramedDisplay(display)); - }); //fin de dmg dus \xE0 l'\xE9chec critique + sendFramedDisplay(display); + }); //fin de dmg dus à l'échec critique } }); //fin du jet de dmg } else if (tr.reussite) { @@ -34003,82 +34132,82 @@ var COFantasy = COFantasy || function() { maxVal: infosAdditionelles }); addLineToFramedDisplay(display, armeEnduite + " est maintenant enduit de poison"); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } else { //echec normal au jet d'INT - jet += " < " + testINT + " : \xE9chec" + tr.rerolls + tr.modifiers; + jet += " < " + testINT + " : échec" + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, jet); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }); //fin du test de carac } const listeElixirs = [{ - nom: '\xC9lixir fortifiant', + nom: 'Élixir fortifiant', attrName: 'fortifiant', action: "!cof-fortifiant $rang", rang: 1 }, { - nom: '\xC9lixir de feu gr\xE9geois', - attrName: 'feu_gr\xE9geois', - action: "!cof-attack @{selected|token_id} @{target|token_id} Feu Gr\xE9geois --auto --dm $rangd6 --feu --psave DEX [[$base_save+@{selected|INT}]] --disque 3 --portee 10 --targetFx burst-fire", + nom: 'Élixir de feu grégeois', + attrName: 'feu_grégeois', + action: "!cof-attack @{selected|token_id} @{target|token_id} Feu Grégeois --auto --dm $rangd6 --feu --psave DEX [[$base_save+@{selected|INT}]] --disque 3 --portee 10 --targetFx burst-fire", rang: 2 }, { - nom: '\xC9lixir de gu\xE9rison', - attrName: '\xE9lixir_de_gu\xE9rison', + nom: 'Élixir de guérison', + attrName: 'élixir_de_guérison', action: "!cof-soin 3d6+$INT", rang: 3 }, { - nom: "\xC9lixir d'agrandissement", + nom: "Élixir d'agrandissement", attrName: "potion_d_agrandissement", action: "!cof-effet-temp agrandissement [[5+$INT]]", rang: 4 }, { - nom: "\xC9lixir de forme gazeuse", + nom: "Élixir de forme gazeuse", attrName: "potion_de_forme_gazeuse", action: "!cof-effet-temp formeGazeuse [[1d4+$INT]]", rang: 4 }, { - nom: "\xC9lixir de protection contre les \xE9l\xE9ments", - attrName: "potion_de_protection_contre_les_\xE9l\xE9ments", + nom: "Élixir de protection contre les éléments", + attrName: "potion_de_protection_contre_les_éléments", action: "!cof-effet-temp protectionContreLesElements [[5+$INT]] --valeur $rang", rang: 4 }, { - nom: "\xC9lixir d'armure de mage", + nom: "Élixir d'armure de mage", attrName: "potion_d_armure_de_mage", action: "!cof-effet-combat armureDuMage", rang: 4 }, { - nom: "\xC9lixir de chute ralentie", + nom: "Élixir de chute ralentie", attrName: "potion_de_chute_ralentie", - action: "est l\xE9ger comme une plume.", + action: "est léger comme une plume.", rang: 4 }, { - nom: "\xC9lixir d'invisibilit\xE9", - attrName: "potion_d_invisibilit\xE9", + nom: "Élixir d'invisibilité", + attrName: "potion_d_invisibilité", action: "!cof-set-state invisible true --message se rend invisible ([[1d6+$INT]] minutes)", rang: 5 }, { - nom: "\xC9lixir de vol", + nom: "Élixir de vol", attrName: "potion_de_vol", - action: "se met \xE0 voler", + action: "se met à voler", rang: 5 }, { - nom: "\xC9lixir de respiration aquatique", + nom: "Élixir de respiration aquatique", attrName: "potion_de_respiration_aquatique", action: "peut respirer sous l'eau", rang: 5 }, { - nom: "\xC9lixir de flou", + nom: "Élixir de flou", attrName: "potion_de_flou", action: "!cof-effet-temp flou [[1d4+$INT]]", rang: 5 }, { - nom: "\xC9lixir de h\xE2te", - attrName: "potion_de_h\xE2te", + nom: "Élixir de hâte", + attrName: "potion_de_hâte", action: "!cof-effet-temp hate [[1d6+$INT]]", rang: 5 }, - //Le \xE9lixirs pour les terres d'Arran + //Le élixirs pour les terres d'Arran { nom: 'Huile instable', attrName: 'huileInstable', @@ -34086,25 +34215,25 @@ var COFantasy = COFantasy || function() { rang: 3, arran: true }, { - nom: '\xC9lixir de gu\xE9rison', - attrName: '\xE9lixirGu\xE9rison', + nom: 'Élixir de guérison', + attrName: 'élixirGuérison', action: "!cof-soin 3d6+$INT", rang: 4, arran: true }, { - nom: "\xC9lixir de peau d'\xE9corce", + nom: "Élixir de peau d'écorce", attrName: 'peauEcorce', action: "!cof-effet-temp peauDEcorce [[5+$SAG]] --valeur 4", rang: 5, arran: true }, { - nom: "\xC9lixir d'image d\xE9cal\xE9e", + nom: "Élixir d'image décalée", attrName: 'imageDecalee', action: "!cof-effet-temp imageDecalee [[5+$SAG]]", rang: 5, arran: true }, { - nom: "\xC9lixir de protection contre les \xE9l\xE9ments", + nom: "Élixir de protection contre les éléments", attrName: 'protectionContreElements', action: "!cof-effet-temp protectionContreLesElements [[5+$SAG]] --valeur 5", rang: 5, @@ -34128,7 +34257,7 @@ var COFantasy = COFantasy || function() { getSelected(msg, function(selected, playerId) { iterSelected(selected, function(perso) { if (perso.token.get('bar1_link') === '') { - error("La liste de consommables n'est pas au point pour les tokens non li\xE9s", perso); + error("La liste de consommables n'est pas au point pour les tokens non liés", perso); return; } let display = startFramedDisplay(playerId, 'Liste de vos consommables :', perso, { @@ -34194,7 +34323,7 @@ var COFantasy = COFantasy || function() { var aConsommable; _.each(consommables, function(c, prefix) { if (c.effet === undefined || c.effet === '' || c.nom === undefined || c.nom === '') return; - //La quantit\xE9 est de 1 par d\xE9faut sur la fiche + //La quantité est de 1 par défaut sur la fiche if (c.quantite === undefined) { c.quantite = 1; c.attr = createObj('attribute', { @@ -34211,15 +34340,15 @@ var COFantasy = COFantasy || function() { ressource: c.attr }); // Pictos : https://wiki.roll20.net/CSS_Wizardry#Pictos - var overlay = ' title="Cliquez pour \xE9changer"'; + var overlay = ' title="Cliquez pour échanger"'; ligne += boutonSimple('!cof-echange-consommable ' + perso.token.id + ' @{target|token_id} ' + c.attr.id, 'r', overlay); addLineToFramedDisplay(display, ligne); }); //fin de la boucle sur les onsommables if (aConsommable) - addLineToFramedDisplay(display, 'Cliquez sur le consommable pour l\'utiliser ou sur r pour l\'\xE9changer avec un autre personnage.'); + addLineToFramedDisplay(display, 'Cliquez sur le consommable pour l\'utiliser ou sur r pour l\'échanger avec un autre personnage.'); else addLineToFramedDisplay(display, "Vous n'avez aucun consommable"); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); //fin du getSelected } @@ -34235,15 +34364,15 @@ var COFantasy = COFantasy || function() { cmd.shift(); var perso = persoOfId(cmd[0]); if (perso === undefined) { - log("Propri\xE9taire perdu"); - sendChat('COF', "Plus possible d'utiliser cette action. R\xE9afficher les consommables."); + log("Propriétaire perdu"); + sendChat('COF', "Plus possible d'utiliser cette action. Réafficher les consommables."); return; } - // V\xE9rifie les droits d'utiliser le consommable + // Vérifie les droits d'utiliser le consommable if (msg.selected && msg.selected.length == 1) { var utilisateur = persoOfId(msg.selected[0]._id); if (utilisateur === undefined) { - sendChat('COF', "Le token s\xE9lectionn\xE9 n'est pas valide"); + sendChat('COF', "Le token sélectionné n'est pas valide"); return; } var d = distanceCombat(perso.token, utilisateur.token); @@ -34253,19 +34382,19 @@ var COFantasy = COFantasy || function() { } perso = utilisateur; } else { - //On regarde si le joueur contr\xF4le le token + //On regarde si le joueur contrôle le token if (!peutController(msg, perso)) { - sendPlayer(msg, "Pas les droits pour \xE7a"); + sendPlayer(msg, "Pas les droits pour ça"); return; } } - //on r\xE9cup\xE8re l'attribut \xE0 utiliser + //on récupère l'attribut à utiliser cmd.shift(); var attr = getObj('attribute', cmd[0]); if (attr === undefined) { - log("Attribut a chang\xE9/perdu"); + log("Attribut a changé/perdu"); log(msg.content); - sendChat('COF', "Plus possible d'utiliser cette action. Veuillez r\xE9afficher les consommables."); + sendChat('COF', "Plus possible d'utiliser cette action. Veuillez réafficher les consommables."); return; } //Nom du consommable (pour affichage) @@ -34314,40 +34443,40 @@ var COFantasy = COFantasy || function() { return; } if (cmd[1] == cmd[2]) { - sendChat('COF', "\xC9change avec soi-m\xEAme, sans effet"); + sendChat('COF', "Échange avec soi-même, sans effet"); return; } - //perso1 = token avec qui va \xE9changer le consommable + //perso1 = token avec qui va échanger le consommable var perso1 = persoOfId(cmd[1]); if (perso1 === undefined) { - log("Propri\xE9taire perdu"); - sendChat('COF', "Plus possible d'utiliser cette action. R\xE9afficher les consommables."); + log("Propriétaire perdu"); + sendChat('COF', "Plus possible d'utiliser cette action. Réafficher les consommables."); return; } - //perso2 = token avec lequel on va faire l'\xE9change + //perso2 = token avec lequel on va faire l'échange let perso2 = persoOfId(cmd[2]); if (perso2 === undefined) { log("Destinataire perdu"); - sendChat('COF', "Erreur concernant le destinataire. Veuillez r\xE9essayer."); + sendChat('COF', "Erreur concernant le destinataire. Veuillez réessayer."); return; } - //On regarde si le joueur contr\xF4le le token + //On regarde si le joueur contrôle le token if (!peutController(msg, perso1)) { - sendPlayer(msg, "Pas les droits pour \xE7a"); + sendPlayer(msg, "Pas les droits pour ça"); return; } - //on r\xE9cup\xE8re l'attribut \xE0 \xE9changer de perso1 + //on récupère l'attribut à échanger de perso1 var attr1 = getObj('attribute', cmd[3]); if (attr1 === undefined) { - log("Attribut a chang\xE9/perdu"); + log("Attribut a changé/perdu"); log(cmd); - sendChat('COF', "Plus possible d'utiliser cette action. Veuillez r\xE9afficher les consommables."); + sendChat('COF', "Plus possible d'utiliser cette action. Veuillez réafficher les consommables."); return; } var consName; var quantite1 = parseInt(attr1.get('current')); var evt = { - type: "\xC9change de consommable", + type: "Échange de consommable", attributes: [{ attribute: attr1, current: quantite1, @@ -34377,7 +34506,7 @@ var COFantasy = COFantasy || function() { whisperChar(perso1.charId, "Vous ne disposez plus de " + consName); return; } - // on baisse la valeur de 1 du consommable qu'on s'appr\xEAte \xE0 \xE9changer + // on baisse la valeur de 1 du consommable qu'on s'apprête à échanger quantite1--; attr1.set('current', quantite1); // ajout du consommable dans perso2 : @@ -34404,7 +34533,7 @@ var COFantasy = COFantasy || function() { attribute: attrEffet2, }); } else if (attrEffet2[0].get('current').trim() != effet) { - error("\xC9change dangereux : pas le m\xEAme effet pour le consommable selon le personnage \n" + + error("Échange dangereux : pas le même effet pour le consommable selon le personnage \n" + "Effet chez " + nomPerso(perso1) + " : " + effet + "\n" + "Effet chez " + nomPerso(perso2) + " : " + attrEffet2[0].get('current'), attr2.get('name')); return false; @@ -34433,7 +34562,7 @@ var COFantasy = COFantasy || function() { return true; } else if (!m1 && attrName == attrName2.trim()) { if (attr2.get('max').trim() != effet) { - error("\xC9change dangereux : pas le m\xEAme effet pour le consommable selon le personnage \n" + + error("Échange dangereux : pas le même effet pour le consommable selon le personnage \n" + "Effet chez " + nomPerso(perso1) + " : " + effet + "\n" + "Effet chez " + nomPerso(perso2) + " : " + attr2.get('max'), attr2); return false; @@ -34450,7 +34579,7 @@ var COFantasy = COFantasy || function() { } return false; }); - // si le consommable n'a pas \xE9t\xE9 trouv\xE9, on le cr\xE9e avec une valeur de 1. + // si le consommable n'a pas été trouvé, on le crée avec une valeur de 1. if (!found) { if (m1) { var pref = 'repeating_equipement_' + generateRowID() + '_'; @@ -34483,12 +34612,12 @@ var COFantasy = COFantasy || function() { } } quantite2++; - // on envoie un petit message pr\xE9cisant la r\xE9sultante de l'action. - sendChat('COF', "Echange entre " + nomPerso(perso1) + " et " + nomPerso(perso2) + " termin\xE9e."); + // on envoie un petit message précisant la résultante de l'action. + sendChat('COF', "Echange entre " + nomPerso(perso1) + " et " + nomPerso(perso2) + " terminée."); whisperChar(perso1.charId, " Il vous reste " + quantite1 + " " + consName + "."); - whisperChar(perso2.charId, " Vous poss\xE9dez d\xE9sormais " + quantite2 + " " + consName + "."); - // le MJ est notifi\xE9 : - sendChat('COF', "/w GM " + nomPerso(perso1) + " vient de donner 1 " + consName + " \xE0 " + nomPerso(perso2) + "."); + whisperChar(perso2.charId, " Vous possédez désormais " + quantite2 + " " + consName + "."); + // le MJ est notifié : + sendChat('COF', "/w GM " + nomPerso(perso1) + " vient de donner 1 " + consName + " à " + nomPerso(perso2) + "."); addEvent(evt); } @@ -34497,7 +34626,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -34511,7 +34640,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-provocation n'est pas un token valide"); + error("Le deuxième argument de !cof-provocation n'est pas un token valide"); return; } if (cmd.length > 3 && cmd[3] == 'raillerie') { @@ -34560,16 +34689,16 @@ var COFantasy = COFantasy || function() { }); let reussite; switch (res) { - case 0: //en cas d'\xE9galit\xE9, on consid\xE8re que la provocation est r\xE9ussie + case 0: //en cas d'égalité, on considère que la provocation est réussie diminueMalediction(cible, evt); switch (crit) { case -1: - reussite = "Sur un malentendu, la " + action + " r\xE9ussit..."; + reussite = "Sur un malentendu, la " + action + " réussit..."; if (options.raillerie) setAttrDuree(cible, 'enerve', 1, evt); break; case 0: case 1: - reussite = "La " + action + " r\xE9ussit tout juste."; + reussite = "La " + action + " réussit tout juste."; if (options.raillerie) { setAttrDuree(cible, 'enerve', 1, evt); setTokenAttr(cible, 'resistanceRaillerie', @@ -34580,7 +34709,7 @@ var COFantasy = COFantasy || function() { case 1: switch (crit) { case -1: - reussite = nomCible + " marche compl\xE8tement, il attaque " + nomVoleur; + reussite = nomCible + " marche complètement, il attaque " + nomVoleur; if (options.raillerie) { setAttrDuree(cible, 'enerve', 1, evt); removeTokenAttr(cible, 'resistanceRaillerie', evt); @@ -34589,13 +34718,13 @@ var COFantasy = COFantasy || function() { case 0: if (options.raillerie) { setAttrDuree(cible, 'enerve', 1, evt); - reussite = nomVoleur + " a r\xE9ussi \xE0 bien \xE9nerver " + nomCible; + reussite = nomVoleur + " a réussi à bien énerver " + nomCible; setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) + 1, evt); - } else reussite = "La provocation r\xE9ussit."; + } else reussite = "La provocation réussit."; break; case 1: - reussite = "La provocation est une r\xE9ussite critique !"; + reussite = "La provocation est une réussite critique !"; setAttrDuree(cible, 'enerve', 1, evt); setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) - 1, evt); @@ -34604,7 +34733,7 @@ var COFantasy = COFantasy || function() { case 2: switch (crit) { case -1: - reussite = "\xC9chec critique de la " + action + " !"; + reussite = "Échec critique de la " + action + " !"; if (options.raillerie) { setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) + 5, evt); @@ -34615,19 +34744,19 @@ var COFantasy = COFantasy || function() { setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) + 1, evt); } - reussite = "La provocation \xE9choue"; + reussite = "La provocation échoue"; break; case 1: if (options.raillerie) { setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) + 10, evt); } - reussite = nomCible + " voit clair dans le jeu de " + nomVoleur + ". La provocation \xE9choue."; + reussite = nomCible + " voit clair dans le jeu de " + nomVoleur + ". La provocation échoue."; } } addLineToFramedDisplay(display, reussite); - sendChat('', endFramedDisplay(display)); - }); //Fin du test oppos\xE9 + sendFramedDisplay(display); + }); //Fin du test opposé } function enSelle(msg) { @@ -34671,14 +34800,14 @@ var COFantasy = COFantasy || function() { let nomMonture = cmd.join(' '); let monture = persoOfId(nomMonture, nomMonture, pageId); if (monture === undefined || !predicateAsBool(monture, 'monture')) { - sendPerso(cavalier, "ne peut pas monter l\xE0-dessus"); + sendPerso(cavalier, "ne peut pas monter là-dessus"); log(nomMonture); return; } const tokenM = monture.token; nomMonture = tokenM.get('name'); if (attributeAsBool(monture, 'estMontePar')) { - //V\xE9rifie si le cavalier existe bien sur cette page. + //Vérifie si le cavalier existe bien sur cette page. let cavalierBis; let estMontePar = tokenAttribute(monture, 'estMontePar'); estMontePar.forEach(function(emp) { @@ -34687,7 +34816,7 @@ var COFantasy = COFantasy || function() { if (cavalierBis === undefined) emp.remove(); }); if (cavalierBis) { - sendPerso(cavalier, "ne peut monter sur " + nomMonture + " car " + onGenre(monture, 'il', 'elle') + " a d\xE9j\xE0 un cavalier, " + nomPerso(cavalierBis)); + sendPerso(cavalier, "ne peut monter sur " + nomMonture + " car " + onGenre(monture, 'il', 'elle') + " a déjà un cavalier, " + nomPerso(cavalierBis)); return; } } @@ -34721,9 +34850,9 @@ var COFantasy = COFantasy || function() { } else voieDesElixirs = predicateAsInt(perso, 'voieDesElixirs', 0); if (voieDesElixirs < 1 && !noMsg) { if (arran) - sendPerso(perso, "ne conna\xEEt pas la Voie de l'Alchimie"); + sendPerso(perso, "ne connaît pas la Voie de l'Alchimie"); else - sendPerso(perso, "ne conna\xEEt pas la Voie des \xC9lixirs"); + sendPerso(perso, "ne connaît pas la Voie des Élixirs"); return; } return voieDesElixirs; @@ -34747,7 +34876,7 @@ var COFantasy = COFantasy || function() { if (forgesort === undefined) { let c = getObj('character', cmd[1]); if (c === undefined) { - error("Impossible de savoir qui cr\xE9e l'\xE9lixir", cmd); + error("Impossible de savoir qui crée l'élixir", cmd); return; } forgesort = { @@ -34761,7 +34890,7 @@ var COFantasy = COFantasy || function() { if (exilirInconnu(i, forgesort, voieDesElixirs)) return false; return i.attrName == cmd[2]; }); - if (elixir === undefined) { //Version perso des \xE9lixirs + if (elixir === undefined) { //Version perso des élixirs let altElixirs = findObjs({ _type: 'attribute', _characterid: forgesort.charId @@ -34782,16 +34911,16 @@ var COFantasy = COFantasy || function() { return true; }); if (elixir === undefined) { - error(nomPerso(forgesort) + " est incapable de cr\xE9er " + cmd[2], cmd); + error(nomPerso(forgesort) + " est incapable de créer " + cmd[2], cmd); return; } } const evt = { - type: "Cr\xE9ation d'\xE9lixir" + type: "Création d'élixir" }; addEvent(evt); let arran = persoArran(forgesort); - //D\xE9pense de mana + //Dépense de mana if (!arran && reglesOptionelles.mana.val.elixirs_sorts.val && ficheAttributeAsBool(forgesort, 'option_pm', true)) { if (reglesOptionelles.mana.val.mana_totale.val) { switch (elixir.rang) { @@ -34817,14 +34946,14 @@ var COFantasy = COFantasy || function() { } let elixirsACreer = tokenAttribute(forgesort, 'elixirsACreer'); if (elixirsACreer.length === 0) { - error(nomPerso(forgesort) + " ne peut cr\xE9er d'\xE9lixirs " + cmd[2], cmd); + error(nomPerso(forgesort) + " ne peut créer d'élixirs " + cmd[2], cmd); return; } elixirsACreer = elixirsACreer[0]; let extraFortifiants = toInt(elixirsACreer.get('max'), 0); let extra = extraFortifiants > 0 && elixir.rang == 1; if (!extra) options.decrAttribute = elixirsACreer.id; - if (limiteRessources(forgesort, options, 'elixirsACreer', '\xE9lixirs \xE0 cr\xE9er', evt)) return; + if (limiteRessources(forgesort, options, 'elixirsACreer', 'élixirs à créer', evt)) return; if (extra) { evt.attributes = evt.attributes || []; evt.attributes.push({ @@ -34835,7 +34964,7 @@ var COFantasy = COFantasy || function() { elixirsACreer.set('max', extraFortifiants - 1); } let attrName = 'elixir_' + elixir.attrName; - let message = "cr\xE9e un " + elixir.nom; + let message = "crée un " + elixir.nom; let attr = tokenAttribute(forgesort, attrName); if (attr.length === 0) { let rang = voieDesElixirs; @@ -34886,20 +35015,20 @@ var COFantasy = COFantasy || function() { let titre; if (elixirsACreer < 1) { if (fortifiantExtra < 1) - titre = "Impossible de cr\xE9er un autre \xE9lixir aujourd'hui"; + titre = "Impossible de créer un autre élixir aujourd'hui"; else { titre = "Encore " + fortifiantExtra + " fortifiant"; if (fortifiantExtra > 1) titre += 's'; - titre += "\xE0 cr\xE9er"; + titre += "à créer"; } } else { - titre = "Encore " + elixirsACreer + " \xE9lixir"; + titre = "Encore " + elixirsACreer + " élixir"; if (elixirsACreer > 1) titre += 's'; if (fortifiantExtra > 0) { titre += " et " + fortifiantExtra + " fortifiant"; if (fortifiantExtra > 1) titre += 's'; } - titre += " \xE0 cr\xE9er"; + titre += " à créer"; } let display = startFramedDisplay(playerId, titre, forgesort, { chuchote: true @@ -34907,7 +35036,7 @@ var COFantasy = COFantasy || function() { listeElixirs.forEach(function(elixir) { if (exilirInconnu(elixir, forgesort, voieDesElixirs)) return; if (elixir.rang < 4) { - //Il est possible de changer l'\xE9lixir par d\xE9faut + //Il est possible de changer l'élixir par défaut let altElixir = charAttribute(forgesort.charId, 'Elixir ' + elixir.rang); if (altElixir.length > 0) { elixir.nom = altElixir[0].get('current'); @@ -34955,7 +35084,7 @@ var COFantasy = COFantasy || function() { } addLineToFramedDisplay(display, options); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); //Fin du getSelected } @@ -34999,17 +35128,17 @@ var COFantasy = COFantasy || function() { function proposerRenouveauElixirs(evt, attrs, options) { let attrsNamed = allAttributesNamed(attrs, 'elixir'); if (attrsNamed.length === 0) return attrs; - // Trouver les forgesorts avec des \xE9lixirs sur eux + // Trouver les forgesorts avec des élixirs sur eux let forgesorts = {}; attrsNamed.forEach(function(attr) { - // Check de l'existence d'un cr\xE9ateur + // Check de l'existence d'un créateur let charId = attr.get('characterid'); - let personnage = persoOfCharId(charId, options.pageId, "avec un \xE9lixir"); + let personnage = persoOfCharId(charId, options.pageId, "avec un élixir"); if (personnage === undefined) personnage = { charId }; let voieDesElixirs = rangVoieDesElixirs(personnage, true); - //TODO: r\xE9fl\xE9chir \xE0 une solution pour le renouveau des \xE9lixirs \xE9chang\xE9s + //TODO: réfléchir à une solution pour le renouveau des élixirs échangés if (voieDesElixirs > 0) { let elixirsDuForgesort = forgesorts[charId]; if (elixirsDuForgesort === undefined) { @@ -35019,24 +35148,24 @@ var COFantasy = COFantasy || function() { elixirsParRang: {} }; } - // Check de l'\xE9lixir \xE0 renouveler + // Check de l'élixir à renouveler let nomElixir = attr.get('name'); let typeElixir = listeElixirs.find(function(i) { if (i.rang > voieDesElixirs) return false; return "elixir_" + i.attrName == nomElixir; }); if (typeElixir === undefined) { - error("Impossible de trouver l'\xE9lixir \xE0 renouveler"); + error("Impossible de trouver l'élixir à renouveler"); return; } // Check des doses let doses = attr.get("current"); if (isNaN(doses)) { - error("Erreur interne : \xE9lixir mal form\xE9"); + error("Erreur interne : élixir mal formé"); return; } if (doses > 0) { - // Tout est ok, cr\xE9ation de l'item + // Tout est ok, création de l'item let elixirArenouveler = { typeElixir: typeElixir, doses: doses @@ -35070,7 +35199,7 @@ var COFantasy = COFantasy || function() { opt.maxVal = 2; } setTokenAttr(forgesort, 'elixirsACreer', elixirsDuForgesort.voieDesElixirs * 2, evt, opt); - let display = startFramedDisplay(allPlayers[0], "Renouveler les \xE9lixirs", forgesort, displayOpt); + let display = startFramedDisplay(allPlayers[0], "Renouveler les élixirs", forgesort, displayOpt); let actionToutRenouveler = ""; // Boucle par rang de rune for (const rang in elixirsDuForgesort.elixirsParRang) { @@ -35079,7 +35208,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, "Elixirs de rang " + rang, undefined, true); let actionTout = ''; let ligneBoutons = ''; - // Boucle par \xE9lixir de ce rang \xE0 renouveler + // Boucle par élixir de ce rang à renouveler for (const i in elixirsDeRang) { let elixir = elixirsDeRang[i]; // Boucle par dose @@ -35104,7 +35233,7 @@ var COFantasy = COFantasy || function() { buttonStyle: "background-color: green;" }); addLineToFramedDisplay(display, boutonToutRenouveler, undefined, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } return removeAllAttributes("elixir", evt, attrs); } @@ -35113,9 +35242,9 @@ var COFantasy = COFantasy || function() { var liste = []; if (rang < 2) return liste; liste.push({ - nom: "Rune d'\xE9nergie", + nom: "Rune d'énergie", action: "!cof-rune-energie", - attrName: "runeForgesort_\xE9nergie", + attrName: "runeForgesort_énergie", rang: 2 }); if (rang < 3) return liste; @@ -35145,23 +35274,23 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(forgesort) { let voieDesRunes = predicateAsInt(forgesort, 'voieDesRunes', 0); if (voieDesRunes < 1) { - sendPerso(forgesort, "ne conna\xEEt pas la Voie des Runes."); + sendPerso(forgesort, "ne connaît pas la Voie des Runes."); return; } else if (voieDesRunes < 2) { - sendPerso(forgesort, "ne peut \xE9crire que des Runes de d\xE9fense."); + sendPerso(forgesort, "ne peut écrire que des Runes de défense."); return; } - let titre = "Cr\xE9ation de runes"; + let titre = "Création de runes"; let display = startFramedDisplay(playerId, titre, forgesort, { chuchote: true }); listeRunes(voieDesRunes).forEach(function(rune) { var action = "!cof-creer-rune " + forgesort.token.id + " @{target|token_id} " + rune.rang; - if (rune.rang === 4) action += " ?{Num\xE9ro de l'arme de la cible?}"; + if (rune.rang === 4) action += " ?{Numéro de l'arme de la cible?}"; var options = bouton(action, rune.nom, forgesort); addLineToFramedDisplay(display, options); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); //Fin du getSelected } @@ -35181,40 +35310,40 @@ var COFantasy = COFantasy || function() { forgesort = persoOfId(msg.selected[0]._id); } if (forgesort === undefined) { - error("Impossible de savoir qui cr\xE9e la rune", cmd); + error("Impossible de savoir qui crée la rune", cmd); return; } } var target = persoOfId(cmd[2], cmd[2], options.pageId); if (target === undefined) { - error("Impossible de savoir \xE0 qui octroyer la rune", cmd); + error("Impossible de savoir à qui octroyer la rune", cmd); return; } var voieDesRunes = predicateAsInt(forgesort, 'voieDesRunes', 0); if (voieDesRunes < 1) { - sendPerso(forgesort, "ne conna\xEEt pas la Voie des Runes"); + sendPerso(forgesort, "ne connaît pas la Voie des Runes"); return; } else if (voieDesRunes < 2) { - sendPerso(forgesort, "ne peut \xE9crire que des Runes de d\xE9fense."); + sendPerso(forgesort, "ne peut écrire que des Runes de défense."); return; } var rune = listeRunes(voieDesRunes).find(function(i) { return i.rang == cmd[3]; }); if (rune === undefined) { - error(nomPerso(forgesort) + " est incapable de cr\xE9er " + cmd[3], cmd); + error(nomPerso(forgesort) + " est incapable de créer " + cmd[3], cmd); return; } var labelArme; if (rune.rang == 4) { if (cmd.length < 5) { - error("La rune de puissance n\xE9cessite de choisir un label d'arme."); + error("La rune de puissance nécessite de choisir un label d'arme."); return; } labelArme = parseInt(cmd[4]); } var evt = { - type: "Cr\xE9ation de rune" + type: "Création de rune" }; addEvent(evt); if (ficheAttributeAsBool(forgesort, 'option_pm', true)) { @@ -35235,11 +35364,11 @@ var COFantasy = COFantasy || function() { } } let attrName = rune.attrName; - let message = "re\xE7oit "; + let message = "reçoit "; let typeRune; switch (rune.rang) { case 2: - typeRune = "une rune d'\xE9nergie"; + typeRune = "une rune d'énergie"; break; case 3: typeRune = "une rune de protection"; @@ -35254,10 +35383,10 @@ var COFantasy = COFantasy || function() { } message += typeRune; if (attributeAsInt(target, attrName, 0) > 0) { - error("La cible poss\xE8de d\xE9j\xE0 une rune " + typeRune, cmd); + error("La cible possède déjà une rune " + typeRune, cmd); return; } - if (options.mana !== undefined && limiteRessources(forgesort, options, undefined, "cr\xE9er " + typeRune, evt)) return; + if (options.mana !== undefined && limiteRessources(forgesort, options, undefined, "créer " + typeRune, evt)) return; setTokenAttr(target, attrName, 1, evt, { msg: message, maxVal: forgesort.charId @@ -35273,19 +35402,19 @@ var COFantasy = COFantasy || function() { function proposerRenouveauRunes(evt, attrs, options) { let attrsNamed = allAttributesNamed(attrs, 'runeForgesort'); if (attrsNamed.length === 0) return attrs; - // Filtrer par Forgesort, dans l'\xE9ventualit\xE9 qu'il y en ait plusieurs actifs + // Filtrer par Forgesort, dans l'éventualité qu'il y en ait plusieurs actifs let forgesorts = {}; attrsNamed.forEach(function(attr) { - // Check de l'existence d'un cr\xE9ateur + // Check de l'existence d'un créateur let forgesortId = attr.get('max'); if (forgesortId === undefined) { - error("Impossible de retrouver le cr\xE9ateur de la rune : " + attr); + error("Impossible de retrouver le créateur de la rune : " + attr); return; } let runesDuForgesort = forgesorts[forgesortId]; if (runesDuForgesort === undefined) { - // Check de l'existence d'un token pr\xE9sent pour le cr\xE9ateur - let forgesort = persoOfCharId(forgesortId, options.pageId, "ayant cr\xE9\xE9 une rune"); + // Check de l'existence d'un token présent pour le créateur + let forgesort = persoOfCharId(forgesortId, options.pageId, "ayant créé une rune"); if (forgesort === undefined) { attr.remove(); return; @@ -35293,10 +35422,10 @@ var COFantasy = COFantasy || function() { // Check du perso voie des Runes let voieDesRunes = predicateAsInt(forgesort, 'voieDesRunes', 0); if (voieDesRunes < 1) { - sendPerso(forgesort, "ne conna\xEEt pas la Voie des Runes"); + sendPerso(forgesort, "ne connaît pas la Voie des Runes"); return; } else if (voieDesRunes < 2) { - sendPerso(forgesort, "ne peut \xE9crire que des Runes de d\xE9fense."); + sendPerso(forgesort, "ne peut écrire que des Runes de défense."); return; } runesDuForgesort = { @@ -35305,21 +35434,21 @@ var COFantasy = COFantasy || function() { runesParRang: {} }; } - // Check de la pr\xE9sence d'un token pour la cible + // Check de la présence d'un token pour la cible let targetCharId = attr.get('characterid'); let target = persoOfCharId(targetCharId, options.pageId, "ayant une rune"); if (target === undefined) return; - // Check de la rune \xE0 renouveler + // Check de la rune à renouveler let runeName = attr.get('name'); let typeRune = listeRunes(runesDuForgesort.voieDesRunes).find(function(i) { return i.attrName == runeName.split("(")[0]; }); if (typeRune === undefined) { - error("Impossible de trouver la rune \xE0 renouveler"); + error("Impossible de trouver la rune à renouveler"); return; } - // Tout est ok, cr\xE9ation de l'item + // Tout est ok, création de l'item let runeARenouveler = { target: target, typeRune: typeRune, @@ -35356,7 +35485,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, runesDeRang[0].typeRune.nom, undefined, true); let actionTout = ""; let ligneBoutons = ""; - // Boucle par rune de ce rang \xE0 renouveler + // Boucle par rune de ce rang à renouveler for (const i in runesDeRang) { let rune = runesDeRang[i]; let action = @@ -35379,7 +35508,7 @@ var COFantasy = COFantasy || function() { buttonStyle: "background-color: green;" }); addLineToFramedDisplay(display, boutonToutRenouveler, undefined, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } return removeAllAttributes("runeForgesort", evt, attrs); } @@ -35389,7 +35518,7 @@ var COFantasy = COFantasy || function() { if (msg.content.includes(' --furie')) typeRage = 'furie'; getSelected(msg, function(selection, playerId) { if (selection.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour la rage", playerId); + sendPlayer(msg, "Pas de token sélectionné pour la rage", playerId); return; } const options = parseOptions(msg); @@ -35420,20 +35549,20 @@ var COFantasy = COFantasy || function() { typeRage = attrRage.get('current'); let difficulte = 13; if (typeRage == 'furie') difficulte = 16; - //Jet de sagesse difficult\xE9 13 pou 16 pour sortir de cet \xE9tat + //Jet de sagesse difficulté 13 pou 16 pour sortir de cet état let display = startFramedDisplay(options.playerId, "Essaie de calmer sa " + typeRage, perso); let testId = 'rageDuBerserk_' + perso.token.id; testCaracteristique(perso, 'SAG', difficulte, testId, options, evt, function(tr) { - addLineToFramedDisplay(display, "R\xE9sultat du jet de SAG : " + tr.texte); + addLineToFramedDisplay(display, "Résultat du jet de SAG : " + tr.texte); if (tr.reussite) { - addLineToFramedDisplay(display, "C'est r\xE9ussi, " + nomPerso(perso) + " se calme." + tr.modifiers); + addLineToFramedDisplay(display, "C'est réussi, " + nomPerso(perso) + " se calme." + tr.modifiers); removeTokenAttr(perso, 'rageDuBerserk', evt); } else { - let msgRate = "C'est rat\xE9, " + nomPerso(perso) + " reste enrag\xE9" + tr.rerolls + tr.modifiers; + let msgRate = "C'est raté, " + nomPerso(perso) + " reste enragé" + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, msgRate); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); } else { //Le barbare passe en rage @@ -35457,17 +35586,17 @@ var COFantasy = COFantasy || function() { var options = parseOptions(msg); var cmd = msg.content.split(' '); if (cmd.length < 3) { - error("Il faut deux arguments \xE0 !cof-arme-secrete", cmd); + error("Il faut deux arguments à !cof-arme-secrete", cmd); return; } var barde = persoOfId(cmd[1]); var cible = persoOfId(cmd[2]); if (barde === undefined || cible === undefined) { - error("Token non valide pour l'arme secr\xE8te", cmd); + error("Token non valide pour l'arme secrète", cmd); return; } if (attributeAsInt(barde, 'armeSecreteBardeUtilisee')) { - sendPerso(barde, "a d\xE9j\xE0 utilis\xE9 son arme secr\xE8te durant ce combat"); + sendPerso(barde, "a déjà utilisé son arme secrète durant ce combat"); return; } doArmeSecrete(barde, cible, options); @@ -35495,21 +35624,21 @@ var COFantasy = COFantasy || function() { var testId = 'armeSecreteBarde'; testCaracteristique(perso, 'CHA', intCible, testId, options, evt, function(tr) { var display = startFramedDisplay(options.playerId, - "Arme secr\xE8te", perso, { + "Arme secrète", perso, { perso2: cible }); var line = "Jet de CHA : " + tr.texte; if (tr.reussite) { line += " ≥ " + intCible + tr.modifiers; addLineToFramedDisplay(display, line); - addLineToFramedDisplay(display, nomPerso(cible) + " est compl\xE8tement d\xE9stabilis\xE9"); + addLineToFramedDisplay(display, nomPerso(cible) + " est complètement déstabilisé"); setAttrDuree(cible, 'armeSecreteBarde', 1, evt); } else { line += " < " + intCible + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, line); addLineToFramedDisplay(display, nomPerso(cible) + " reste insensible au charme de " + nomPerso(perso)); } - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); //fin testCarac } @@ -35531,15 +35660,15 @@ var COFantasy = COFantasy || function() { } } - //Cr\xE9e un nouveau personnage (de type PNJ par d\xE9faut) - //spec contient les charact\xE9ristiques, attributs et abilities - // - attributesFiche contient les attributs d\xE9finis dans la fiche + //Crée un nouveau personnage (de type PNJ par défaut) + //spec contient les charactéristiques, attributs et abilities + // - attributesFiche contient les attributs définis dans la fiche // nom_attribut: valeur - // - pv (permet d'\xEAtre ind\xE9pendant de PJ ou PNJ) + // - pv (permet d'être indépendant de PJ ou PNJ) // - attaques, liste d'attaques, chacune avec (nom, atk, dmnbde, dmde, dm,...) // - attributes autres attributs (name, current, max) - // - abilities (name, action), toujours rajout\xE9es \xE0 la liste d'actions - // - actions (titre, code), ajout\xE9es aux listes d'actions + // - abilities (name, action), toujours rajoutées à la liste d'actions + // - actions (titre, code), ajoutées aux listes d'actions function createCharacter(nom, playerId, avatar, token, spec, evt, createur) { let res = createObj('character', { name: nom, @@ -35756,7 +35885,7 @@ var COFantasy = COFantasy || function() { } let tokenArbre = getObj('graphic', cmd[2]); if (tokenArbre === undefined) { - error("Le deuxi\xE8me argument de !cof-animer-arbre n'est pas un token", cmd); + error("Le deuxième argument de !cof-animer-arbre n'est pas un token", cmd); return; } if (tokenArbre.get('represents') !== '') { @@ -35771,10 +35900,10 @@ var COFantasy = COFantasy || function() { } } let rang = predicateAsInt(druide, 'voieDesVegetaux', 3); - if (cmd.length > 3) { //Le rang est sp\xE9cifi\xE9 en argument optionnel + if (cmd.length > 3) { //Le rang est spécifié en argument optionnel let cmd3 = parseInt(cmd[3]); if (isNaN(cmd3) || cmd3 < 1) { - error("Le rang n'est pas un nombre valie. On utilise " + rang + " \xE0 la place", cmd); + error("Le rang n'est pas un nombre valie. On utilise " + rang + " à la place", cmd); } else rang = cmd3; } const evt = { @@ -35786,7 +35915,7 @@ var COFantasy = COFantasy || function() { initPerso(druide, evt); } let niveau = ficheAttributeAsInt(druide, 'niveau', 1); - let nomArbre = nouveauNomDePerso('Arbre anim\xE9'); + let nomArbre = nouveauNomDePerso('Arbre animé'); let avatar = "https://s3.amazonaws.com/files.d20.io/images/42323556/6qxlm965aFhBXGoYFy5fqg/thumb.png?1510582137"; let specArbre = { pv: rang * 10, @@ -35829,11 +35958,11 @@ var COFantasy = COFantasy || function() { }; let charArbre = createCharacter(nomArbre, options.playerId, avatar, tokenArbre, specArbre, evt, druide); evt.characters = [charArbre]; - sendChar(charArbre.id, "commence \xE0 s'animer", true); + sendChar(charArbre.id, "commence à s'animer", true); initiative([{ _id: tokenArbre.id }], evt); - // Ajout de l'arbre anim\xE9 aux alli\xE9s du Druide + // Ajout de l'arbre animé aux alliés du Druide let alliesDruide = alliesParPerso[druide.charId] || new Set(); alliesDruide.add(charArbre.id); alliesParPerso[druide.charId] = alliesDruide; @@ -35849,20 +35978,20 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; var cmd = options.cmd; var evt = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } if (evt.type != 'Attaque') { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour absorber l'attaque pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour absorber l'attaque précédente"); return; } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Personne n'est s\xE9lectionn\xE9 pour utiliser une rune", msg); + error("Personne n'est sélectionné pour utiliser une rune", msg); return; } var action = evt.action; @@ -35875,7 +36004,7 @@ var COFantasy = COFantasy || function() { return (target.token.id === perso.token.id); }); if (cible === undefined) { - sendPerso(perso, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(perso, "n'est pas la cible de la dernière attaque"); return; } if (!attributeAsBool(perso, 'runeForgesort_protection')) { @@ -35883,7 +36012,7 @@ var COFantasy = COFantasy || function() { return; } if (attributeAsInt(perso, 'limiteParCombat_runeForgesort_protection', 1) < 1) { - sendPerso(perso, "a d\xE9j\xE0 utilis\xE9 sa rune de protection durant ce combat"); + sendPerso(perso, "a déjà utilisé sa rune de protection durant ce combat"); return; } action.choices = action.choices || {}; @@ -35922,7 +36051,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2], options.pageId); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-delivrance n'est pas un token valide", msg.content); + error("Le deuxième argument de !cof-delivrance n'est pas un token valide", msg.content); return; } if (options.portee !== undefined) { @@ -35933,12 +36062,12 @@ var COFantasy = COFantasy || function() { } } const evt = { - type: "D\xE9livrance", + type: "Délivrance", deletedAttributes: [] }; addEvent(evt); - if (limiteRessources(pretre, options, 'd\xE9livrance', 'd\xE9livrance', evt)) return; - let display = startFramedDisplay(getPlayerIdFromMsg(msg), 'D\xE9livrance', pretre, { + if (limiteRessources(pretre, options, 'délivrance', 'délivrance', evt)) return; + let display = startFramedDisplay(getPlayerIdFromMsg(msg), 'Délivrance', pretre, { perso2: cible }); let printEffet = function(message) { @@ -35950,7 +36079,7 @@ var COFantasy = COFantasy || function() { }; _.each(messageEffetTemp, function(effet, nomEffet) { if (effet.prejudiciable) { - //Attention, ne fonctionne pas avec les effets g\xE9n\xE9riques + //Attention, ne fonctionne pas avec les effets génériques let attr = tokenAttribute(cible, nomEffet); if (attr.length > 0) finDEffet(attr[0], nomEffet, attr[0].get('name'), cible.charId, evt, optFin); @@ -35984,7 +36113,7 @@ var COFantasy = COFantasy || function() { printEffet("n'a plus de point de sang."); removeTokenAttr(cible, 'pointsDeSang', evt); } - //On enl\xE8ve les \xE9tats pr\xE9judiciables + //On enlève les états préjudiciables if (getState(cible, 'aveugle')) { printEffet("retrouve la vue"); setState(cible, 'aveugle', false, evt); @@ -35998,7 +36127,7 @@ var COFantasy = COFantasy || function() { setState(cible, 'etourdi', false, evt); } if (getState(cible, 'paralyse')) { - printEffet("peut \xE0 nouveau bouger"); + printEffet("peut à nouveau bouger"); setState(cible, 'paralyse', false, evt); } if (getState(cible, 'ralenti')) { @@ -36006,41 +36135,41 @@ var COFantasy = COFantasy || function() { setState(cible, 'ralenti', false, evt); } if (getState(cible, 'endormi')) { - printEffet("se r\xE9veille"); + printEffet("se réveille"); setState(cible, 'endormi', false, evt); } if (getState(cible, 'apeure')) { printEffet("reprend courage"); setState(cible, 'apeure', false, evt); } - //R\xE9g\xE9n\xE9ration d'une carac affaiblie de 1d4, si il y en a. + //Régénération d'une carac affaiblie de 1d4, si il y en a. if (attributeAsInt(cible, 'affaiblissementdesagesse', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'sagesse', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de sagesse"); + printEffet("récupère " + d4.roll + " points de sagesse"); } else if (attributeAsInt(cible, 'affaiblissementdecharisme', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'charisme', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de charisme"); + printEffet("récupère " + d4.roll + " points de charisme"); } else if (attributeAsInt(cible, 'affaiblissementdeintelligence', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'intelligence', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points d'intelligence"); + printEffet("récupère " + d4.roll + " points d'intelligence"); } if (attributeAsInt(cible, 'affaiblissementdeconstitution', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'constitution', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de constitution"); + printEffet("récupère " + d4.roll + " points de constitution"); } else if (attributeAsInt(cible, 'affaiblissementdeforce', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'force', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de force"); + printEffet("récupère " + d4.roll + " points de force"); } else if (attributeAsInt(cible, 'affaiblissementdedexterite', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'dexterite', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de dext\xE9rit\xE9"); + printEffet("récupère " + d4.roll + " points de dextérité"); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } function guerisonPerso(perso, evt, lanceur) { @@ -36052,32 +36181,36 @@ var COFantasy = COFantasy || function() { msgSoin = 'soigne ' + nomPerso(perso); } } else { - msgSoin = 'r\xE9cup\xE8re'; + msgSoin = 'récupère'; } msgSoin += ' de toutes les blessures subies'; if (lanceur) sendPerso(lanceur, msgSoin); else sendPerso(perso, msgSoin); if (getState(perso, 'blesse')) { setState(perso, 'blesse', false, evt); - } else { //On peut bien faire r\xE9cup\xE9rer un PR + } else { //On peut bien faire récupérer un PR let d = rajouterPointDeRecuperation(perso, evt); - if (d) sendPerso(perso, "r\xE9cup\xE8re un point de r\xE9cup\xE9ration"); + if (d) sendPerso(perso, "récupère un point de récupération"); } let soins = perso.token.get('bar1_max') - perso.token.get('bar1_value'); if (isNaN(soins)) { updateCurrentBar(perso, 1, perso.token.get('bar1_max'), evt); return; } - //Les affaiblissements de caract\xE9ristiques + //Les affaiblissements de caractéristiques allCaracs.forEach(function(carac) { let malus = attributeAsInt(perso, 'affaiblissementde' + carac, 0); if (malus > 0) { diminueAffaiblissement(perso, carac, malus, evt, malus); - sendPerso(perso, "r\xE9cup\xE8re " + malus + " points " + deCarac(carac)); + sendPerso(perso, "récupère " + malus + " points " + deCarac(carac)); } }); + //La putréfaction des momies + if (attributeAsBool(perso, 'putrefaction')) { + finDEffetDeNom(perso, 'putrefaction', evt); + } if (soins <= 0) { - //Rien d'autre \xE0 faire (le script ne g\xE8re pas encore le reste) + //Rien d'autre à faire (le script ne gère pas encore le reste) return; } soigneToken(perso, soins, evt); @@ -36099,7 +36232,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2], options.pageId); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-guerison n'est pas un token valide", msg.content); + error("Le deuxième argument de !cof-guerison n'est pas un token valide", msg.content); return; } if (options.dose === undefined && options.decrAttribute === undefined) { @@ -36113,10 +36246,10 @@ var COFantasy = COFantasy || function() { } } const evt = { - type: "Gu\xE9rison", + type: "Guérison", }; addEvent(evt); - if (limiteRessources(lanceur, options, 'gu\xE9rison', 'gu\xE9rison', evt)) return; + if (limiteRessources(lanceur, options, 'guérison', 'guérison', evt)) return; guerisonPerso(cible, evt, lanceur); if (options.messages) { options.messages.forEach(function(m) { @@ -36130,16 +36263,16 @@ var COFantasy = COFantasy || function() { arme = armesEnMain(perso); if (arme === undefined && labelArmeDefaut) arme = getWeaponStats(perso, labelArmeDefaut); - //L'arme doit \xEAtre une arme de contact ? + //L'arme doit être une arme de contact ? if (armeContact && arme && arme.portee) { - sendPerso(perso, armeContact + " " + arme.name + " est une arme \xE0 distance."); + sendPerso(perso, armeContact + " " + arme.name + " est une arme à distance."); return; } if (arme) { return arme; } arme = { - name: 'Attaque par d\xE9faut', + name: 'Attaque par défaut', attSkillDiv: 0, attSkill: "@{ATKCAC}", crit: 20, @@ -36155,12 +36288,12 @@ var COFantasy = COFantasy || function() { }; options.contact = true; entrerEnCombat(attaquant, [defenseur], explications, evt); - //Recherche des armes utilis\xE9es + //Recherche des armes utilisées let armeAttaquant = armeDeContact(attaquant, options.armeAttaquant, options.labelArmeAttaquant, options.armeAttaquantContact); let armeDefenseur = armeDeContact(defenseur, options.armeDefenseur, options.labelArmeDefenseur, options.armeDefenseurContact); - let action = options.action || "Attaque oppos\xE9e"; + let action = options.action || "Attaque opposée"; if (!armeAttaquant.parDefaut) { action += " (" + armeAttaquant.name + ")"; } @@ -36180,7 +36313,7 @@ var COFantasy = COFantasy || function() { } } else if (getState(attaquant, 'immobilise')) { dice = 12; - explications.push("Attaquant immobilis\xE9 => D12 au lieu de D20 en Attaque"); + explications.push("Attaquant immobilisé => D12 au lieu de D20 en Attaque"); } let toEvaluateAttack = attackExpression(attaquant, 1, dice, critAttaquant, true, armeAttaquant); @@ -36213,20 +36346,20 @@ var COFantasy = COFantasy || function() { }); } addLineToFramedDisplay(display, "Jet de " + nomPerso(attaquant) + " : " + attRollValue); - var critDefenseur = critEnAttaque(defenseur, armeDefenseur, options); + let critDefenseur = critEnAttaque(defenseur, armeDefenseur, options); dice = 20; malusAttaque = 0; if (estAffaibli(defenseur)) { if (predicateAsBool(defenseur, 'insensibleAffaibli')) { malusAttaque = -2; - explications.push("D\xE9fenseur affaibli, mais insensible => -2 en Attaque"); + explications.push("Défenseur affaibli, mais insensible => -2 en Attaque"); } else { dice = 12; - explications.push("D\xE9fenseur affaibli => D12 au lieu de D20 en Attaque"); + explications.push("Défenseur affaibli => D12 au lieu de D20 en Attaque"); } } else if (getState(defenseur, 'immobilise')) { dice = 12; - explications.push("D\xE9fenseur immobilis\xE9 => D12 au lieu de D20 en Attaque"); + explications.push("Défenseur immobilisé => D12 au lieu de D20 en Attaque"); } toEvaluateAttack = attackExpression(defenseur, 1, dice, critDefenseur, true, armeDefenseur); sendChat('', toEvaluateAttack, function(resAttack) { @@ -36256,10 +36389,10 @@ var COFantasy = COFantasy || function() { }); } addLineToFramedDisplay(display, "Jet de " + nomPerso(defenseur) + " : " + attRollValue); - var resultat = { + let resultat = { rollAttaquant: attackRollAttaquant, rollDefenseur: attackRollDefenseur, - armeAttaquant: armeAttaquant + armeAttaquant }; if (d20rollAttaquant == 1 && d20rollDefenseur > 1) { resultat.echec = true; @@ -36284,11 +36417,11 @@ var COFantasy = COFantasy || function() { resultat.succes = true; diminueMalediction(defenseur, evt); } - callback(resultat, display, explications); //evt est mis \xE0 jour - }); //fin du sendchat pour jet du d\xE9fenseur + callback(resultat, display, explications); //evt est mis à jour + }); //fin du sendchat pour jet du défenseur }); //Fin du sendChat pour jet de l'attaquant } catch (rollError) { - error("Erreur pendant le jet " + toEvaluateAttack + " dans attaqueContactOppos\xE9", options); + error("Erreur pendant le jet " + toEvaluateAttack + " dans attaqueContactOpposé", options); } } @@ -36301,15 +36434,15 @@ var COFantasy = COFantasy || function() { const attaquant = persoOfId(cmd[1], cmd[1]); const defenseur = persoOfId(cmd[2], cmd[2]); if (attaquant === undefined) { - error("Le premier argument de !cof-test-attaque-opposee doit \xEAtre un token valide", cmd[1]); + error("Le premier argument de !cof-test-attaque-opposee doit être un token valide", cmd[1]); return; } if (defenseur === undefined) { - error("Le deuxi\xE8me argument de !cof-test-attaque-opposee doit \xEAtre un token valide", cmd[2]); + error("Le deuxième argument de !cof-test-attaque-opposee doit être un token valide", cmd[2]); return; } const evt = { - type: "Test d'attaque oppos\xE9e" + type: "Test d'attaque opposée" }; const options = { pasDeDmg: true @@ -36325,7 +36458,7 @@ var COFantasy = COFantasy || function() { explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addEvent(evt); }); } @@ -36334,7 +36467,7 @@ var COFantasy = COFantasy || function() { function desarmer(msg) { let cmd = msg.content.split(' '); if (cmd.length < 3) { - error("Il manque des arguments \xE0 !cof-desarmer", msg.content); + error("Il manque des arguments à !cof-desarmer", msg.content); return; } const guerrier = persoOfId(cmd[1], cmd[1]); @@ -36344,21 +36477,21 @@ var COFantasy = COFantasy || function() { } const cible = persoOfId(cmd[2], cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-desarmer n'est pas un token valide", cmd); + error("Le deuxième argument de !cof-desarmer n'est pas un token valide", cmd); return; } let pageId = guerrier.token.get('pageid'); if (distanceCombat(guerrier.token, cible.token, pageId)) { - sendPerso(guerrier, "est trop loin de " + nomPerso(cible) + " pour le d\xE9sarmer."); + sendPerso(guerrier, "est trop loin de " + nomPerso(cible) + " pour le désarmer."); return; } var options = { - action: "D\xE9sarmement", - armeContact: "doit porter une arme de contact pour d\xE9sarmer son adversaire.", + action: "Désarmement", + armeContact: "doit porter une arme de contact pour désarmer son adversaire.", pasDeDmg: true, pageId: pageId, }; - //On cherche l'arme de la cible. On en aura besoin pour d\xE9sarmer + //On cherche l'arme de la cible. On en aura besoin pour désarmer let armeCible = armesEnMain(cible); let attrArmeCible = cible.attrArmeEnMain; if (armeCible) { @@ -36366,7 +36499,7 @@ var COFantasy = COFantasy || function() { if (armeCible.deuxMains) { options.bonusAttaqueDefenseur = [{ val: 5, - explication: nomPerso(cible) + " porte une arme \xE0 2 mains => +5 \xE0 son jet" + explication: nomPerso(cible) + " porte une arme à 2 mains => +5 à son jet" }]; } } @@ -36379,7 +36512,7 @@ var COFantasy = COFantasy || function() { } }; const evt = { - type: 'D\xE9sarmer' + type: 'Désarmer' }; if (cmd.length > 3) options.labelArmeAttaquant = cmd[3]; const playerId = getPlayerIdFromMsg(msg); @@ -36387,37 +36520,37 @@ var COFantasy = COFantasy || function() { function(res, display, explications) { let resultat; if (res.echecCritique) { - resultat = "\xE9chec critique"; + resultat = "échec critique"; } else if (res.echecCritiqueDefenseur) { - resultat = "succ\xE8s, " + nomPerso(cible) + " laisse tomber son arme, difficile de la r\xE9cup\xE9rer..."; + resultat = "succès, " + nomPerso(cible) + " laisse tomber son arme, difficile de la récupérer..."; enleverArmeCible(); } else if (res.critique) { - resultat = "r\xE9ussite critique : " + nomPerso(cible) + " est d\xE9sarm\xE9, et " + nomPerso(guerrier) + " emp\xEAche de reprendre l'arme"; + resultat = "réussite critique : " + nomPerso(cible) + " est désarmé, et " + nomPerso(guerrier) + " empêche de reprendre l'arme"; enleverArmeCible(); } else if (res.critiqueDefenseur) { - resultat = "\xE9chec, " + nomPerso(cible) + " garde son arme bien en main"; + resultat = "échec, " + nomPerso(cible) + " garde son arme bien en main"; } else if (res.echec) { - resultat = "\xE9chec, " + nomPerso(guerrier) + " n'a pas r\xE9ussi \xE0 d\xE9sarmer son adversaire"; - } else { //succ\xE8s + resultat = "échec, " + nomPerso(guerrier) + " n'a pas réussi à désarmer son adversaire"; + } else { //succès enleverArmeCible(); if (res.rollAttaquant > res.rollDefenseur + 9) { - resultat = "succ\xE8s, " + nomPerso(guerrier) + " d\xE9sarme son adversaire et l'emp\xEAche de r\xE9cup\xE9rer son arme"; + resultat = "succès, " + nomPerso(guerrier) + " désarme son adversaire et l'empêche de récupérer son arme"; } else { - resultat = "succ\xE8s, " + nomPerso(guerrier) + " d\xE9sarme son adversaire."; + resultat = "succès, " + nomPerso(guerrier) + " désarme son adversaire."; } } addLineToFramedDisplay(display, resultat); explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addEvent(evt); }); } function appliquerBloquer(attaquant, cible, critique, evt, envoyerMessage) { let msg; - if (envoyerMessage) msg = "est bloqu\xE9 par son adversaire"; + if (envoyerMessage) msg = "est bloqué par son adversaire"; setAttrDuree(cible, 'bloqueManoeuvre', 1, evt, msg); if (critique) appliquerTenirADistance(attaquant, cible, false, evt, envoyerMessage); @@ -36425,7 +36558,7 @@ var COFantasy = COFantasy || function() { function appliquerTenirADistance(attaquant, cible, critique, evt, envoyerMessage) { let msg; - if (envoyerMessage) msg = "est tenu \xE0 distance par son adversaire"; + if (envoyerMessage) msg = "est tenu à distance par son adversaire"; setAttrDuree( cible, 'tenuADistanceManoeuvre(' + attaquant.token.id + ')', 1, evt, msg); if (critique) appliquerBloquer(attaquant, cible, false, evt, envoyerMessage); @@ -36437,7 +36570,7 @@ var COFantasy = COFantasy || function() { let duree = 1; if (critique) duree = randomInteger(6); let msg; - if (envoyerMessage) msg = "est aveugl\xE9 par son adversaire"; + if (envoyerMessage) msg = "est aveuglé par son adversaire"; setAttrDuree( cible, 'aveugleManoeuvre', duree, evt, msg); return critique; //Pour les DMs en plus @@ -36461,19 +36594,19 @@ var COFantasy = COFantasy || function() { attrArmeCible.remove(); } if (envoyerMessage) { - let msgDesarme = "est d\xE9sarm\xE9" + onGenre(cible, '', 'e'); + let msgDesarme = "est désarmé" + onGenre(cible, '', 'e'); if (critique) msgDesarme += ", son adversaire lui a pris son arme."; else msgDesarme += "."; sendPerso(cible, msgDesarme); } }, - verbe: 'd\xE9sarmer', + verbe: 'désarmer', duelliste: true }, faireDiversion: { appliquer: function(attaquant, cible, critique, evt, envoyerMessage) { var msg; - if (envoyerMessage) msg = "a son attention attir\xE9e ailleurs"; + if (envoyerMessage) msg = "a son attention attirée ailleurs"; var malus = -5; if (critique) malus = -10; setAttrDuree(cible, 'diversionManoeuvre', 1, evt, msg); @@ -36509,7 +36642,7 @@ var COFantasy = COFantasy || function() { var distance = rollDePlus(6); if (critique && distance < 3) distance = 3; if (envoyerMessage) - sendPerso(cible, "est repouss\xE9" + onGenre(cible, '', 'e') + " et doit reculer de " + distance.roll + "m."); + sendPerso(cible, "est repoussé" + onGenre(cible, '', 'e') + " et doit reculer de " + distance.roll + "m."); if (critique) setState(cible, 'renverse', true, evt); }, penalitePlusPetit: true, @@ -36518,13 +36651,13 @@ var COFantasy = COFantasy || function() { }, tenirADistance: { appliquer: appliquerTenirADistance, - verbe: 'tenir \xE0 distance', + verbe: 'tenir à distance', duelliste: true } }; //!cof-appliquer-manoeuvre id1 id2 effet attrId - //attrId est utilis\xE9 pour limiter le nombre d'utilisations + //attrId est utilisé pour limiter le nombre d'utilisations function appliquerManoeuvre(msg) { var cmd = msg.content.split(' '); if (cmd.length < 5) { @@ -36537,7 +36670,7 @@ var COFantasy = COFantasy || function() { } var limiteAttr = getObj('attribute', cmd[4]); if (limiteAttr === undefined) { - sendPlayer(msg, "La manoeuvre a d\xE9j\xE0 \xE9t\xE9 choisie"); + sendPlayer(msg, "La manoeuvre a déjà été choisie"); return; } var attaquant = persoOfId(cmd[1], cmd[1]); @@ -36547,7 +36680,7 @@ var COFantasy = COFantasy || function() { } var cible = persoOfId(cmd[2], cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-appliquer-manoeuvre n'est pas un token valide", cmd); + error("Le deuxième argument de !cof-appliquer-manoeuvre n'est pas un token valide", cmd); return; } var effet = listeManoeuvres[cmd[3]]; @@ -36582,7 +36715,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-manoeuvre n'est pas un token valide", cmd); + error("Le deuxième argument de !cof-manoeuvre n'est pas un token valide", cmd); return; } const evt = { @@ -36605,7 +36738,7 @@ var COFantasy = COFantasy || function() { function(res, display, explications) { let dmSupp; if (res.succes) { - addLineToFramedDisplay(display, nomPerso(attaquant) + " r\xE9ussit \xE0 " + effet.verbe + " " + nomPerso(cible)); + addLineToFramedDisplay(display, nomPerso(attaquant) + " réussit à " + effet.verbe + " " + nomPerso(cible)); dmSupp = effet.appliquer(attaquant, cible, res.critique, evt); if (manoeuvreDuelliste && !dmSupp) { let pageId = cible.token.get('pageid'); @@ -36613,8 +36746,8 @@ var COFantasy = COFantasy || function() { dmSupp = res.rollAttaquant >= defense + 10; } } else { - addLineToFramedDisplay(display, nomPerso(attaquant) + " ne r\xE9ussit pas \xE0 " + effet.verbe + " " + nomPerso(cible)); - //Envoyer \xE0 la cible la possibilit\xE9 d'appliquer un effet de son choix + addLineToFramedDisplay(display, nomPerso(attaquant) + " ne réussit pas à " + effet.verbe + " " + nomPerso(cible)); + //Envoyer à la cible la possibilité d'appliquer un effet de son choix } explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); @@ -36622,9 +36755,9 @@ var COFantasy = COFantasy || function() { if (dmSupp) { let actionGratuite = "!cof-attack " + attaquant.token.id + " " + cible.token.id + " -1 --auto"; - addLineToFramedDisplay(display, nomPerso(attaquant) + " fait en plus des d\xE9g\xE2ts \xE0 " + nomPerso(cible) + boutonSimple(actionGratuite, "lancer une attaque pour d\xE9terminer le montant"), 80); + addLineToFramedDisplay(display, nomPerso(attaquant) + " fait en plus des dégâts à " + nomPerso(cible) + boutonSimple(actionGratuite, "lancer une attaque pour déterminer le montant"), 80); } - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); addEvent(evt); /*if (dmSupp) { turnAction(attaquant, playerId); @@ -36632,11 +36765,11 @@ var COFantasy = COFantasy || function() { if (!res.succes && !manoeuvreDuelliste) { let charCible = getObj('character', cible.charId); if (charCible === undefined) { - error("Cible sans personnage associ\xE9", cible); + error("Cible sans personnage associé", cible); return; } let titre = "Choisir un effet contre " + nomPerso(attaquant); - //On cr\xE9e un display sans le header + //On crée un display sans le header display = startFramedDisplay(undefined, titre, cible, { retarde: true }); @@ -36651,15 +36784,15 @@ var COFantasy = COFantasy || function() { let ligneManoeuvre = boutonSimple(appliquerManoeuvre, man); addLineToFramedDisplay(display, ligneManoeuvre, 90); } - // on envoie la liste aux joueurs qui g\xE8rent le voleur + // on envoie la liste aux joueurs qui gèrent le voleur let playerIds = getPlayerIds(cible); playerIds.forEach(function(playerid) { addFramedHeader(display, playerid, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); if (playerIds.length === 0) { addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } }); @@ -36673,7 +36806,7 @@ var COFantasy = COFantasy || function() { return; } if (cmd.length < 3) { - error("Il manque des arguments \xE0 !cof-expert-combat-bousculer", msg.content); + error("Il manque des arguments à !cof-expert-combat-bousculer", msg.content); return; } let expert = persoOfId(cmd[1], cmd[1]); @@ -36683,7 +36816,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-expert-combat-bousculer n'est pas un token valide", cmd); + error("Le deuxième argument de !cof-expert-combat-bousculer n'est pas un token valide", cmd); return; } if (!predicateAsBool(expert, 'expertDuCombat')) { @@ -36709,19 +36842,19 @@ var COFantasy = COFantasy || function() { var display = startFramedDisplay(playerId, "Bousculer", expert, { perso2: cible }); - explications.push("D\xE9 d'expertise : " + deExpertise.roll); + explications.push("Dé d'expertise : " + deExpertise.roll); if (resultat === 1) { - addLineToFramedDisplay(display, nomPerso(cible) + " est repouss\xE9 de " + - Math.ceil(deExpertise.val / 2) + " m\xE8tre" + (deExpertise.val > 1 ? "s" : "") + "
S'il est accul\xE9 : " + + addLineToFramedDisplay(display, nomPerso(cible) + " est repoussé de " + + Math.ceil(deExpertise.val / 2) + " mètre" + (deExpertise.val > 1 ? "s" : "") + "
S'il est acculé : " + boutonSimple("!cof-dmg " + deExpertise.val + " --target " + cmd[2], "Appliquer " + deExpertise.val + " DM")); setState(cible, "renverse", "true", evt); } else { - addLineToFramedDisplay(display, nomPerso(cible) + " n'est pas renvers\xE9"); + addLineToFramedDisplay(display, nomPerso(cible) + " n'est pas renversé"); } explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); } @@ -36827,7 +36960,7 @@ var COFantasy = COFantasy || function() { dm: 3, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }], abilities: [{ @@ -36878,7 +37011,7 @@ var COFantasy = COFantasy || function() { dm: 5, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }], abilities: [{ @@ -36929,7 +37062,7 @@ var COFantasy = COFantasy || function() { dm: 5, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }, { name: 'predicats_script', @@ -36943,7 +37076,7 @@ var COFantasy = COFantasy || function() { titre: 'Attaque en embuscade', code: '!cof-attack @{selected|token_id} @{target|token_id} 1 --sournoise 1 --if moins FOR --etat renverse --endif' }, { - titre: 'D\xE9vorer', + titre: 'Dévorer', code: '!cof-attack @{selected|token_id} @{target|token_id} 1' }] }, @@ -36985,7 +37118,7 @@ var COFantasy = COFantasy || function() { dm: 7, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }, { name: 'predicats_script', @@ -36999,7 +37132,7 @@ var COFantasy = COFantasy || function() { titre: 'Attaque en embuscade', code: '!cof-attack @{selected|token_id} @{target|token_id} 1 --sournoise 1 --if moins FOR --etat renverse --endif' }, { - titre: 'D\xE9vorer', + titre: 'Dévorer', code: '!cof-attack @{selected|token_id} @{target|token_id} 1' }] }, @@ -37050,7 +37183,7 @@ var COFantasy = COFantasy || function() { }, ] }, tigreDentsDeSabre: { - nom: 'Tigre \xE0 dents de sabre', + nom: 'Tigre à dents de sabre', avatar: "https://s3.amazonaws.com/files.d20.io/images/59486272/f5lUcN3Y9H0thmJPrqa6FQ/max.png?1533041702", token: "https://s3.amazonaws.com/files.d20.io/images/60186469/ShcrgpvgXKiQsLVOyg4SZQ/thumb.png?1533903741", attributesFiche: { @@ -37089,7 +37222,7 @@ var COFantasy = COFantasy || function() { dm: 12, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }, { name: 'predicats_script', @@ -37103,12 +37236,12 @@ var COFantasy = COFantasy || function() { titre: 'Attaque en embuscade', code: '!cof-attack @{selected|token_id} @{target|token_id} 1 --sournoise 1 --if moins FOR --etat renverse --endif' }, { - titre: 'D\xE9vorer', + titre: 'Dévorer', ccode: '!cof-attack @{selected|token_id} @{target|token_id} 1' }] }, oursPrehistorique: { - nom: 'Ours pr\xE9historique', + nom: 'Ours préhistorique', avatar: "https://s3.amazonaws.com/files.d20.io/images/59486323/V6RVSlBbeRJi_aIaIuGGBw/max.png?1533041814", token: "https://s3.amazonaws.com/files.d20.io/images/60186633/lNHXvCOsvfPMZDQnqJKQVw/thumb.png?1533904189", attributesFiche: { @@ -37133,7 +37266,7 @@ var COFantasy = COFantasy || function() { pnj_init: 10, RDS: 2, race: 'ours', - taille: '\xE9norme' + taille: 'énorme' }, pv: 110, attaques: [{ @@ -37172,11 +37305,11 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - error("pas de lanceur pour la conjuration de pr\xE9dateurs", msg); + error("pas de lanceur pour la conjuration de prédateurs", msg); return; } let evt = { - type: 'conjuration de pr\xE9dateurs' + type: 'conjuration de prédateurs' }; let combat = initiative(selected, evt); let abort; @@ -37184,12 +37317,12 @@ var COFantasy = COFantasy || function() { if (abort) return; if (options.tempeteDeMana) { if (selected.length > 1) { - sendPlayerAndGM(msg, playerId, "Il faut s\xE9lectionner un seul token pour les options de temp\xEAte de mana"); + sendPlayerAndGM(msg, playerId, "Il faut sélectionner un seul token pour les options de tempête de mana"); abort = true; return; } if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, portee: false, @@ -37203,11 +37336,11 @@ var COFantasy = COFantasy || function() { return; } else { if (options.tempeteDeMana.cout > 1) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } - if (limiteRessources(invocateur, options, 'invocationPredateur', 'lancer une invocation de pr\xE9dateur', evt)) return; + if (limiteRessources(invocateur, options, 'invocationPredateur', 'lancer une invocation de prédateur', evt)) return; let pageId = invocateur.token.get('pageid'); let niveau = ficheAttributeAsInt(invocateur, 'niveau', 1); if (!renforce) { @@ -37259,13 +37392,13 @@ var COFantasy = COFantasy || function() { toFront(token); let charPredateur = createCharacter(nomPredateur, playerId, predateur.avatar, token, predateur, evt); - //Tous les pr\xE9dateurs sont des quadrup\xE8des + //Tous les prédateurs sont des quadrupèdes let persoPredateur = { token: token, charId: charPredateur.id }; setPredicate(persoPredateur, 'quadrupede', evt); - //Attribut de predateur conjur\xE9 pour la disparition automatique + //Attribut de predateur conjuré pour la disparition automatique let attr = createObj('attribute', { name: 'predateurConjure', _characterid: charPredateur.id, @@ -37287,7 +37420,7 @@ var COFantasy = COFantasy || function() { initiative([{ _id: token.id }], evt); - // Ajout du Pr\xE9dateur aux alli\xE9s de l'invocateur + // Ajout du Prédateur aux alliés de l'invocateur let alliesInvocateur = alliesParPerso[invocateur.charId] || new Set(); alliesInvocateur.add(charPredateur.id); alliesParPerso[invocateur.charId] = alliesInvocateur; @@ -37311,11 +37444,11 @@ var COFantasy = COFantasy || function() { return; } let evt = { - type: "invocation d'une sph\xE8re de feu", + type: "invocation d'une sphère de feu", }; let combat = initiative(selected, evt); iterSelected(selected, function(invocateur) { - if (limiteRessources(invocateur, options, 'sphereDeFeu', 'lancer un sort de sph\xE8re de feu', evt)) return; + if (limiteRessources(invocateur, options, 'sphereDeFeu', 'lancer un sort de sphère de feu', evt)) return; let character = getObj('character', invocateur.charId); if (character === undefined) { error("Impossible de trouver le personnage de " + nomPerso(invocateur), invocateur); @@ -37324,7 +37457,7 @@ var COFantasy = COFantasy || function() { let pageId = invocateur.token.get('pageid'); let niveau = ficheAttributeAsInt(invocateur, 'niveau', 1); let sphere = { - nom: 'Sph\xE8re de feu', + nom: 'Sphère de feu', avatar: "https://s3.amazonaws.com/files.d20.io/images/260057530/nL8O6US3f1BpeTJkodWNCg/max.png?16394116785", token: "https://s3.amazonaws.com/files.d20.io/images/260057530/nL8O6US3f1BpeTJkodWNCg/thumb.png?16394116785", attributesFiche: { @@ -37333,7 +37466,7 @@ var COFantasy = COFantasy || function() { }, pv: 1, attaques: [{ - nom: 'Br\xFBlure', + nom: 'Brûlure', atk: 0, dmnbde: 3, dmde: 6, @@ -37346,7 +37479,7 @@ var COFantasy = COFantasy || function() { name: 'predicats_script', current: 'nonVivant immunite_feu sansEsprit initiativeDeriveeDe::' + character.get('name') + '\n', }, { - name: 'predateurConjure', //Pas exactement \xE7a, mais \xE7a fait ce qu'il faut + name: 'predateurConjure', //Pas exactement ça, mais ça fait ce qu'il faut current: niveau, max: combat.init, lie: options.mana !== undefined @@ -37371,7 +37504,7 @@ var COFantasy = COFantasy || function() { has_limit_field_of_vision: true, }); if (token === undefined) { - error("Impossible de cr\xE9er le token de la sph\xE8re de feu ", sphere); + error("Impossible de créer le token de la sphère de feu ", sphere); return; } toFront(token); @@ -37382,7 +37515,7 @@ var COFantasy = COFantasy || function() { initiative([{ _id: token.id }], evt); - // Ajout du Pr\xE9dateur aux alli\xE9s de l'invocateur + // Ajout du Prédateur aux alliés de l'invocateur let alliesInvocateur = alliesParPerso[invocateur.charId] || new Set(); alliesInvocateur.add(charSphere.id); alliesParPerso[invocateur.charId] = alliesInvocateur; @@ -37391,18 +37524,18 @@ var COFantasy = COFantasy || function() { }); //end getSelected } - //!cof-conjuration-armee [d\xE9 de DM] --limiteParJour... + //!cof-conjuration-armee [dé de DM] --limiteParJour... function conjurationArmee(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Il faut s\xE9lectionner le lanceur de la conjuration d'arm\xE9\xE9", playerId); + sendPlayer(msg, "Il faut sélectionner le lanceur de la conjuration d'arméé", playerId); return; } let abort; @@ -37410,12 +37543,12 @@ var COFantasy = COFantasy || function() { if (abort) return; if (options.tempeteDeMana) { if (selected.length > 1) { - sendPlayerAndGM(msg, playerId, "Il faut s\xE9lectionner un seul token pour les options de temp\xEAte de mana"); + sendPlayerAndGM(msg, playerId, "Il faut sélectionner un seul token pour les options de tempête de mana"); abort = true; return; } if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, portee: false, @@ -37429,16 +37562,16 @@ var COFantasy = COFantasy || function() { return; } else { if (options.tempeteDeMana.cout > 1) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } let pageId = invocateur.token.get('pageid'); let niveau = ficheAttributeAsInt(invocateur, 'niveau', 1); const evt = { - type: "Conjuration d'arm\xE9e" + type: "Conjuration d'armée" }; - if (limiteRessources(invocateur, options, 'conjurationArmee', "conjurer une arm\xE9e", evt)) { + if (limiteRessources(invocateur, options, 'conjurationArmee', "conjurer une armée", evt)) { addEvent(evt); return; } @@ -37459,7 +37592,7 @@ var COFantasy = COFantasy || function() { dm.nbDe = 2; } } - let nomArmee = "Arm\xE9e de " + nomPerso(invocateur); + let nomArmee = "Armée de " + nomPerso(invocateur); let token = createObj('graphic', { name: nomArmee, subtype: 'token', @@ -37519,13 +37652,13 @@ var COFantasy = COFantasy || function() { } //!cof-tenebres token-lanceur token-cible - // possibilit\xE9 de --brumes pour un effet de brumes + // possibilité de --brumes pour un effet de brumes function tenebres(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("!cof-tenebres mal form\xE9, il faut un token comme premier argument", msg.content); + error("!cof-tenebres mal formé, il faut un token comme premier argument", msg.content); return; } let necromant = persoOfId(cmd[1], cmd[1], options.pageId); @@ -37542,7 +37675,7 @@ var COFantasy = COFantasy || function() { const playerId = getPlayerIdFromMsg(msg); if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, portee: true, @@ -37554,7 +37687,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.tempeteDeMana.cout > 1) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -37570,7 +37703,7 @@ var COFantasy = COFantasy || function() { if (distanceCombat(necromant.token, target.token, options.pageId, { strict2: true }) > portee) { - sendPlayer(msg, "Le point vis\xE9 est trop loin (port\xE9e " + portee + ")", playerId); + sendPlayer(msg, "Le point visé est trop loin (portée " + portee + ")", playerId); return; } let duree = 5; @@ -37586,7 +37719,7 @@ var COFantasy = COFantasy || function() { if (options.brumes) { if (limiteRessources(necromant, options, 'brumes', 'lancer un sort de brumes', evt)) return; } else { - if (limiteRessources(necromant, options, 'tenebres', 'lancer un sort de t\xE9n\xE8bres', evt)) return; + if (limiteRessources(necromant, options, 'tenebres', 'lancer un sort de ténèbres', evt)) return; } if (!stateCOF.combat) { initPerso(necromant, evt); @@ -37606,7 +37739,7 @@ var COFantasy = COFantasy || function() { tokSpec.height = rayonUnite * PIX_PER_UNIT; tokSpec.layer = 'map'; } else { - tokSpec.name = "T\xE9n\xE8bres de " + nomPerso(necromant); + tokSpec.name = "Ténèbres de " + nomPerso(necromant); tokSpec.imgsrc = 'https://s3.amazonaws.com/files.d20.io/images/192072874/eJXFx20fD931DuBDvzAnQQ/thumb.png?1610469273'; tokSpec.width = 70; tokSpec.height = 70; @@ -37626,9 +37759,9 @@ var COFantasy = COFantasy || function() { if (options.brumes) sendPerso(necromant, "lance un sort de brumes pour " + duree + " tours"); else - sendPerso(necromant, "lance un sort de t\xE9n\xE8bres pour " + duree + " tours"); + sendPerso(necromant, "lance un sort de ténèbres pour " + duree + " tours"); } - // Calcul des cibles \xE0 aveugler + // Calcul des cibles à aveugler let cibles = []; let allToksDisque = findObjs({ @@ -37678,8 +37811,8 @@ var COFantasy = COFantasy || function() { if (options.brumes) effetTenebres.effet = 'brumes'; setEffetTemporaire(necromant, effetTenebres, duree, evt, options); if (target.token.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir le disque - target.token.remove(); //On l'enl\xE8ve, normalement plus besoin + //C'est juste un token utilisé pour définir le disque + target.token.remove(); //On l'enlève, normalement plus besoin } if (options.messages) { options.messages.forEach(function(m) { @@ -37689,7 +37822,7 @@ var COFantasy = COFantasy || function() { } const demonInvoque = { - nom: 'D\xE9mon', + nom: 'Démon', avatar: "https://s3.amazonaws.com/files.d20.io/images/183633585/DWpHYp4SLPCDCMHdmTyKOw/thumb.png?1607339938", token: "https://s3.amazonaws.com/files.d20.io/images/183633585/DWpHYp4SLPCDCMHdmTyKOw/thumb.png?1607339938", attributesFiche: { @@ -37714,7 +37847,7 @@ var COFantasy = COFantasy || function() { DEFDIV: 3, pnj_def: 17, pnj_init: 16, - race: 'd\xE9mon', + race: 'démon', taille: 'moyen' }, attaques: [{ @@ -37726,7 +37859,7 @@ var COFantasy = COFantasy || function() { }], attributes: [{ name: 'predicats_script', - current: 'd\xE9mon' + current: 'démon' }], abilities: [] }; @@ -37736,7 +37869,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("!cof-invoquer-demon mal form\xE9, il faut un token comme premier argument", msg.content); + error("!cof-invoquer-demon mal formé, il faut un token comme premier argument", msg.content); return; } let necromant = persoOfId(cmd[1], cmd[1], options.pageId); @@ -37753,7 +37886,7 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - if (limiteRessources(necromant, options, 'invoquerDemon', 'lance une invocation de d\xE9mon', evt)) return; + if (limiteRessources(necromant, options, 'invoquerDemon', 'lance une invocation de démon', evt)) return; let d6 = rollDePlus(6); evt.action.rolls.invocationDemonDmg = d6; let r = { @@ -37768,7 +37901,7 @@ var COFantasy = COFantasy || function() { if (!stateCOF.combat) { initPerso(necromant, evt); } - let tokenDemon = "D\xE9mon de " + nomPerso(necromant); + let tokenDemon = "Démon de " + nomPerso(necromant); let token = createObj('graphic', { name: tokenDemon, showname: 'true', @@ -37796,7 +37929,7 @@ var COFantasy = COFantasy || function() { evt.characters = [charDemon]; evt.tokens = [token]; let duree = 5 + modCarac(necromant, 'intelligence'); - //Attribut de d\xE9mon invoqu\xE9 pour la disparition automatique + //Attribut de démon invoqué pour la disparition automatique createObj('attribute', { name: 'demonInvoque', _characterid: charDemon.id, @@ -37811,13 +37944,13 @@ var COFantasy = COFantasy || function() { initiative([{ _id: token.id }], evt); - // Ajout du D\xE9mon aux alli\xE9s du N\xE9cromant + // Ajout du Démon aux alliés du Nécromant var alliesNecromant = alliesParPerso[necromant.charId] || new Set(); alliesNecromant.add(charDemon.id); alliesParPerso[necromant.charId] = alliesNecromant; - var msg = "invoque un d\xE9mon"; + var msg = "invoque un démon"; if (stateCOF.options.affichage.val.duree_effets.val) msg += " pour " + duree + " tours"; - msg += " mais cela lui co\xFBte " + dmgDisplay + " PV"; + msg += " mais cela lui coûte " + dmgDisplay + " PV"; sendPerso(necromant, msg); }); }, options); @@ -37864,7 +37997,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("!cof-animer-mort mal form\xE9, il faut un token comme premier argument", msg.content); + error("!cof-animer-mort mal formé, il faut un token comme premier argument", msg.content); return; } const necromant = persoOfId(cmd[1], cmd[1], options.pageId); @@ -37875,7 +38008,7 @@ var COFantasy = COFantasy || function() { let zombiesControles = attributeAsInt(necromant, 'zombiesControles', 0); let rangVoie = predicateAsInt(necromant, 'voieOutreTombe', 1); if (zombiesControles >= rangVoie) { - sendPerso(necromant, "ne peut plus animer de Zombie car il en contr\xF4le d\xE9j\xE0 assez."); + sendPerso(necromant, "ne peut plus animer de Zombie car il en contrôle déjà assez."); return; } options.lanceur = necromant; @@ -37919,7 +38052,7 @@ var COFantasy = COFantasy || function() { let charZombie = createCharacter(nomToken, playerId, zombieAnime.avatar, token, zombie, evt); evt.characters.push(charZombie); evt.tokens.push(token); - // D\xE9gradation du Zombie + // Dégradation du Zombie createObj('attribute', { name: 'degradationZombie', _characterid: charZombie.id, @@ -37935,7 +38068,7 @@ var COFantasy = COFantasy || function() { initiative([{ _id: token.id }], evt); - // Ajout du Zombie aux alli\xE9s du N\xE9cromant + // Ajout du Zombie aux alliés du Nécromant let alliesNecromant = alliesParPerso[necromant.charId] || new Set(); alliesNecromant.add(charZombie.id); alliesParPerso[necromant.charId] = alliesNecromant; @@ -37953,7 +38086,7 @@ var COFantasy = COFantasy || function() { const MONTER = String.fromCharCode(0x2197); const DESCENDRE = String.fromCharCode(0x2198); - //Cr\xE9e les macros utiles au jeu + //Crée les macros utiles au jeu const gameMacros = [{ name: 'Actions', action: "!cof-liste-actions", @@ -38031,7 +38164,7 @@ var COFantasy = COFantasy || function() { istokenaction: true }, { name: 'Surprise', - action: "!cof-surprise ?{difficult\xE9}", + action: "!cof-surprise ?{difficulté}", visibleto: '', istokenaction: false, inBar: true @@ -38041,20 +38174,20 @@ var COFantasy = COFantasy || function() { visibleto: 'all', istokenaction: true, }, { - name: '\xC9teindre', - action: "!cof-eteindre-lumiere ?{Quelle lumi\xE8re?|Tout}", + name: 'Éteindre', + action: "!cof-eteindre-lumiere ?{Quelle lumière?|Tout}", visibleto: '', istokenaction: false, inBar: true }, { name: 'devient', - action: "!cof-set-state ?{\xC9tat|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blesse|encombre} true", + action: "!cof-set-state ?{État|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blesse|encombre} true", visibleto: '', istokenaction: false, inBar: true }, { - name: 'enl\xE8ve', - action: "!cof-set-state ?{\xC9tat|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blesse|encombre} false", + name: 'enlève', + action: "!cof-set-state ?{État|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blesse|encombre} false", visibleto: '', istokenaction: false, inBar: true @@ -38092,20 +38225,20 @@ var COFantasy = COFantasy || function() { if (prev === undefined) { m.playerid = playerId; createObj('macro', m); - sendPlayer(msg, "Macro " + m.name + " cr\xE9\xE9e."); + sendPlayer(msg, "Macro " + m.name + " créée."); if (m.inBar) inBar.push(m.name); } else if (force) { prev.set('action', m.action); prev.set('visibleto', m.visibleto); prev.set('istokenaction', m.istokenaction); - sendPlayer(msg, "Macro " + m.name + " r\xE9\xE9crite."); + sendPlayer(msg, "Macro " + m.name + " réécrite."); if (m.inBar) inBar.push(m.name); } else { - sendPlayer(msg, "Macro " + m.name + " d\xE9j\xE0 pr\xE9sente (utiliser --force pour r\xE9\xE9crire)."); + sendPlayer(msg, "Macro " + m.name + " déjà présente (utiliser --force pour réécrire)."); } }); if (inBar.length > 0) { - sendPlayer(msg, "Macros \xE0 mettre dans la barre d'action du MJ : " + inBar.join(', ')); + sendPlayer(msg, "Macros à mettre dans la barre d'action du MJ : " + inBar.join(', ')); } stateCOF.gameMacros = gameMacros; } @@ -38115,24 +38248,24 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd === undefined || cmd.length < 3) { - error("Il faut au moins 2 arguments \xE0 !cof-lumiere", cmd); + error("Il faut au moins 2 arguments à !cof-lumiere", cmd); return; } const cible = persoOfId(cmd[1]); if (cible === undefined) { - error("le premier argument de !cof-lumi\xE8re doit \xEAtre un token", cmd); + error("le premier argument de !cof-lumière doit être un token", cmd); return; } const radius = parseInt(cmd[2]); if (isNaN(radius) || radius <= 0) { - error("La distance de vue de la lumi\xE8re doit \xEAtre positive", cmd[2]); + error("La distance de vue de la lumière doit être positive", cmd[2]); return; } let dimRadius = ''; if (cmd.length > 3) { dimRadius = parseInt(cmd[3]); if (isNaN(dimRadius)) { - error("La distance de vue de la lumi\xE8re assombrie doit \xEAtre un nombre", cmd[3]); + error("La distance de vue de la lumière assombrie doit être un nombre", cmd[3]); dimRadius = ''; } } @@ -38145,7 +38278,7 @@ var COFantasy = COFantasy || function() { type: 'lumiere', }; addEvent(evt); - if (limiteRessources(options.lanceur, options, 'lumi\xE8re', "lumi\xE8re", evt)) return; + if (limiteRessources(options.lanceur, options, 'lumière', "lumière", evt)) return; ajouteUneLumiere(cible, nomToken, radius, dimRadius, evt); } @@ -38159,7 +38292,7 @@ var COFantasy = COFantasy || function() { } let lumId = al.get('max'); if (lumId == 'surToken') { - //Il faut enlever la lumi\xE8re sur tous les tokens + //Il faut enlever la lumière sur tous les tokens let allTokens = [perso.token]; if (perso.token.get('bar1_value') !== '') { allTokens = findObjs({ @@ -38187,7 +38320,7 @@ var COFantasy = COFantasy || function() { name: lumName }); if (tokensLumiere.length === 0) { - log("Pas de token pour la lumi\xE8re " + lumName); + log("Pas de token pour la lumière " + lumName); al.remove(); return; } @@ -38219,7 +38352,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lectionn\xE9e pour !cof-eteindre-lumiere", playerId); + sendPlayer(msg, "Pas de cible sélectionnée pour !cof-eteindre-lumiere", playerId); return; } const cmd = options.cmd; @@ -38228,7 +38361,7 @@ var COFantasy = COFantasy || function() { if (groupe && groupe.toLowerCase() == 'tout') groupe = ''; let pageId = options.pageId; const evt = { - type: "Eteindre la lumi\xE8re" + type: "Eteindre la lumière" }; iterSelected(selected, function(perso) { pageId = pageId || perso.token.get('pageid'); @@ -38247,7 +38380,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd.length < 2) { - error("Il faut pr\xE9ciser le token en argument de !cof-torche"); + error("Il faut préciser le token en argument de !cof-torche"); return; } let pageId = options.pageId; @@ -38259,15 +38392,15 @@ var COFantasy = COFantasy || function() { pageId = pageId || perso.token.get('pageid'); var diminueDuree = 0; if (cmd.length > 2) { - //Dans ce cas, c'est pour diminuer la dur\xE9e de vie de la torche + //Dans ce cas, c'est pour diminuer la durée de vie de la torche diminueDuree = parseInt(cmd[2]); if (isNaN(diminueDuree) || diminueDuree <= 0) { - sendPlayer(msg, "Le deuxi\xE8me argument de !cof-torche doit \xEAtre un nombre strictement positif " + msg.content); + sendPlayer(msg, "Le deuxième argument de !cof-torche doit être un nombre strictement positif " + msg.content); return; } } var evt; - //On commence par chercher si une torche est allum\xE9e + //On commence par chercher si une torche est allumée var torcheAllumee = false; var attrLumiere = tokenAttribute(perso, 'lumiere').filter(function(a) { return a.get('current').startsWith('torche'); @@ -38275,7 +38408,7 @@ var COFantasy = COFantasy || function() { if (!diminueDuree && attrLumiere.length > 0) { torcheAllumee = true; evt = { - type: "\xC9teindre les torches" + type: "Éteindre les torches" }; attrLumiere.forEach(function(al) { let lumName = al.get('current'); @@ -38303,8 +38436,8 @@ var COFantasy = COFantasy || function() { return; } if (tempsTorche === 0) { - if (nbTorches === 0) { //Donc forc\xE9ment torcheAllumee - //On remet l'attribut dans un \xE9tat convenable + if (nbTorches === 0) { //Donc forcément torcheAllumee + //On remet l'attribut dans un état convenable setTokenAttr(perso, 'torches', 0, evt, { maxVal: 60 }); @@ -38324,7 +38457,7 @@ var COFantasy = COFantasy || function() { nbTorches--; temps += tempsTorche; tempsTorche = 60; - var msgDiminue = "torche \xE9puis\xE9e."; + var msgDiminue = "torche épuisée."; if (nbTorches === 0) { msgDiminue += " Plus de torche !"; } else if (nbTorches == 1) { @@ -38337,23 +38470,23 @@ var COFantasy = COFantasy || function() { setTokenAttr(perso, 'torches', nbTorches, evt, { maxVal: tempsTorche }); - sendChar(perso.charId, '/w gm temps de torche diminu\xE9 de ' + temps + ' minutes'); + sendChar(perso.charId, '/w gm temps de torche diminué de ' + temps + ' minutes'); addEvent(evt); return; } if (torcheAllumee) { - var msgTorche = "/w gm torche \xE9teinte. "; + var msgTorche = "/w gm torche éteinte. "; if (nbTorches > 1) { msgTorche += "Reste " + (nbTorches - 1) + " torche"; if (nbTorches > 2) msgTorche += "s neuves"; else msgTorche += " neuve"; - msgTorche += ", et une torche pouvant encore \xE9clairer " + tempsTorche + " minutes."; + msgTorche += ", et une torche pouvant encore éclairer " + tempsTorche + " minutes."; } else { - msgTorche += "Elle peut encore \xE9clairer " + tempsTorche + " minutes."; + msgTorche += "Elle peut encore éclairer " + tempsTorche + " minutes."; } sendChar(perso.charId, msgTorche + - boutonSimple("!cof-torche " + perso.token.id + " ?{Dur\xE9e?}", "Temps depuis allumage")); + boutonSimple("!cof-torche " + perso.token.id + " ?{Durée?}", "Temps depuis allumage")); addEvent(evt); return; } @@ -38362,7 +38495,7 @@ var COFantasy = COFantasy || function() { }; ajouteUneLumiere(perso, 'torche', 13, 7, evt); var msgAllume = - "allume une torche, qui peut encore \xE9clairer pendant " + tempsTorche + + "allume une torche, qui peut encore éclairer pendant " + tempsTorche + " minute"; if (tempsTorche > 1) msgAllume += 's'; msgAllume += '.'; @@ -38375,9 +38508,9 @@ var COFantasy = COFantasy || function() { addEvent(evt); return; } - //On ne tient pas le compte pr\xE9cis des torches + //On ne tient pas le compte précis des torches if (torcheAllumee) { - whisperChar(perso.charId, "\xE9teint sa torche"); + whisperChar(perso.charId, "éteint sa torche"); } else { evt = { type: "Allumer une torche" @@ -38389,9 +38522,9 @@ var COFantasy = COFantasy || function() { } //!cof-options - //!cof-options opt1 [... optn] val, met l'option \xE0 val - //!cof-options [opt0 ... optk] reset remet toutes les options \xE0 leur valeur patr d\xE9faut - //Dans tous les cas, affiche les options du niveau demand\xE9 + //!cof-options opt1 [... optn] val, met l'option à val + //!cof-options [opt0 ... optk] reset remet toutes les options à leur valeur patr défaut + //Dans tous les cas, affiche les options du niveau demandé function setCofOptions(msg) { const playerId = getPlayerIdFromMsg(msg); if (!playerIsGM(playerId)) { @@ -38414,7 +38547,7 @@ var COFantasy = COFantasy || function() { cmd.shift(); cmd.forEach(function(c) { if (fini) { - sendPlayer(msg, "Option " + c + " ignor\xE9e", playerId); + sendPlayer(msg, "Option " + c + " ignorée", playerId); return; } if (c == 'reset') { @@ -38424,7 +38557,7 @@ var COFantasy = COFantasy || function() { } else if (cofOptions[c]) { if (cofOptions[c].type == 'options') { if (defOpt[c] === undefined) { - sendPlayer(msg, "Option " + c + " inconnue dans les options par d\xE9faut", playerId); + sendPlayer(msg, "Option " + c + " inconnue dans les options par défaut", playerId); fini = true; return; } @@ -38436,7 +38569,7 @@ var COFantasy = COFantasy || function() { newOption = cofOptions[c]; } } else { - if (newOption) { //on met newOption \xE0 c + if (newOption) { //on met newOption à c let val = c; switch (newOption.type) { case 'bool': @@ -38452,7 +38585,7 @@ var COFantasy = COFantasy || function() { val = false; break; default: - sendPlayer(msg, "L'option " + lastCmd + " ne peut \xEAtre que true ou false", playerId); + sendPlayer(msg, "L'option " + lastCmd + " ne peut être que true ou false", playerId); val = newOption.val; } fini = true; @@ -38460,7 +38593,7 @@ var COFantasy = COFantasy || function() { case 'int': val = parseInt(c); if (isNaN(val)) { - sendPlayer(msg, "L'option " + lastCmd + " est une valeur enti\xE8re", playerId); + sendPlayer(msg, "L'option " + lastCmd + " est une valeur entière", playerId); val = newOption.val; } fini = true; @@ -38501,7 +38634,7 @@ var COFantasy = COFantasy || function() { case 'bool': action += ' ?{Nouvelle valeur de ' + optVu + '|actif,true|inactif,false}'; if (displayedVal) - // Bizarrement, le caract\xE8re '*' modifie la suite du tableau + // Bizarrement, le caractère '*' modifie la suite du tableau displayedVal = '3'; else displayedVal = '*'; @@ -38531,8 +38664,8 @@ var COFantasy = COFantasy || function() { line += boutonSimple(action, displayedVal) + after; addLineToFramedDisplay(display, line); } - addLineToFramedDisplay(display, boutonSimple('!cof-options' + prefix + ' reset', 'Valeurs par d\xE9faut'), 70); - sendChat('', endFramedDisplay(display)); + addLineToFramedDisplay(display, boutonSimple('!cof-options' + prefix + ' reset', 'Valeurs par défaut'), 70); + sendFramedDisplay(display); } function lancerDefiSamourai(msg) { @@ -38547,20 +38680,20 @@ var COFantasy = COFantasy || function() { let pageId = options.pageId; let samourai = persoOfId(cmd[1], cmd[1], pageId); if (samourai === undefined) { - error("Le token s\xE9lectionn\xE9 n'est pas valide", msg.content); + error("Le token sélectionné n'est pas valide", msg.content); return; } if (attributeAsBool(samourai, 'defiSamourai')) { - sendPlayer(msg, nomPerso(samourai) + " a d\xE9j\xE0 lanc\xE9 un d\xE9fi durant ce combat."); + sendPlayer(msg, nomPerso(samourai) + " a déjà lancé un défi durant ce combat."); return; } let cible = persoOfId(cmd[2], cmd[2], pageId); if (cible === undefined) { - error("Le deuxi\xE8me token s\xE9lectionn\xE9 n'est pas valide", msg.content); + error("Le deuxième token sélectionné n'est pas valide", msg.content); return; } const evt = { - type: 'D\xE9fi samoura\xEF' + type: 'Défi samouraï' }; let explications = []; entrerEnCombat(samourai, [cible], explications, evt); @@ -38571,14 +38704,14 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3) { bonus = parseInt(cmd[3]); if (isNaN(bonus) || bonus < 1) { - error("Bonus de d\xE9fi de samoura\xEF incorrect", cmd[3]); + error("Bonus de défi de samouraï incorrect", cmd[3]); bonus = undefined; } } if (bonus === undefined) bonus = predicateAsInt(samourai, 'voieDeLHonneur', 2); setTokenAttr(samourai, 'defiSamourai', bonus, evt, { - msg: nomPerso(samourai) + " lance un d\xE9fi \xE0 " + nomPerso(cible), + msg: nomPerso(samourai) + " lance un défi à " + nomPerso(cible), maxVal: idName(cible) }); } @@ -38588,16 +38721,16 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 6) { - error("Il manque des arguments \xE0 !cof-enveloppement", cmd); + error("Il manque des arguments à !cof-enveloppement", cmd); return; } let cube = persoOfId(cmd[1]); if (cube === undefined) { - error("Token non d\xE9fini", cmd[1]); + error("Token non défini", cmd[1]); return; } if (!peutController(msg, cube)) { @@ -38606,12 +38739,12 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2]); if (cible === undefined) { - error("Token non d\xE9fini", cmd[2]); + error("Token non défini", cmd[2]); return; } let difficulte = parseInt(cmd[3]); if (isNaN(difficulte)) { - error("Difficult\xE9 n'est pas un nombre, on prend 15 par d\xE9faut", cmd[3]); + error("Difficulté n'est pas un nombre, on prend 15 par défaut", cmd[3]); difficulte = 15; } let exprDM; @@ -38623,18 +38756,18 @@ var COFantasy = COFantasy || function() { exprDM = cmd[4] + ' ' + cmd[5]; break; case 'etreinte': - type = '\xE9treinte'; + type = 'étreinte'; exprDM = cmd[4] + ' ' + cmd[5]; break; default: - error("Impossible de d\xE9terminer les d\xE9g\xE2ts quand envelopp\xE9", cmd[4]); + error("Impossible de déterminer les dégâts quand enveloppé", cmd[4]); return; } doEnveloppement(cube, cible, difficulte, type, exprDM, options); } //!cof-enveloppement cubeId targetId Difficulte Attaque - //Attaque peut \xEAtre soit label l, soit ability a, soit etreinte expr + //Attaque peut être soit label l, soit ability a, soit etreinte expr function doEnveloppement(attaquant, cible, difficulte, type, exprDM, options) { const evt = { type: type, @@ -38649,9 +38782,9 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - //Choix de la caract\xE9ristique pour r\xE9sister : FOR ou DEX + //Choix de la caractéristique pour résister : FOR ou DEX let caracRes = meilleureCarac('FOR', 'DEX', cible, 10 + modCarac(attaquant, 'force')); - let titre = (type == '\xE9treinte') ? '\xC9treinte' : 'Enveloppement'; + let titre = (type == 'étreinte') ? 'Étreinte' : 'Enveloppement'; let display = startFramedDisplay(options.playerId, titre, attaquant, { perso2: cible }); @@ -38660,14 +38793,14 @@ var COFantasy = COFantasy || function() { testOppose(rollId, attaquant, 'FOR', options, cible, caracRes, options, explications, evt, function(res, crit, rt1, rt2) { - let act = " a absorb\xE9 "; + let act = " a absorbé "; switch (res) { case 1: - if (type == '\xE9treinte') act = " s'est enroul\xE9 autour de "; + if (type == 'étreinte') act = " s'est enroulé autour de "; explications.push(nomPerso(attaquant) + act + nomPerso(cible)); let attaquantId = idName(attaquant); let maxval = difficulte; - if (type == '\xE9treinte') maxval = 'etreinte ' + difficulte; + if (type == 'étreinte') maxval = 'etreinte ' + difficulte; setTokenAttr(cible, 'enveloppePar', attaquantId, evt, { maxVal: maxval }); @@ -38677,28 +38810,28 @@ var COFantasy = COFantasy || function() { setTokenAttr(attaquant, 'enveloppe', cibleId, evt, { maxVal: exprDM }); - if (type == '\xE9treinte') setState(cible, 'immobilise', true, evt); + if (type == 'étreinte') setState(cible, 'immobilise', true, evt); break; case 2: if (caracRes == 'FOR') { - if (type == '\xE9treinte') act = '\xE9treindre'; + if (type == 'étreinte') act = 'étreindre'; else act = 'absorber'; - explications.push(nomPerso(cible) + " r\xE9siste et ne se laisse pas " + act); + explications.push(nomPerso(cible) + " résiste et ne se laisse pas " + act); } else { - if (type == '\xE9treinte') act = "l'\xE9treinte"; + if (type == 'étreinte') act = "l'étreinte"; else act = "l'absorption"; - explications.push(nomPerso(cible) + " \xE9vite " + act); + explications.push(nomPerso(cible) + " évite " + act); } break; default: //match null, la cible s'en sort - if (type == '\xE9treinte') act = "l'\xE9treinte"; + if (type == 'étreinte') act = "l'étreinte"; else act = "l'enveloppement"; - explications.push(nomPerso(cible) + " \xE9chappe de justesse \xE0 " + act); + explications.push(nomPerso(cible) + " échappe de justesse à " + act); } explications.forEach(function(e) { addLineToFramedDisplay(display, e); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); } @@ -38710,8 +38843,8 @@ var COFantasy = COFantasy || function() { options.cmd && options.cmd.length > 1 && options.cmd[1] == 'libere'; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "!cof-echapper-enveloppement sans s\xE9lection de token", playerId); - log("!cof-echapper-enveloppement requiert de s\xE9lectionner des tokens"); + sendPlayer(msg, "!cof-echapper-enveloppement sans sélection de token", playerId); + log("!cof-echapper-enveloppement requiert de sélectionner des tokens"); return; } iterSelected(selected, function(perso) { @@ -38723,7 +38856,7 @@ var COFantasy = COFantasy || function() { attr = attr[0]; let cube = persoOfIdName(attr.get('current'), options.pageId); if (cube === undefined) { - error("Attribut enveloppePar mal form\xE9, on le supprime", attr.get('current')); + error("Attribut enveloppePar mal formé, on le supprime", attr.get('current')); attr.remove(); unlockToken(perso); return; @@ -38736,7 +38869,7 @@ var COFantasy = COFantasy || function() { } if (libere) { let evt = { - type: 'Lib\xE9ration', + type: 'Libération', deletedAttributes: [attr] }; addEvent(evt); @@ -38751,12 +38884,12 @@ var COFantasy = COFantasy || function() { a.remove(); } }); - sendChar(cube.charId, "lib\xE8re " + nomPerso(perso)); + sendChar(cube.charId, "libère " + nomPerso(perso)); return; } let difficulte = parseInt(maxAttr); if (isNaN(difficulte)) { - error("Difficult\xE9 mal form\xE9e", attr.get('max')); + error("Difficulté mal formée", attr.get('max')); difficulte = 15; } doEchapperEnveloppement(perso, etreinte, cube, difficulte, options); @@ -38779,16 +38912,16 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); let titre = "Tentative de sortir de " + nomPerso(cube); - if (etreinte) titre = "Tentative de se lib\xE9rer de l'etreinte de " + cube.tokName; + if (etreinte) titre = "Tentative de se libérer de l'etreinte de " + cube.tokName; const display = startFramedDisplay(options.playerId, titre, perso, { chuchote: options.secret }); const testId = 'enveloppement_' + perso.token.id; testCaracteristique(perso, 'FOR', difficulte, testId, options, evt, function(tr) { - addLineToFramedDisplay(display, "R\xE9sultat : " + tr.texte); + addLineToFramedDisplay(display, "Résultat : " + tr.texte); if (tr.reussite) { - addLineToFramedDisplay(display, "C'est r\xE9ussi, " + nomPerso(perso) + " s'extirpe de " + cube.tokName + tr.modifiers); + addLineToFramedDisplay(display, "C'est réussi, " + nomPerso(perso) + " s'extirpe de " + cube.tokName + tr.modifiers); toFront(perso.token); evt.deletedAttributes = evt.deletedAttributes || []; let attr = tokenAttribute(perso, 'enveloppePar')[0]; @@ -38805,10 +38938,10 @@ var COFantasy = COFantasy || function() { } }); } else { - var msgRate = "C'est rat\xE9." + tr.rerolls + tr.modifiers; + let msgRate = "C'est raté." + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, msgRate); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); } @@ -38817,7 +38950,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { @@ -38825,6 +38958,10 @@ var COFantasy = COFantasy || function() { return; } let perso = persoOfId(cmd[1], cmd[1], options.pageId); + if (!perso) { + error("Token invalide", cmd); + return; + } let attrName = 'estAgrippePar'; let attr = tokenAttribute(perso, 'estAgrippePar'); if (attr.length === 0) { @@ -38837,7 +38974,7 @@ var COFantasy = COFantasy || function() { attr = tokenAttribute(perso, 'estDevorePar'); attrName = 'estDevorePar'; if (attr.length === 0) { - sendPlayer(msg, nomPerso(perso) + " n'est pas agripp\xE9."); + sendPlayer(msg, nomPerso(perso) + " n'est pas agrippé."); return; } } @@ -38846,28 +38983,63 @@ var COFantasy = COFantasy || function() { attr = attr[0]; let agrippant = persoOfIdName(attr.get('current'), options.pageId); if (agrippant === undefined) { - error("Attribut " + attrName + " mal form\xE9, on le supprime", attr.get('current')); + error("Attribut " + attrName + " mal formé, on le supprime", attr.get('current')); attr.remove(); unlockToken(perso); return; } + if (cmd.length > 2 && cmd[2] == 'libere') { + finAgripper(perso, agrippant, attrName); + return; + } doLibererAgrippe(perso, agrippant, attrName, options); } + function finAgripper(perso, agrippant, attrName, evt) { + evt.deletedAttributes = evt.deletedAttributes || []; + let attr = tokenAttribute(perso, attrName); + attr[0].remove(); + unlockToken(perso, evt); + evt.deletedAttributes.push(attr[0]); + if (attrName == 'estAgrippePar') removeTokenAttr(perso, 'agrippeParUnDemon', evt); + if (attrName == 'etreinteImmolePar' || attrName == 'estDevorePar' || attr[0].get('max')) + setState(perso, 'immobilise', false, evt); + if (attrName == 'etreinteScorpionPar') { + let etrScorpAttr = tokenAttribute(perso, "etreinteScorpionRatee"); + if (etrScorpAttr && etrScorpAttr.length > 0) { + etrScorpAttr[0].remove(); + evt.deletedAttributes.push(etrScorpAttr[0]); + } + } + let attrAgrippant = 'agrippe'; + if (attrName == 'etreinteImmolePar') attrAgrippant = 'etreinteImmole'; + if (attrName == 'etreinteScorpionPar') attrAgrippant = 'etreinteScorpionSur'; + if (attrName == 'estDevorePar') attrAgrippant = 'devore'; + attr = tokenAttribute(agrippant, attrAgrippant); + attr.forEach(function(a) { + let ca = persoOfIdName(a.get('current')); + if (ca && ca.token.id == perso.token.id) { + evt.deletedAttributes.push(a); + a.remove(); + unlockToken(ca, evt); + } + }); + } + //!cof-liberer-agrippe token_id function doLibererAgrippe(perso, agrippant, attrName, options) { const evt = { type: 'libererAgrippe', action: { - titre: "Se lib\xE9rer", - perso: perso, - agrippant: agrippant, - attrName: attrName, - options: options + titre: "Se libérer", + perso, + agrippant, + attrName, + options } }; addEvent(evt); - let titre = "Tentative de se lib\xE9rer de " + nomPerso(agrippant); + let titre = "Tentative de se libérer de " + nomPerso(agrippant); let playerId = options.playerId; let display = startFramedDisplay(playerId, titre, perso, { chuchote: options.secret @@ -38884,14 +39056,14 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, e); }); if (tr == 2) { - let msgRate = "C'est rat\xE9, " + nomPerso(perso) + " est toujours "; + let msgRate = "C'est raté, " + nomPerso(perso) + " est toujours "; if (attrName == 'etreinteImmolePar' || attrName == 'etreinteScorpionPar') - msgRate += "prisonnier de l'\xE9treinte de " + nomPerso(agrippant); + msgRate += "prisonnier de l'étreinte de " + nomPerso(agrippant); else if (attrName == 'estDevorePar') msgRate += 'saisi' + eForFemale(perso) + '.'; - else msgRate += "agripp\xE9" + eForFemale(perso) + "."; + else msgRate += "agrippé" + eForFemale(perso) + "."; addLineToFramedDisplay(display, msgRate); - if (attrName == 'etreinteScorpionPar') { // Cas d'\xE9treinte de scorpion avec dommages automatiques + if (attrName == 'etreinteScorpionPar') { // Cas d'étreinte de scorpion avec dommages automatiques let d6 = evt.action.rolls.etreinteDmg || rollDePlus(6, { bonus: 3 }); @@ -38904,52 +39076,25 @@ var COFantasy = COFantasy || function() { let explications2 = []; perso.ignoreTouteRD = true; dealDamage(perso, r, [], evt, false, {}, explications2, function(dmgDisplay) { - let dmgMsg = "L'\xE9treinte du scorpion inflige " + dmgDisplay + " d\xE9g\xE2ts."; + let dmgMsg = "L'étreinte du scorpion inflige " + dmgDisplay + " dégâts."; setTokenAttr(perso, "etreinteScorpionRatee", true, evt); addLineToFramedDisplay(display, dmgMsg); explications2.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); } else { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } else { if (tr === 0) - addLineToFramedDisplay(display, "R\xE9ussi de justesse, " + nomPerso(perso) + " se lib\xE8re."); + addLineToFramedDisplay(display, "Réussi de justesse, " + nomPerso(perso) + " se libère."); else //tr == 1 - addLineToFramedDisplay(display, "R\xE9ussi, " + nomPerso(perso) + " se lib\xE8re."); + addLineToFramedDisplay(display, "Réussi, " + nomPerso(perso) + " se libère."); toFront(perso.token); - evt.deletedAttributes = evt.deletedAttributes || []; - let attr = tokenAttribute(perso, attrName); - attr[0].remove(); - unlockToken(perso, evt); - evt.deletedAttributes.push(attr[0]); - if (attrName == 'estAgrippePar') removeTokenAttr(perso, 'agrippeParUnDemon', evt); - if (attrName == 'etreinteImmolePar' || attrName == 'estDevorePar' || attr[0].get('max')) - setState(perso, 'immobilise', false, evt); - if (attrName == 'etreinteScorpionPar') { - let etrScorpAttr = tokenAttribute(perso, "etreinteScorpionRatee"); - if (etrScorpAttr && etrScorpAttr.length > 0) { - etrScorpAttr[0].remove(); - evt.deletedAttributes.push(etrScorpAttr[0]); - } - } - let attrAgrippant = 'agrippe'; - if (attrName == 'etreinteImmolePar') attrAgrippant = 'etreinteImmole'; - if (attrName == 'etreinteScorpionPar') attrAgrippant = 'etreinteScorpionSur'; - if (attrName == 'estDevorePar') attrAgrippant = 'devore'; - attr = tokenAttribute(agrippant, attrAgrippant); - attr.forEach(function(a) { - let ca = persoOfIdName(a.get('current')); - if (ca && ca.token.id == perso.token.id) { - evt.deletedAttributes.push(a); - a.remove(); - unlockToken(ca, evt); - } - }); - sendChat('', endFramedDisplay(display)); + finAgripper(perso, agrippant, attrName, evt); + sendFramedDisplay(display); if (attrName == 'etreinteScorpionPar') { turnAction(perso); } @@ -38962,7 +39107,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { @@ -38973,13 +39118,13 @@ var COFantasy = COFantasy || function() { let attrName = 'estEcrasePar'; let attr = tokenAttribute(perso, attrName); if (attr.length === 0) { - sendPlayer(msg, nomPerso(perso) + " n'est pas \xE9cras\xE9."); + sendPlayer(msg, nomPerso(perso) + " n'est pas écrasé."); return; } attr = attr[0]; let agrippant = persoOfIdName(attr.get('current'), options.pageId); if (agrippant === undefined) { - error("Attribut " + attrName + " mal form\xE9, on le supprime", attr.get('current')); + error("Attribut " + attrName + " mal formé, on le supprime", attr.get('current')); attr.remove(); unlockToken(perso); return; @@ -38992,15 +39137,15 @@ var COFantasy = COFantasy || function() { estMauvais(agrippant)) { let bonusProtectionContreLeMal = getIntValeurOfEffet(perso, 'protectionContreLeMal', 2); bonus += bonusProtectionContreLeMal; - explications.push("Protection contre le mal => +" + bonusProtectionContreLeMal + " au jet pour se lib\xE9rer"); + explications.push("Protection contre le mal => +" + bonusProtectionContreLeMal + " au jet pour se libérer"); } if (predicateAsBool(perso, 'actionLibre')) { bonus += 5; - explications.push("Action libre => +5 pour r\xE9sister aux entraves"); + explications.push("Action libre => +5 pour résister aux entraves"); } let carac = meilleureCarac('FOR', 'DEX', perso, difficulte - bonus); if (bonus) options.bonus = bonus; - let titre = "Tentative de se lib\xE9rer de " + nomPerso(agrippant); + let titre = "Tentative de se libérer de " + nomPerso(agrippant); doLibererEcrase(perso, agrippant, titre, carac, difficulte, explications, options); } @@ -39039,7 +39184,7 @@ var COFantasy = COFantasy || function() { smsg += '">' + tr.texte + ''; } if (tr.reussite) { - smsg += " => r\xE9ussi, " + nomPerso(perso) + " se lib\xE8re."; + smsg += " => réussi, " + nomPerso(perso) + " se libère."; smsg += tr.modifiers; addLineToFramedDisplay(display, smsg); toFront(perso.token); @@ -39058,11 +39203,11 @@ var COFantasy = COFantasy || function() { } }); } else { - smsg += " => \xE9chec, " + nomPerso(perso) + " est toujours saisi dans les bras de " + nomPerso(agrippant); + smsg += " => échec, " + nomPerso(perso) + " est toujours saisi dans les bras de " + nomPerso(agrippant); smsg += tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, smsg); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); if (tr.reussite) turnAction(perso); }); } @@ -39083,7 +39228,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2], options.pageId); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-animer-cadavre n'est pas un token valide", msg.content); + error("Le deuxième argument de !cof-animer-cadavre n'est pas un token valide", msg.content); return; } if (!getState(cible, 'mort')) { @@ -39091,13 +39236,13 @@ var COFantasy = COFantasy || function() { return; } if (attributeAsBool(cible, 'cadavreAnime')) { - sendPlayer(msg, nomPerso(cible) + " a d\xE9j\xE0 \xE9t\xE9 anim\xE9" + eForFemale(cible) + "."); + sendPlayer(msg, nomPerso(cible) + " a déjà été animé" + eForFemale(cible) + "."); return; } var niveauLanceur = ficheAttributeAsInt(lanceur, 'niveau', 1); var niveauCible = ficheAttributeAsInt(cible, 'niveau', 1); if (niveauCible > niveauLanceur) { - sendPlayer(msg, nomPerso(cible) + " est de NC " + niveauCible + ", sup\xE9rieur \xE0 celui de " + nomPerso(lanceur) + " (" + niveauLanceur + ")"); + sendPlayer(msg, nomPerso(cible) + " est de NC " + niveauCible + ", supérieur à celui de " + nomPerso(lanceur) + " (" + niveauLanceur + ")"); return; } var evt = { @@ -39105,27 +39250,27 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); if (limiteRessources(lanceur, options, 'animerUnCadavre', "animer un cadavre", evt)) return; - sendPerso(lanceur, 'r\xE9anime ' + nomPerso(cible)); + sendPerso(lanceur, 'réanime ' + nomPerso(cible)); setState(cible, 'mort', false, evt); var pvmax = parseInt(cible.token.get("bar1_max")); updateCurrentBar(cible, 1, pvmax, evt); setTokenAttr(cible, 'cadavreAnime', true, evt, { - msg: 'se rel\xE8ve' + msg: 'se relève' }); } var niveauxEbriete = [ "sobre", "pompette", - "bourr\xE9", + "bourré", "ivre-mort", - "en coma \xE9thylique" + "en coma éthylique" ]; function augmenteEbriete(personnage, evt, expliquer) { let n = attributeAsInt(personnage, 'niveauEbriete', 0) + 1; if (n >= niveauxEbriete.length) { - expliquer(nomPerso(personnage) + " est d\xE9j\xE0 en coma \xE9thylique."); + expliquer(nomPerso(personnage) + " est déjà en coma éthylique."); return; } expliquer(nomPerso(personnage) + " devient " + niveauxEbriete[n]); @@ -39147,7 +39292,7 @@ var COFantasy = COFantasy || function() { var cibles = []; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "pas de cible trouv\xE9e, action annul\xE9e", playerId); + sendPlayer(msg, "pas de cible trouvée, action annulée", playerId); return; } iterSelected(selected, function(perso) { @@ -39167,23 +39312,23 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - if (limiteRessources(options.lanceur, options, 'vapeursEthyliques', "lancer une fiole de vapeurs \xE9thyliques", evt)) { + if (limiteRessources(options.lanceur, options, 'vapeursEthyliques', "lancer une fiole de vapeurs éthyliques", evt)) { addEvent(evt); return; } - let display = startFramedDisplay(playerId, 'Vapeurs \xE9thyliques'); + let display = startFramedDisplay(playerId, 'Vapeurs éthyliques'); let expliquer = function(m) { addLineToFramedDisplay(display, m); }; const explications = []; if (options.save) { - explications.push(" Jet de " + options.save.carac + " " + options.save.seuil + " pour r\xE9sister \xE0 l'alcool"); + explications.push(" Jet de " + options.save.carac + " " + options.save.seuil + " pour résister à l'alcool"); } entrerEnCombat(options.lanceur, persos, explications, evt); explications.forEach(explication => expliquer(explications)); let count = persos.length; let finalize = function() { - if (count == 1) sendChat('', endFramedDisplay(display)); + if (count == 1) sendFramedDisplay(display); count--; }; persos.forEach(function(perso) { @@ -39216,11 +39361,11 @@ var COFantasy = COFantasy || function() { function desaouler(msg) { getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Aucune s\xE9lection pour !cof-desaouler", playerId); + sendPlayer(msg, "Aucune sélection pour !cof-desaouler", playerId); return; } var evt = { - type: 'desao\xFBler' + type: 'desaoûler' }; var expliquer = function(s) { sendChat('', s); @@ -39254,7 +39399,7 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - if (limiteRessources(options.lanceur, options, 'boireAlcool', "est affect\xE9 par l'alcool", evt)) { + if (limiteRessources(options.lanceur, options, 'boireAlcool', "est affecté par l'alcool", evt)) { return; } var display = startFramedDisplay(playerId, 'Alcool'); @@ -39262,11 +39407,11 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, m); }; if (options.save) { - expliquer("Jet de " + options.save.carac + " " + options.save.seuil + " pour r\xE9sister \xE0 l'alcool"); + expliquer("Jet de " + options.save.carac + " " + options.save.seuil + " pour résister à l'alcool"); } var count = persos.length; var finalize = function() { - if (count == 1) sendChat('', endFramedDisplay(display)); + if (count == 1) sendFramedDisplay(display); count--; }; persos.forEach(function(perso) { @@ -39298,7 +39443,7 @@ var COFantasy = COFantasy || function() { //On joue un son let son = msg.content.substring(sonIndex + 1); playSound(son); - } else { //On arr\xEAte tous les sons + } else { //On arrête tous les sons let AMdeclared; try { AMdeclared = Roll20AM; @@ -39335,7 +39480,7 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error('pas de token s\xE9lectionn\xE9 pour !cof-bonus-couvert'); + error('pas de token sélectionné pour !cof-bonus-couvert'); return; } var evt = { @@ -39346,12 +39491,12 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(perso) { if (nouveauBonus) { setTokenAttr(perso, 'bonusCouvert', nouveauBonus, evt, { - msg: "se met \xE0 couvert", + msg: "se met à couvert", secret: options.secret }); } else { removeTokenAttr(perso, 'bonusCouvert', evt, { - msg: "n'est plus \xE0 couvert", + msg: "n'est plus à couvert", secret: options.secret }); } @@ -39383,7 +39528,7 @@ var COFantasy = COFantasy || function() { return; }*/ if (selected.length === 0) { - error('pas de token s\xE9lectionn\xE9 pour !cof-set-attribute'); + error('pas de token sélectionné pour !cof-set-attribute'); return; } const evt = { @@ -39436,7 +39581,7 @@ var COFantasy = COFantasy || function() { let predicats = state.COFantasy.predicats; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error('pas de token s\xE9lectionn\xE9 pour !cof-set-predicate'); + error('pas de token sélectionné pour !cof-set-predicate'); return; } const evt = { @@ -39451,14 +39596,14 @@ var COFantasy = COFantasy || function() { case 'vrai': case 'oui': if (pred.includes(predicat)) { - sendPlayer(msg, 'Pr\xE9dicat ' + predicat + ' d\xE9j\xE0 pr\xE9sent', playerId); + sendPlayer(msg, 'Prédicat ' + predicat + ' déjà présent', playerId); return; } if (pred === '') pred = predicat; else pred = pred + ' ' + predicat; setFicheAttr(perso, 'predicats_script', pred, evt); if (predicats) predicats[perso.charId] = undefined; - sendPlayer(msg, 'Pr\xE9dicat ' + predicat + ' ajout\xE9', playerId); + sendPlayer(msg, 'Prédicat ' + predicat + ' ajouté', playerId); break; case 'false': case 'faux': @@ -39466,11 +39611,11 @@ var COFantasy = COFantasy || function() { let regPred = new RegExp('(^| |,|\n)' + predicat + '($| |,|\n)'); let newPred = pred.replace(regPred, ' '); if (newPred == pred) { - sendPlayer(msg, 'Pr\xE9dicat ' + predicat + ' non trouv\xE9', playerId); + sendPlayer(msg, 'Prédicat ' + predicat + ' non trouvé', playerId); } else { setFicheAttr(perso, 'predicats_script', newPred, evt); if (predicats) predicats[perso.charId] = undefined; - sendPlayer(msg, 'Pr\xE9dicat ' + predicat + ' enlev\xE9', playerId); + sendPlayer(msg, 'Prédicat ' + predicat + ' enlevé', playerId); } break; default: @@ -39498,11 +39643,11 @@ var COFantasy = COFantasy || function() { } var perso = persoOfId(cmd[1]); if (perso === undefined) { - error("Le token renseign\xE9 pour !cof-defense-armee-des-morts est inconnu", cmd); + error("Le token renseigné pour !cof-defense-armee-des-morts est inconnu", cmd); return; } if (!peutController(msg, perso)) { - sendPlayer(msg, "ne peut pas faire \xE7a."); + sendPlayer(msg, "ne peut pas faire ça."); return; } var evt = { @@ -39510,7 +39655,7 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); var opt = { - msg: "se d\xE9fend contre les morts" + msg: "se défend contre les morts" }; setTokenAttr(perso, "defenseArmeeDesMorts", true, evt, opt); } @@ -39530,8 +39675,8 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, ligne); } - //!cof-options-d-attaque, affiche les options d'attaque du token s\xE9lectionn\xE9 - // si on donne reset en argument, remet tout \xE0 z\xE9ro + //!cof-options-d-attaque, affiche les options d'attaque du token sélectionné + // si on donne reset en argument, remet tout à zéro // si on donne en argument option valeur, change la valeur de l'option function optionsDAttaque(msg) { const options = parseOptions(msg); @@ -39661,7 +39806,7 @@ var COFantasy = COFantasy || function() { break; default: error("Argument de !cof-options-d-attaque non reconnu", cmd); - //Mais on peut quand m\xEAme afficher les options + //Mais on peut quand même afficher les options } turnAction(perso, playerId); return; @@ -39673,7 +39818,7 @@ var COFantasy = COFantasy || function() { }; if (aepc || arc || aac || adtc || (persoEstPNJ(perso) && adg > 1)) { action = "!cof-options-d-attaque reset --target " + perso.token.id; - opt_display.action_right = boutonSimple(action, 'r\xE9init.'); + opt_display.action_right = boutonSimple(action, 'réinit.'); } var display = startFramedDisplay(playerId, title, perso, opt_display); var ligne = ''; @@ -39682,7 +39827,7 @@ var COFantasy = COFantasy || function() { ligne = "Attaque de groupe : "; action = "!cof-options-d-attaque attaque_de_groupe ?{Combien d'adversaires par jet?}"; action += " --target " + perso.token.id; - overlay = 'title="+2 Att. par cr\xE9ature, si Att > DEF + 5, DM x2, si critique DM x3"'; + overlay = 'title="+2 Att. par créature, si Att > DEF + 5, DM x2, si critique DM x3"'; ligne += boutonSimple(action, adg, overlay); if (adg < 2) { ligne += "attaquant"; @@ -39702,7 +39847,7 @@ var COFantasy = COFantasy || function() { } action += " --target " + perso.token.id; ligne = boutonSimple(action, text) + "Attaque en puissance"; - action = "!cof-options-d-attaque attaque_en_puissance ?{nombre de d\xE9s de bonus (-5 att par d\xE9)?}"; + action = "!cof-options-d-attaque attaque_en_puissance ?{nombre de dés de bonus (-5 att par dé)?}"; action += " --target " + perso.token.id; ligne += "(+" + boutonSimple(action, aep) + "d"; if (predicateAsBool(perso, 'tropPetit') && !attributeAsBool(perso, 'grandeTaille')) { @@ -39711,16 +39856,16 @@ var COFantasy = COFantasy || function() { ligne += "6 DM)"; } addLineToFramedDisplay(display, ligne); - addLigneOptionAttaque(display, perso, arc, "Attaque risqu\xE9e", 'attaque_risquee'); - addLigneOptionAttaque(display, perso, aac, "Attaque assur\xE9e", 'attaque_assuree'); + addLigneOptionAttaque(display, perso, arc, "Attaque risquée", 'attaque_risquee'); + addLigneOptionAttaque(display, perso, aac, "Attaque assurée", 'attaque_assuree'); addLigneOptionAttaque(display, perso, adtc, "Attaque pour assommer", 'attaque_dm_temp'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); if (evt.attributes) addEvent(evt); } - //si evt est d\xE9fini, on ajoute les actions \xE0 evt + //si evt est défini, on ajoute les actions à evt function nePlusSuivre(perso, pageId, evt, reutilise) { let attrSuit = tokenAttribute(perso, 'suit'); if (attrSuit.length > 0) { @@ -39793,7 +39938,7 @@ var COFantasy = COFantasy || function() { } let perso = persoOfId(cmd[1], cmd[1], options.pageId); if (perso === undefined) { - error("Token s\xE9lectionne incorrect pour !cof-suivre", cmd); + error("Token sélectionne incorrect pour !cof-suivre", cmd); return; } let pageId = perso.token.get('pageid'); @@ -39806,7 +39951,7 @@ var COFantasy = COFantasy || function() { type: 'Suivre', attributes: [] }; - //D'abord on arr\xEAte de suivre si on suivait quelqu'un + //D'abord on arrête de suivre si on suivait quelqu'un let attrSuit = nePlusSuivre(perso, pageId, evt, true); let cibleId = idName(cible); let attr = tokenAttribute(cible, 'estSuiviPar'); @@ -39829,7 +39974,7 @@ var COFantasy = COFantasy || function() { let yc = cible.token.get('top'); let distance = Math.floor(Math.sqrt((xc - xt) * (xc - xt) + (yc - yt) * (yc - yt))); if (attrSuit) { - //alors evt contient d\xE9j\xE0 attrSuit + //alors evt contient déjà attrSuit attrSuit.set('current', cibleId); attrSuit.set('max', distance); } else { @@ -39849,7 +39994,7 @@ var COFantasy = COFantasy || function() { return c !== ''; }); if (cmd.length < 2) { - error("Il faut pr\xE9ciser un token sur lequel se centrer", cmd); + error("Il faut préciser un token sur lequel se centrer", cmd); return; } let playerId = getPlayerIdFromMsg(msg); @@ -39857,7 +40002,7 @@ var COFantasy = COFantasy || function() { if (playerIsGM(playerId)) { let p = getObj('player', playerId); if (p === undefined) { - error("Impossible de trouver le joueur qui a lanc\xE9 la commande", msg); + error("Impossible de trouver le joueur qui a lancé la commande", msg); return; } pageId = p.get('_lastpage'); @@ -39904,7 +40049,7 @@ var COFantasy = COFantasy || function() { else possede = true; msg += pc + " PC"; } - if (possede) msg = 'poss\xE8de ' + msg; + if (possede) msg = 'possède ' + msg; else msg = "n'a pas d'argent"; if (dest) sendPlayer(dest, nomPerso(perso) + ' ' + msg); else whisperChar(perso.charId, msg); @@ -39926,19 +40071,19 @@ var COFantasy = COFantasy || function() { let val = ficheAttributeAsInt(perso, 'bourse_' + unite, 0); let line = '
'; let action = - "!cof-bourse fixer ?{Nouveau montant de pi\xE8ces " + piece + " ?} " + finAction; + "!cof-bourse fixer ?{Nouveau montant de pièces " + piece + " ?} " + finAction; line += boutonSimple(action, val) + '' + nom + ''; line += ''; - action = "!cof-bourse depenser ?{Pi\xE8ces " + piece + " \xE0 d\xE9penser ?} " + finAction; - line += boutonSimple(action, 'D\xE9penser'); - action = "!cof-bourse gagner ?{Pi\xE8ces " + piece + " ?} " + finAction; + action = "!cof-bourse depenser ?{Pièces " + piece + " à dépenser ?} " + finAction; + line += boutonSimple(action, 'Dépenser'); + action = "!cof-bourse gagner ?{Pièces " + piece + " ?} " + finAction; line += boutonSimple(action, 'Gagner'); line += '
'; addLineToFramedDisplay(display, line); } //!cof-bourse [action] - //Les actions peuvent \xEAtre depenser val [unite], fixer val unite ou gagner val [unite] + //Les actions peuvent être depenser val [unite], fixer val unite ou gagner val [unite] function gestionBourse(msg) { var cmd = msg.content.split(' ').filter(function(c) { return c.trim() !== ''; @@ -39955,11 +40100,11 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { switch (cmd[1]) { case 'depenser': - case 'd\xE9penser': + case 'dépenser': case 'gagner': case 'fixer': if (cmd.length < 3) { - error("Il faut sp\xE9cifier un montant \xE0 " + cmd[1], msg.content); + error("Il faut spécifier un montant à " + cmd[1], msg.content); return; } montant = parseInt(cmd[2]); @@ -39972,7 +40117,7 @@ var COFantasy = COFantasy || function() { action = 'depenser'; } else if (cmd[1] == 'fixer') { if (montant < 0) { - error("On ne peut avoir qu'un nombre positif de pi\xE8ces", cmd); + error("On ne peut avoir qu'un nombre positif de pièces", cmd); return; } action = 'fixer'; @@ -39980,12 +40125,12 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3 && !cmd[3].startsWith('--')) { unite = cmd[3].toLowerCase().trim(); if (unite != 'pp' && unite != 'po' && unite != 'pa' && unite != 'pc') { - error("Pi\xE8ces non reconnues : " + cmd[3], cmd); + error("Pièces non reconnues : " + cmd[3], cmd); return; } depense[unite] = montant; } else if (action == 'fixer') { - error("Il faut pr\xE9ciser les unit\xE9s pour !cof-bourse fixer", msg.content); + error("Il faut préciser les unités pour !cof-bourse fixer", msg.content); return; } depense.total = depense.pc + 10 * (depense.pa + 10 * (depense.po + 10 * depense.pp)); @@ -39993,7 +40138,7 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de personnage s\xE9lectionn\xE9 pour !cof-bourse", playerId); + sendPlayer(msg, "Pas de personnage sélectionné pour !cof-bourse", playerId); return; } var evt = { @@ -40037,7 +40182,7 @@ var COFantasy = COFantasy || function() { } var montantPossede = pc + 10 * (pa + 10 * (po + 10 * pp)); if (montantPossede < depense.total) { - sendPerso(perso, "ne poss\xE8de pas assez d'argent pour cette d\xE9pense"); + sendPerso(perso, "ne possède pas assez d'argent pour cette dépense"); afficherRichesse(perso, msg); return; } @@ -40047,7 +40192,7 @@ var COFantasy = COFantasy || function() { po: po, pp: pp }; - // On privil\xE9gie les d\xE9penses directes + // On privilégie les dépenses directes var dpp = depense.pp; if (dpp <= bourse.pp) { bourse.pp -= dpp; @@ -40080,14 +40225,14 @@ var COFantasy = COFantasy || function() { dpc -= bourse.pc; bourse.pc = 0; } - // Puis on d\xE9pense d'abord la petite monnaie + // Puis on dépense d'abord la petite monnaie var v = dpc + 10 * (dpa + 10 * (dpo + 10 * dpp)); v = depenserSous(perso, 'pc', bourse, v); v = depenserSous(perso, 'pa', bourse, v); v = depenserSous(perso, 'po', bourse, v); v = depenserSous(perso, 'pp', bourse, v); if (v > 0) { - error("Erreur interne de calcul, il reste " + v + " PP \xE0 d\xE9penser ??", bourse); + error("Erreur interne de calcul, il reste " + v + " PP à dépenser ??", bourse); return; } if (bourse.pc != pc) @@ -40131,7 +40276,7 @@ var COFantasy = COFantasy || function() { ajouteLignePieces(perso, display, 'po', 'Or', "d'or"); ajouteLignePieces(perso, display, 'pa', 'Argent', "d'argent"); ajouteLignePieces(perso, display, 'pc', 'Cuivre', "de cuivre"); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }); }); @@ -40146,7 +40291,7 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); if (options.lanceur) { - sendPerso(options.lanceur, "prononce un mot avec la Voix d'une puissance sup\xE9rieure. Tous ses ennemis sont immobilis\xE9s et ses alli\xE9s sont galvanis\xE9s."); + sendPerso(options.lanceur, "prononce un mot avec la Voix d'une puissance supérieure. Tous ses ennemis sont immobilisés et ses alliés sont galvanisés."); let allies = alliesParPerso[options.lanceur.charId]; if (allies) { let tokens = findObjs({ @@ -40182,8 +40327,8 @@ var COFantasy = COFantasy || function() { }, options); } - // Ajoute evt \xE0 l'historique si pr\xE9sent - // msg n'est pas forc\xE9ment pr\xE9sent + // Ajoute evt à l'historique si présent + // msg n'est pas forcément présent function nextTurnChargeFantastique(msg, oldTurnOrder) { if (oldTurnOrder) Campaign().set('turnorder', oldTurnOrder); let cf = stateCOF.chargeFantastique; @@ -40222,9 +40367,9 @@ var COFantasy = COFantasy || function() { stateCOF.chargeFantastique.activeTokenId = perso.token.id; setTokenInitAura(perso); let display = startFramedDisplay(playerId, "Charge fantastique", perso, optionsDisplay); - addLineToFramedDisplay(display, "Phase de mouvement : d\xE9placez votre token en ligne droite"); + addLineToFramedDisplay(display, "Phase de mouvement : déplacez votre token en ligne droite"); addLineToFramedDisplay(display, "puis " + boutonSimple("!cof-next-charge-fantastique", "cliquez ici")); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } if (cf.attaques && cf.attaques.length > 0) { @@ -40256,12 +40401,12 @@ var COFantasy = COFantasy || function() { } const chevalier = persoOfId(cmd[1], cmd[1], options.pageId); if (chevalier === undefined) { - error("Le token s\xE9lectionn\xE9 ne repr\xE9sente pas un personnage", cmd); + error("Le token sélectionné ne représente pas un personnage", cmd); return; } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error('pas de token s\xE9lectionn\xE9 pour !cof-charge-fantastique', msg.content); + error('pas de token sélectionné pour !cof-charge-fantastique', msg.content); return; } const evt = { @@ -40269,7 +40414,7 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); if (limiteRessources(chevalier, options, 'chargeFantastique', 'charge fantastique', evt)) return; - sendPerso(chevalier, "m\xE8ne une charge fantastique !"); + sendPerso(chevalier, "mène une charge fantastique !"); initiative(selected, evt); stateCOF.chargeFantastique = {}; let ordreActions = []; @@ -40287,14 +40432,14 @@ var COFantasy = COFantasy || function() { ordreActions.sort(function(p1, p2) { if (p1.init < p2.init) return 1; if (p1.init > p2.init) return -1; - // Priorit\xE9 aux joueurs - // Premier crit\xE8re : la barre de PV des joueurs est li\xE9e + // Priorité aux joueurs + // Premier critère : la barre de PV des joueurs est liée if (p1.perso.token.get('bar1_link') === '') { if (p2.perso.token.get('bar1_link') === '') return 0; return 1; } if (p2.perso.token.get('bar1_link') === '') return -1; - // Deuxi\xE8me crit\xE8re : les joueurs ont un DV + // Deuxième critère : les joueurs ont un DV let dvA = ficheAttributeAsInt(p1.perso, "DV", 0); let dvB = ficheAttributeAsInt(p2.perso, "DV", 0); if (dvA === 0) { @@ -40302,7 +40447,7 @@ var COFantasy = COFantasy || function() { return 1; } if (dvB === 0) return -1; - //Entre joueurs, priorit\xE9 \xE0 la plus grosse sagesse + //Entre joueurs, priorité à la plus grosse sagesse let sagA = ficheAttributeAsInt(p1.perso, 'sagesse', 10); let sagB = ficheAttributeAsInt(p2.perso, 'sagesse', 10); if (sagA < sagB) return 1; @@ -40356,9 +40501,9 @@ var COFantasy = COFantasy || function() { error("Impossible d'utiliser la prescience car l'historique est vide", cmd); return; } - //Au cas o\xF9, on v\xE9rifie que l'\xE9v\xE9nement de d\xE9but de tour est bien pr\xE9sent + //Au cas où, on vérifie que l'événement de début de tour est bien présent if (!findEvent(stateCOF.prescience.evt.id)) { - error("Impossible de trouver le d\xE9but du tour dans l'historique.", stateCOF.prescience); + error("Impossible de trouver le début du tour dans l'historique.", stateCOF.prescience); return; } while (evt && evt.id != stateCOF.prescience.evt.id) { @@ -40398,7 +40543,7 @@ var COFantasy = COFantasy || function() { updateNextInit(ensorceleur); } - //Synchronise les tokens de m\xEAme nom entre les cartes + //Synchronise les tokens de même nom entre les cartes function multiCartes(msg) { let options = parseOptions(msg); let enlever = options && options.cmd && options.cmd.length > 1 && @@ -40413,13 +40558,13 @@ var COFantasy = COFantasy || function() { addEvent(evt); return; } - sendPlayer(msg, "Aucun token selectionn\xE9 pour !cof-multi-cartes", playerId); + sendPlayer(msg, "Aucun token selectionné pour !cof-multi-cartes", playerId); return; } addEvent(evt); if (enlever) { iterSelected(selected, function(perso) { - sendPlayer(msg, nomPerso(perso) + " n'est plus synchronis\xE9", playerId); + sendPlayer(msg, nomPerso(perso) + " n'est plus synchronisé", playerId); removeTokenAttr(perso, 'tokensSynchronises', evt); }); return; @@ -40434,7 +40579,7 @@ var COFantasy = COFantasy || function() { let left = perso.token.get('left'); let top = perso.token.get('top'); let listTokens = [perso.token.id]; - //On cherche les tokens de m\xEAme nom et on les met en m\xEAme position + //On cherche les tokens de même nom et on les met en même position allTokens.forEach(function(tok) { if (tok.get('represents') != perso.charId) return; if (tok.get('name') != name) return; @@ -40457,7 +40602,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof-ombre-mouvante", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof-ombre-mouvante", playerId); return; } iterSelected(selected, function(perso) { @@ -40476,16 +40621,16 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - if (limiteRessources(voleur, options, 'ombreMouvante', 'dispara\xEEtre dans les ombres', evt)) return; + if (limiteRessources(voleur, options, 'ombreMouvante', 'disparaître dans les ombres', evt)) return; let optionsDisplay = { secret: options.secret }; let display = startFramedDisplay(playerId, 'Ombre mouvante', voleur, optionsDisplay); testCaracteristique(voleur, 'DEX', 10, 'ombreMouvante', options, evt, function(tr, explications) { - let msgRes = "R\xE9sultat : " + tr.texte; + let msgRes = "Résultat : " + tr.texte; if (tr.reussite) { - msgRes += ", " + nomPerso(voleur) + " dispara\xEEt dans les ombres"; + msgRes += ", " + nomPerso(voleur) + " disparaît dans les ombres"; addLineToFramedDisplay(display, msgRes + tr.modifiers); let ef = { effet: 'invisibleTemp', @@ -40496,7 +40641,7 @@ var COFantasy = COFantasy || function() { if (options.fx) spawnFx(voleur.token.get('left'), voleur.token.get('top'), options.fx, voleur.token.get('pageid')); } else { - msgRes += ", " + nomPerso(voleur) + " ne r\xE9ussit pas \xE0 se fondre dans les ombres."; + msgRes += ", " + nomPerso(voleur) + " ne réussit pas à se fondre dans les ombres."; addLineToFramedDisplay(display, msgRes + tr.rerolls + tr.modifiers); } explications.forEach(function(m) { @@ -40509,10 +40654,10 @@ var COFantasy = COFantasy || function() { } if (display.retarde) { addFramedHeader(display, playerId, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); - } else sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); + } else sendFramedDisplay(display); }); } @@ -40524,22 +40669,22 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof-reveler-nom", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof-reveler-nom", playerId); return; } let nouveauNomToken; if (cmd.length > 1) nouveauNomToken = cmd.slice(1).join(' '); if (selected.length > 1 && nouveauNomToken) { - sendPlayer(msg, "Attention, on ne peut s\xE9lectionner qu'un seul token quand on pr\xE9cise le nouveau nom des tokens", playerId); + sendPlayer(msg, "Attention, on ne peut sélectionner qu'un seul token quand on précise le nouveau nom des tokens", playerId); return; } const evt = { - type: "R\xE9v\xE9lation de nom", + type: "Révélation de nom", characterNames: [], defaultTokens: [], attributes: [] @@ -40570,24 +40715,24 @@ var COFantasy = COFantasy || function() { }); ancienNom = ficheAttribute(perso, 'alias', ''); nouveauNom = character.get('name'); - sendChat('', ancienNom + " \xE9tait en r\xE9alit\xE9 " + nouveauNom + " !"); + sendChat('', ancienNom + " était en réalité " + nouveauNom + " !"); } else { nouveauNom = ficheAttribute(perso, 'alias', ''); ancienNom = character.get('name'); if (nouveauNom === '') { - sendPlayer(msg, ancienNom + " n'a pas d'alias, rien \xE0 r\xE9v\xE9ler."); + sendPlayer(msg, ancienNom + " n'a pas d'alias, rien à révéler."); return; } setFicheAttr(perso, 'alias', '', evt, { default: '' }); - sendChar(perso.charId, "\xE9tait en r\xE9alit\xE9 " + nouveauNom + " !"); + sendChar(perso.charId, "était en réalité " + nouveauNom + " !"); evt.characterNames.push({ character: character, name: ancienNom }); character.set('name', nouveauNom); - //On change aussi les pr\xE9dicats qui stoquent le nom du personnage + //On change aussi les prédicats qui stoquent le nom du personnage if (attrsWithCharNames === undefined) { attrsWithCharNames = allAttrs.filter(function(attr) { return attr.get('name') == 'predicats_script'; @@ -40680,7 +40825,7 @@ var COFantasy = COFantasy || function() { sendPlayer(msg, "Pas de renommage de " + tokName, playerId); } } else { - sendPlayer(msg, "Pas de token par d\xE9faut pour " + tokName + ", ce n'est pas encore g\xE9r\xE9 dans !cof-reveler-nom", playerId); + sendPlayer(msg, "Pas de token par défaut pour " + tokName + ", ce n'est pas encore géré dans !cof-reveler-nom", playerId); } } else { if (defaultTokenName && tokName == defaultTokenName) { @@ -40735,14 +40880,14 @@ var COFantasy = COFantasy || function() { } if (b) { if (stateCOF.tenebresMagiques) { - sendPlayer('GM', "Les personnages sont d\xE9j\xE0 dans des t\xE9n\xE8bres magiques"); + sendPlayer('GM', "Les personnages sont déjà dans des ténèbres magiques"); return; } - sendPlayer('GM', "Les personnages entrent dans des t\xE9n\xE8bres magiques"); + sendPlayer('GM', "Les personnages entrent dans des ténèbres magiques"); stateCOF.tenebresMagiques = {}; } else { stateCOF.tenebresMagiques = undefined; - sendPlayer('GM', "Les personnages sortent des t\xE9n\xE8bres magiques"); + sendPlayer('GM', "Les personnages sortent des ténèbres magiques"); } } @@ -40750,24 +40895,24 @@ var COFantasy = COFantasy || function() { let cmd = msg.content.split(' '); let tm = stateCOF.tenebresMagiques; if (tm === undefined) { - sendPlayer(msg, "Pas de t\xE9n\xE8bres magiques, pas d'effet de fiole"); + sendPlayer(msg, "Pas de ténèbres magiques, pas d'effet de fiole"); return; } cmd = cmd.filter(function(c) { return c.trim() !== ''; }); if (cmd.length < 2) { - error("Il faut un argument \xE0 !cof-fiole-de-lumiere", cmd); + error("Il faut un argument à !cof-fiole-de-lumiere", cmd); return; } var distance = parseInt(cmd[1]); getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Aucun personnage s\xE9lectionn\xE9", cmd); + error("Aucun personnage sélectionné", cmd); return; } if (selected.length > 1) { - error("Il n'y a qu'une seule fiole de lumi\xE8re", cmd); + error("Il n'y a qu'une seule fiole de lumière", cmd); return; } var evt = { @@ -40788,7 +40933,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3) { dimRadius = parseInt(cmd[3]); if (isNaN(dimRadius)) { - error("La distance de vue de la lumi\xE8re assombrie doit \xEAtre un nombre", cmd[3]); + error("La distance de vue de la lumière assombrie doit être un nombre", cmd[3]); dimRadius = ''; } } @@ -40805,25 +40950,25 @@ var COFantasy = COFantasy || function() { return c !== ''; }); if (cmd.length < 3) { - error("Il faut sp\xE9cifier un attaquant et un d\xE9fenseur pour !cof-agripper-de-demon", cmd); + error("Il faut spécifier un attaquant et un défenseur pour !cof-agripper-de-demon", cmd); return; } let attaquant = persoOfId(cmd[1], cmd[1]); let defenseur = persoOfId(cmd[2], cmd[2]); if (attaquant === undefined) { - error("Le premier argument de !cof-agripper-de-demon doit \xEAtre un token valide", cmd[1]); + error("Le premier argument de !cof-agripper-de-demon doit être un token valide", cmd[1]); return; } if (defenseur === undefined) { - error("Le deuxi\xE8me argument de !cof-agripper-de-demon doit \xEAtre un token valide", cmd[2]); + error("Le deuxième argument de !cof-agripper-de-demon doit être un token valide", cmd[2]); return; } if (attributeAsBool(defenseur, 'armureDEau')) { - sendChat("L'armure d'eau emp\xEAche " + nomPerso(defenseur) + " d'\xEAtre aggrip\xE9"); + sendChat("L'armure d'eau empêche " + nomPerso(defenseur) + " d'être aggripé"); return; } const evt = { - type: "Agripper (d\xE9mon)" + type: "Agripper (démon)" }; let options = { pasDeDmg: true @@ -40838,12 +40983,12 @@ var COFantasy = COFantasy || function() { setTokenAttr(defenseur, 'estAgrippePar', idName(attaquant), evt); setTokenAttr(defenseur, 'agrippeParUnDemon', true, evt); } else { - addLineToFramedDisplay(display, nomPerso(defenseur) + " \xE9chappe \xE0 la tentative de saisie."); + addLineToFramedDisplay(display, nomPerso(defenseur) + " échappe à la tentative de saisie."); } explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); addEvent(evt); }); } @@ -40889,7 +41034,7 @@ var COFantasy = COFantasy || function() { evt.attributes.push({ attribute: attr }); - if ((carac == 'DEX' && comp != 'crochetage' && comp != 'd\xE9samor\xE7age') || + if ((carac == 'DEX' && comp != 'crochetage' && comp != 'désamorçage') || (carac == 'CON' && comp == 'survie') || comp == 'natation' || comp == 'escalade') { attrSpec.name = prefix + 'malus'; @@ -40935,7 +41080,7 @@ var COFantasy = COFantasy || function() { if (treatedChars.has(perso.charId)) return; treatedChars.add(perso.charId); if (!charAttributeAsBool(perso, 'ac')) { - sendPlayer(msg, nomPerso(perso) + " d\xE9j\xE0 converti (pas d'attribut ac)"); + sendPlayer(msg, nomPerso(perso) + " déjà converti (pas d'attribut ac)"); return; } let attributes = findObjs({ @@ -40987,6 +41132,10 @@ var COFantasy = COFantasy || function() { race = "Humain"; c = c.substring(6).trim(); attr.set('current', c); + } else if (c.startsWith('kobold')) { + race = "Kobold"; + c = c.substring(7).trim(); + attr.set('current', c); } changeAttributeName(attr, 'profil', evt); return; @@ -41009,11 +41158,14 @@ var COFantasy = COFantasy || function() { return; case 'rejuvenation': return; //Pas d'effet en combat + case 'rock catching': + notes += d + '\n'; + return; default: if (d.startsWith('channel resistance ')) { let resChannel = parseInt(d.substring(19)); if (isNaN(resChannel)) { - log("Capacit\xE9 d\xE9fensive " + d + " non connue"); + log("Capacité défensive " + d + " non connue"); } else { predicats += 'bonusSaveContre_positif:' + resChannel + ' '; return; @@ -41021,16 +41173,16 @@ var COFantasy = COFantasy || function() { } else if (d.startsWith('bravery ')) { let courage = parseInt(d.substring(8)); if (isNaN(courage)) { - log("Capacit\xE9 d\xE9fensive " + d + " non connue"); + log("Capacité défensive " + d + " non connue"); } else { predicats += 'courage:' + courage + ' '; return; } } else { - log("Capacit\xE9 d\xE9fensive " + d + " non connue"); + log("Capacité défensive " + d + " non connue"); } if (nonPrisEnCompte === '') - nonPrisEnCompte = 'Capacit\xE9s d\xE9fensives : ' + d; + nonPrisEnCompte = 'Capacités défensives : ' + d; else nonPrisEnCompte += ', ' + d; } }); @@ -41046,24 +41198,30 @@ var COFantasy = COFantasy || function() { if (w === '') return; switch (w) { case 'resurrection vulnerability': - notes += "D\xE9truit par un sort de r\xE9surection \n"; + notes += "Détruit par un sort de résurection \n"; return; case 'vulnerable to acid': + case 'vulnerability to acid': predicats += 'vulnerableA_acide '; return; case 'vulnerable to cold': + case 'vulnerability to cold': predicats += 'vulnerableA_froid '; return; case 'vulnerable to disease': + case 'vulnerability to disease': predicats += 'vulnerableA_maladie '; return; case 'vulnerable to electricity': + case 'vulnerability to electricity': predicats += 'vulnerableA_electrique '; return; case 'vulnerable to fire': + case 'vulnerability to fire': predicats += 'vulnerableA_feu '; return; case 'vulnerable to poison': + case 'vulnerability to poison': predicats += 'vulnerableA_poison '; return; default: @@ -41130,24 +41288,31 @@ var COFantasy = COFantasy || function() { case 'poison': predicats += 'immunite_poison '; return; - case 'poison': - predicats += 'immunite_sommeil '; + case 'fear': + predicats += 'immunite_peur '; + return; + case 'sleep': + predicats += 'immunite_endormi '; return; case 'construct': - predicats += 'sansEsprit creatureArtificielle immuniteSaignement'; + predicats += 'sansEsprit creatureArtificielle immuniteSaignement '; + return; + case 'blindness': + predicats += 'immunite_aveugle '; return; case 'undead': case 'traits': case 'effects': case 'plants': + case 'and': return; default: - log("Immunit\xE9 \xE0 " + i + " non trait\xE9e"); + log("Immunité à " + i + " non traitée"); immunitesNonTraitees += i + ' '; } }); if (immunitesNonTraitees !== '') { - log("Immunit\xE9s non trait\xE9es : " + immunitesNonTraitees); + log("Immunités non traitées : " + immunitesNonTraitees); attributsIgnores += 'immune : ' + immunitesNonTraitees + '.\n'; } deleteAttribute(attr, evt); @@ -41193,13 +41358,17 @@ var COFantasy = COFantasy || function() { if (rd === '') rd = 'poison:' + resVal; else rd += ', poison:' + resVal; return; + case 'sonic': + if (rd === '') rd = 'sonique:' + resVal; + else rd += ', sonique:' + resVal; + return; default: - log("R\xE9sistance \xE0 " + res[0] + " non trait\xE9e"); + log("Résistance à " + res[0] + " non traitée"); resistancesNonTraitees += r + ', '; } }); if (resistancesNonTraitees !== '') { - log("Resistances non trait\xE9es : " + resistancesNonTraitees); + log("Resistances non traitées : " + resistancesNonTraitees); attributsIgnores += 'resist : ' + resistancesNonTraitees + '.\n'; } deleteAttribute(attr, evt); @@ -41246,13 +41415,13 @@ var COFantasy = COFantasy || function() { predicats += 'nonVivant '; break; case 'dragon': - predicats += 'nonVivant '; + predicats += 'dragon '; break; case 'fey': - predicats += 'f\xE9e '; + predicats += 'fée '; break; case 'outsider': - predicats += 'ext\xE9rieur '; + predicats += 'extérieur '; break; case 'undead': predicats += 'nonVivant mortVivant '; @@ -41282,7 +41451,7 @@ var COFantasy = COFantasy || function() { taille = 'minuscule'; break; case 'tiny': - taille = 'tr\xE8s petit'; + taille = 'très petit'; break; case 'small': taille = 'petite'; @@ -41293,7 +41462,7 @@ var COFantasy = COFantasy || function() { taille = 'grand'; break; case 'huge': - taille = '\xE9norme'; + taille = 'énorme'; break; case 'gargantuan': case 'colossal': @@ -41382,15 +41551,15 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); return; case 'disable_device': - ajouteCompetence(perso, 'd\xE9samor\xE7age', 'DEX', attr.get('current'), evt); + ajouteCompetence(perso, 'désamorçage', 'DEX', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'disguise': - ajouteCompetence(perso, 'd\xE9guisement', 'CHA', attr.get('current'), evt); + ajouteCompetence(perso, 'déguisement', 'CHA', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'escape_artist': - ajouteCompetence(perso, '\xE9vasion', 'DEX', attr.get('current'), evt); + ajouteCompetence(perso, 'évasion', 'DEX', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'fly': @@ -41418,11 +41587,11 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); return; case 'knowledge_engineering': - ajouteCompetence(perso, 'connaissance (ing\xE9ni\xE9rie)', 'INT', attr.get('current'), evt); + ajouteCompetence(perso, 'connaissance (ingéniérie)', 'INT', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'knowledge_geography': - ajouteCompetence(perso, 'connaissance (g\xE9ographie)', 'INT', attr.get('current'), evt); + ajouteCompetence(perso, 'connaissance (géographie)', 'INT', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'knowledge_history': @@ -41466,7 +41635,7 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); return; case 'ride': - ajouteCompetence(perso, '\xC9quitation', 'DEX', attr.get('current'), evt); + ajouteCompetence(perso, 'Équitation', 'DEX', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'sense_motive': @@ -41478,11 +41647,11 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); return; case 'spellcraft': - ajouteCompetence(perso, 'sortil\xE8ges', 'INT', attr.get('current'), evt); + ajouteCompetence(perso, 'sortilèges', 'INT', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'stealth': - ajouteCompetence(perso, 'discr\xE9tion', 'DEX', attr.get('current'), evt); + ajouteCompetence(perso, 'discrétion', 'DEX', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'survival': @@ -41493,7 +41662,7 @@ var COFantasy = COFantasy || function() { ajouteCompetence(perso, 'natation', 'FOR', attr.get('current'), evt); deleteAttribute(attr, evt); return; - //Attributs de toutes facons modifi\xE9s: + //Attributs de toutes facons modifiés: case 'tab': case 'type_personnage': return; @@ -41521,7 +41690,7 @@ var COFantasy = COFantasy || function() { case 'skills_racial_modifiers': case 'fortitude': case 'reflex': - case 'will': //On n'y touche pas pour l'instant. \xC0 voir plus tard + case 'will': //On n'y touche pas pour l'instant. À voir plus tard let x = attr.get('current'); if (x === undefined || x === '') deleteAttribute(attr, evt); return; @@ -41580,7 +41749,7 @@ var COFantasy = COFantasy || function() { case 'spellabilities_flag': case 'sq': case 'xp': - case 'l1mancer_status': //Attributs ignor\xE9s + case 'l1mancer_status': //Attributs ignorés deleteAttribute(attr, evt); return; default: @@ -41620,6 +41789,48 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); } }); + let cleave = false; + for (let pref in feats) { + let feat = feats[pref]; + switch (feat.name) { + case undefined: + break; + case 'Improved Initiative': + case 'Toughness': + case 'Weapon Finesse': + case 'Dodge': + case 'Combat Casting': + case 'Brew Potion': + break; + case 'Alertness': + predicats += 'vigilance:2 '; + break; + case 'Cleave': + cleave = true; + break; + case 'Defect Arrows': + predicats += 'paradeDeProjectiles '; + break; + case 'Point-Blank Shot': + predicats += 'tirPrecis:1 '; + break; + case 'Iron Will': + predicats += 'bonusSagesseMagie:2 '; + break; + default: + if (feat.name.startsWith('Weapon Focus (')) continue; + if (feat.name.startsWith('Weapon Specialization (')) continue; + notes += feat.name + ' : '; + if (feat.benefits) notes += feat.benefits + '\n'; + else if (feat.description) notes += feat.description + '\n'; + attributsIgnores += 'Feat ' + feat.name + ' : {'; + for (let field in feat) { + if (field == 'name') continue; + attributsIgnores += ' ' + field + ' : ' + feat[field] + ','; + } + attributsIgnores += '} .\n'; + } + } let maxAttackLabel = 0; for (let pref in attaques) { let attaque = attaques[pref]; @@ -41676,7 +41887,7 @@ var COFantasy = COFantasy || function() { break; default: if (!e.startsWith('+')) { - log("Ennemi jur\xE9 non reconnu : " + e); + log("Ennemi juré non reconnu : " + e); } } } @@ -41696,6 +41907,7 @@ var COFantasy = COFantasy || function() { }); let spec = ''; let options = ''; + let portee = 0; for (let field in attaque) { switch (field) { case 'atkmod': @@ -41713,7 +41925,7 @@ var COFantasy = COFantasy || function() { }); break; case 'dmgbase': - let dm = parseDice(attaque.dmgbase, 'd\xE9g\xE2ts'); + let dm = parseDice(attaque.dmgbase, 'dégâts'); if (dm) { if (dm.nbDe) createObj('attribute', { @@ -41769,13 +41981,13 @@ var COFantasy = COFantasy || function() { } break; case 'atkrange': - let range = parseInt(attaque.atkrange); - if (isNaN(range) || range < 0) range = 1; - else range = Math.floor(range / 2); + portee = parseInt(attaque.atkrange); + if (isNaN(portee) || portee < 0) portee = 1; + else portee = Math.floor(portee / 2); createObj('attribute', { _characterid: perso.charId, name: prefix + 'portee', - current: range + current: portee }); break; case 'dmgcritmulti': @@ -41784,7 +41996,7 @@ var COFantasy = COFantasy || function() { options += '--incrCritCoef ' + (cm - 2) + ' '; } break; - case 'atkname': //d\xE9j\xE0 trait\xE9 plus haut + case 'atkname': //déjà traité plus haut case 'options-flag': case 'dmgflag': case 'dmg2type': @@ -41796,6 +42008,7 @@ var COFantasy = COFantasy || function() { spec += field + ' : ' + attaque[field]; } } + if (cleave && portee === 0) options += '--target @{target|Cible 2|token_id} '; if (spec) createObj('attribute', { _characterid: perso.charId, @@ -41825,43 +42038,8 @@ var COFantasy = COFantasy || function() { if (ab.name) notes += ab.name + ' : '; if (ab.description) notes += ab.description + '\n'; } - for (let pref in feats) { - let feat = feats[pref]; - switch (feat.name) { - case undefined: - continue; - case 'Improved Initiative': - case 'Toughness': - case 'Weapon Finesse': - case 'Dodge': - case 'Combat Casting': - case 'Brew Potion': - continue; - case 'Defect Arrows': - predicats += 'paradeDeProjectiles '; - break; - case 'Point-Blank Shot': - predicats += 'tirPrecis:1 '; - break; - case 'Iron Will': - predicats += 'bonusSagesseMagie:2 '; - break; - default: - if (feat.name.startsWith('Weapon Focus (')) continue; - if (feat.name.startsWith('Weapon Specialization (')) continue; - notes += feat.name + ' : '; - if (feat.benefits) notes += feat.benefits + '\n'; - else if (feat.description) notes += feat.description + '\n'; - attributsIgnores += 'Feat ' + feat.name + ' : {'; - for (let field in feat) { - if (field == 'name') continue; - attributsIgnores += ' ' + field + ' : ' + feat[field] + ','; - } - attributsIgnores += '} .\n'; - } - } if (maxAttackLabel > 0) setAttr('max_attack_label', maxAttackLabel); - //Puis on met les attributs n\xE9cessaires + //Puis on met les attributs nécessaires if (attributsIgnores !== '') setAttr('Attributs Pathfinder', attributsIgnores); if (predicats !== '') setAttr('predicats_script', predicats); @@ -41877,10 +42055,10 @@ var COFantasy = COFantasy || function() { let initiative = dexterite + init - mod_dex; if (isNaN(initiative)) initiative = 10 + 2 * init; setAttr('pnj_init', initiative); - // N\xE9cessaire pour \xE9viter que les sheetworkers re-calculent init et def + // Nécessaire pour éviter que les sheetworkers re-calculent init et def if (initiative != dexterite) setAttr('INIT_DIV', initiative - dexterite); if (def != 10 + mod_dex) setAttr('DEFDIV', def - 10 - mod_dex); - //Finalement, on change le token par d\xE9faut + //Finalement, on change le token par défaut let acAttr = perso.token.get('bar2_link'); affectToken(perso.token, 'bar2_link', acAttr, evt); perso.token.set('bar2_link', ''); @@ -41947,7 +42125,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { @@ -41955,15 +42133,15 @@ var COFantasy = COFantasy || function() { return; } let positif = true; - if (cmd[1] === 'false' || cmd[1] === 'negatif' || cmd[1] === 'n\xE9gatif') + if (cmd[1] === 'false' || cmd[1] === 'negatif' || cmd[1] === 'négatif') positif = false; if (options.soin === undefined && options.dm === undefined) { - sendPlayer(msg, "Rien \xE0 canaliser. Il faut pr\xE9ciser un montant de soins ou de d\xE9g\xE2ts"); + sendPlayer(msg, "Rien à canaliser. Il faut préciser un montant de soins ou de dégâts"); return; } getSelected(msg, function(selected, playerId) { if (selected.length != 1) { - sendPlayer(msg, "Il faut s\xE9lectionner un personnage", playerId); + sendPlayer(msg, "Il faut sélectionner un personnage", playerId); return; } let token = getObj('graphic', selected[0]._id); @@ -41973,7 +42151,7 @@ var COFantasy = COFantasy || function() { } let charId = token.get('represents'); if (charId === undefined || charId === '') { - error("Le token ne repr\xE9sente pas un personnage", token); + error("Le token ne représente pas un personnage", token); return; } let pretre = { @@ -42053,7 +42231,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, e); }); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }; if (options.soin) { @@ -42068,18 +42246,18 @@ var COFantasy = COFantasy || function() { let soins = res[0].inlinerolls[0].results.total; let soinTxt = buildinline(res[0].inlinerolls[0], 'normal', true); if (soins <= 0) { - sendPerso(pretre, "ne r\xE9ussit pas \xE0 soigner (total de soins " + soinTxt + ")", true); + sendPerso(pretre, "ne réussit pas à soigner (total de soins " + soinTxt + ")", true); sync(); return; } - //TODO: tenir compte des PV partag\xE9s + //TODO: tenir compte des PV partagés soigneToken(target, soins, evt, function(soinsEffectifs) { let line = "" + nomPerso(target) + " : + "; if (soinsEffectifs == soins) { line += soinTxt + 'PV'; } else { - line += soinsEffectifs + 'PV (jet: ' + soinTxt + ')'; + line += soinsEffectifs + ' PV (jet: ' + soinTxt + ')'; } addLineToFramedDisplay(display, line); sync(); @@ -42090,7 +42268,7 @@ var COFantasy = COFantasy || function() { }, options); }); } catch (rollError) { - error("Jet " + options.soin + " mal form\xE9", options); + error("Jet " + options.soin + " mal formé", options); } }); } @@ -42124,7 +42302,7 @@ var COFantasy = COFantasy || function() { copyDmgOptionsToTarget(target, options); dealDamage(target, dmg, [], evt, false, options, explications, function(dmgDisplay, dmgFinal) { addLineToFramedDisplay(display, - nomPerso(target) + " re\xE7oit " + dmgDisplay + " DM"); + nomPerso(target) + " reçoit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); @@ -42132,7 +42310,7 @@ var COFantasy = COFantasy || function() { }); }); } catch (rollError) { - error("Jet " + options.dm + " mal form\xE9", dm); + error("Jet " + options.dm + " mal formé", dm); } }); } @@ -42143,7 +42321,7 @@ var COFantasy = COFantasy || function() { 1: { token: "https://s3.amazonaws.com/files.d20.io/images/250177368/mJsYWMFqDeEmJDJy8tJKWA/thumb.png?1634130296", avatar: "https://s3.amazonaws.com/files.d20.io/images/250177753/IMzDqEpNpuznVnAMYRil8A/max.jpg?1634130507", - taille: 'tr\xE8s petite', + taille: 'très petite', force: 4, pnj_for: -3, constitution: 4, @@ -42213,13 +42391,13 @@ var COFantasy = COFantasy || function() { }; //!cof-animation-des-objets lid niveau [tid] - // la cible optionelle correspond \xE0 un token existant non associ\xE9 \xE0 un personnage + // la cible optionelle correspond à un token existant non associé à un personnage function animationDesObjets(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -42233,7 +42411,7 @@ var COFantasy = COFantasy || function() { } let niveauObjet = parseInt(cmd[2]); if (isNaN(niveauObjet) || niveauObjet < 1) { - error("Le niveau de l'objet anim\xE9 doit \xEAtre un nombre positif", cmd); + error("Le niveau de l'objet animé doit être un nombre positif", cmd); return; } if (niveauObjet > 10) niveauObjet = 10; @@ -42246,7 +42424,7 @@ var COFantasy = COFantasy || function() { let dejaAnime = attributeAsInt(lanceur, 'niveauDesObjetsAnimes', 0); let playerId = getPlayerIdFromMsg(msg); if (dejaAnime + niveauObjet > niveau) { - sendPlayer(msg, "Impossible d'animer plus d'objets pour le moment : somme des niveau anim\xE9s = " + dejaAnime, playerId); + sendPlayer(msg, "Impossible d'animer plus d'objets pour le moment : somme des niveau animés = " + dejaAnime, playerId); return; } let evt = { @@ -42256,7 +42434,7 @@ var COFantasy = COFantasy || function() { if (limiteRessources(lanceur, options, 'animationObjet', "animation d'un objet", evt)) return; let tokenSize = 70; switch (stats.taille) { - case 'tr\xE8s petite': + case 'très petite': tokenSize = 35; break; case 'petite': @@ -42275,7 +42453,7 @@ var COFantasy = COFantasy || function() { let pageId = lanceur.token.get('pageid'); tokenObjet = tokenObjet || createObj('graphic', { - name: 'Objet anim\xE9', + name: 'Objet animé', subtype: 'token', pageid: pageId, imgsrc: stats.token, @@ -42293,12 +42471,12 @@ var COFantasy = COFantasy || function() { limit_field_of_vision_total: 0, }); if (tokenObjet === undefined) { - error("Impossible de cr\xE9er le token", stats); + error("Impossible de créer le token", stats); return; } toFront(tokenObjet); let persoObjet = { - nom: 'Objet anim\xE9 par ' + nomPerso(lanceur), + nom: 'Objet animé par ' + nomPerso(lanceur), attributesFiche: { type_personnage: 'PNJ', niveau: niveauObjet, @@ -42365,7 +42543,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -42380,9 +42558,9 @@ var COFantasy = COFantasy || function() { break; case 'DEX': case 'dexterite': - case 'dexterit\xE9': - case 'dext\xE9rit\xE9': - case 'dext\xE9rite': + case 'dexterité': + case 'dextérité': + case 'dextérite': carac = 'dexterite'; break; case 'CON': @@ -42402,18 +42580,18 @@ var COFantasy = COFantasy || function() { carac = 'charisme'; break; default: - error("Caract\xE9ristique " + carac + " non reconnue", cmd); + error("Caractéristique " + carac + " non reconnue", cmd); return; } let valeur = parseInt(cmd[2]); if (isNaN(valeur) || valeur < 1) { - error("La valeur de soin d'affaiblissement doit \xEAtre un nombre positif", cmd); + error("La valeur de soin d'affaiblissement doit être un nombre positif", cmd); return; } let lanceur = options.lanceur; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour le soin d'affaiblissement", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour le soin d'affaiblissement", playerId); return; } if (lanceur === undefined) { @@ -42458,7 +42636,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -42473,9 +42651,9 @@ var COFantasy = COFantasy || function() { break; case 'DEX': case 'dexterite': - case 'dexterit\xE9': - case 'dext\xE9rit\xE9': - case 'dext\xE9rite': + case 'dexterité': + case 'dextérité': + case 'dextérite': carac = 'dexterite'; break; case 'CON': @@ -42500,18 +42678,18 @@ var COFantasy = COFantasy || function() { carac = 'random'; break; default: - error("Caract\xE9ristique " + carac + " non reconnue", cmd); + error("Caractéristique " + carac + " non reconnue", cmd); return; } - let valeur = parseInt(cmd[2]); - if (isNaN(valeur) || valeur < 1) { - error("La valeur d'affaiblissement doit \xEAtre un nombre positif", cmd); + let valeur = parseDice(cmd[2]); + if (!valeur || !dePositif(valeur)) { + error("La valeur d'affaiblissement doit être un nombre positif", cmd); return; } let lanceur = options.lanceur; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour l'affaiblissement", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour l'affaiblissement", playerId); return; } if (lanceur === undefined) { @@ -42537,7 +42715,7 @@ var COFantasy = COFantasy || function() { } } if (options.type && immuniseAuType(perso, options.type, lanceur)) { - sendPerso(perso, "ne semble pas affect\xE9 par " + stringOfType(options.type)); + sendPerso(perso, "ne semble pas affecté par " + stringOfType(options.type)); return; } cibles.push(perso); @@ -42578,17 +42756,38 @@ var COFantasy = COFantasy || function() { return carac; } - //carac est une caract\xE9ristique enti\xE8re + //carac est une caractéristique entière + //valeur est soit un nombre, soit le résultat de parseDice function affaiblirCaracPerso(perso, carac, valeur, expliquer, evt) { let nomAttr = 'affaiblissementde' + carac; + let valeurText = valeur; + if (isNaN(valeur)) { + let rid = valeur.id; + if (rid === undefined) { + error("Résultat de parseDice sans id", valeur); + return; + } + if (perso.affaiblirCaracRoll && perso.affaiblirCaracRoll[rid]) { + let r = perso.affaiblirCaracRoll[rid]; + valeur = r.val; + valeurText = r.roll; + } else { + let r = rollDePlus(valeur); + valeur = r.val; + valeurText = r.roll; + perso.affaiblirCaracRoll = perso.affaiblirCaracRoll || {}; + perso.affaiblirCaracRoll[rid] = r; + } + } let malus = addToAttributeAsInt(perso, nomAttr, 0, valeur, evt); let cn = caracNormale(perso, carac); if (malus > cn) { valeur += cn - malus; + valeurText = valeur; setTokenAttr(perso, nomAttr, cn, evt); } if (valeur < 1) return; - expliquer("perd " + valeur + " points de " + carac); + expliquer("perd " + valeurText + " points de " + carac); if (carac == 'constitution') { if (malus >= cn) { mort(perso, expliquer, evt); @@ -42621,7 +42820,7 @@ var COFantasy = COFantasy || function() { updateCurrentBar(perso, 1, bar1, evt, pvmax); if (bar1 === 0) mort(perso, expliquer, evt); } - } else { //autre caract\xE9ristiques + } else { //autre caractéristiques if (malus >= cn) { setState(perso, 'renverse', true, evt); setState(perso, 'assomme', true, evt); @@ -42629,16 +42828,17 @@ var COFantasy = COFantasy || function() { } } + // valeur peut être un nombre ou le résultat de parseDice function affaiblirCarac(playerId, cibles, carac, valeur, options) { const evt = { type: 'affaiblissement', action: { titre: "Affaiblissement de " + carac, - playerId: playerId, - cibles: cibles, - carac: carac, - valeur: valeur, - options: options + playerId, + cibles, + carac, + valeur, + options, } }; let lanceur = options.lanceur; @@ -42664,8 +42864,8 @@ var COFantasy = COFantasy || function() { }; if (options.save) { let saveOpts = { - msgPour: " pour r\xE9sister \xE0 un affaiblissement de " + car, - msgRate: ", rat\xE9.", + msgPour: " pour résister à un affaiblissement de " + car, + msgRate: ", raté.", attaquant: lanceur, rolls: options.rolls, chanceRollId: options.chanceRollId, @@ -42690,7 +42890,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { @@ -42705,19 +42905,19 @@ var COFantasy = COFantasy || function() { let playerId = getPlayerIdFromMsg(msg); let attr = tokenAttribute(perso, 'reactionViolente'); if (attr.length === 0) { - sendPlayer(msg, "Action inutile, " + perso.token.ge('name') + " n'est pas sous l'effet d'une r\xE9action violente", playerId); + sendPlayer(msg, "Action inutile, " + perso.token.ge('name') + " n'est pas sous l'effet d'une réaction violente", playerId); return; } attr = attr[0]; let duree = parseInt(attr.get('current')); if (isNaN(duree) || duree < 1) duree = 1; let evt = { - type: "Fin de r\xE9action violente", + type: "Fin de réaction violente", deletedAttributes: [attr] }; addEvent(evt); attr.remove(); - sendPerso(perso, "prend sur " + onGenre(perso, 'lui', 'elle') + " pour contenir sa r\xE9action violente"); + sendPerso(perso, "prend sur " + onGenre(perso, 'lui', 'elle') + " pour contenir sa réaction violente"); options.ignoreRD = true; let de = 6; if (predicateAsBool(perso, 'sangFroid')) de = 4; @@ -42735,16 +42935,16 @@ var COFantasy = COFantasy || function() { }); } - //!cof-explosion correspond \xE0 !cof-attack token token --explosion pour chaque token s\xE9lectionn\xE9 + //!cof-explosion correspond à !cof-attack token token --explosion pour chaque token sélectionné function attaqueExplosion(msg) { if (!msg.content) return; let index = msg.content.indexOf(' '); if (index < 1) { - error("Il manque le label de l'attaque \xE0 utiliser pour !cof-explosion", msg.content); + error("Il manque le label de l'attaque à utiliser pour !cof-explosion", msg.content); return; } let args_msg = msg.content.substring(index); - //On va ensuite enlever tout ce qui vient apr\xE8s --target + //On va ensuite enlever tout ce qui vient après --target index = args_msg.indexOf(' --target '); if (index > 0) args_msg = args_msg.substring(0, index); args_msg += ' --explosion'; @@ -42759,7 +42959,7 @@ var COFantasy = COFantasy || function() { }, { ignoreAllies: true, ignoreDisque: true - }); //On ignore les options d'alli\xE9s dans le getSelected + }); //On ignore les options d'alliés dans le getSelected } const listeEffetsAuD20 = { @@ -42785,7 +42985,7 @@ var COFantasy = COFantasy || function() { function setEffetChaqueD20(msg) { let playerId = getPlayerIdFromMsg(msg); if (!playerIsGM(playerId)) { - sendPlayer(msg, "Commande r\xE9serv\xE9e au MJ", playerId); + sendPlayer(msg, "Commande réservée au MJ", playerId); return; } let cmd = msg.content.split(' '); @@ -42879,7 +43079,7 @@ var COFantasy = COFantasy || function() { } let playerId = getPlayerIdFromMsg(msg); if (!playerIsGM(playerId)) { - sendPlayer(msg, "Commande r\xE9serv\xE9e aux MJs", playerId); + sendPlayer(msg, "Commande réservée aux MJs", playerId); return; } let pageId = getPageId(playerId); @@ -42889,7 +43089,7 @@ var COFantasy = COFantasy || function() { } let page = getObj('page', pageId); if (page === undefined) { - error("Impossible de trouver la page correspondant \xE0 l'id", pageId); + error("Impossible de trouver la page correspondant à l'id", pageId); return; } let agrandir = function(o, field) { @@ -42928,31 +43128,31 @@ var COFantasy = COFantasy || function() { texts.forEach(function(t) { move(t); }); - sendPlayer('GM', "Agrandissement termin\xE9"); + sendPlayer('GM', "Agrandissement terminé"); } function decoincer(msg) { getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9", playerId); + sendPlayer(msg, "Pas de token sélectionné", playerId); return; } if (!playerIsGM(playerId)) { - sendPlayer(msg, "Action r\xE9serv\xE9e au MJ", playerId); + sendPlayer(msg, "Action réservée au MJ", playerId); return; } const evt = { - type: "D\xE9coincer", + type: "Décoincer", tokens: [] }; let pageId; iterSelected(selected, function(perso) { if (attributeAsBool(perso, 'decoince')) { - sendPlayer(msg, nomPerso(perso) + " peut d\xE9j\xE0 \xEAtre d\xE9plac\xE9", playerId); + sendPlayer(msg, nomPerso(perso) + " peut déjà être déplacé", playerId); return; } if (!perso.token.get('lockMovement')) { - sendPlayer(msg, nomPerso(perso) + "n'est pas bloqu\xE9", playerId); + sendPlayer(msg, nomPerso(perso) + "n'est pas bloqué", playerId); return; } let nom = 'decoince ' + perso.token.get('name'); @@ -43006,14 +43206,14 @@ var COFantasy = COFantasy || function() { }; let tokenBouge = createObj('graphic', tokenFields); if (!tokenBouge) { - error("Impossible de cr\xE9er de token pour d\xE9coincer " + nomPerso(perso), tokenFields); + error("Impossible de créer de token pour décoincer " + nomPerso(perso), tokenFields); return; } evt.tokens.push(tokenBouge); toFront(tokenBouge); setTokenAttr(perso, 'bougeGraceA', tokenBouge.id, evt); }); - if (pageId) sendPlayer(msg, "Penser \xE0 supprimer le token invisible quand vous aurez termin\xE9 le d\xE9placement", playerId); + if (pageId) sendPlayer(msg, "Penser à supprimer le token invisible quand vous aurez terminé le déplacement", playerId); }); } @@ -43082,7 +43282,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -43096,7 +43296,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-sentir-la-corruption n'est pas un token valide", msg.content); + error("Le deuxième argument de !cof-sentir-la-corruption n'est pas un token valide", msg.content); return; } let portee = 30; @@ -43139,10 +43339,10 @@ var COFantasy = COFantasy || function() { } if (display.retarde) { addFramedHeader(display, playerId, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); - } else sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); + } else sendFramedDisplay(display); }; if (tr.reussite) { addLineToFramedDisplay(display, msgRes + tr.modifiers); @@ -43150,7 +43350,7 @@ var COFantasy = COFantasy || function() { testCaracteristique(cible, 'INT', 15, 'sentirLaCorruptionCible', options, evt, function(tr, explications) { let msgRes = "Jet d'INT de " + nomPerso(cible) + " : " + tr.texte; - //On n'affiche pas les possibilit\xE9s de rerolls, sinon il faudrait un bouton pour "continuer" afin de ne pas afficher le r\xE9sultat. + //On n'affiche pas les possibilités de rerolls, sinon il faudrait un bouton pour "continuer" afin de ne pas afficher le résultat. addLineToFramedDisplay(display, msgRes + tr.modifiers); explications.forEach(function(m) { addLineToFramedDisplay(display, m, 80); @@ -43179,7 +43379,7 @@ var COFantasy = COFantasy || function() { } } else { addLineToFramedDisplay(display, msgRes + tr.rerolls + tr.modifiers); - addLineToFramedDisplay(display, nomPerso(chasseur) + " ne r\xE9ussit pas \xE0 sentir la corruption."); + addLineToFramedDisplay(display, nomPerso(chasseur) + " ne réussit pas à sentir la corruption."); endDisplay(); } }); @@ -43191,28 +43391,28 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } let nbBaies; if (cmd.length > 1) { nbBaies = parseInt(cmd[1]); if (isNaN(nbBaies) || nbBaies < 1) { - sendPlayer(msg, "Aucune baie cr\xE9\xE9e. la commnde en demandait " + cmd[1]); + sendPlayer(msg, "Aucune baie créée. la commnde en demandait " + cmd[1]); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Utilisation de !cof-creer-baies sans s\xE9lection de token", playerId); + sendPlayer(msg, "Utilisation de !cof-creer-baies sans sélection de token", playerId); return; } const evt = { - type: "Cr\xE9ation de baies" + type: "Création de baies" }; addEvent(evt); iterSelected(selected, function(druide) { - if (limiteRessources(druide, options, 'creationDeBaies', "cr\xE9er des baies", evt)) return; + if (limiteRessources(druide, options, 'creationDeBaies', "créer des baies", evt)) return; let niveau = ficheAttributeAsInt(druide, 'niveau', 1); let mangerBaie = "!cof-consommer-baie " + niveau + " --limiteParJour 1 baieMagique"; let nb; @@ -43227,7 +43427,7 @@ var COFantasy = COFantasy || function() { }); } ajouterConsommable(druide, 'Baie magique', nb.val, mangerBaie, evt); - sendPerso(druide, "cr\xE9e " + nb.roll + " baies magiques"); + sendPerso(druide, "crée " + nb.roll + " baies magiques"); }); }); } @@ -43255,12 +43455,12 @@ var COFantasy = COFantasy || function() { if (attr.length > 0) { attr = attr[0]; if (attr.length > 1) { - error("Plus d'un attribut pour la quantit\xE9 d'armes de jet", attr); + error("Plus d'un attribut pour la quantité d'armes de jet", attr); attr[1].remove(); } max = parseInt(attr.get('max')); if (isNaN(max) || max < 1) { - error("Maximum de " + weaponStats.name + " mal form\xE9, v\xE9rifier sur la fiche", attr); + error("Maximum de " + weaponStats.name + " mal formé, vérifier sur la fiche", attr); max = 1; } evt.attributes.push({ @@ -43280,7 +43480,7 @@ var COFantasy = COFantasy || function() { }); } if (weaponStats.nbArmesDeJet >= max) { - error(nomPerso(lanceur) + " a d\xE9j\xE0 toutes ses armes de jet (" + max + ")", weaponStats); + error(nomPerso(lanceur) + " a déjà toutes ses armes de jet (" + max + ")", weaponStats); return; } attr.set('current', weaponStats.nbArmesDeJet + 1); @@ -43293,16 +43493,16 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { - error("Il manque des arguments \xE0 !cof-retour-boomerang", cmd); + error("Il manque des arguments à !cof-retour-boomerang", cmd); return; } let lanceur = persoOfId(cmd[1]); if (!lanceur) { - error("L'id du token ayan lanc\xE9 les armes est incorrecte", cmd); + error("L'id du token ayan lancé les armes est incorrecte", cmd); return; } let evt = { @@ -43319,11 +43519,11 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { - error("Il manque un argument \xE0 !cof-open-door", cmd); + error("Il manque un argument à !cof-open-door", cmd); return; } let door = getObj('door', cmd[1]); @@ -43334,7 +43534,7 @@ var COFantasy = COFantasy || function() { door.set('isOpen', true); } - //Demande de bouger son token jusqu'\xE0 destination + //Demande de bouger son token jusqu'à destination function attaqueLigneBouger(msg) { const playerId = getPlayerIdFromMsg(msg); if (stateCOF.pause && !playerIsGM(playerId)) { @@ -43343,7 +43543,7 @@ var COFantasy = COFantasy || function() { } let args = msg.content.split(' '); if (args.length < 2) { - error("Il manque un argument \xE0 !cof-attack-line", args); + error("Il manque un argument à !cof-attack-line", args); return; } const attaquant = persoOfId(args[1]); @@ -43354,12 +43554,12 @@ var COFantasy = COFantasy || function() { let token = attaquant.token; let restArgs = args.slice(2).join(' '); let command = '!cof-attack-line-from ' + token.get('left') + ' ' + token.get('top') + ' ' + token.id + ' ' + restArgs; - sendPlayer(msg, "D\xE9placer votre token jusqu'au bout de la ligne (l'emplacement doit \xEAtre libre), et " + boutonSimple(command, "cliquer ici"), playerId); + sendPlayer(msg, "Déplacer votre token jusqu'au bout de la ligne (l'emplacement doit être libre), et " + boutonSimple(command, "cliquer ici"), playerId); return; } - //En partant de from, retourne la premi\xE8re position sur le segment [from, to] - // \xE0 distance dist de pt. S'il n'y en a pas, retourne la projection de pt sur le segment + //En partant de from, retourne la première position sur le segment [from, to] + // à distance dist de pt. S'il n'y en a pas, retourne la projection de pt sur le segment function positionLigne(from, to, token, dist) { let fx = from.x; let fy = from.y; @@ -43405,7 +43605,7 @@ var COFantasy = COFantasy || function() { let originLeft = parseInt(args[1]); let originTop = parseInt(args[2]); if (isNaN(originLeft) || isNaN(originTop)) { - error("Coordonn\xE9es non num\xE9riques dans !co-attack-line", args); + error("Coordonnées non numériques dans !co-attack-line", args); return; } const attaquant = persoOfId(args[3]); @@ -43415,7 +43615,7 @@ var COFantasy = COFantasy || function() { } let destLeft = attaquant.token.get('left'); let destTop = attaquant.token.get('top'); - //On remet l'attaquant \xE0 sa place + //On remet l'attaquant à sa place attaquant.token.set('left', originLeft); attaquant.token.set('top', originTop); let combat = stateCOF.combat; @@ -43442,12 +43642,12 @@ var COFantasy = COFantasy || function() { y: originTop }; let tropLoin = false; - //On cherche si argument --distanceMax, pas utilis\xE9 par cof-attack + //On cherche si argument --distanceMax, pas utilisé par cof-attack optArgs = optArgs.filter(function(cmd) { if (!cmd.startsWith('distanceMax')) return true; let a = cmd.split(' '); if (a.length < 2) { - error("Il manque un argument \xE0 --distanceMax", cmd); + error("Il manque un argument à --distanceMax", cmd); return false; } let distanceMax = parseInt(a[1]); @@ -43500,14 +43700,14 @@ var COFantasy = COFantasy || function() { return; } } - //On d\xE9termine les cibles sur le trajet + //On détermine les cibles sur le trajet let cibles = []; tokens.forEach(function(tok) { let cible = { token: tok, charId: tok.get('represents') }; - if (nePeutPlusPrendreDM(cible, {})) return; //pas de d\xE9g\xE2ts aux morts + if (nePeutPlusPrendreDM(cible, {})) return; //pas de dégâts aux morts let distToTrajectory = distancePixTokenSegment(tok, ptOrigin, ptDest); if (distToTrajectory > attRayon + tokenSize(tok, 0)) return; @@ -43534,7 +43734,7 @@ var COFantasy = COFantasy || function() { }); combat.attackId = combat.attackId || 0; combat.attackCallbacks = combat.attackCallBacks || {}; - //On trie les cibles selon leur distance \xE0 l'origine. + //On trie les cibles selon leur distance à l'origine. cibles.sort(function(c1, c2) { return c1.distanceOrigine - c2.distanceOrigine; }); @@ -43583,11 +43783,11 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { - error("Il manque un argument \xE0 !cof-vision-nocturne", cmd); + error("Il manque un argument à !cof-vision-nocturne", cmd); return; } let distance = parseInt(cmd[1]); @@ -43598,7 +43798,7 @@ var COFantasy = COFantasy || function() { let pageId = options.pageId; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Utilisation de !cof-vision-nocturne sans s\xE9lection de token", playerId); + sendPlayer(msg, "Utilisation de !cof-vision-nocturne sans sélection de token", playerId); return; } const evt = { @@ -43618,27 +43818,27 @@ var COFantasy = COFantasy || function() { const listeDesRunesMortes = { Melianil: { - description: "+2 en attaque et +1d6 aux DM (\xE0 tous les sorts ou aux attaques au contact avec le b\xE2ton)", + description: "+2 en attaque et +1d6 aux DM (à tous les sorts ou aux attaques au contact avec le bâton)", }, Isulys: { - description: "une fois par tour, par une action d'attaque, peut produire un rayon d\x2019\xE9nergie n\xE9gative d\x2019une port\xE9e de 40 m\xE8tres. Sur test d\x2019attaque magique r\xE9ussit, la victime subit [2d6 + Mod. %SAGINT] DM et doit utiliser un d12 \xE0 tous ses tests au lieu d\x2019un d20 pendant un tour.", + description: "une fois par tour, par une action d'attaque, peut produire un rayon d’énergie négative d’une portée de 40 mètres. Sur test d’attaque magique réussit, la victime subit [2d6 + Mod. %SAGINT] DM et doit utiliser un d12 à tous ses tests au lieu d’un d20 pendant un tour.", }, Bryniza: { - description: "permet de voir parfaitement dans le noir \xE0 une port\xE9e de 30 m, et comme dans la p\xE9nombre jusqu'\xE0 50 m. Au prix d'une action limit\xE9e, le porteur peut utiliser le sort D\xE9tection de la magie 3 fois par jour.", + description: "permet de voir parfaitement dans le noir à une portée de 30 m, et comme dans la pénombre jusqu'à 50 m. Au prix d'une action limitée, le porteur peut utiliser le sort Détection de la magie 3 fois par jour.", activation: "Les yeux de %NOM deviennent d'un noir d'encre.", fin: "Les yeux de %NOM redeviennent normaux.", }, Lizura: { - description: "immunit\xE9 au souffle de Swarathnak, \xE0 l'acide et au poison.", - activation: "La boue noire du b\xE2ton s'\xE9coule le long du bras de %NOM et recouvre tout son corps \xE0 l'exception des yeux.", - fin: "La boue se retire dans le b\xE2ton, %NOM retrouve une apparence normale.", + description: "immunité au souffle de Swarathnak, à l'acide et au poison.", + activation: "La boue noire du bâton s'écoule le long du bras de %NOM et recouvre tout son corps à l'exception des yeux.", + fin: "La boue se retire dans le bâton, %NOM retrouve une apparence normale.", memeEffetQue: 'Mitrah', }, Mitrah: { - description: "RD 5 \xE0 tous les DM.", - activation: "La boue noire du b\xE2ton s'\xE9coule le long du bras de %NOM et recouvre tout son corps \xE0 l'exception des yeux.", - fin: "La boue se retire dans le b\xE2ton, %NOM retrouve une apparence normale.", + description: "RD 5 à tous les DM.", + activation: "La boue noire du bâton s'écoule le long du bras de %NOM et recouvre tout son corps à l'exception des yeux.", + fin: "La boue se retire dans le bâton, %NOM retrouve une apparence normale.", memeEffetQue: 'Lizura', }, }; @@ -43650,13 +43850,13 @@ var COFantasy = COFantasy || function() { function gererRunesMortes(msg) { let cmd = msg.content.split(' '); if (cmd.length < 2) { - error("il manque l'id du personnage qui g\xE8re ses runes mortes", cmd); + error("il manque l'id du personnage qui gère ses runes mortes", cmd); return; } let perso = persoOfId(cmd[1]); if (perso === undefined) return; if (!predicateAsBool(perso, 'batonDesRunesMortes')) { - sendPerso(perso, "ne porte pas le b\xE2ton des runes mortes"); + sendPerso(perso, "ne porte pas le bâton des runes mortes"); return; } let niveau = ficheAttributeAsInt(perso, 'niveau', 1); @@ -43680,7 +43880,7 @@ var COFantasy = COFantasy || function() { error("Rune " + cmd[3] + " non reconnue", cmd); break; } - //V\xE9rification qu'on n'a pas d\xE9j\xE0 le max de runes + //Vérification qu'on n'a pas déjà le max de runes let runesLibres = Math.ceil(niveau / 4); for (let rune in listeDesRunesMortes) { if (attributeAsBool(perso, 'rune' + rune)) runesLibres--; @@ -43694,11 +43894,11 @@ var COFantasy = COFantasy || function() { if (attr[0].get('current') == 'false') { let donne = attr[0].get('max'); if (donne) { - sendPerso(perso, "a donn\xE9 " + cmd[3] + " \xE0 " + donne + ". Impossible de l'activer.", true); + sendPerso(perso, "a donné " + cmd[3] + " à " + donne + ". Impossible de l'activer.", true); break; } } else { - sendPerso(perso, cmd[3] + " est d\xE9j\xE0 active", true); + sendPerso(perso, cmd[3] + " est déjà active", true); break; } } @@ -43738,7 +43938,7 @@ var COFantasy = COFantasy || function() { break; } if (!attributeAsBool(perso, 'rune' + cmd[3])) { - sendPerso(perso, cmd[3] + " n'est pas activ\xE9e.", true); + sendPerso(perso, cmd[3] + " n'est pas activée.", true); break; } let msg; @@ -43750,7 +43950,7 @@ var COFantasy = COFantasy || function() { msg }); if (cmd[3] == 'Bryniza') { - //On enl\xE8ve la vision dans le noir + //On enlève la vision dans le noir let token = perso.token; let pageId = token.get('pageid'); let visionNoir = predicateAsInt(perso, 'visionDansLeNoir', 0); @@ -43773,12 +43973,12 @@ var COFantasy = COFantasy || function() { case 'donner': { if (cmd.length < 4) { - error("Il faut pr\xE9ciser le token \xE0 qui donner la rune", cmd); + error("Il faut préciser le token à qui donner la rune", cmd); break; } let cible = persoOfId(cmd[4]); if (!cible) { - error("Impossible de trouver \xE0 qui donner la rune", cmd); + error("Impossible de trouver à qui donner la rune", cmd); break; } let attr = tokenAttribute(perso, 'rune' + cmd[3]); @@ -43786,11 +43986,11 @@ var COFantasy = COFantasy || function() { if (attr[0].get('current') == 'false') { let donne = attr[0].get('max'); if (donne) { - sendPerso(perso, "a d\xE9j\xE0 donn\xE9 " + cmd[3] + " \xE0 " + donne + ".", true); + sendPerso(perso, "a déjà donné " + cmd[3] + " à " + donne + ".", true); break; } } else { - sendPerso(perso, "Il faut d'abord d\xE9sactiver " + cmd[3] + " avant de la donner", true); + sendPerso(perso, "Il faut d'abord désactiver " + cmd[3] + " avant de la donner", true); break; } } @@ -43799,14 +43999,14 @@ var COFantasy = COFantasy || function() { error("Rune " + cmd[3] + " non reconnue", cmd); break; } - let msg = nomPerso(perso) + " donne une rune \xE0 " + nomPerso(cible); + let msg = nomPerso(perso) + " donne une rune à " + nomPerso(cible); let maxVal = nomPerso(cible); setTokenAttr(perso, 'rune' + cmd[3], 'false', evt, { msg, maxVal }); - sendPerso(perso, "peut maintenant communiquer par t\xE9l\xE9pathie avec " + nomPerso(cible), true); - sendPerso(cible, "peut maintenant communiquer par t\xE9l\xE9pathie avec " + nomPerso(perso), true); + sendPerso(perso, "peut maintenant communiquer par télépathie avec " + nomPerso(cible), true); + sendPerso(cible, "peut maintenant communiquer par télépathie avec " + nomPerso(perso), true); break; } case 'recuperer': @@ -43818,23 +44018,23 @@ var COFantasy = COFantasy || function() { } let attr = tokenAttribute(perso, 'rune' + cmd[3]); if (attr.length === 0) { - sendPerso(perso, "a d\xE9j\xE0 " + cmd[3], true); + sendPerso(perso, "a déjà " + cmd[3], true); break; } if (attr[0].get('current') != 'false') { - sendPerso(perso, "a d\xE9j\xE0 " + cmd[3], true); + sendPerso(perso, "a déjà " + cmd[3], true); break; } let donne = attr[0].get('max'); if (!donne) { - sendPerso(perso, "a d\xE9j\xE0 " + cmd[3], true); + sendPerso(perso, "a déjà " + cmd[3], true); break; } - let msg = nomPerso(perso) + " rappelle une rune sur le b\xE2ton"; + let msg = nomPerso(perso) + " rappelle une rune sur le bâton"; removeTokenAttr(perso, 'rune' + cmd[3], evt, { msg }); - sendPerso(perso, "ne peut plus communiquer par t\xE9l\xE9pathie avec " + donne, true); + sendPerso(perso, "ne peut plus communiquer par télépathie avec " + donne, true); break; } default: @@ -43871,13 +44071,13 @@ var COFantasy = COFantasy || function() { if (er.actif) { ligne = ' 0) { ef = ef.substring(0, pu); if (messageEffetTemp[ef]) return ef; } - //Ensuite on enl\xE8ve les parties entre parenth\xE8se pour les effets g\xE9n\xE9riques + //Ensuite on enlève les parties entre parenthèse pour les effets génériques pu = ef.indexOf('('); if (pu > 0) { ef = ef.substring(0, pu); if (messageEffetTemp[ef]) return ef; } - error("Impossible de d\xE9terminer l'effet correspondant \xE0 " + ef, attr); + error("Impossible de déterminer l'effet correspondant à " + ef, attr); } function messageOfEffetTemp(effetC) { @@ -45670,61 +45910,61 @@ var COFantasy = COFantasy || function() { res = messageEffetTemp[ef]; return res; } - error("Effet temporaire non trouv\xE9", effetC); + error("Effet temporaire non trouvé", effetC); } const messageEffetCombat = { a0PVDepuis: { - activation: "est \xE0 0 PV", - actif: "est \xE0 0 PV", + activation: "est à 0 PV", + actif: "est à 0 PV", fin: "" }, armureMagique: { - activation: "est entour\xE9 d'un halo magique", - activationF: "est entour\xE9e d'un halo magique", - actif: "est prot\xE9g\xE9 par une armure magique", - actifF: "est prot\xE9g\xE9e par une armure magique", - fin: "n'est plus entour\xE9 d'un halo magique", - finF: "n'est plus entour\xE9e d'un halo magique" + activation: "est entouré d'un halo magique", + activationF: "est entourée d'un halo magique", + actif: "est protégé par une armure magique", + actifF: "est protégée par une armure magique", + fin: "n'est plus entouré d'un halo magique", + finF: "n'est plus entourée d'un halo magique" }, armureDuMage: { - activation: "fait appara\xEEtre un nuage magique argent\xE9 qui le prot\xE8ge", - activationF: "fait appara\xEEtre un nuage magique argent\xE9 qui la prot\xE8ge", - actif: "est entour\xE9 d'une armure du mage", - actifF: "est entour\xE9e d'une armure du mage", + activation: "fait apparaître un nuage magique argenté qui le protège", + activationF: "fait apparaître un nuage magique argenté qui la protège", + actif: "est entouré d'une armure du mage", + actifF: "est entourée d'une armure du mage", fin: "n'a plus son armure du mage" }, armureDEau: { - activation: "fait appara\xEEtre une couche d'eau de quelques centim\xE8tres qui le prot\xE8ge", - activationF: "fait appara\xEEtre une couche d'eau de quelques centim\xE8tres qui la prot\xE8ge", - actif: "est entour\xE9 d'une armure d'eau'", - actifF: "est entour\xE9e d'une armure d'eau'", + activation: "fait apparaître une couche d'eau de quelques centimètres qui le protège", + activationF: "fait apparaître une couche d'eau de quelques centimètres qui la protège", + actif: "est entouré d'une armure d'eau'", + actifF: "est entourée d'une armure d'eau'", fin: "n'a plus son armure d'eau'" }, armeDArgent: { - activation: "cr\xE9e une arme d'argent et de lumi\xE8re", - actif: "poss\xE8de une arme d'argent et de lumi\xE8re", - fin: "ne poss\xE8de plus d'arme d'argent et de lumi\xE8re", + activation: "crée une arme d'argent et de lumière", + actif: "possède une arme d'argent et de lumière", + fin: "ne possède plus d'arme d'argent et de lumière", dm: true }, attaqueAOutrance: { - activation: "attaque \xE0 outrance", - actif: "attaque \xE0 outrance", + activation: "attaque à outrance", + actif: "attaque à outrance", fin: "attaque normalement", }, - bonusInitEmbuscade: { //Effet interne pour la capacit\xE9 Surveillance + bonusInitEmbuscade: { //Effet interne pour la capacité Surveillance activation: "a un temps d'avance en cas d'embuscade", actif: "a un temps d'avance", fin: "" }, criDeGuerre: { activation: "pousse son cri de guerre", - actif: "a effray\xE9 ses adversaires", + actif: "a effrayé ses adversaires", fin: "" }, criDuPredateur: { activation: "pousse un hurlement effrayant", - actif: "a lib\xE9r\xE9 son \xE2me de pr\xE9dateur", + actif: "a libéré son âme de prédateur", fin: "" }, danseDesLames: { @@ -45733,22 +45973,22 @@ var COFantasy = COFantasy || function() { fin: "termine sa danse des lames" }, detournerLeRegard: { - activation: "d\xE9tourne le regard", - actif: "d\xE9tourne le regard", + activation: "détourne le regard", + actif: "détourne le regard", fin: "regarde normalement", }, enflamme: { activation: "prend feu !", actif: "est en feu", - fin: "les flammes s'\xE9teignent", + fin: "les flammes s'éteignent", dm: true, statusMarker: 'red', }, enrage: { - activation: "devient enrag\xE9", - activationF: "devient enrag\xE9e", - actif: "est enrag\xE9", - actifF: "est enrag\xE9e", + activation: "devient enragé", + activationF: "devient enragée", + actif: "est enragé", + actifF: "est enragée", fin: "retrouve son calme", msgSave: "retrouver son calme", }, @@ -45759,17 +45999,17 @@ var COFantasy = COFantasy || function() { fin: "retrouve son calme" }, protectionContreLeMal: { - activation: "re\xE7oit une b\xE9n\xE9diction de protection contre le mal", - actif: "est prot\xE9g\xE9 contre le mal", - actifF: "est prot\xE9g\xE9e contre le mal", - fin: "n'est plus prot\xE9g\xE9 contre le mal", - finF: "n'est plus prot\xE9g\xE9e contre le mal", + activation: "reçoit une bénédiction de protection contre le mal", + actif: "est protégé contre le mal", + actifF: "est protégée contre le mal", + fin: "n'est plus protégé contre le mal", + finF: "n'est plus protégée contre le mal", }, putrefactionOutreTombe: { activation: "sent ses chairs pourrir", - actif: "subit le contrecoup d'une putr\xE9faction", - fin: "se remet de la putr\xE9faction", - msgSave: "ne plus \xEAtre putr\xE9fi\xE9", + actif: "subit le contrecoup d'une putréfaction", + fin: "se remet de la putréfaction", + msgSave: "ne plus être putréfié", prejudiciable: true, dm: true }, @@ -45791,8 +46031,8 @@ var COFantasy = COFantasy || function() { fin: '' }, defiSamourai: { - activation: "lance un d\xE9fi", - actif: "a lanc\xE9 un d\xE9fi", + activation: "lance un défi", + actif: "a lancé un défi", fin: '' }, agrippe: { @@ -45801,12 +46041,12 @@ var COFantasy = COFantasy || function() { fin: "lache sa cible" }, estAgrippePar: { - activation: "est agripp\xE9", - activationF: "est agripp\xE9e", - actif: "est agripp\xE9", - actifF: "est agripp\xE9e", - fin: "se lib\xE8re", - msgSave: "se lib\xE9rer", + activation: "est agrippé", + activationF: "est agrippée", + actif: "est agrippé", + actifF: "est agrippée", + fin: "se libère", + msgSave: "se libérer", entrave: true }, devore: { @@ -45819,8 +46059,8 @@ var COFantasy = COFantasy || function() { activationF: "est saisie", actif: "est saisi", actifF: "est saisie", - fin: "se lib\xE8re", - msgSave: "se lib\xE9rer", + fin: "se libère", + msgSave: "se libérer", entrave: true }, ecrase: { @@ -45833,34 +46073,34 @@ var COFantasy = COFantasy || function() { activationF: "est saisie", actif: "est saisi", actifF: "est saisie", - fin: "se lib\xE8re", - msgSave: "se lib\xE9rer", + fin: "se libère", + msgSave: "se libérer", entrave: true }, aGobe: { activation: "avale sa cible", - actif: "a aval\xE9 une cr\xE9ature vivante", - fin: "dig\xE8re sa cible" + actif: "a avalé une créature vivante", + fin: "digère sa cible" }, estGobePar: { - activation: "est aval\xE9", - activationF: "est aval\xE9e", - actif: "est dans le ventre d'une cr\xE9ature", + activation: "est avalé", + activationF: "est avalée", + actif: "est dans le ventre d'une créature", fin: "fin de la digestion, sort du ventre", msgSave: "sortir du ventre", entrave: true }, inconfort: { - activation: "commence \xE0 \xEAtre g\xEAn\xE9 par son armure", - activationF: "commence \xE0 \xEAtre g\xEAn\xE9e par son armure", - actif: "est g\xEAn\xE9 par son armure", - actifF: "est g\xEAn\xE9e par son armure", - fin: "r\xE9ajuste son armure", + activation: "commence à être gêné par son armure", + activationF: "commence à être gênée par son armure", + actif: "est gêné par son armure", + actifF: "est gênée par son armure", + fin: "réajuste son armure", }, noyade: { - activation: "commence \xE0 se noyer", + activation: "commence à se noyer", actif: "se noie", - fin: "peut \xE0 nouveau respirer", + fin: "peut à nouveau respirer", msgSave: "surnager", prejudiciable: true, seulementVivant: true, @@ -45868,8 +46108,8 @@ var COFantasy = COFantasy || function() { visible: true }, blessureQuiSaigne: { - activation: "re\xE7oit une blessure qui saigne", - actif: "saigne \xE0 cause d'une blessure", + activation: "reçoit une blessure qui saigne", + actif: "saigne à cause d'une blessure", fin: "saigne beaucoup moins", msgSave: "ne plus saigner", prejudiciable: true, @@ -45877,10 +46117,10 @@ var COFantasy = COFantasy || function() { }, poisonAffaiblissant: { activation: "sent le poison ralentir ses mouvements", - actif: "est empoisonn\xE9", - actifF: "est empoisonn\xE9e", + actif: "est empoisonné", + actifF: "est empoisonnée", fin: "le poison n'agit plus", - msgSave: "r\xE9sister au poison", + msgSave: "résister au poison", prejudiciable: true, seulementVivant: true, }, @@ -45902,16 +46142,16 @@ var COFantasy = COFantasy || function() { function effetCombatOfAttribute(attr) { let ef = attr.get('name'); if (ef === undefined || messageEffetCombat[ef]) return ef; - //D'abord on enl\xE8ve le nom du token + //D'abord on enlève le nom du token let pu = ef.indexOf('_'); if (pu > 0) { ef = ef.substring(0, pu); if (messageEffetCombat[ef]) return ef; } - error("Impossible de d\xE9terminer l'effet correspondant \xE0 " + ef, attr); + error("Impossible de déterminer l'effet correspondant à " + ef, attr); } - // Si un effet est prejudiciable, enlev\xE9 par d\xE9livrance + // Si un effet est prejudiciable, enlevé par délivrance const messageEffetIndetermine = { armesNaturelles: { activation: "se fait pousser griffes et crocs", @@ -45932,29 +46172,29 @@ var COFantasy = COFantasy || function() { }, constructionTailleHumaine: { activation: "rentre dans une construction de taille humaine.", - actif: "est un peu \xE0 l'\xE9troit, le b\xE2timent est trop petit", + actif: "est un peu à l'étroit, le bâtiment est trop petit", fin: "sort de la construction de taille humains." }, dominationPsy: { - activation: "est maintenant sous le contr\xF4le de quelqu'un", + activation: "est maintenant sous le contrôle de quelqu'un", actif: "est sous l'effet d'une domination psy", - fin: "retrouve le contr\xF4le de son corps", + fin: "retrouve le contrôle de son corps", prejudiciable: true, }, fievreux: { - activation: "se sent fi\xE9vreux", - activationF: "se sent fi\xE9vreuse", - actif: "est fi\xE9vreux", - actifF: "est fi\xE9vreuse", + activation: "se sent fiévreux", + activationF: "se sent fiévreuse", + actif: "est fiévreux", + actifF: "est fiévreuse", fin: "se sent mieux", prejudiciable: true }, foretVivanteEnnemie: { - activation: "est g\xEAn\xE9 par la for\xEAt", - activationF: "est g\xEAn\xE9e par la for\xEAt", - actif: "est d\xE9sorient\xE9 par la for\xEAt", - actifF: "est d\xE9sorient\xE9e par la for\xEAt", - fin: "se retrouve dans une for\xEAt normale", + activation: "est gêné par la forêt", + activationF: "est gênée par la forêt", + actif: "est désorienté par la forêt", + actifF: "est désorientée par la forêt", + fin: "se retrouve dans une forêt normale", entrave: true }, grandeTaille: { @@ -45965,9 +46205,9 @@ var COFantasy = COFantasy || function() { fin: "retrouve sa taille normale" }, lameDeLigneePerdue: { - activation: "perd sa lame de lign\xE9e", - actif: "a perdu sa lame de lign\xE9e", - fin: "retrouve sa lame de lign\xE9e", + activation: "perd sa lame de lignée", + actif: "a perdu sa lame de lignée", + fin: "retrouve sa lame de lignée", }, marcheSylvestre: { activation: "se deplace maintenant en terrain difficile", @@ -45980,8 +46220,8 @@ var COFantasy = COFantasy || function() { fin: "retrouve une peau normale" }, mutationEcaillesRouges: { - activation: "recouvre sa peau d'\xE9cailles rouges", - actif: "a la peau recouverte d'\xE9cailles rouges", + activation: "recouvre sa peau d'écailles rouges", + actif: "a la peau recouverte d'écailles rouges", fin: "retrouve une peau normale" }, mutationFourrureViolette: { @@ -45990,15 +46230,15 @@ var COFantasy = COFantasy || function() { fin: "retrouve une peau normale" }, mutationMusclesHypertrophies: { - activation: "devient plus muscl\xE9", - activationF: "devient plus muscl\xE9e", - actif: "a les muscles hypertrophi\xE9s", + activation: "devient plus musclé", + activationF: "devient plus musclée", + actif: "a les muscles hypertrophiés", fin: "retrouve des muscles normaux", }, mutationOuies: { - activation: "se fait pousser des ou\xEFes", - actif: "poss\xE8de des ou\xEFes", - fin: "n'a plus d'ou\xEFes" + activation: "se fait pousser des ouïes", + actif: "possède des ouïes", + fin: "n'a plus d'ouïes" }, mutationSangNoir: { activation: "prend un teint plus sombre", @@ -46019,8 +46259,8 @@ var COFantasy = COFantasy || function() { }, presenceGlaciale: { activation: "transforme son corps en glace vivante", - actif: "est form\xE9 de glace", - actifF: "est form\xE9e de glace", + actif: "est formé de glace", + actifF: "est formée de glace", fin: "retrouve un corps normal", }, sensDuDevoir: { @@ -46030,12 +46270,12 @@ var COFantasy = COFantasy || function() { }, sixiemeSens: { activation: "fait un rituel de divination", - actif: "sait un peu \xE0 l'avance ce qu'il va se passer", + actif: "sait un peu à l'avance ce qu'il va se passer", fin: "l'effet du rituel de divination prend fin", }, espaceExigu: { activation: "entre dans un espace exigu.", - actif: "est \xE0 l'\xE9troit.", + actif: "est à l'étroit.", fin: "sort de l'espace exigu." }, sangDeLArbreCoeur: { @@ -46043,36 +46283,36 @@ var COFantasy = COFantasy || function() { actif: "a bu une potion de Sang de l'Arbre-Coeur", fin: "les effets de la potion de Sang de l'Arbre-Coeur diminuent un peu" }, - ondesCorruptrices: { //nombre, \xE0 mettre avec !cof-effet ondesCorruptrices 2 - activation: "se sent naus\xE9eux", - activationF: "se sent naus\xE9euse", - actif: "se sent naus\xE9eux", - actifF: "se sent naus\xE9euse", + ondesCorruptrices: { //nombre, à mettre avec !cof-effet ondesCorruptrices 2 + activation: "se sent nauséeux", + activationF: "se sent nauséeuse", + actif: "se sent nauséeux", + actifF: "se sent nauséeuse", fin: "se sent un peu mieux", prejudiciable: true }, petrifie: { activation: "se change en pierre", - actif: "est transform\xE9 en pierre", - actifF: "est transform\xE9e en pierre", - fin: "n'est plus p\xE9trifi\xE9", - finF: "n'est plus p\xE9trifi\xE9e", + actif: "est transformé en pierre", + actifF: "est transformée en pierre", + fin: "n'est plus pétrifié", + finF: "n'est plus pétrifiée", prejudiciable: true, - msgSave: "r\xE9sister \xE0 la p\xE9trification", + msgSave: "résister à la pétrification", }, poisonAffaiblissantLong: { activation: "sent le poison ralentir ses mouvements", - actif: "est empoisonn\xE9", - actifF: "est empoisonn\xE9e", + actif: "est empoisonné", + actifF: "est empoisonnée", fin: "le poison n'agit plus", - msgSave: "r\xE9sister au poison", + msgSave: "résister au poison", prejudiciable: true, seulementVivant: true, }, reactionAllergique: { - activation: "ressent de fortes d\xE9mangeaisons", - actif: "est victime d'une r\xE9action allergique", - fin: "les d\xE9mangeaisons cessent", + activation: "ressent de fortes démangeaisons", + actif: "est victime d'une réaction allergique", + fin: "les démangeaisons cessent", prejudiciable: true }, }; @@ -46086,13 +46326,13 @@ var COFantasy = COFantasy || function() { function effetIndetermineOfAttribute(attr) { let ef = attr.get('name'); if (ef === undefined || messageEffetIndetermine[ef]) return ef; - //D'abord on enl\xE8ve le nom du token + //D'abord on enlève le nom du token let pu = ef.indexOf('_'); if (pu > 0) { ef = ef.substring(0, pu); if (messageEffetIndetermine[ef]) return ef; } - error("Impossible de d\xE9terminer l'effet correspondant \xE0 " + ef, attr); + error("Impossible de déterminer l'effet correspondant à " + ef, attr); } function attributeExtending(charId, attrName, effetC, extension) { @@ -46104,10 +46344,10 @@ var COFantasy = COFantasy || function() { }); } - //Nom de l'effet, avec la partie g\xE9n\xE9rique, mais sans le nom de token + //Nom de l'effet, avec la partie générique, mais sans le nom de token function effetComplet(effet, attrName) { if (effet == attrName) return effet; - //On a un effet li\xE9 \xE0 un token ou bien un effet g\xE9n\xE9rique + //On a un effet lié à un token ou bien un effet générique if (attrName.charAt(effet.length) == '(') { let p = attrName.indexOf(')', effet.length); if (p > 0) return attrName.substring(0, p + 1); @@ -46148,7 +46388,7 @@ var COFantasy = COFantasy || function() { //alors dmg = '' et type = '' let valAttr = tokenAttribute(perso, effet + 'Valeur'); if (valAttr.length === 0) { - //Par d\xE9faut, 1d6 DM normaux + //Par défaut, 1d6 DM normaux dmgExpr = "1d6"; type = 'normal'; } else { @@ -46183,7 +46423,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, m); }); addLineToFramedDisplay(display, nomPerso(perso) + ' ' + msgDm + " subit " + dmgDisplay + " DM"); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else if (effet == attrName) { sendPerso(perso, msgDm + " subit " + dmgDisplay + " DM"); } else { @@ -46194,7 +46434,7 @@ var COFantasy = COFantasy || function() { count.v--; if (count.v === 0) callback(); }); - }); //fin sendChat du jet de d\xE9 + }); //fin sendChat du jet de dé } //asynchrone @@ -46225,7 +46465,7 @@ var COFantasy = COFantasy || function() { let expliquer = function(m) { addLineToFramedDisplay(display, m); }; - let msgPour = " pour ne pas prendre de d\xE9g\xE2ts de " + nameEffet; + let msgPour = " pour ne pas prendre de dégâts de " + nameEffet; let sujet = onGenre(perso, 'il', 'elle'); let msgReussite = ", " + sujet + " ne perd pas de PV ce tour"; let saveOpts = { @@ -46237,7 +46477,7 @@ var COFantasy = COFantasy || function() { }; save(options.save, perso, saveId, expliquer, saveOpts, evt, function(reussite, texte) { if (reussite) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } rollAndDealDmg(perso, dmg, type, effet, attrName, msg, count, evt, options, callback, display); @@ -46277,8 +46517,8 @@ var COFantasy = COFantasy || function() { let displaySoins = buildinline(soinRoll, 'normal', true); soigneToken(perso, soins, evt, function(s) { - if (s < soins) sendPerso(perso, "r\xE9cup\xE8re tous ses PV."); - else sendPerso(perso, "r\xE9cup\xE8re " + displaySoins + " PV."); + if (s < soins) sendPerso(perso, "récupère tous ses PV."); + else sendPerso(perso, "récupère " + displaySoins + " PV."); count--; if (count === 0) callback(); }, @@ -46286,7 +46526,7 @@ var COFantasy = COFantasy || function() { count--; if (count === 0) callback(); }); - }); //fin sendChat du jet de d\xE9 + }); //fin sendChat du jet de dé }); //fin iterTokensOfAttribute } @@ -46300,9 +46540,9 @@ var COFantasy = COFantasy || function() { return options; } - // gestion des effets qui se d\xE9clenchent \xE0 la fin de chaque tour - // N'ajoute pas evt \xE0 l'historique - // Asynchrone (\xE0 cause des saves par tour) + // gestion des effets qui se déclenchent à la fin de chaque tour + // N'ajoute pas evt à l'historique + // Asynchrone (à cause des saves par tour) function changementDeTour(tour, attrs, evt, combat, pageId, options) { // Enlever les bonus d'un tour attrs = removeAllAttributes('limiteParTour', evt, attrs); @@ -46313,7 +46553,7 @@ var COFantasy = COFantasy || function() { attrs = removeAllAttributes('prescienceUtilisee', evt, attrs); attrs = removeAllAttributes('increvableHumainUtilise', evt, attrs); resetAttr(attrs, 'cercleDeProtectionActif', evt); - // Pour d\xE9faut dans la cuirasse, on diminue si la valeur est 2, et on supprime si c'est 1 + // Pour défaut dans la cuirasse, on diminue si la valeur est 2, et on supprime si c'est 1 let defautsDansLaCuirasse = allAttributesNamed(attrs, 'defautDansLaCuirasse'); defautsDansLaCuirasse.forEach(function(attr) { if (attr.get('current') < 2) { @@ -46345,7 +46585,7 @@ var COFantasy = COFantasy || function() { attr.set('current', 1); } }); - //Les tests rat\xE9s + //Les tests ratés let trTour = allAttributesNamed(attrs, 'testsRatesDuTour'); trTour.forEach(function(tr) { let curTr = tr.get('current'); @@ -46374,7 +46614,7 @@ var COFantasy = COFantasy || function() { attr.set('current', ve + 1); let veCharId = attr.get('characterid'); if (veCharId === undefined || veCharId === '') { - error("Attribut sans personnage associ\xE9", attr); + error("Attribut sans personnage associé", attr); return; } let veSeuil = parseInt(attr.get('max')); @@ -46389,9 +46629,9 @@ var COFantasy = COFantasy || function() { }; let testId = 'vapeursEthyliques_' + perso.token.id; testCaracteristique(perso, 'CON', veSeuil, testId, options, evt, function(testRes) { - let res = "tente un jet de CON " + veSeuil + " pour combattre les vapeurs \xE9thyliques " + testRes.texte; + let res = "tente un jet de CON " + veSeuil + " pour combattre les vapeurs éthyliques " + testRes.texte; if (testRes.reussite) { - res += " => r\xE9ussi." + testRes.modifiers; + res += " => réussi." + testRes.modifiers; let expliquer; if (attr.get('name') == 'vapeursEthyliques') { expliquer = function(s) { @@ -46405,14 +46645,14 @@ var COFantasy = COFantasy || function() { expliquer(res); diminueEbriete(perso, evt, expliquer); } else { - res += " => rat\xE9" + testRes.rerolls + testRes.modifiers; + res += " => raté" + testRes.rerolls + testRes.modifiers; sendPerso(perso, res); } }); }); }); // nouveau tour : enlever le statut surpris - // et faire les actions de d\xE9but de tour + // et faire les actions de début de tour let selected = []; updateNextInitSet.forEach(function(id) { selected.push({ @@ -46457,14 +46697,14 @@ var COFantasy = COFantasy || function() { }; dealDamage(perso, dmg, [], evt, false, {}, undefined, function(dmgDisplay, dmgFinal) { - sendPerso(perso, " est \xE9cras\xE9 ! " + + sendPerso(perso, " est écrasé ! " + onGenre(perso, 'Il', 'Elle') + " subit " + dmgDisplay + " DM"); }); } let enflammeAttr = tokenAttribute(perso, 'enflamme'); if (enflammeAttr.length > 0) { let enflamme = parseInt(enflammeAttr[0].get('current')); - // Pour ne pas faire les d\xE9g\xE2ts plusieurs fois (plusieurs tokens pour un m\xEAme personnage), on utilise la valeur max de l'attribut + // Pour ne pas faire les dégâts plusieurs fois (plusieurs tokens pour un même personnage), on utilise la valeur max de l'attribut let dernierTourEnflamme = parseInt(enflammeAttr[0].get('max')); if ((isNaN(dernierTourEnflamme) || dernierTourEnflamme < tour) && !isNaN(enflamme) && enflamme > 0) { @@ -46483,7 +46723,7 @@ var COFantasy = COFantasy || function() { display: roll }; if (getState(perso, 'mort')) { - sendChat('', "Le cadavre de " + nomPerso(perso) + " continue de br\xFBler"); + sendChat('', "Le cadavre de " + nomPerso(perso) + " continue de brûler"); } else { dealDamage(perso, dmgEnflamme, [], evt, false, {}, undefined, function(dmgDisplay, dmgFinal) { @@ -46492,7 +46732,7 @@ var COFantasy = COFantasy || function() { }); } if (d6Enflamme < 3) { - sendPerso(perso, ": les flammes s'\xE9teignent"); + sendPerso(perso, ": les flammes s'éteignent"); removeTokenAttr(perso, 'enflamme', evt); let ms = messageEffetCombat.enflamme.statusMarker; if (ms) { @@ -46509,14 +46749,14 @@ var COFantasy = COFantasy || function() { nbDes: 3 }); let dmg = { - type: 'normal', //correspond \xE0 de l'asphyxie + type: 'normal', //correspond à de l'asphyxie total: jet.val, display: jet.roll }; if (immuniseAsphyxie(perso)) dmg.type = 'acide'; dealDamage(perso, dmg, [], evt, false, {}, undefined, function(dmgDisplay, dmgFinal) { - sendPerso(perso, "est en train d'\xEAtre dig\xE9r\xE9. " + onGenre(perso, 'Il', 'Elle') + " perd " + dmgDisplay + " PVs"); + sendPerso(perso, "est en train d'être digéré. " + onGenre(perso, 'Il', 'Elle') + " perd " + dmgDisplay + " PVs"); }); } if (attributeAsBool(perso, 'blessureQuiSaigne') && @@ -46542,7 +46782,7 @@ var COFantasy = COFantasy || function() { let expliquer = function(m) { addLineToFramedDisplay(display, m); }; - let msgPour = " pour ne pas prendre de d\xE9g\xE2ts de noyade"; + let msgPour = " pour ne pas prendre de dégâts de noyade"; let sujet = onGenre(perso, 'il', 'elle'); let msgReussite = ", " + sujet + " ne perd pas de PV ce tour"; let saveOpts = { @@ -46558,7 +46798,7 @@ var COFantasy = COFantasy || function() { }; save(saveNoyade, perso, saveId, expliquer, saveOpts, evt, function(reussite, texte) { if (reussite) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } let jetNoyade = rollDePlus(6); @@ -46574,7 +46814,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, m); }); addLineToFramedDisplay(display, nomPerso(perso) + "se noie et subit " + dmgDisplay + " DM"); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); } @@ -46598,7 +46838,7 @@ var COFantasy = COFantasy || function() { saufDMType = vitaliteSurnaturelle.substring(indexType + 1).split(','); soigneToken(perso, vitaliteSurnat, evt, function(s) { - whisperChar(perso.charId, 'r\xE9cup\xE8re ' + s + ' PVs.'); + whisperChar(perso.charId, 'récupère ' + s + ' PVs.'); }, function() {}, { saufDMType @@ -46610,7 +46850,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(perso, 'sangDeLArbreCoeur') && !getState(perso, 'mort')) { soigneToken(perso, 5, evt, function(s) { - whisperChar(perso.charId, "r\xE9g\xE9n\xE8re " + s + " PVs. (gr\xE2ce \xE0 la potion de sang de l'Arbre Coeur)"); + whisperChar(perso.charId, "régénère " + s + " PVs. (grâce à la potion de sang de l'Arbre Coeur)"); }, function() {} ); @@ -46620,9 +46860,9 @@ var COFantasy = COFantasy || function() { increvableActif[0].remove(); let soins = randomInteger(6) + randomInteger(6) + randomInteger(6) + modCarac(perso, 'constitution'); soigneToken(perso, soins, evt, function(soinsEffectifs) { - let msgSoins = "est increvable et r\xE9cup\xE8re "; + let msgSoins = "est increvable et récupère "; if (soinsEffectifs == soins) msgSoins += soins + " points de vie"; - else msgSoins += soinsEffectifs + " PV (le jet \xE9tait " + soins + ")"; + else msgSoins += soinsEffectifs + " PV (le jet était " + soins + ")"; whisperChar(perso.charId, msgSoins); }); } @@ -46635,16 +46875,16 @@ var COFantasy = COFantasy || function() { }; perso.ignoreTouteRD = true; dealDamage(perso, r, [], evt, false, {}, [], function() { - // V\xE9rification si le Zombie est toujours vivant + // Vérification si le Zombie est toujours vivant let token = getObj('graphic', perso.token.id); - if (token) whisperChar(perso.charId, "se d\xE9grade et perd 1 PV"); + if (token) whisperChar(perso.charId, "se dégrade et perd 1 PV"); }); } }); setActiveToken(combat, undefined, evt); - initiative(selected, evt, true); // met Tour \xE0 la fin et retrie + initiative(selected, evt, true); // met Tour à la fin et retrie updateNextInitSet = new Set(); - // Saves \xE0 faire \xE0 la fin de chaque tour. Asynchrone, mais pas grave ? + // Saves à faire à la fin de chaque tour. Asynchrone, mais pas grave ? attrs.forEach(function(attr) { let attrName = attr.get('name'); let indexSave = attrName.indexOf('SaveParTour'); @@ -46656,12 +46896,12 @@ var COFantasy = COFantasy || function() { if (!cof_states[effetC] && !effetTemp && !estEffetCombat(effetC)) return; let carac = attr.get('current'); if (!isCarac(carac)) { - error("Save par tour " + attrName + " mal form\xE9", carac); + error("Save par tour " + attrName + " mal formé", carac); return; } let seuil = parseInt(attr.get('max')); if (isNaN(seuil)) { - error("Save par tour " + attrName + " mal form\xE9", seuil); + error("Save par tour " + attrName + " mal formé", seuil); return; } let charId = attr.get('characterid'); @@ -46690,7 +46930,7 @@ var COFantasy = COFantasy || function() { let se = stringOfEtat(effetC, perso); met = { etat: true, - msgSave: "ne plus \xEAtre " + se, + msgSave: "ne plus être " + se, fin: "n'est plus " + se, actif: "est toujours " + se }; @@ -46698,7 +46938,7 @@ var COFantasy = COFantasy || function() { let msgPour = " pour "; if (met.msgSave) msgPour += met.msgSave; else { - msgPour += "ne plus \xEAtre sous l'effet de "; + msgPour += "ne plus être sous l'effet de "; if (effetC.startsWith('dotGen(')) msgPour += effetC.substring(7, effetC.indexOf(')')); else msgPour += effetC; @@ -46784,7 +47024,7 @@ var COFantasy = COFantasy || function() { //Pour chaque token representant ce perso allPersos.forEach(function(perso) { if (perso.charId != charId) return; - //On cherche ensuite les tokens \xE0 portee + //On cherche ensuite les tokens à portee allPersos.forEach(function(target) { if (target.token.id == perso.token.id) return; let tokRepresents = target.charId; @@ -46813,19 +47053,19 @@ var COFantasy = COFantasy || function() { targetLine += " --target " + tokId; }); if (targetLine != "") - sendChat('player|' + gmId, "!cof-dmg 3d6" + targetLine + " --titre D\xE9g\xE2ts des morts-vivants anim\xE9s"); + sendChat('player|' + gmId, "!cof-dmg 3d6" + targetLine + " --titre Dégâts des morts-vivants animés"); targetLine = ""; Object.keys(degatsArmeeDefense).forEach(function(tokId) { targetLine += " --target " + tokId; }); if (targetLine != "") - sendChat('player|' + gmId, "!cof-dmg 1d6" + targetLine + " --titre D\xE9g\xE2ts des morts-vivants anim\xE9s sur les cibles qui les combattent"); + sendChat('player|' + gmId, "!cof-dmg 1d6" + targetLine + " --titre Dégâts des morts-vivants animés sur les cibles qui les combattent"); removeAllAttributes("defenseArmeeDesMorts", evt, attrs); if (stateCOF.prescience) { - //On affiche la prescience aux joueurs concern\xE9s + //On affiche la prescience aux joueurs concernés allPersos.forEach(function(perso) { if (capaciteDisponible(perso, 'prescience', 'combat')) { - whisperChar(perso.charId, "Possibilit\xE9 d'utiliser la " + boutonSimple('!cof-prescience ' + perso.token.id + ' --mana 2', "Prescience")); + whisperChar(perso.charId, "Possibilité d'utiliser la " + boutonSimple('!cof-prescience ' + perso.token.id + ' --mana 2', "Prescience")); } }); stateCOF.nextPrescience = { @@ -46846,7 +47086,7 @@ var COFantasy = COFantasy || function() { } //evt a un champ attributes et un champ deletedAttributes - //evt n'est pas ajout\xE9 \xE0 l'historique dans cette fonction + //evt n'est pas ajouté à l'historique dans cette fonction function nextTurnOfActive(active, attrs, evt, combat, pageId, options) { if (active === undefined) return; if (active.id == "-1" && active.custom == "Tour") { //Nouveau tour @@ -46859,8 +47099,8 @@ var COFantasy = COFantasy || function() { }; evt.combat.tour = tour - 1; evt.updateNextInitSet = updateNextInitSet; - active.pr = tour - 1; // pr\xE9paration au calcul de l'undo - sendChat("GM", "D\xE9but du tour " + tour); + active.pr = tour - 1; // préparation au calcul de l'undo + sendChat("GM", "Début du tour " + tour); combat.tour = tour; combat.init = 1000; changementDeTour(tour, attrs, evt, combat, pageId, options); @@ -46923,7 +47163,7 @@ var COFantasy = COFantasy || function() { nbDe: 1, de: 4 }, 'feu', - "br\xFBle dans son armure", evt, { + "brûle dans son armure", evt, { valeur: 'armureBrulanteValeur' }, callBack); return; @@ -46931,7 +47171,7 @@ var COFantasy = COFantasy || function() { degatsParTour(charId, pageId, effet, attrName, { cst: 1 }, 'normal', - "est piqu\xE9 par les insectes", evt, { + "est piqué par les insectes", evt, { valeur: 'nueeDInsectesValeur' }, callBack); return; @@ -46939,31 +47179,31 @@ var COFantasy = COFantasy || function() { degatsParTour(charId, pageId, effet, attrName, { cst: 2 }, 'normal', - "est piqu\xE9 par les criquets", evt, {}, callBack); + "est piqué par les criquets", evt, {}, callBack); return; case 'nueeDeScorpions': //prend 1D6 DM degatsParTour(charId, pageId, effet, attrName, { nbDe: 1, de: 6 }, 'normal', - "est piqu\xE9 par les scorpions", evt, {}, callBack); + "est piqué par les scorpions", evt, {}, callBack); return; case 'armeBrulante': //prend 1 DM degatsParTour(charId, pageId, effet, attrName, { cst: 1 }, 'feu', - "se br\xFBle avec son arme", evt, { + "se brûle avec son arme", evt, { valeur: 'armeBrulanteValeur' }, callBack); return; case 'regeneration': //soigne - soigneParTour(charId, pageId, effet, attrName, 3, "r\xE9g\xE9n\xE8re", evt, { + soigneParTour(charId, pageId, effet, attrName, 3, "régénère", evt, { valeur: 'regenerationValeur' }, callBack); return; case 'strangulation': let nameDureeStrang = 'dureeStrangulation'; - if (effet != attrName) { //concerne un token non li\xE9 + if (effet != attrName) { //concerne un token non lié nameDureeStrang += attrName.substring(attrName.indexOf('_')); } let dureeStrang = findObjs({ @@ -46983,18 +47223,18 @@ var COFantasy = COFantasy || function() { }); } else { let strangUpdate = dureeStrang[0].get('max'); - if (strangUpdate) { //a \xE9t\xE9 mis \xE0 jour il y a au plus 1 tour + if (strangUpdate) { //a été mis à jour il y a au plus 1 tour evt.attributes.push({ attribute: dureeStrang[0], current: dureeStrang[0].get('current'), max: strangUpdate }); dureeStrang[0].set('max', false); - } else { //Ça fait trop longtemps, on arr\xEAte tout + } else { //Ça fait trop longtemps, on arrête tout sendChar(charId, messageFin({ charId }, messageEffetTemp[effet]), true); - evt.attributes.pop(); //On enl\xE8ve des attributs modifi\xE9s pour mettre dans les attribute supprim\xE9s. + evt.attributes.pop(); //On enlève des attributs modifiés pour mettre dans les attribute supprimés. evt.deletedAttributes.push(attr); attr.remove(); evt.deletedAttributes.push(dureeStrang[0]); @@ -47072,8 +47312,8 @@ var COFantasy = COFantasy || function() { fin(); return; } - count --; //On a fini avec perso. - count += cibles.length;//On ajoute les cibles + count--; //On a fini avec perso. + count += cibles.length; //On ajoute les cibles cibles.forEach(function(cible) { sendChat('', "[[2d6]]", function(res) { let rolls = res[0]; @@ -47082,14 +47322,14 @@ var COFantasy = COFantasy || function() { let displaySoins = buildinline(soinRoll, 'normal', true); soigneToken(cible, soins, evt, function(s) { - if (s < soins) sendPerso(cible, "r\xE9cup\xE8re tous ses PV."); + if (s < soins) sendPerso(cible, "récupère tous ses PV."); else if (s == soins) - sendPerso(cible, "r\xE9cup\xE8re " + displaySoins + " PV."); + sendPerso(cible, "récupère " + displaySoins + " PV."); else - sendPerso(cible, "r\xE9cup\xE8re " + s + " PV. (Le jet \xE9tait "+displaySoins+")"); + sendPerso(cible, "récupère " + s + " PV. (Le jet était " + displaySoins + ")"); fin(); }, fin); - }); //fin sendChat du jet de d\xE9 + }); //fin sendChat du jet de dé }); }); return; @@ -47100,8 +47340,8 @@ var COFantasy = COFantasy || function() { } } - //Appel\xE9 si le turn order change, mais aussi en interne - //si evt est d\xE9j\xE0 d\xE9fini, ne l'ajoute pas au turn order + //Appelé si le turn order change, mais aussi en interne + //si evt est déjà défini, ne l'ajoute pas au turn order function nextTurn(cmp, options, evt) { if (!cmp.get('initiativepage')) return; let combat = stateCOF.combat; @@ -47160,7 +47400,7 @@ var COFantasy = COFantasy || function() { let attrs = findObjs({ _type: 'attribute' }); - // Si on a chang\xE9 d'initiative, alors diminue les effets temporaires + // Si on a changé d'initiative, alors diminue les effets temporaires if (combat.init > init) { if (stateCOF.tokensTemps && stateCOF.tokensTemps.length > 0) { stateCOF.tokensTemps = stateCOF.tokensTemps.filter(function(tt) { @@ -47190,7 +47430,7 @@ var COFantasy = COFantasy || function() { } }); } - //attrsTemp ne contient que les attributs dont la dur\xE9e doit baisser + //attrsTemp ne contient que les attributs dont la durée doit baisser let attrsTemp = attrs.filter(function(obj) { if (!estEffetTemp(obj.get('name'))) return false; let obji = obj.get('max'); @@ -47199,7 +47439,7 @@ var COFantasy = COFantasy || function() { if (!evt.combat) evt.combat = {...stateCOF.combat }; combat.init = init; - // Boucle sur les effets temps peut \xEAtre asynchrone \xE0 cause des DM + // Boucle sur les effets temps peut être asynchrone à cause des DM let count = attrsTemp.length; if (count === 0) { nextTurnOfActive(active, attrs, evt, combat, pageId, options); @@ -47222,8 +47462,8 @@ var COFantasy = COFantasy || function() { let effetC = effetComplet(effet, attrName); let v = parseInt(attr.get('current')); if (isNaN(v)) v = 1; - if (v <= 1) { //L'effet arrive en fin de vie, doit \xEAtre supprim\xE9 - //Sauf si on a accumul\xE9 plusieurs fois l'effet + if (v <= 1) { //L'effet arrive en fin de vie, doit être supprimé + //Sauf si on a accumulé plusieurs fois l'effet let accumuleAttr = attributeExtending(charId, attrName, effetC, 'DureeAccumulee'); if (accumuleAttr.length > 0) { accumuleAttr = accumuleAttr[0]; @@ -47274,16 +47514,16 @@ var COFantasy = COFantasy || function() { if (v > 1) attr.set('current', v - 1); actionEffet(attr, effet, attrName, charId, pageId, evt, fin); }); //fin de la boucle sur tous les attributs d'effets temporaires - } else { //L'initiative n'a pas boug\xE9e + } else { //L'initiative n'a pas bougée nextTurnOfActive(active, attrs, evt, combat, pageId, options); } } - //Fonction appel\xE9e par !cof-tour-suivant + //Fonction appelée par !cof-tour-suivant function tourSuivant(msg) { let combat = stateCOF.combat; if (!combat) { - sendPlayer(msg, "Vous n'\xEAtes pas en combat"); + sendPlayer(msg, "Vous n'êtes pas en combat"); return; } let cmp = Campaign(); @@ -47321,10 +47561,10 @@ var COFantasy = COFantasy || function() { nextTurn(cmp); } - //nb \xE0 11 pour ne pas retenter de lire les attributs + //nb à 11 pour ne pas retenter de lire les attributs function scriptVersionToCharacter(character, nb) { let charId = character.id; - //On v\xE9rifie que les attributs sont peupl\xE9s + //On vérifie que les attributs sont peuplés let attrs = findObjs({ _type: 'attribute', _characterid: charId, @@ -47390,7 +47630,7 @@ var COFantasy = COFantasy || function() { removeTokenAttr(perso, 'bougeGraceA'); return; } - //On regarde si il existe une copie de ce token, par exemple \xE0 cause de l'invisibilit\xE9 + //On regarde si il existe une copie de ce token, par exemple à cause de l'invisibilité let otherTokens = findObjs({ _type: 'graphic', _pageid: pageId, @@ -47502,7 +47742,7 @@ var COFantasy = COFantasy || function() { activerEffetTemporaire(origine, cibles, 'drainDeForce', mEffet, 1, options, evtEffet, '', [], display); } - //retourne le nombre de cibles affect\xE9es + //retourne le nombre de cibles affectées function appliquerAura(origine, cibles, pageId, aura, evt, renew) { let effet; cibles = cibles.filter(function(perso) { @@ -47523,7 +47763,7 @@ var COFantasy = COFantasy || function() { save: { carac: 'CON', seuil: 12, - msgPour: ' pour ne pas \xEAtre affaibli' + eForFemale(cibles[0]) + msgPour: ' pour ne pas être affaibli' + eForFemale(cibles[0]) } }; let mEffet = messageEffetTemp.drainDeForce; @@ -47555,8 +47795,8 @@ var COFantasy = COFantasy || function() { return cibles.length; } - //R\xE9agit au d\xE9placement manuel d'un token. - // suivis est l'ensemble des tokens qui a d\xE9j\xE0 \xE9t\xE9 boug\xE9 suite \xE0 ce d\xE9placement + //Réagit au déplacement manuel d'un token. + // suivis est l'ensemble des tokens qui a déjà été bougé suite à ce déplacement function moveToken(token, prev, synchronisation, suivis) { let charId = token.get('represents'); if (charId === '') return; @@ -47609,7 +47849,7 @@ var COFantasy = COFantasy || function() { if (tid == token.id) return; let tok = getObj('graphic', tid); if (tok === undefined) { - error("Impossible de trouver le token d'id " + tid + " synchronis\xE9 avec " + token.get('name'), attr); + error("Impossible de trouver le token d'id " + tid + " synchronisé avec " + token.get('name'), attr); return; } tok.set('left', x); @@ -47676,7 +47916,7 @@ var COFantasy = COFantasy || function() { type: "initiative" }; updateInit(monture.token, evt); - // R\xE9adapter l'init_dynamique au token du perso + // Réadapter l'init_dynamique au token du perso if (stateCOF.options.affichage.val.init_dynamique.val) { setTokenInitAura(perso); } @@ -47758,7 +47998,7 @@ var COFantasy = COFantasy || function() { autreInvisible.set('top', y); } } - //si non, perso est peut-\xEAtre une monture + //si non, perso est peut-être une monture let attrMontePar = tokenAttribute(perso, 'estMontePar'); attrMontePar.forEach(function(a) { let cavalier = persoOfIdName(a.get('current'), pageId); @@ -47784,7 +48024,7 @@ var COFantasy = COFantasy || function() { //Si le token suivait quelqu'un, ce n'est plus le cas if (prev.suit === undefined) nePlusSuivre(perso, pageId); //On bouge tous les tokens qui suivent le personnage - //sauf si on a d\xE9j\xE0 \xE9t\xE9 boug\xE9. + //sauf si on a déjà été bougé. if (!suivis.has(token.id)) { suivis.add(token.id); let attrSuivi = tokenAttribute(perso, 'estSuiviPar'); @@ -47818,7 +48058,7 @@ var COFantasy = COFantasy || function() { if (sh > width) return false; let sx = suivant.token.get('left'); let sy = suivant.token.get('top'); - //On essaie de garder la m\xEAme position par rapport au token, en supposant qu'on \xE9tait derri\xE8re lui + //On essaie de garder la même position par rapport au token, en supposant qu'on était derrière lui let attrSuit = tokenAttribute(suivant, 'suit'); let dp; if (attrSuit.length > 0) { @@ -47833,10 +48073,10 @@ var COFantasy = COFantasy || function() { if (nsy < 0) nsy = 0; if (nsx + sw / 2 > width) nsx = Math.floor(width - sw / 2); if (nsy + sh / 2 > height) nsy = Math.floor(height - sh / 2); - //v\xE9rifie si de la nouvelle position on peut voir le suivi + //vérifie si de la nouvelle position on peut voir le suivi if (obstaclePresent(nsx, nsy, pt, murs)) { - //On essaie de suivre le chemin du token, \xE0 la place - //D'abord se d\xE9placer vers l'ancienne position de perso, au maximum de distance pixels + //On essaie de suivre le chemin du token, à la place + //D'abord se déplacer vers l'ancienne position de perso, au maximum de distance pixels let distLoc = distance; if (distLoc - dp < 5) { nsx = prev.left; @@ -47893,7 +48133,7 @@ var COFantasy = COFantasy || function() { roundMarker.set('left', x); roundMarker.set('top', y); } else { - // Cas sp\xE9ciaux du cavaliers : au tour du cavalier, l'init_dynamique suit la monture + // Cas spéciaux du cavaliers : au tour du cavalier, l'init_dynamique suit la monture let estMontePar = tokenAttribute(perso, 'estMontePar'); if (estMontePar.length > 0) { let sp = splitIdName(estMontePar[0].get('current')); @@ -47905,7 +48145,7 @@ var COFantasy = COFantasy || function() { } } } - //On d\xE9place les tokens de lumi\xE8re, si il y en a + //On déplace les tokens de lumière, si il y en a let attrLumiere = tokenAttribute(perso, 'lumiere'); attrLumiere.forEach(function(al) { let lumId = al.get('max'); @@ -47925,13 +48165,13 @@ var COFantasy = COFantasy || function() { }); if (tokensLumiere.length === 0) { if (lumiereExiste) return; - log("Pas de token pour la lumi\xE8re " + al.get('current')); + log("Pas de token pour la lumière " + al.get('current')); al.remove(); return; } lumiere = tokensLumiere.shift(); if (tokensLumiere.length > 0) { - //On cherche le token le plus proche de la position pr\xE9c\xE9dente + //On cherche le token le plus proche de la position précédente let d = distanceTokenPrev(lumiere, prev); tokensLumiere.forEach(function(tl) { let d2 = distanceTokenPrev(tl, prev); @@ -47944,7 +48184,7 @@ var COFantasy = COFantasy || function() { } if (lumiere === undefined) { if (lumiereExiste) return; - log("Pas de token pour la lumi\xE8re " + al.get('current')); + log("Pas de token pour la lumière " + al.get('current')); al.remove(); return; } @@ -47967,7 +48207,7 @@ var COFantasy = COFantasy || function() { function synchronisationDesEtats(perso) { for (let etat in cof_states) { - // R\xE9cup\xE8re la valeur de l'\xE9tat sur la fiche + // Récupère la valeur de l'état sur la fiche let valEtat; if (etat == 'affaibli') { // Cas particulier affaibli sur la fiche perso valEtat = (ficheAttributeAsInt(perso, 'affaibli', 20) == 12); @@ -47979,10 +48219,10 @@ var COFantasy = COFantasy || function() { } } - //Op\xE9rations diverses au moment o\xF9 on pose un token. - //Si le token repr\xE9sente un personnage et avec la barre de vie non li\xE9e, - // assure un nom unique en ajoutant un num\xE9ro - // On en profite aussi pour mettre certaines valeurs par d\xE9faut + //Opérations diverses au moment où on pose un token. + //Si le token représente un personnage et avec la barre de vie non liée, + // assure un nom unique en ajoutant un numéro + // On en profite aussi pour mettre certaines valeurs par défaut // retourne un perso si c'est un token de personnage function renameToken(token, tokenName) { let charId = token.get('represents'); @@ -48045,11 +48285,11 @@ var COFantasy = COFantasy || function() { } return perso; } - //cas des mooks : num\xE9rotation + //cas des mooks : numérotation let copyOf = 0; let tokenBaseName = tokenName; if (tokenBaseName.includes('%%NUMBERED%%')) { - if (typeof TokenNameNumber !== 'undefined') return perso; //On laisse tokenNameNumber g\xE9rer \xE7a + if (typeof TokenNameNumber !== 'undefined') return perso; //On laisse tokenNameNumber gérer ça tokenBaseName = tokenBaseName.replace('%%NUMBERED%%', ''); } else { // On regarde si le nom se termine par un entier @@ -48101,7 +48341,7 @@ var COFantasy = COFantasy || function() { function addToken(token, nb) { let tokenName = token.get('name'); - //La plupart du temps, il faut attendre un peu que le nom soit affect\xE9 + //La plupart du temps, il faut attendre un peu que le nom soit affecté if (tokenName !== '') { let perso = renameToken(token, tokenName); if (perso === undefined) return; @@ -48115,16 +48355,16 @@ var COFantasy = COFantasy || function() { return; } nb = nb || 1; - if (nb > 10) return; //Tant pis, peut-\xEAtre que le nom est vide + if (nb > 10) return; //Tant pis, peut-être que le nom est vide _.delay(function() { addToken(token, nb + 1); }, 50); } - // Surveillance sur le changement d'\xE9tat du token + // Surveillance sur le changement d'état du token function changeMarker(token, prev) { const charId = token.get('represents'); - if (charId === undefined || charId === '') return; // Uniquement si token li\xE9 \xE0 un perso + if (charId === undefined || charId === '') return; // Uniquement si token lié à un perso const perso = { token, charId @@ -48190,7 +48430,7 @@ var COFantasy = COFantasy || function() { let lumId = al.get('max'); if (lumId == 'surToken') { if (!token.get('emits_bright_light') && !token.get('emits_low_light')) { - //On cherche un token qui repr\xE9sente le m\xEAme personnage et \xE9met de la lumi\xE8re + //On cherche un token qui représente le même personnage et émet de la lumière let allTokens = findObjs({ type: 'graphic', represents: perso.charId @@ -48209,7 +48449,7 @@ var COFantasy = COFantasy || function() { } return; } - //Lumi\xE8re sur un token qui suit le perso. + //Lumière sur un token qui suit le perso. let lumiere = getObj('graphic', lumId); if (lumiere && lumiere.get('pageid') != pageId) { let copyLum = createObj('graphic', { @@ -48235,7 +48475,7 @@ var COFantasy = COFantasy || function() { } } - //Actions \xE0 faire pour maintenir la coh\xE9rence des tokens qui repr\xE9sentent le m\xEAme personnage. + //Actions à faire pour maintenir la cohérence des tokens qui représentent le même personnage. function changePlayerPage(campaign) { let currentMap = getObj('page', campaign.get('playerpageid')); let tokens = findObjs({ @@ -48245,7 +48485,7 @@ var COFantasy = COFantasy || function() { }); tokens.forEach(function(token) { let charId = token.get('represents'); - if (charId === undefined || charId === '') return; // Si token li\xE9 \xE0 un perso + if (charId === undefined || charId === '') return; // Si token lié à un perso if (token.get('bar1_link') === '') return; // Si unique let perso = { token, @@ -48287,8 +48527,8 @@ var COFantasy = COFantasy || function() { function changeTokenLock(token, prev) { const charId = token.get('represents'); - if (charId === undefined || charId === '') return; // Uniquement si token li\xE9 \xE0 un perso - if (token.get('lockMovement')) return; //Rien de sp\xE9cial \xE0 faire + if (charId === undefined || charId === '') return; // Uniquement si token lié à un perso + if (token.get('lockMovement')) return; //Rien de spécial à faire const perso = { token, charId @@ -48317,8 +48557,8 @@ var COFantasy = COFantasy || function() { state.COFantasy.eventId = 0; } if (version < 1.0) { - log("Mise \xE0 jour des attributs et macros vers la version 1.0"); - //Mise \xE0 jour des effets temporaires avec _ + log("Mise à jour des attributs et macros vers la version 1.0"); + //Mise à jour des effets temporaires avec _ let strReg = "(rayon_affaiblissant|peau_d_ecorce|chant_des_heros|image_decalee|a_couvert|sous_tension|forgeron_|armeEnflammee)"; let regName = new RegExp("^" + strReg); let regText = new RegExp(strReg); @@ -48371,10 +48611,10 @@ var COFantasy = COFantasy || function() { m.set('action', action); } }); - log("Mise \xE0 jour effectu\xE9e."); + log("Mise à jour effectuée."); } if (version < 2.0) { - log("Mise \xE0 jour des attributs et macros vers la version 2.0"); + log("Mise à jour des attributs et macros vers la version 2.0"); let strReg = "(--argent)"; let regName = new RegExp("^" + strReg); let regText = new RegExp(strReg); @@ -48406,7 +48646,7 @@ var COFantasy = COFantasy || function() { m.set('action', action); } }); - log("Mise \xE0 jour effectu\xE9e."); + log("Mise à jour effectuée."); } if (version < 2.02) { let attrs = findObjs({ @@ -48416,7 +48656,7 @@ var COFantasy = COFantasy || function() { let attrName = attr.get('name'); if (attrName == 'mort-vivant') attr.set('name', 'mortVivant'); }); - log("Mise \xE0 jour effectu\xE9e."); + log("Mise à jour effectuée."); } if (version < 2.03) { let attrs = findObjs({ @@ -48424,13 +48664,13 @@ var COFantasy = COFantasy || function() { }); attrs.forEach(function(attr) { let attrName = attr.get('name'); - if (attrName == 'runeDEnergie') attr.set('name', 'runeForgesort_\xE9nergie'); + if (attrName == 'runeDEnergie') attr.set('name', 'runeForgesort_énergie'); if (attrName == 'runeDeProtection') attr.set('name', 'runeForgesort_protection'); if (attrName.includes('runeDePuissance')) { attr.set('name', 'runeForgesort_puissance(' + attrName.substring(attrName.indexOf("(") + 1, attrName.indexOf(")")) + ')'); } }); - log("Mise \xE0 jour des runes effectu\xE9e."); + log("Mise à jour des runes effectuée."); } if (version < 2.04) { let attrs = findObjs({ @@ -48478,7 +48718,7 @@ var COFantasy = COFantasy || function() { attrRDS.set('current', rdPerso); a.remove(); }); - log("Mise \xE0 jour de la RD effectu\xE9e"); + log("Mise à jour de la RD effectuée"); } if (version < 2.05) { let attrs = findObjs({ @@ -48493,7 +48733,7 @@ var COFantasy = COFantasy || function() { let message = action.substring(19); a.set("max", "!cof-lancer-sort --message " + message + " --mana " + mana); }); - log("Mise \xE0 jour des consommables !cof-lancer-sort effectu\xE9e"); + log("Mise à jour des consommables !cof-lancer-sort effectuée"); let macros = findObjs({ _type: 'macro' }).concat(findObjs({ @@ -48506,7 +48746,7 @@ var COFantasy = COFantasy || function() { let message = macro.substring(19); m.set("action", "!cof-lancer-sort --message " + message + " --mana " + mana); }); - log("Mise \xE0 jour des ability & macros !cof-lancer-sort effectu\xE9e"); + log("Mise à jour des ability & macros !cof-lancer-sort effectuée"); } if (version < 2.10) { let tokens = findObjs({ @@ -48535,7 +48775,7 @@ var COFantasy = COFantasy || function() { let removeAttrs = function() { charsToTreat--; if (charsToTreat > 0) return; - log("Supression des attributs obsol\xE8tes"); + log("Supression des attributs obsolètes"); let attrs = findObjs({ _type: 'attribute', }); @@ -48600,13 +48840,13 @@ var COFantasy = COFantasy || function() { setDefaultTokenForCharacter(character, newToken); newToken.remove(); } else { - log('Impossible de cr\xE9er un token pour ' + token.name); + log('Impossible de créer un token pour ' + token.name); log(token); } removeAttrs(); }); }); - log("Mise \xE0 jour des attributs et tokens effectu\xE9e"); + log("Mise à jour des attributs et tokens effectuée"); } if (version < 2.11) { let attrs = findObjs({ @@ -48622,7 +48862,7 @@ var COFantasy = COFantasy || function() { }; a.set(na); }); - log("Mise \xE0 jour des attributs de capitaine effectu\xE9e"); + log("Mise à jour des attributs de capitaine effectuée"); } if (version < 2.12) { let attrs = findObjs({ @@ -48691,10 +48931,10 @@ var COFantasy = COFantasy || function() { } a.remove(); }); - log("D\xE9placement des attributs de consommables vers la fiche"); + log("Déplacement des attributs de consommables vers la fiche"); } if (version < 2.13) { - //On enl\xE8ve les attributs obsol\xE8tes de la verison 4.00 de la fiche + //On enlève les attributs obsolètes de la verison 4.00 de la fiche let attrs = findObjs({ _type: 'attribute', }); @@ -48734,7 +48974,7 @@ var COFantasy = COFantasy || function() { }); } if (version < 2.14) { - //Migration des \xE9l\xE9ments de r\xE8gles optionnels + //Migration des éléments de règles optionnels //Divers if (state.COFantasy.options.regles.val.poudre_explosif) { state.COFantasy.options.regles.val.divers.val.poudre_explosif.val = state.COFantasy.options.regles.val.poudre_explosif.val; @@ -48767,13 +49007,13 @@ var COFantasy = COFantasy || function() { delete state.COFantasy.options.regles.val.usure_DEF; } if (state.COFantasy.options.regles.val.generer_options_attaques) { - log("Options d'attaques supprim\xE9es ; veuiller utiliser le bouton 'Options' de la liste d'Actions \xE0 la place"); - sendChat('COFantasy', "Options d'attaques supprim\xE9es ; veuiller utiliser le bouton 'Options' de la liste d'Actions \xE0 la place"); + log("Options d'attaques supprimées ; veuiller utiliser le bouton 'Options' de la liste d'Actions à la place"); + sendChat('COFantasy', "Options d'attaques supprimées ; veuiller utiliser le bouton 'Options' de la liste d'Actions à la place"); delete state.COFantasy.options.regles.val.generer_options_attaques; } if (state.COFantasy.options.regles.val.generer_attaque_groupe) { - log("Attaques de groupe supprim\xE9es ; veuiller utiliser le bouton 'Options' de la liste d'Actions \xE0 la place"); - sendChat('COFantasy', "Options d'attaques supprim\xE9es ; veuiller utiliser le bouton 'Options' de la liste d'Actions \xE0 la place"); + log("Attaques de groupe supprimées ; veuiller utiliser le bouton 'Options' de la liste d'Actions à la place"); + sendChat('COFantasy', "Options d'attaques supprimées ; veuiller utiliser le bouton 'Options' de la liste d'Actions à la place"); delete state.COFantasy.options.regles.val.generer_attaque_groupe; } if (state.COFantasy.options.regles.val.bonus_attaque_groupe) { @@ -48802,7 +49042,7 @@ var COFantasy = COFantasy || function() { state.COFantasy.options.regles.val.mana.val.elixirs_sorts.val = state.COFantasy.options.regles.val.elixirs_sorts.val; delete state.COFantasy.options.regles.val.elixirs_sorts; } - log("R\xE8gles optionelles mises \xE0 jour"); + log("Règles optionelles mises à jour"); } if (version < 2.15) { let attrs = findObjs({ @@ -48844,7 +49084,7 @@ var COFantasy = COFantasy || function() { }); a.remove(); }); - log("D\xE9placement des attributs de consommables de PNJs vers la fiche"); + log("Déplacement des attributs de consommables de PNJs vers la fiche"); } if (version < 2.16) { let attrs = findObjs({ @@ -48855,7 +49095,7 @@ var COFantasy = COFantasy || function() { }); let handhoutComp = handouts.find(function(h) { let handName = h.get('name'); - return (handName == 'Comp\xE9tences' || handName == 'Competences'); + return (handName == 'Compétences' || handName == 'Competences'); }); if (handhoutComp) { let listeCompetences = { @@ -48868,7 +49108,7 @@ var COFantasy = COFantasy || function() { nombre: 0 }; handhoutComp.get('notes', function(note) { // asynchronous - let carac; //La carac dont on sp\xE9cifie les comp\xE9tences actuellement + let carac; //La carac dont on spécifie les compétences actuellement note = note.trim(); if (note.startsWith('

')) note = note.substring(3); note = note.trim().replace(/]*>|<\/span>/g, ''); @@ -48886,7 +49126,7 @@ var COFantasy = COFantasy || function() { } if (ligne.length === 0) return; if (carac === undefined) { - log("Comp\xE9tences sans caract\xE9ristique associ\xE9e"); + log("Compétences sans caractéristique associée"); return; } let comps = ligne.split(/, |\/| /); @@ -48964,9 +49204,9 @@ var COFantasy = COFantasy || function() { a.set('name', 'charisme'); return; } - //Les comp\xE9tences + //Les compétences let charId = a.get('characterid'); - //On ne bouge les comp\xE9tences que pour les persos de type PJ + //On ne bouge les compétences que pour les persos de type PJ let typePerso = findObjs({ _type: 'attribute', _characterid: charId, @@ -48992,7 +49232,7 @@ var COFantasy = COFantasy || function() { attrSpec.current = compToCarac[attrName]; createObj('attribute', attrSpec); let attrMalus; - if ((attrSpec.current == 'DEX' && attrName != 'crochetage' && attrName != 'd\xE9samor\xE7age') || + if ((attrSpec.current == 'DEX' && attrName != 'crochetage' && attrName != 'désamorçage') || (attrSpec.current == 'CON' && attrName == 'survie') || attrName == 'natation' || attrName == 'escalade') { attrSpec.name = prefix + 'malus'; @@ -49056,7 +49296,7 @@ var COFantasy = COFantasy || function() { } }); } - log("Mise \xE0 jour des attributs de comp\xE9tence effectu\xE9"); + log("Mise à jour des attributs de compétence effectué"); } if (version < 2.17) { let macros = findObjs({ @@ -49071,7 +49311,7 @@ var COFantasy = COFantasy || function() { if (macro !== newMacro) m.set("action", newMacro); }); - log("Mise \xE0 jour des ability T\xE9n\xE8bres effectu\xE9e"); + log("Mise à jour des ability Ténèbres effectuée"); } let updateReset = function(a, nom, typ) { let c = parseInt(a.get('current')); @@ -49113,7 +49353,7 @@ var COFantasy = COFantasy || function() { } }); } - log("Mise \xE0 jour des attributs effectu\xE9e"); + log("Mise à jour des attributs effectuée"); } if (version < 3.00) { let macros = findObjs({ @@ -49361,7 +49601,7 @@ var COFantasy = COFantasy || function() { characterid: cid, }); if (abilitiesInList.has(actionCmd) || abilitie.get('istokenaction')) { - //On garde le texte partag\xE9 de l'ability. + //On garde le texte partagé de l'ability. createObj('attribute', { name: pref + 'actiontitre', current: action, @@ -49408,7 +49648,7 @@ var COFantasy = COFantasy || function() { characterid: cid, }); // Macro - //D'abord le cas de #Attaque, car le nom affich\xE9 est celui de l'arme + //D'abord le cas de #Attaque, car le nom affiché est celui de l'arme if (actionCmd == '#Attaque' && actionCommands.length > 1) { createObj('attribute', { name: pref + 'actiontitre', @@ -49471,7 +49711,7 @@ var COFantasy = COFantasy || function() { state.COFantasy.options.affichage && state.COFantasy.options.affichage.val && state.COFantasy.options.affichage.val.actions_par_defaut.val) { - //Par d\xE9faut, on montrait la liste de toutes les abilities + //Par défaut, on montrait la liste de toutes les abilities abilities.forEach(function(a) { n++; let pref = 'repeating_actions_' + generateRowID() + '_'; @@ -49522,17 +49762,17 @@ var COFantasy = COFantasy || function() { } if (n > 0) attrRang.set('current', n); }); - log("Mise \xE0 jour des listes d'action effectu\xE9e"); - //Ensuite les pr\xE9dicats bool\xE9ens + log("Mise à jour des listes d'action effectuée"); + //Ensuite les prédicats booléens let predicates = '^(' + 'actionLibre|agripper|ambidextreDuelliste|animal|argumentDeTaille' + '|armureProtection|aucuneActionCombat|baroudHonneur' + '|botteMortelle|bouclierPsi|briseurDOs|bucheron|champion' + '|chasseurEmerite|chatimentDuMale|chimiste|ciblesMultiples' + '|combatEnPhalange|combatKinetique|commandant|controleDuMetabolisme' + - '|creatureArtificielle|crocEnJambe|defenseIntuitive|d\xE9mon|devorer' + + '|creatureArtificielle|crocEnJambe|defenseIntuitive|démon|devorer' + '|durACuire|ecuyer|elfeNoir|enchainement|energieDeLaMort' + - '|estUneIllusion|exsangue|f\xE9e|fievreChene|frappeChirurgicale|gober' + + '|estUneIllusion|exsangue|fée|fievreChene|frappeChirurgicale|gober' + '|graceFeline|graceFelineVoleur|grosMonstreGrosseArme|grosseTete' + '|hachesEtMarteaux|hausserLeTon|horsDePortee|humanoide' + '|ignorerLaDouleur|immuniteAuxArmes|immuniteAuxSournoises' + @@ -49583,7 +49823,7 @@ var COFantasy = COFantasy || function() { { let charId = attribute.get('characterid'); parChar[charId] = parChar[charId] || new Set(); - parChar[charId].add('g\xE9ant'); + parChar[charId].add('géant'); attribute.remove(); } break; @@ -49614,7 +49854,7 @@ var COFantasy = COFantasy || function() { attr.set('current', predText + attr.get('current')); } } - log("Transformation des attributs bool\xE9ens en pr\xE9dicats"); + log("Transformation des attributs booléens en prédicats"); } let getPredicateAttr = function(charId) { let attr = findObjs({ @@ -49682,7 +49922,7 @@ var COFantasy = COFantasy || function() { } attr.set('current', predText); } - log("Transformation des attributs num\xE9riques en pr\xE9dicats"); + log("Transformation des attributs numériques en prédicats"); } if (version < 3.02) { const regPJ = new RegExp("^(repeating_armes_[^_]*_)(.*)$"); @@ -49751,7 +49991,7 @@ var COFantasy = COFantasy || function() { taux = parseInt(cmd[2]); if (isNaN(taux) || taux < 0 || taux > 100) taux = 0; } else { - taux = 100; //La valeur par d\xE9faut en option. + taux = 100; //La valeur par défaut en option. } return false; }); @@ -49798,7 +50038,7 @@ var COFantasy = COFantasy || function() { } }); }); - log("Mise \xE0 jour des armes de jet effectu\xE9e"); + log("Mise à jour des armes de jet effectuée"); } if (version < 3.03) { findObjs({ @@ -49817,7 +50057,7 @@ var COFantasy = COFantasy || function() { if (arme.trim() !== '') predText += ':' + arme; attr.set('current', predText); }); - log("Mise \xE0 jour de pr\xE9dicats effectu\xE9e"); + log("Mise à jour de prédicats effectuée"); } if (version < 3.04) { let attrs = findObjs({ @@ -49898,7 +50138,7 @@ var COFantasy = COFantasy || function() { } attr.set('current', predText); } - log("Transformation d'attributs de combat en pr\xE9dicats"); + log("Transformation d'attributs de combat en prédicats"); } if (version < 3.05) { let attrs = findObjs({ @@ -49911,7 +50151,7 @@ var COFantasy = COFantasy || function() { log("Suppression des attributs pnj d'armure et de bouclier"); } if (version < 3.07) { - //Collecte des persos ayant un pr\xE9dicat charge_ ou eclaire_ + //Collecte des persos ayant un prédicat charge_ ou eclaire_ let charIds = {}; let attrs = findObjs({ _type: 'attribute', @@ -50004,7 +50244,7 @@ var COFantasy = COFantasy || function() { } } } - log("Copie des pr\xE9dicats de charge et \xE9clairage vers les attaques des armes"); + log("Copie des prédicats de charge et éclairage vers les attaques des armes"); } if (version < 3.08) { let attrs = findObjs({ @@ -50045,10 +50285,10 @@ var COFantasy = COFantasy || function() { a.set('current', preds); } }); - log("Changement du pr\xE9dicat laissez-le-moi"); + log("Changement du prédicat laissez-le-moi"); } if (version < 3.11) { - //aura sera pass\xE9 en actions plus tard + //aura sera passé en actions plus tard let predicates = '^(' + 'attributsDeStatut|chairACanonDe|defDeriveeDe|dmSiToucheContact' + '|ecuyerDe|ennemiJure|entrerEnCombatAvec|familier|guetteur' + @@ -50087,7 +50327,7 @@ var COFantasy = COFantasy || function() { for (let charId in parChar) { parChar[charId].attr.set('current', parChar[charId].predText); } - log("Transformation des attributs complexes en pr\xE9dicats"); + log("Transformation des attributs complexes en prédicats"); } if (version < 3.12) { if (state.COFantasy.foudresDuTemps) { @@ -50111,7 +50351,7 @@ var COFantasy = COFantasy || function() { charAttr: true }); }); - log("Mise \xE0 jour effectu\xE9e"); + log("Mise à jour effectuée"); } } @@ -50157,7 +50397,7 @@ on('ready', function() { handout.forEach(function(hand) { COFantasy.changeHandout(hand); }); - //V\xE9rification de la version sur les fiches + //Vérification de la version sur les fiches characters.forEach(function(c) { COFantasy.scriptVersionToCharacter(c, 11); }); @@ -50176,8 +50416,8 @@ on("chat:message", function(msg) { try { COFantasy.apiCommand(msg); } catch (e) { - sendChat('COF', "Erreur durant l'ex\xE9cution de " + msg.content); - log("Erreur durant l'ex\xE9cution de " + msg.content); + sendChat('COF', "Erreur durant l'exécution de " + msg.content); + log("Erreur durant l'exécution de " + msg.content); log(msg); let errMsg = e.name; if (e.lineNumber) errMsg += " at " + e.lineNumber; diff --git a/COFantasy/3.13/doc.html b/COFantasy/3.13/doc.html index 555b52488f..c71932c9e4 100644 --- a/COFantasy/3.13/doc.html +++ b/COFantasy/3.13/doc.html @@ -4,7 +4,7 @@ - Scripts pour Chroniques Oubliées Fantasy sous Roll20 + Scripts pour Chroniques Oubli\xE9es Fantasy sous Roll20 @@ -57,26 +57,26 @@

Sommaire

  • Actions principales
  • -
  • Capacités par Classe
  • +
  • Capacit\xE9s par Classe
  • -
  • Autres capacités
  • +
  • Autres capacit\xE9s
  • Terres d'Arran
  • -
  • Markers personnalisés
  • +
  • Markers personnalis\xE9s
  • Console API
  • Conversion depuis Pathfinder
  • @@ -135,129 +136,129 @@

    1. Comment utiliser Le scr

    1.1 Tokens et personnages

    -

    Ces scripts ont été écrits pour fonctionner avec les fiches de personnages développées par Natha.

    +

    Ces scripts ont \xE9t\xE9 \xE9crits pour fonctionner avec les fiches de personnages d\xE9velopp\xE9es par Natha.

    -
    A choisir pendant la création de la partie sur Roll20.
    +
    A choisir pendant la cr\xE9ation de la partie sur Roll20.
    -

    Chaque token avec lequel vous souhaitez interagir doit représenter un personnage.

    -

    La barre 1 représente toujours les points de vie du token.
    - La barre 2 est soit la mana, pour les personnages qui ont des points de mana, soit les dégâts temporaires pour les personnages qui n’ont pas de points de mana
    - La barre 3 est utilisée pour donner un modificateur temporaire à l’attaque du token. +

    Chaque token avec lequel vous souhaitez interagir doit repr\xE9senter un personnage.

    +

    La barre 1 repr\xE9sente toujours les points de vie du token.
    + La barre 2 est soit la mana, pour les personnages qui ont des points de mana, soit les d\xE9g\xE2ts temporaires pour les personnages qui n\x2019ont pas de points de mana
    + La barre 3 est utilis\xE9e pour donner un modificateur temporaire \xE0 l\x2019attaque du token.

    -

    Les statuts des tokens sont en partie utilisés pour représenter des états. Voir plus loin pour la liste des statuts utilisés par les scripts.
    - Pour tenir compte d'autre états non visibles sur les tokens, les scripts utilisent des attributs supplémentaires (hors fiche). Parfois, le MJ devra créer et remplir lui-même certains attributs, d'autres fois cela sera géré par les scripts. +

    Les statuts des tokens sont en partie utilis\xE9s pour repr\xE9senter des \xE9tats. Voir plus loin pour la liste des statuts utilis\xE9s par les scripts.
    + Pour tenir compte d'autre \xE9tats non visibles sur les tokens, les scripts utilisent des attributs suppl\xE9mentaires (hors fiche). Parfois, le MJ devra cr\xE9er et remplir lui-m\xEAme certains attributs, d'autres fois cela sera g\xE9r\xE9 par les scripts.

    -

    Il est important de noter la différence entre les tokens liés à un personnage (la barre 1 est liée aux points de vie du personnage, tout changement sur la fiche se répercute sur le token), et les tokens non liés (dans ce cas, la fiche de personnage est générique, et chaque token est une instance différente, avec des PV indépendants).

    -

    Pour gérer les états spécifiques à un token non lié, les scripts utilisent des conventions de nom d'attribut utilisant le nom du token. Pour que cela fonctionne correctement, il est important que deux tokens indépendants ne portent pas le même nom, même si ils représentent le même personnage. Pour cette raison, le script va automatiquement renommer les tokens indépendants, en leur associant un numéro. Il est toujours possible de remodifier le nom après la création du token, mais dans ce cas, c'est vous qui gérez...

    -

    Certains messages tiennent compte du genre (masculin ou féminin) des personnages. Ils utilisent le champ Sexe de la fiche de personnage. Un personnage est reconnu comme féminin si ce champ commence par la lettre F. +

    Il est important de noter la diff\xE9rence entre les tokens li\xE9s \xE0 un personnage (la barre 1 est li\xE9e aux points de vie du personnage, tout changement sur la fiche se r\xE9percute sur le token), et les tokens non li\xE9s (dans ce cas, la fiche de personnage est g\xE9n\xE9rique, et chaque token est une instance diff\xE9rente, avec des PV ind\xE9pendants).

    +

    Pour g\xE9rer les \xE9tats sp\xE9cifiques \xE0 un token non li\xE9, les scripts utilisent des conventions de nom d'attribut utilisant le nom du token. Pour que cela fonctionne correctement, il est important que deux tokens ind\xE9pendants ne portent pas le m\xEAme nom, m\xEAme si ils repr\xE9sentent le m\xEAme personnage. Pour cette raison, le script va automatiquement renommer les tokens ind\xE9pendants, en leur associant un num\xE9ro. Il est toujours possible de remodifier le nom apr\xE8s la cr\xE9ation du token, mais dans ce cas, c'est vous qui g\xE9rez...

    +

    Certains messages tiennent compte du genre (masculin ou f\xE9minin) des personnages. Ils utilisent le champ Sexe de la fiche de personnage. Un personnage est reconnu comme f\xE9minin si ce champ commence par la lettre F.

    1.2 Macros et Abilities

    -

    Comme tous les scripts, ces scripts sont utilisables tels quels dans le chat, mais ils sont pensés pour être utilisés par des macros qui permettent un autre niveau d'automatisation parfois difficile d'accès au sein des scripts. le script génère d'ailleurs la plupart des macros utiles à la première utilisation, et il met automatiquement les macros à jour à chaque changement de version. Il est possible de demander des les re-créer en tapant la commande !cof-set-macros dans le chat.

    +

    Comme tous les scripts, ces scripts sont utilisables tels quels dans le chat, mais ils sont pens\xE9s pour \xEAtre utilis\xE9s par des macros qui permettent un autre niveau d'automatisation parfois difficile d'acc\xE8s au sein des scripts. le script g\xE9n\xE8re d'ailleurs la plupart des macros utiles \xE0 la premi\xE8re utilisation, et il met automatiquement les macros \xE0 jour \xE0 chaque changement de version. Il est possible de demander des les re-cr\xE9er en tapant la commande !cof-set-macros dans le chat.

    - Le script ne peut pas mettre les macros dans la barre de raccourci. Je recommande que chaque joueur se crée sa macro Centrer, contenant le code !cof-centrer-sur-token nom_de_leur_token_principal, qui leur permettra en un click de centrer la vue de la carte sur leur token. Pour le MJ, le script suggère de mettre un certain nombre des macros qu'il crée, au moment de la première utilisation.

    -

    Une partie des capacités et attaques des personnages devraient être utilisées au sein d'abilities de personnages, accessibles comme "Token action". Si ces abilities utilisent des macros, ne pas oublier de rendre ces macros accessibles aux joueurs.

    + Le script ne peut pas mettre les macros dans la barre de raccourci. Je recommande que chaque joueur se cr\xE9e sa macro Centrer, contenant le code !cof-centrer-sur-token nom_de_leur_token_principal, qui leur permettra en un click de centrer la vue de la carte sur leur token. Pour le MJ, le script sugg\xE8re de mettre un certain nombre des macros qu'il cr\xE9e, au moment de la premi\xE8re utilisation.

    +

    Une partie des capacit\xE9s et attaques des personnages devraient \xEAtre utilis\xE9es au sein d'abilities de personnages, accessibles comme "Token action". Si ces abilities utilisent des macros, ne pas oublier de rendre ces macros accessibles aux joueurs.

    -

    1.3 Prédicats

    +

    1.3 Pr\xE9dicats

    -

    Une façon courante d'informer le script qu'un personnage dispose d'une capacité particulière (que ce soit dû à son entraînement ou à un objet porté) consiste à utiliser des prédicats. Il s'agit de mots clés à rentrer dans la zone de texte Prédicats, visible depuis l'onglet Script de la fiche. Ces mots clés peuvent être séparés de blancs ou de retours à la ligne.

    -

    On peut associer une valeur à un prédicat (le plus souvent un nombre, mais en fait n'importe quel mot qui ne contienne ni virgule, ni blanc, ni :). Pour cela, faire suivre le prédicat de : puis de la valeur.

    -

    Dans chaque ligne de la zone de prédicats, tout ce qui vient après // est considéré comme du commentaire et ignoré (exception: les valeurs complexes, si le // vient après ::, voir plus bas).

    +

    Une fa\xE7on courante d'informer le script qu'un personnage dispose d'une capacit\xE9 particuli\xE8re (que ce soit d\xFB \xE0 son entra\xEEnement ou \xE0 un objet port\xE9) consiste \xE0 utiliser des pr\xE9dicats. Il s'agit de mots cl\xE9s \xE0 rentrer dans la zone de texte Pr\xE9dicats, visible depuis l'onglet Script de la fiche. Ces mots cl\xE9s peuvent \xEAtre s\xE9par\xE9s de blancs ou de retours \xE0 la ligne.

    +

    On peut associer une valeur \xE0 un pr\xE9dicat (le plus souvent un nombre, mais en fait n'importe quel mot qui ne contienne ni virgule, ni blanc, ni :). Pour cela, faire suivre le pr\xE9dicat de : puis de la valeur.

    +

    Dans chaque ligne de la zone de pr\xE9dicats, tout ce qui vient apr\xE8s // est consid\xE9r\xE9 comme du commentaire et ignor\xE9 (exception: les valeurs complexes, si le // vient apr\xE8s ::, voir plus bas).

    -
    Exemple de prédicats.
    -

    Certains prédicats ont des valeurs complexes, qui peuvent contenir des blancs, des virgules, des guillements, ou même des : ou //. Afin de pouvoir utliser ces valeurs, vous pouvez faire suivre le nom du prédicat de ::. Tout ce qui viendra après jusqu'à la fin de la ligne sera considéré comme étant la valeur associée à ce prédicat. Un exemple typique d'utilisation : quand la valeur est un nom de personnage.

    -

    Il est aussi possible d'associer des prédicats à des attaques. Ces prédicats sont pris en compte quand ses attaques sont des armes, et ce que ces armes sont tenues en main. Cela permet de coder une grande variété d'effets magiques des armes. Attention, cela ne fonctionne pas pour les mooks avec les prédicats animeAPartirDExistant, intercepter, lienEpique, attaqueEnTraitre, sansPeur, immuniteSaignement, et controleSanguin.

    +
    Exemple de pr\xE9dicats.
    +

    Certains pr\xE9dicats ont des valeurs complexes, qui peuvent contenir des blancs, des virgules, des guillements, ou m\xEAme des : ou //. Afin de pouvoir utliser ces valeurs, vous pouvez faire suivre le nom du pr\xE9dicat de ::. Tout ce qui viendra apr\xE8s jusqu'\xE0 la fin de la ligne sera consid\xE9r\xE9 comme \xE9tant la valeur associ\xE9e \xE0 ce pr\xE9dicat. Un exemple typique d'utilisation : quand la valeur est un nom de personnage.

    +

    Il est aussi possible d'associer des pr\xE9dicats \xE0 des attaques. Ces pr\xE9dicats sont pris en compte quand ses attaques sont des armes, et ce que ces armes sont tenues en main. Cela permet de coder une grande vari\xE9t\xE9 d'effets magiques des armes. Attention, cela ne fonctionne pas pour les mooks avec les pr\xE9dicats animeAPartirDExistant, intercepter, lienEpique, attaqueEnTraitre, sansPeur, immuniteSaignement, et controleSanguin.

    -
    Une épée +1 affûtée avec le prédicat enchainement (actif pour toute attaque, tant que cette épée est en main).
    +
    Une \xE9p\xE9e +1 aff\xFBt\xE9e avec le pr\xE9dicat enchainement (actif pour toute attaque, tant que cette \xE9p\xE9e est en main).
    -

    1.4 Méthodes de sélection de groupes

    +

    1.4 M\xE9thodes de s\xE9lection de groupes

    -

    Comme les joueurs ne peuvent pas sélectionner un nombre arbitraire d'ennemis, 7 méthodes sont disponibles :

    +

    Comme les joueurs ne peuvent pas s\xE9lectionner un nombre arbitraire d'ennemis, 7 m\xE9thodes sont disponibles :

      -
    • Le MJ lance la macro en sélectionnant les cibles
    • -
    • option --allies : cela fait chercher tous les handout dont le nom est Equipe suivi d'un nom, et tels que le handout contienne une liste de noms (un par ligne), parmis lesquels, celui du personnage qui agit. Le personnage qui agit est celui qui est sélectionné. Les cibles sont tous les alliés du personnage sélectionné, mais pas le personnage lui-même. Attention, les noms de personnages ne doivent pas contenir de balise XML (texte encadré par des < et >). Optionellement, on peut préciser une distance maximale entre le personnage sélectionné et ses allies.
    • -
    • option --alliesEnVue : comme --allies, mais ne garde que les alliés en vue (en fonction des murs sur le layer lumière).
    • -
    • option --equipe nom : agit sur tous les personnages mentionnés dans le handout s'appelant Equipe nom.
    • -
    • option --self : pour rajouter le personnage sélectionné. Utile si on veut le personnage et ses alliés, par exemple.
    • -
    • option --target : pour ajouter une seule cible, avec une id de token. Le personnage qui agit est celui qui est sélectionné.
    • -
    • option --disque : le premier argument, optionnel, est l'id ou le nom d'un token qui représente un personnage, le deuxième argument un rayon. Cela sélectionne tous les tokens à une distance de moins que le rayon du premier argument (ou du personnage à l'origine de l'effet, si le premier argument est absent). Si un troisième argument est donné, il est interprété comme la portée maximum entre le centre du disque et le token du personnage à l'origine de l'effet. Si le premier argument représente un personnage avec un max de PV à 0, il est compris comme un personnage fictif créé juste pour définir le disque, et il sera supprimé après la sélection. À noter que le script crée par défaut un tel personnage, utilisable par tous, et appelé Cible.
    • +
    • Le MJ lance la macro en s\xE9lectionnant les cibles
    • +
    • option --allies : cela fait chercher tous les handout dont le nom est Equipe suivi d'un nom, et tels que le handout contienne une liste de noms (un par ligne), parmis lesquels, celui du personnage qui agit. Le personnage qui agit est celui qui est s\xE9lectionn\xE9. Les cibles sont tous les alli\xE9s du personnage s\xE9lectionn\xE9, mais pas le personnage lui-m\xEAme. Attention, les noms de personnages ne doivent pas contenir de balise XML (texte encadr\xE9 par des < et >). Optionellement, on peut pr\xE9ciser une distance maximale entre le personnage s\xE9lectionn\xE9 et ses allies.
    • +
    • option --alliesEnVue : comme --allies, mais ne garde que les alli\xE9s en vue (en fonction des murs sur le layer lumi\xE8re).
    • +
    • option --equipe nom : agit sur tous les personnages mentionn\xE9s dans le handout s'appelant Equipe nom.
    • +
    • option --self : pour rajouter le personnage s\xE9lectionn\xE9. Utile si on veut le personnage et ses alli\xE9s, par exemple.
    • +
    • option --target : pour ajouter une seule cible, avec une id de token. Le personnage qui agit est celui qui est s\xE9lectionn\xE9.
    • +
    • option --disque : le premier argument, optionnel, est l'id ou le nom d'un token qui repr\xE9sente un personnage, le deuxi\xE8me argument un rayon. Cela s\xE9lectionne tous les tokens \xE0 une distance de moins que le rayon du premier argument (ou du personnage \xE0 l'origine de l'effet, si le premier argument est absent). Si un troisi\xE8me argument est donn\xE9, il est interpr\xE9t\xE9 comme la port\xE9e maximum entre le centre du disque et le token du personnage \xE0 l'origine de l'effet. Si le premier argument repr\xE9sente un personnage avec un max de PV \xE0 0, il est compris comme un personnage fictif cr\xE9\xE9 juste pour d\xE9finir le disque, et il sera supprim\xE9 apr\xE8s la s\xE9lection. \xC0 noter que le script cr\xE9e par d\xE9faut un tel personnage, utilisable par tous, et appel\xE9 Cible.
    • option --disquePasseMur : comme --disque, mais l'effet traverse les murs.
    • -
    • option --enVue : sélectionne tous les tokens en vue du personnage qui lance l'effet. Accepte aussi un argument d'id de token, dans ce cas on garde les token en vue de celui avec cette id.
    • -
    • option --saufAllies permet d'exclure les alliés de la sélection (voir plus haut pour la définition des alliés).
    • +
    • option --enVue : s\xE9lectionne tous les tokens en vue du personnage qui lance l'effet. Accepte aussi un argument d'id de token, dans ce cas on garde les token en vue de celui avec cette id.
    • +
    • option --saufAllies permet d'exclure les alli\xE9s de la s\xE9lection (voir plus haut pour la d\xE9finition des alli\xE9s).

    -
    Exemple d'handout avec différentes équipes.
    +
    Exemple d'handout avec diff\xE9rentes \xE9quipes.

    1.5 Options de mana

    -

    COF sous ses différentes formes est une boîte à outils et nombreuses sont les variantes de système de magie qui peuvent être utilisées. Le script propose un support pour les plus populaires d'entre elles. Voici quelques consignes pour les implémenter.

    -

    Spécifier un coût en mana

    +

    COF sous ses diff\xE9rentes formes est une bo\xEEte \xE0 outils et nombreuses sont les variantes de syst\xE8me de magie qui peuvent \xEAtre utilis\xE9es. Le script propose un support pour les plus populaires d'entre elles. Voici quelques consignes pour les impl\xE9menter.

    +

    Sp\xE9cifier un co\xFBt en mana

      -
    • Les points de mana sont dépensés en ajoutant l'option --mana X à une action ou dans les options d'une attaque. Toutes les capacités implémentées dans la documentation donnent par défaut le coût en mana selon les règles de base.
    • -
    • Même un sort qui ne coûte pas de mana devrait utiliser --mana 0. Cela permet au script de dissiper automatiquement un effet généré par un lanceur de sort mis hors de combat.
    • -
    • Une option d'affichage disponible via !cof-options permet de demander au script d'afficher explicitement dans le chat toute dépense de PM effectuée par un personnage.
    • +
    • Les points de mana sont d\xE9pens\xE9s en ajoutant l'option --mana X \xE0 une action ou dans les options d'une attaque. Toutes les capacit\xE9s impl\xE9ment\xE9es dans la documentation donnent par d\xE9faut le co\xFBt en mana selon les r\xE8gles de base.
    • +
    • M\xEAme un sort qui ne co\xFBte pas de mana devrait utiliser --mana 0. Cela permet au script de dissiper automatiquement un effet g\xE9n\xE9r\xE9 par un lanceur de sort mis hors de combat.
    • +
    • Une option d'affichage disponible via !cof-options permet de demander au script d'afficher explicitement dans le chat toute d\xE9pense de PM effectu\xE9e par un personnage.
    -

    Système de base (COF p. 79)

    -

    Le support des effets supplémentaires à disposition du lanceur de sort sont gérées via l'utilisation d'options sur les commandes utilisées.

    +

    Syst\xE8me de base (COF p. 79)

    +

    Le support des effets suppl\xE9mentaires \xE0 disposition du lanceur de sort sont g\xE9r\xE9es via l'utilisation d'options sur les commandes utilis\xE9es.

    • Magie rapide : pas de support particulier
    • -
    • Magie puissante (dés) : utiliser l'option --puissant dans vos abilities ou attaques
    • -
    • Magie puissante (portée) : utiliser l'option --puissant portee dans vos abilities ou attaques
    • -
    • Magie puissante (durée) : utiliser l'option --puissant duree dans vos abilities ou attaques
    • +
    • Magie puissante (d\xE9s) : utiliser l'option --puissant dans vos abilities ou attaques
    • +
    • Magie puissante (port\xE9e) : utiliser l'option --puissant portee dans vos abilities ou attaques
    • +
    • Magie puissante (dur\xE9e) : utiliser l'option --puissant duree dans vos abilities ou attaques
    -

    On peut facilement combiner ces options avec un input de choix roll20 qui permettra au joueur de choisir le type d'incantation lorsqu'il lance le sort, tout en spécifiant la dépense de Mana.

    -

    --mana X ?{Incantation ?|Rapide,&#32;|Puissante (L),--puissant|Portée étendue (L),--puissant portee|Durée étendue (L),--puissant duree}

    +

    On peut facilement combiner ces options avec un input de choix roll20 qui permettra au joueur de choisir le type d'incantation lorsqu'il lance le sort, tout en sp\xE9cifiant la d\xE9pense de Mana.

    +

    --mana X ?{Incantation ?|Rapide,&#32;|Puissante (L),--puissant|Port\xE9e \xE9tendue (L),--puissant portee|Dur\xE9e \xE9tendue (L),--puissant duree}

    Mana Totale (COF p. 180)

    -

    La première chose à faire est d'activer l'option Mana totale via !cof-options. Pour le reste, vous pouvez réutiliser le principe du système de base ci-dessus.

    -
    Coût aléatoire
    -

    Vous pouvez utiliser des lancers de dés dans vos options --mana. Par exemple pour un sort de rang 1, on peut renseigner --mana [[1d3]]. L'option d'affichage de la dépense de mana prend ici tout son sens, activable via !cof-options.

    +

    La premi\xE8re chose \xE0 faire est d'activer l'option Mana totale via !cof-options. Pour le reste, vous pouvez r\xE9utiliser le principe du syst\xE8me de base ci-dessus.

    +
    Co\xFBt al\xE9atoire
    +

    Vous pouvez utiliser des lancers de d\xE9s dans vos options --mana. Par exemple pour un sort de rang 1, on peut renseigner --mana [[1d3]]. L'option d'affichage de la d\xE9pense de mana prend ici tout son sens, activable via !cof-options.

    Contrecoup
    -

    Vous pouvez activer la règle spécifique de Contrecoup via !cof-options.

    -

    Tempête de Mana (COF Compagnon p. 105)

    -

    Le script implémente un support complet des règles de Tempête de Mana. Pour ce faire, il faut ajouter les options --tempeteDeMana --rang X sur les sorts combinables avec Tempête de Mana. L'option rang permet d'indiquer le rang du sort afin que le script puisse calculer le maximum de PM qu'on peut dépenser lors du lancement du sort. Pour mettre ça de manière générique sur une action ou une attaque et permettre au joueur de choisir de faire appel à Tempête de Mana ou pas, on peut utiliser :

    -

    --mana X --rang Y ?{Tempête de Mana ?|Non,&#32;|Oui,--tempeteDeMana}

    -

    Tempête de Mana est compatible avec Mana Totale et Brûlure de Magie.

    +

    Vous pouvez activer la r\xE8gle sp\xE9cifique de Contrecoup via !cof-options.

    +

    Temp\xEAte de Mana (COF Compagnon p. 105)

    +

    Le script impl\xE9mente un support complet des r\xE8gles de Temp\xEAte de Mana. Pour ce faire, il faut ajouter les options --tempeteDeMana --rang X sur les sorts combinables avec Temp\xEAte de Mana. L'option rang permet d'indiquer le rang du sort afin que le script puisse calculer le maximum de PM qu'on peut d\xE9penser lors du lancement du sort. Pour mettre \xE7a de mani\xE8re g\xE9n\xE9rique sur une action ou une attaque et permettre au joueur de choisir de faire appel \xE0 Temp\xEAte de Mana ou pas, on peut utiliser :

    +

    --mana X --rang Y ?{Temp\xEAte de Mana ?|Non,&#32;|Oui,--tempeteDeMana}

    +

    Temp\xEAte de Mana est compatible avec Mana Totale et Br\xFBlure de Magie.

    Option altruiste
    -

    Si vous désirez jouer avec l'option de Magie altruiste, il suffit de changer l'option en --tempeteDeMana altruiste sur les sorts où c'est utile.

    +

    Si vous d\xE9sirez jouer avec l'option de Magie altruiste, il suffit de changer l'option en --tempeteDeMana altruiste sur les sorts o\xF9 c'est utile.

    Terres d'Arran (COTA p. 112)

    -

    Première chose à faire, activer l'option Brûlure de Magie via !cof-options. Note : si vous utilisez l'option de Brûlure de Magie avec l'option Mana Totale, vous pouvez utiliser un prédicat coefPVMana qui va diviser le nombre de PVs dépensé par point de mana.

    -

    Vous pouvez ensuite réutiliser le même principe que le système de base en combinant dépense de Mana et effets supplémentaires. Voici un exemple pour une Boule de Feu (Voie de l'élémentaliste, rang 4) :

    -

    --mana 2 ?{Incantation ?|Normale,--mana 2|Économe (L),&#32;|Puissante (L),--mana 2 --puissant|Portée étendue (L),--mana 2 --puissant portee} (notez que les coût total pour une incantation normale sera de 4 points de mana)

    +

    Premi\xE8re chose \xE0 faire, activer l'option Br\xFBlure de Magie via !cof-options. Note : si vous utilisez l'option de Br\xFBlure de Magie avec l'option Mana Totale, vous pouvez utiliser un pr\xE9dicat coefPVMana qui va diviser le nombre de PVs d\xE9pens\xE9 par point de mana.

    +

    Vous pouvez ensuite r\xE9utiliser le m\xEAme principe que le syst\xE8me de base en combinant d\xE9pense de Mana et effets suppl\xE9mentaires. Voici un exemple pour une Boule de Feu (Voie de l'\xE9l\xE9mentaliste, rang 4) :

    +

    --mana 2 ?{Incantation ?|Normale,--mana 2|\xC9conome (L),&#32;|Puissante (L),--mana 2 --puissant|Port\xE9e \xE9tendue (L),--mana 2 --puissant portee} (notez que les co\xFBt total pour une incantation normale sera de 4 points de mana)

    -

    1.6 Règles optionnelles utilisées

    +

    1.6 R\xE8gles optionnelles utilis\xE9es

    -

    Le script supporte l'utilisation de la règle des points de chance et des points de récupération.

    -

    J'ai aussi choisi, comme proposé par Kegron, de diminuer la DEF de tous les protagonistes après un certain nombre de tours de combat (-2 tous les 5 tours, peut être désactivé pendant un combat par la commande !cof-usure-off, ou bien dans les options de jeu).

    -

    Le script utilise aussi par défaut une règle de blessure grave : chaque fois qu'un personnage tombe à 0 PV, il encaisse une perte d'un point de récupération. S'il était à 0 points de récupération, il devient gravement blessé, ce qui le rend affaibli. Si le personnage était déjà gravement blessé, il meurt. Pour récupérer d'une blessure grave, le personnage doit se reposer une nuit, et réussir un test de CON difficulté 8 (avec le d12). Il est impossible de régénérer les points de récupération quand on est gravement blessé.

    -

    Le script utilise également une règle de dommages importants : chaque fois qu'un PJ reçoit plus de dommages en une fois que la somme de sa valeur de constitution et de son niveau, il perd 1PR et la règle de blessure grave s'applique. S'il était déjà blessé mais qu'il lui reste des PV, il tombe inconscient. Les deux règles sont désactivables séparément via !cof-options, dans la section dommages.

    -

    Le script propose également quelques autres options qui sont activables et/ou modifiables via la commande !cof-options. Quelques exemples :

    +

    Le script supporte l'utilisation de la r\xE8gle des points de chance et des points de r\xE9cup\xE9ration.

    +

    J'ai aussi choisi, comme propos\xE9 par Kegron, de diminuer la DEF de tous les protagonistes apr\xE8s un certain nombre de tours de combat (-2 tous les 5 tours, peut \xEAtre d\xE9sactiv\xE9 pendant un combat par la commande !cof-usure-off, ou bien dans les options de jeu).

    +

    Le script utilise aussi par d\xE9faut une r\xE8gle de blessure grave : chaque fois qu'un personnage tombe \xE0 0 PV, il encaisse une perte d'un point de r\xE9cup\xE9ration. S'il \xE9tait \xE0 0 points de r\xE9cup\xE9ration, il devient gravement bless\xE9, ce qui le rend affaibli. Si le personnage \xE9tait d\xE9j\xE0 gravement bless\xE9, il meurt. Pour r\xE9cup\xE9rer d'une blessure grave, le personnage doit se reposer une nuit, et r\xE9ussir un test de CON difficult\xE9 8 (avec le d12). Il est impossible de r\xE9g\xE9n\xE9rer les points de r\xE9cup\xE9ration quand on est gravement bless\xE9.

    +

    Le script utilise \xE9galement une r\xE8gle de dommages importants : chaque fois qu'un PJ re\xE7oit plus de dommages en une fois que la somme de sa valeur de constitution et de son niveau, il perd 1PR et la r\xE8gle de blessure grave s'applique. S'il \xE9tait d\xE9j\xE0 bless\xE9 mais qu'il lui reste des PV, il tombe inconscient. Les deux r\xE8gles sont d\xE9sactivables s\xE9par\xE9ment via !cof-options, dans la section dommages.

    +

    Le script propose \xE9galement quelques autres options qui sont activables et/ou modifiables via la commande !cof-options. Quelques exemples :

    • Initiative variable (individuelle / de groupe)
    • -
    • Versions alternatives de capacités (interchangeable, forme d'arbre, rune de protection)
    • -
    • Critiques étendus
    • +
    • Versions alternatives de capacit\xE9s (interchangeable, forme d'arbre, rune de protection)
    • +
    • Critiques \xE9tendus
    • Dommages minimums
    • Attaques de groupe

    2. Actions principales

    -

    Pour la plupart des actions ci-dessous, il est généralement utile de créer des macros facilitant leur utilisation. Pour mettre en place un jeu de macros par défaut, vous pouvez taper !cof-set-macros dans le chat. Si vous souhaitez redéfinir des macros existantes, vous pouvez taper !cof-set-macros --force.

    +

    Pour la plupart des actions ci-dessous, il est g\xE9n\xE9ralement utile de cr\xE9er des macros facilitant leur utilisation. Pour mettre en place un jeu de macros par d\xE9faut, vous pouvez taper !cof-set-macros dans le chat. Si vous souhaitez red\xE9finir des macros existantes, vous pouvez taper !cof-set-macros --force.

    2.1 Le combat

    Initiative : !cof-init

    -

    Les tokens sélectionnés sont ajouté au tracker de tour. Si celui-ci n'existe pas, un nouveau est créé, avec compteur de tour à 1, et on rentre en combat. Les tokens ayant un prédicat aucuneActionCombat ne sont jamais ajoutés au turn tracker.

    -

    Une option du script (ajustable en utilisant !cof-options) permet d'utiliser la règle de l'initiative variable (ajout d'un d6 explosif à l'initiative). Il est alors possible de faire lancer les dés d'initiative par les joueurs.

    -

    Les règles de tri suivent ce qui est donné p 70 : priorité aux PJs. Pour l'instant, on distingue un PJ d'un PNJ au dé de vie : si le personnage d'a pas de dé de vie, c'est un PNJ. Ensuite, entre PJs, priorité à la plus haute sagesse. Pour les PNJ, c'est aléatoire.

    -

    À chaque instant, le token dont c'est le tour d'agir est signalé par une aura qui bouge lentement. L'image de cette aura peut être modifiée dans les options (!cof-options images), et il est possible de spécifier une aura pour chaque token, en ajoutant une ligne dans le champ GM Notes du token (en bas de la partie basique de l'édition du token). Cette ligne doit commencer par init_aura:, et contenir une url valide pour un token. N'oubliez pas de sauvegarder le token comme token par défaut our un personnage si vous voulez que ce personnage ait toujours cette aura.

    +

    Les tokens s\xE9lectionn\xE9s sont ajout\xE9 au tracker de tour. Si celui-ci n'existe pas, un nouveau est cr\xE9\xE9, avec compteur de tour \xE0 1, et on rentre en combat. Les tokens ayant un pr\xE9dicat aucuneActionCombat ne sont jamais ajout\xE9s au turn tracker.

    +

    Une option du script (ajustable en utilisant !cof-options) permet d'utiliser la r\xE8gle de l'initiative variable (ajout d'un d6 explosif \xE0 l'initiative). Il est alors possible de faire lancer les d\xE9s d'initiative par les joueurs.

    +

    Les r\xE8gles de tri suivent ce qui est donn\xE9 p 70 : priorit\xE9 aux PJs. Pour l'instant, on distingue un PJ d'un PNJ au d\xE9 de vie : si le personnage d'a pas de d\xE9 de vie, c'est un PNJ. Ensuite, entre PJs, priorit\xE9 \xE0 la plus haute sagesse. Pour les PNJ, c'est al\xE9atoire.

    +

    \xC0 chaque instant, le token dont c'est le tour d'agir est signal\xE9 par une aura qui bouge lentement. L'image de cette aura peut \xEAtre modifi\xE9e dans les options (!cof-options images), et il est possible de sp\xE9cifier une aura pour chaque token, en ajoutant une ligne dans le champ GM Notes du token (en bas de la partie basique de l'\xE9dition du token). Cette ligne doit commencer par init_aura:, et contenir une url valide pour un token. N'oubliez pas de sauvegarder le token comme token par d\xE9faut our un personnage si vous voulez que ce personnage ait toujours cette aura.

    Il est possible de laisser les joueurs passer leur tour, en utilisant la commande !cof-tour-suivant. Une utilisation possible est de le mettre en macro dans les actions du tour (voir Actions du tour ci-dessous).

    Astuces :
      -
    • !cof-attendre ?{Nouvelle initiative} : Permet d'attendre avant d'agir en réduisant temporairement son initiative.

    • -
    • Il est possible de se passer de l'aura qui bouge, et d'utiliser à la place une icône de drapeau ou avec la syntaxe - !cof-init --aura une aura autour du Token de couleur verte (ou rouge si le personnage n'est pas contrôlé par un joueur ou dans une équipe contenant un personnage contrôlé par un joueur). Pour cela, désactiver l'initiative dynamique dans les options d'affichage (!cof-options affichage). +
    • !cof-attendre ?{Nouvelle initiative} : Permet d'attendre avant d'agir en r\xE9duisant temporairement son initiative.

    • +
    • Il est possible de se passer de l'aura qui bouge, et d'utiliser \xE0 la place une ic\xF4ne de drapeau ou avec la syntaxe + !cof-init --aura une aura autour du Token de couleur verte (ou rouge si le personnage n'est pas contr\xF4l\xE9 par un joueur ou dans une \xE9quipe contenant un personnage contr\xF4l\xE9 par un joueur). Pour cela, d\xE9sactiver l'initiative dynamique dans les options d'affichage (!cof-options affichage).
    @@ -265,349 +266,349 @@
    Astuces :

    Liste d'actions pour le personnage dont c'est le tour

    -

    Le script affiche, pour le personnage dont c'est le tour, une liste d'actions. Cette liste est chuchotée au joueur qui contrôle le personnage, ou si aucun joueur le contrôlant n'est connecté, au MJ. Elle se compose par défaut des attaques du personnage et des actions d'attendre, se défendre et faire une manoeuvre. - Pour voir ce message en dehors du changement d'initiative, ou pour le MJ, on peut utiliser !cof-liste-actions en sélectionnant le token (un bon candidat pour une macro de type token action, d'ailleurs généré par la commande !cof-set-macros). - Pour contrôler ce qui est affiché dans cette liste, vous pouvez principalement utiliser la liste des attaques du personnage et surtout la partie script de la fiche.

    -
    Les attaques affichées
    -

    Il est possible de ne pas afficher une attaque en décochant la case sous le dé dans les options d'attaque. Les attaques sont affichées dans l'ordre des labels d'attaques. les attaques avec des conditions impossibles (du genre limite par jour épuisée, etc.) ne sont pas affichées.

    -

    À cela se rajoute éventuellement l'attaque avec l'arme en main. À côté de cette attaque, le script propose un bouton pour rengainer l'arme ou en dégainer une autre (parmis les armes de la fiche cochées). On peut modifier cette liste des armes à dégainer en utilisant des prédicats actionDegainern, de valeur le label de l'arme à afficher en position n dans la liste (seulement pour les premières armes, il n'est pas possible de ne spécifier que la 2nde arme ou la 1ère et le 3ème). On peut ainsi faire afficher 2 armes à dégainer en même temps en séparant les labels d'un - (par exemple pour faire dégainer l'arme 1 en main droite et l'arme 4 en main gauche, en première position dans la liste, on écrira actionDegainer1:1-4). À noter que si aucune arme n'est en main, et qu'aucune attaque naturelle n'est cochée, le script va tout de même afficher une des attaques naturelles non cochées à la place de l'arme en main. Cela permet d'avoir une attaque que l'on n'affiche que quand on n'a pas d'arme en main.

    -

    Notez qu'il est possible d'avoir une arme par défaut en main, en ajoutant un prédicat armeParDefaut, de valeur le label de l'attaque correspondante. C'est parfois bien pratique pour ne pas avoir à dégainer les armes de chacun des orques en embuscade, par exemple.

    -
    Choisir les actions à afficher
    -

    Pour changer les attaques affichées par défaut, rajouter des actions à la liste d'actions du tour, ou utiliser de nouvelles listes, il faut aller dans l'onglet Script de la fiche de personnage.

    +

    Le script affiche, pour le personnage dont c'est le tour, une liste d'actions. Cette liste est chuchot\xE9e au joueur qui contr\xF4le le personnage, ou si aucun joueur le contr\xF4lant n'est connect\xE9, au MJ. Elle se compose par d\xE9faut des attaques du personnage et des actions d'attendre, se d\xE9fendre et faire une manoeuvre. + Pour voir ce message en dehors du changement d'initiative, ou pour le MJ, on peut utiliser !cof-liste-actions en s\xE9lectionnant le token (un bon candidat pour une macro de type token action, d'ailleurs g\xE9n\xE9r\xE9 par la commande !cof-set-macros). + Pour contr\xF4ler ce qui est affich\xE9 dans cette liste, vous pouvez principalement utiliser la liste des attaques du personnage et surtout la partie script de la fiche.

    +
    Les attaques affich\xE9es
    +

    Il est possible de ne pas afficher une attaque en d\xE9cochant la case sous le d\xE9 dans les options d'attaque. Les attaques sont affich\xE9es dans l'ordre des labels d'attaques. les attaques avec des conditions impossibles (du genre limite par jour \xE9puis\xE9e, etc.) ne sont pas affich\xE9es.

    +

    \xC0 cela se rajoute \xE9ventuellement l'attaque avec l'arme en main. \xC0 c\xF4t\xE9 de cette attaque, le script propose un bouton pour rengainer l'arme ou en d\xE9gainer une autre (parmis les armes de la fiche coch\xE9es). On peut modifier cette liste des armes \xE0 d\xE9gainer en utilisant des pr\xE9dicats actionDegainern, de valeur le label de l'arme \xE0 afficher en position n dans la liste (seulement pour les premi\xE8res armes, il n'est pas possible de ne sp\xE9cifier que la 2nde arme ou la 1\xE8re et le 3\xE8me). On peut ainsi faire afficher 2 armes \xE0 d\xE9gainer en m\xEAme temps en s\xE9parant les labels d'un - (par exemple pour faire d\xE9gainer l'arme 1 en main droite et l'arme 4 en main gauche, en premi\xE8re position dans la liste, on \xE9crira actionDegainer1:1-4). \xC0 noter que si aucune arme n'est en main, et qu'aucune attaque naturelle n'est coch\xE9e, le script va tout de m\xEAme afficher une des attaques naturelles non coch\xE9es \xE0 la place de l'arme en main. Cela permet d'avoir une attaque que l'on n'affiche que quand on n'a pas d'arme en main.

    +

    Notez qu'il est possible d'avoir une arme par d\xE9faut en main, en ajoutant un pr\xE9dicat armeParDefaut, de valeur le label de l'attaque correspondante. C'est parfois bien pratique pour ne pas avoir \xE0 d\xE9gainer les armes de chacun des orques en embuscade, par exemple.

    +
    Choisir les actions \xE0 afficher
    +

    Pour changer les attaques affich\xE9es par d\xE9faut, rajouter des actions \xE0 la liste d'actions du tour, ou utiliser de nouvelles listes, il faut aller dans l'onglet Script de la fiche de personnage.

    Exemple d'une liste d'actions pour un magicien
    -

    Pour rajouter des actions à montrer, il faut ajouter des lignes en-dessous de Montrer l'arme en main et dégainer. La case cochée devant chaque action peut être décochée pour ne pas afficher l'action. Les actions seront affichée dans l'ordre des numéros d'action. Attention, si deux actions ont le même numéro, une des deux ne sera pas affichée. Le titre de l'action peut soit être directement une commande (commençant par %, # ou !), et dans ce cas l'action affichée sera déterminée par le script, soit du texte qui sera affiché tel quel. Dans ce cas, il sera souvent nécessaire de préciser le code de l'action : cliquer sur la roue au bout à droite de la ligne de l'action pour faire apparaître les lignes de condition et de code. La ligne de conditions n'est pas encore utilisée par le script.

    -

    Il existe un certain nombre de commandes spéciales, qui peuvent être rentrée dans le titre ou le code : +

    Pour rajouter des actions \xE0 montrer, il faut ajouter des lignes en-dessous de Montrer l'arme en main et d\xE9gainer. La case coch\xE9e devant chaque action peut \xEAtre d\xE9coch\xE9e pour ne pas afficher l'action. Les actions seront affich\xE9e dans l'ordre des num\xE9ros d'action. Attention, si deux actions ont le m\xEAme num\xE9ro, une des deux ne sera pas affich\xE9e. Le titre de l'action peut soit \xEAtre directement une commande (commen\xE7ant par %, # ou !), et dans ce cas l'action affich\xE9e sera d\xE9termin\xE9e par le script, soit du texte qui sera affich\xE9 tel quel. Dans ce cas, il sera souvent n\xE9cessaire de pr\xE9ciser le code de l'action : cliquer sur la roue au bout \xE0 droite de la ligne de l'action pour faire appara\xEEtre les lignes de condition et de code. La ligne de conditions n'est pas encore utilis\xE9e par le script.

    +

    Il existe un certain nombre de commandes sp\xE9ciales, qui peuvent \xEAtre rentr\xE9e dans le titre ou le code :

      -
    • !attaques fera afficher toutes les attaques cochées de la fiche
    • -
    • !arme-en-main affichera l'attaque correspondant à l'arme en main, ou si aucune arme n'est en main, une attaque naturelle non cochée, et si il n'y en a pas non plus, une attaque à mains nues. Vous pouvez faire suivre cette commandes d'options d'attaque, comme --m2d20.
    • -
    • !options passera en option à toutes les actions suivantes tout ce que vous écrirez dans la même ligne (par exemple !options --traquenard passe l'option --traquenard à toutes les actions suivantes).
    • +
    • !attaques fera afficher toutes les attaques coch\xE9es de la fiche
    • +
    • !arme-en-main affichera l'attaque correspondant \xE0 l'arme en main, ou si aucune arme n'est en main, une attaque naturelle non coch\xE9e, et si il n'y en a pas non plus, une attaque \xE0 mains nues. Vous pouvez faire suivre cette commandes d'options d'attaque, comme --m2d20.
    • +
    • !options passera en option \xE0 toutes les actions suivantes tout ce que vous \xE9crirez dans la m\xEAme ligne (par exemple !options --traquenard passe l'option --traquenard \xE0 toutes les actions suivantes).

    Autres listes d'action
    -

    Il est possible d'ouvrir d'autre listes d'actions, à partir des commandes ou même d'une liste d'actions. La fiche propose 4 emplacements pour ces listes d'action, mais si cela ne suffit pas, vous pouvez utiliser des abilities dont le nom commence et termine par #. Pour faire référence à une liste dans une action, inscrivez simplement le nom de la liste dans le titre de l'action et sélectionnez Liste d'actions dans le menu déroulant à côté. Les listes d'action sur la fiche fonctionnent de la même façon que la liste des actions du tour, sauf qu'il n'y a pas d'affichage par défaut des attaques ou de l'arme en main (pour cela, une simple ligne avec en titre #Attaque -1 permet d'y remédier), et que la liste peut avoir une liste d'options globales (cliquer sur la roue à droite du nom de la liste).

    -

    Pour les listes d'actions supplémentaires, dans les abilities, il faut respecter la syntaxe suivante : +

    Il est possible d'ouvrir d'autre listes d'actions, \xE0 partir des commandes ou m\xEAme d'une liste d'actions. La fiche propose 4 emplacements pour ces listes d'action, mais si cela ne suffit pas, vous pouvez utiliser des abilities dont le nom commence et termine par #. Pour faire r\xE9f\xE9rence \xE0 une liste dans une action, inscrivez simplement le nom de la liste dans le titre de l'action et s\xE9lectionnez Liste d'actions dans le menu d\xE9roulant \xE0 c\xF4t\xE9. Les listes d'action sur la fiche fonctionnent de la m\xEAme fa\xE7on que la liste des actions du tour, sauf qu'il n'y a pas d'affichage par d\xE9faut des attaques ou de l'arme en main (pour cela, une simple ligne avec en titre #Attaque -1 permet d'y rem\xE9dier), et que la liste peut avoir une liste d'options globales (cliquer sur la roue \xE0 droite du nom de la liste).

    +

    Pour les listes d'actions suppl\xE9mentaires, dans les abilities, il faut respecter la syntaxe suivante :

    • une action par ligne
    • chaque ligne est donc soit un commentaire, soit une macro (qui commence par #), soit une ability (qui commence par %), soit une commande qui commence par !
    • -
    • l'action affichée sera le nom de la macro ou de l'ability (sauf pour les attaques, pour lesquelles le nom de l'arme sera affichée)
    • +
    • l'action affich\xE9e sera le nom de la macro ou de l'ability (sauf pour les attaques, pour lesquelles le nom de l'arme sera affich\xE9e)
    • les commandes disponibles sont !options et !attaques.
    • -
    • pour les listes d'actions, il suffit de mettre %# suivi du nom de la liste et terminé par #.
    • +
    • pour les listes d'actions, il suffit de mettre %# suivi du nom de la liste et termin\xE9 par #.
    -

    Il est aussi possible de faire afficher une liste quelconque avec une commande, avec !cof-liste-actions nom (où le nom est celui de la liste, ou bien de l'ability sans les #). Par exemple, si on ne souhaite pas afficher la liste complète des sorts d'un personnage à son tour, on peut faire une liste Sorts, puis faire une macro qui lance !cof-liste-actions Sorts pour que le joueur puisse afficher la liste quand il le souhaite.

    +

    Il est aussi possible de faire afficher une liste quelconque avec une commande, avec !cof-liste-actions nom (o\xF9 le nom est celui de la liste, ou bien de l'ability sans les #). Par exemple, si on ne souhaite pas afficher la liste compl\xE8te des sorts d'un personnage \xE0 son tour, on peut faire une liste Sorts, puis faire une macro qui lance !cof-liste-actions Sorts pour que le joueur puisse afficher la liste quand il le souhaite.

    Attaquer une (ou plusieurs) cible : !cof-attack @{selected|token_id} @{target|token_id} n

    -

    n est un argument optionnel qui peut soit correspondre au label de l'attaque sur la fiche du personnage (ce label est automatiquement généré par la fiche et affiché juste devant le nom), soit être le nom de l'attaque. Si cet argument est -1, le script cherchera si le personnage a une arme en main et utilisera cette arme. Si c'est -2, il va chercher l'arme en main gauche. Si cet argument est absent ou qu'il ne correspond pas à un label de la fiche du personnage, l'attaque aura les valeurs par défaut d'une attaque au contact infligeant 1d4 DM. Pour plus de facilité, vous pouvez utiliser la macro Attaque qui fait !cof-attack @{selected|token_id} @{target|token_id}

    +

    o\xF9 n est un argument optionnel qui peut soit correspondre au label de l'attaque sur la fiche du personnage (ce label est automatiquement g\xE9n\xE9r\xE9 par la fiche et affich\xE9 juste devant le nom), soit \xEAtre le nom de l'attaque. Si cet argument est -1, le script cherchera si le personnage a une arme en main et utilisera cette arme. Si c'est -2, il va chercher l'arme en main gauche. Si cet argument est absent ou qu'il ne correspond pas \xE0 un label de la fiche du personnage, l'attaque aura les valeurs par d\xE9faut d'une attaque au contact infligeant 1d4 DM. Pour plus de facilit\xE9, vous pouvez utiliser la macro Attaque qui fait !cof-attack @{selected|token_id} @{target|token_id}

    -

    L'attaque tient alors compte de toutes les informations de l'attaque, y compris chances de critique, portée, type d'attaque, type de dégâs et autres options spécifiées sur la fiche. Par défaut, l'attaque montre le label, le nom de l'attaque, le calcul du bonus d'attaque, le calcul des dégâts, la portée et un champ SPÉCIAL (ou encore appelé divers). En cliquant sur la roue au bout à droite de cette ligne, on affiche une deuxième ligne, avec un case à décocher pour ne pas faire apparaître l'attaque à chaque tour, un choix de type d'attaque, des modificateurs, un choix de type de degâts et un champ d'options. Les modificateurs sont constitués d'options sans argument, séparée par une espace. Les options sont reprises telles quels comme un argument à l'attaque (voir plus bas pour le liste de ces options). Attention, pour l'instant ne traite correctment les jets (parties entre crochets) et les demandes au joueur (de type ?{question?}) que si on passe par une liste d'actions (donc pas directement en faisant #Attaque 1 dans le chat). Une troisième ligne peut aussi s'afficher, pour gérer le nombre d'armes de jet, ou pour les armes portées, pour indiquer des prédicats actifs seulement quand on porte l'arme. Il est possible de spécifier une arme batarde (pouvant se porter à une ou deux mains) en renseignant un prédicat batarde de valeur le dé de DM à utiliser quand on porte l'arme à deux mains.

    +

    L'attaque tient alors compte de toutes les informations de l'attaque, y compris chances de critique, port\xE9e, type d'attaque, type de d\xE9g\xE2s et autres options sp\xE9cifi\xE9es sur la fiche. Par d\xE9faut, l'attaque montre le label, le nom de l'attaque, le calcul du bonus d'attaque, le calcul des d\xE9g\xE2ts, la port\xE9e et un champ SP\xC9CIAL (ou encore appel\xE9 divers). En cliquant sur la roue au bout \xE0 droite de cette ligne, on affiche une deuxi\xE8me ligne, avec un case \xE0 d\xE9cocher pour ne pas faire appara\xEEtre l'attaque \xE0 chaque tour, un choix de type d'attaque, des modificateurs, un choix de type de deg\xE2ts et un champ d'options. Les modificateurs sont constitu\xE9s d'options sans argument, s\xE9par\xE9e par une espace. Les options sont reprises telles quels comme un argument \xE0 l'attaque (voir plus bas pour le liste de ces options). Attention, pour l'instant ne traite correctment les jets (parties entre crochets) et les demandes au joueur (de type ?{question?}) que si on passe par une liste d'actions (donc pas directement en faisant #Attaque 1 dans le chat). Une troisi\xE8me ligne peut aussi s'afficher, pour g\xE9rer le nombre d'armes de jet, ou pour les armes port\xE9es, pour indiquer des pr\xE9dicats actifs seulement quand on porte l'arme. Il est possible de sp\xE9cifier une arme batarde (pouvant se porter \xE0 une ou deux mains) en renseignant un pr\xE9dicat batarde de valeur le d\xE9 de DM \xE0 utiliser quand on porte l'arme \xE0 deux mains.

    Exemple d'attaques.
    -

    En l'absence de label, on peut spécifier ces informations sous forme d'options d'attaque

    +

    En l'absence de label, on peut sp\xE9cifier ces informations sous forme d'options d'attaque

    -

    Malus ou bonus temporaire à une attaque : utiliser la barre 3.

    -

    Toutes les attaques ayant une portée non nulles sont considérées par le script comme des attaques à distance.

    -

    Le test d'attaque à distance tient compte de la portée (malus de -1 à -5 si distance entre portée et deux fois cette valeur), ainsi que des tokens sur le trajet de l'attaque. Une attaque de trop loin ne porte jamais.

    +

    Malus ou bonus temporaire \xE0 une attaque : utiliser la barre 3.

    +

    Toutes les attaques ayant une port\xE9e non nulles sont consid\xE9r\xE9es par le script comme des attaques \xE0 distance.

    +

    Le test d'attaque \xE0 distance tient compte de la port\xE9e (malus de -1 \xE0 -5 si distance entre port\xE9e et deux fois cette valeur), ainsi que des tokens sur le trajet de l'attaque. Une attaque de trop loin ne porte jamais.

    Utiliser une attaque fait rentrer l'attaquant en combat (et le rajoute au turn tracker).

    -

    Il existe une version spécialisée permettant de faire des dégâts dans un disque centré sur un token, !cof-explosion, dont le premier argument doit être le label d'une attaque.

    +

    Il existe une version sp\xE9cialis\xE9e permettant de faire des d\xE9g\xE2ts dans un disque centr\xE9 sur un token, !cof-explosion, dont le premier argument doit \xEAtre le label d'une attaque.

    Options pour l'attaque :

    - Toutes les options sans arguments peuvent être directement utilisées comme modificateurs dans le liste des modifcateurs d'une attaque. + Toutes les options sans arguments peuvent \xEAtre directement utilis\xE9es comme modificateurs dans le liste des modifcateurs d'une attaque.
      -
    • --nom txt : nom de l'attaque à afficher. Remplace le nom dans la ligne d'attaque si on a donné un label en argument. Le nom ne doit pas comporte de blanc usivi de 2 tirets ( --).
    • -
    • --toucher n : bonus de base de l'attaque. Remplace les valeurs dans la ligne d'attaque si on a donné un label en argument. Pour référence, sur les fiches de PJ, l'attaque au contact est [[@{selected|ATKCAC}]], l'attaque à distance [[@{selected|ATKTIR}]], et l'attaque magique [[@{selected|ATKMAG}]].
    • -
    • --crit n : valeur à partir de laquelle le jet de dé est un critique. Remplace les valeurs dans la ligne d'attaque si on a donné un label en argument.
    • -
    • --dm expr : Dégâts de base de l'attaque. Remplace les valeurs dans la ligne d'attaque si on a donné un label en argument. expr peut être un entier ou bien une expression du type adb+c. La partie constante de cette expression est optionnelle et peut être négative.
    • -
    • --portee n : la portée de l'attaque exprimée en mètres. Remplace les valeurs dans la ligne d'attaque si on a donné un label en argument.
    • -
    • --special txt : remplace le champ spécial de l'attaque sur la fiche.
    • -
    • --tempDmg : l'attaque fait des dégâts temporaires (tient compte de la force de l'adversaire, utilise la barre 2 pour les dmg temp, sauf si le token a des PM, auquel cas on utilisera un attribut temporaire).
    • +
    • --nom txt : nom de l'attaque \xE0 afficher. Remplace le nom dans la ligne d'attaque si on a donn\xE9 un label en argument. Le nom ne doit pas comporte de blanc usivi de 2 tirets ( --).
    • +
    • --toucher n : bonus de base de l'attaque. Remplace les valeurs dans la ligne d'attaque si on a donn\xE9 un label en argument. Pour r\xE9f\xE9rence, sur les fiches de PJ, l'attaque au contact est [[@{selected|ATKCAC}]], l'attaque \xE0 distance [[@{selected|ATKTIR}]], et l'attaque magique [[@{selected|ATKMAG}]].
    • +
    • --crit n : valeur \xE0 partir de laquelle le jet de d\xE9 est un critique. Remplace les valeurs dans la ligne d'attaque si on a donn\xE9 un label en argument.
    • +
    • --dm expr : D\xE9g\xE2ts de base de l'attaque. Remplace les valeurs dans la ligne d'attaque si on a donn\xE9 un label en argument. expr peut \xEAtre un entier ou bien une expression du type adb+c. La partie constante de cette expression est optionnelle et peut \xEAtre n\xE9gative.
    • +
    • --portee n : la port\xE9e de l'attaque exprim\xE9e en m\xE8tres. Remplace les valeurs dans la ligne d'attaque si on a donn\xE9 un label en argument.
    • +
    • --special txt : remplace le champ sp\xE9cial de l'attaque sur la fiche.
    • +
    • --tempDmg : l'attaque fait des d\xE9g\xE2ts temporaires (tient compte de la force de l'adversaire, utilise la barre 2 pour les dmg temp, sauf si le token a des PM, auquel cas on utilisera un attribut temporaire).
    • --pasDeDmg : l'attaque ne fait pas de DM.
    • -
    • --poudre : l'arme est une arme à poudre, utilisation d'un dé de poudre. Une arme est aussi considérée comme une arme à poudre si elle contient poudre dans le nom de l'arme ou dans le champ modifcateur ou de prédicats.
    • -
    • --epieu : l'arme est un épieu. À noter que l'arme est aussi considérée comme un épieu si elle contient épieu dans son nom ou epieu dans son champs modificateurs ou prédicats. Cette option augmente de 1 le nombre de dés contre un adversaire sans armure.
    • -
    • --hache : l'arme est une hache. À noter que l'arme est aussi considérée comme une hache si elle contient hache dans son nom ou dans son champs modificateurs ou prédicats. Cette option permet de passer la RD/hache (pour les sylvaniens, par exemple).
    • -
    • --marteau : l'arme est un marteau. À noter que l'arme est aussi considérée comme un marteau si elle contient marteau dans son nom ou dans son champs modificateurs ou prédicats.
    • -
    • --auto : l'attaque réussit automatiquement
    • +
    • --poudre : l'arme est une arme \xE0 poudre, utilisation d'un d\xE9 de poudre. Une arme est aussi consid\xE9r\xE9e comme une arme \xE0 poudre si elle contient poudre dans le nom de l'arme ou dans le champ modifcateur ou de pr\xE9dicats.
    • +
    • --epieu : l'arme est un \xE9pieu. \xC0 noter que l'arme est aussi consid\xE9r\xE9e comme un \xE9pieu si elle contient \xE9pieu dans son nom ou epieu dans son champs modificateurs ou pr\xE9dicats. Cette option augmente de 1 le nombre de d\xE9s contre un adversaire sans armure.
    • +
    • --hache : l'arme est une hache. \xC0 noter que l'arme est aussi consid\xE9r\xE9e comme une hache si elle contient hache dans son nom ou dans son champs modificateurs ou pr\xE9dicats. Cette option permet de passer la RD/hache (pour les sylvaniens, par exemple).
    • +
    • --marteau : l'arme est un marteau. \xC0 noter que l'arme est aussi consid\xE9r\xE9e comme un marteau si elle contient marteau dans son nom ou dans son champs modificateurs ou pr\xE9dicats.
    • +
    • --auto : l'attaque r\xE9ussit automatiquement
    • --bonusAttaque n : ajoute n au jet d'attaque
    • -
    • --bonusCritique n : augmente n à la plage de coups critiques
    • -
    • --modifiePortee n : ajoute n à la portée de l'attaque.
    • -
    • --divisePortee n : divise la portée de base par n. C'est appliqué avant toute modification de portée.
    • -
    • --bonusContreBouclier n : ajoute n au jet d'attaque si le défenseur porte un bouclier. Utile par exemple pour le fléau d'arme.
    • -
    • --bonusContreArmure n : ajoute n au jet d'attaque si le défenseur porte une armure.
    • -
    • --psave carac seuil : jet de carac, si le jet est supérieur à seuil, les dégâts sont divisés par 2. carac est l'abbréviation de caractéristiques de 3 lettres standard (FOR, DEX, ...). Il est possible de prendre la meilleure de 2 caractéristiques pour le save : pour cela indiquer les 2 caractéristiques collées (donc 6 caractères, par exemple FORDEX, pour le meilleur de FOR et de DEX). Le script choisira automatiquement la caractéristique qui donne les meilleures chances de réussite (en tenant compte de la difficulté et des caractéristiques supérieures).
    • Enfin on peut encore ajouter un ou des arguments optionnels. Si vous avez besoin de plus d'un argument optionnel, séparez-les par +: +
    • --bonusCritique n : augmente n \xE0 la plage de coups critiques
    • +
    • --modifiePortee n : ajoute n \xE0 la port\xE9e de l'attaque.
    • +
    • --divisePortee n : divise la port\xE9e de base par n. C'est appliqu\xE9 avant toute modification de port\xE9e.
    • +
    • --bonusContreBouclier n : ajoute n au jet d'attaque si le d\xE9fenseur porte un bouclier. Utile par exemple pour le fl\xE9au d'arme.
    • +
    • --bonusContreArmure n : ajoute n au jet d'attaque si le d\xE9fenseur porte une armure.
    • +
    • --psave carac seuil : jet de carac, si le jet est sup\xE9rieur \xE0 seuil, les d\xE9g\xE2ts sont divis\xE9s par 2. carac est l'abbr\xE9viation de caract\xE9ristiques de 3 lettres standard (FOR, DEX, ...). Il est possible de prendre la meilleure de 2 caract\xE9ristiques pour le save : pour cela indiquer les 2 caract\xE9ristiques coll\xE9es (donc 6 caract\xE8res, par exemple FORDEX, pour le meilleur de FOR et de DEX). Le script choisira automatiquement la caract\xE9ristique qui donne les meilleures chances de r\xE9ussite (en tenant compte de la difficult\xE9 et des caract\xE9ristiques sup\xE9rieures).
    • Enfin on peut encore ajouter un ou des arguments optionnels. Si vous avez besoin de plus d'un argument optionnel, s\xE9parez-les par +:
        -
      • Si on souhaite que le jet ne permette de réduire qu'une partie des dommages (la dernière ajoutée avec --plus), on peut ajouter local. La syntaxe complète est alors --psave carac seuil local.
      • -
      • Si on souhaite que la difficulté soit augmentée en cas de tempête de mana, on peut utiliser le mot clé tempete suivi si besoin de l'incrément en fonction de la mana (par defaut 1 mana augmente de 1 la difficulté).
      • -
      • Si on souhaite indiquer une difficulté alternative pour les cibles au contact, ajouter contact n, où n est la difficulté en question.
      • +
      • Si on souhaite que le jet ne permette de r\xE9duire qu'une partie des dommages (la derni\xE8re ajout\xE9e avec --plus), on peut ajouter local. La syntaxe compl\xE8te est alors --psave carac seuil local.
      • +
      • Si on souhaite que la difficult\xE9 soit augment\xE9e en cas de temp\xEAte de mana, on peut utiliser le mot cl\xE9 tempete suivi si besoin de l'incr\xE9ment en fonction de la mana (par defaut 1 mana augmente de 1 la difficult\xE9).
      • +
      • Si on souhaite indiquer une difficult\xE9 alternative pour les cibles au contact, ajouter contact n, o\xF9 n est la difficult\xE9 en question.
      -
    • --demiAuto : si l'attaque rate, on considère juste que les saves partiels sont automatiquemet réussi. Ça signifie en général que la cible prend au moins la moitié des dégâts.
    • -
    • --dmSiRate dmg : si l'attaque rate, la cible est quand même touchée et se voit infliger dmg dégâts.
    • -
    • --toucheDoubleDmg : si l'attaque rate, elle inflige les dégâts normaux, et si elle touche, elle double les dégâts de base. Pas cumulable avec dmSiRate ou demiAuto.
    • -
    • --save carac seuil : même effet que --psave, mais pour annuler le dernier --effet ou etat (aucun effet sur les DM). Si on rajoute un argument demiDuree au save, alors la réussite du save ne fait que diviser par 2 sa durée.
    • -
    • --saveDM carac seuil : même effet que --psave, mais pour annuler l'ensemble des dégâts.
    • -
    • --saveParTour carac seuil : même effet que --save, mais donne droit à un jet à la fin de chaque tour au lieu d'un jet au moment de l'attaque.
    • -
    • --saveActifParTour carac seuil : même effet que --save, mais affiche un bouton pour faire le save dans la liste d'actions à chaque tour. Utile si les joueurs préfèrent jeter "eux-mêmes" le dé, ou si le save est sensé arriver au tour du joueur.
    • -
    • --saveParJour carac seuil : même effet que --save, mais donne droit à un jet à la fin de chaque jour au lieu d'un jet au moment de l'attaque.
    • -
    • --fx effet : ajoute un effet qui part de l'attaquant à la cible. Si l'attaque rate, l'effet rate aussi, d'autant plus que le jet d'attaque est loin de la défense. Il est possible d'utiliser un effet que vous avez défini vous-même en utilisant l'option --fx custom nom, où nom est le nom de votre effet.
    • -
    • --targetFx effet : ajoute un effet au niveau de la cible (l'effet ne doit pas être directionnel). Comme avec --fx, on peut utiliser un effet qu'on a créé.
    • +
    • --demiAuto : si l'attaque rate, on consid\xE8re juste que les saves partiels sont automatiquemet r\xE9ussi. Ça signifie en g\xE9n\xE9ral que la cible prend au moins la moiti\xE9 des d\xE9g\xE2ts.
    • +
    • --dmSiRate dmg : si l'attaque rate, la cible est quand m\xEAme touch\xE9e et se voit infliger dmg d\xE9g\xE2ts.
    • +
    • --toucheDoubleDmg : si l'attaque rate, elle inflige les d\xE9g\xE2ts normaux, et si elle touche, elle double les d\xE9g\xE2ts de base. Pas cumulable avec dmSiRate ou demiAuto.
    • +
    • --save carac seuil : m\xEAme effet que --psave, mais pour annuler le dernier --effet ou etat (aucun effet sur les DM). Si on rajoute un argument demiDuree au save, alors la r\xE9ussite du save ne fait que diviser par 2 sa dur\xE9e.
    • +
    • --saveDM carac seuil : m\xEAme effet que --psave, mais pour annuler l'ensemble des d\xE9g\xE2ts.
    • +
    • --saveParTour carac seuil : m\xEAme effet que --save, mais donne droit \xE0 un jet \xE0 la fin de chaque tour au lieu d'un jet au moment de l'attaque.
    • +
    • --saveActifParTour carac seuil : m\xEAme effet que --save, mais affiche un bouton pour faire le save dans la liste d'actions \xE0 chaque tour. Utile si les joueurs pr\xE9f\xE8rent jeter "eux-m\xEAmes" le d\xE9, ou si le save est sens\xE9 arriver au tour du joueur.
    • +
    • --saveParJour carac seuil : m\xEAme effet que --save, mais donne droit \xE0 un jet \xE0 la fin de chaque jour au lieu d'un jet au moment de l'attaque.
    • +
    • --fx effet : ajoute un effet qui part de l'attaquant \xE0 la cible. Si l'attaque rate, l'effet rate aussi, d'autant plus que le jet d'attaque est loin de la d\xE9fense. Il est possible d'utiliser un effet que vous avez d\xE9fini vous-m\xEAme en utilisant l'option --fx custom nom, o\xF9 nom est le nom de votre effet.
    • +
    • --targetFx effet : ajoute un effet au niveau de la cible (l'effet ne doit pas \xEAtre directionnel). Comme avec --fx, on peut utiliser un effet qu'on a cr\xE9\xE9.
    • - --si condition : l'attaque n'est possible que si condition est validée. Une condition peut être + --si condition : l'attaque n'est possible que si condition est valid\xE9e. Une condition peut \xEAtre
      • moins attribut : vrai si l'attribut attribut de la cible est moins haute que celle de l'attaquant
      • -
      • etat e : vrai si l'état e est actif sur l'attaquant. Cet état peut être un des états définis plus bas, ou un attribut quelconque.
      • -
      • attribut attr val: vrai si l'attaquant possède un attribut attr, de valeur val, aux majuscules près. On peut optionnellement préciser qu'il s'agit d'un attribut par token en rajoutant le mot clé local, ou encore qu'il sagit d'un attribut de la fiche, avec éventuellement sa valeur par défaut, en ajoutant le mot clé fiche defaut.
      • -
      • etatCible e : vrai si l'état e est actif sur toutes la cible. Cet état peut être un des états définis plus bas, ou un attribut quelconque.
      • -
      • attributCible attr val: vrai si la cible possède un attribut attr, de valeur val, aux majuscules près. On peut optionnellement préciser qu'il s'agit d'un attribut par token en rajoutant le mot clé local, ou encore qu'il sagit d'un attribut de la fiche, avec éventuellement sa valeur par défaut, en ajoutant le mot clé fiche defaut.
      • -
      • predicatCible predicat: vrai si la cible possède un prédicat predicat. On peut aussi spécifier une valeur auquel le prédicat doit être égal.
      • -
      • typeCible type: vrai si la cible est du type spécifié. Les types reconnus sont animal, démon, dragon, fée, insecte, mauvais, mort-vivant, géant, gobelin, et si le type n'est pas reconnu, va chercher si la race ou un prédicat correspondant.
      • -
      • deAttaque n : vrai si le jet de dé d'attaque est supérieur ou égal à n.
      • +
      • etat e : vrai si l'\xE9tat e est actif sur l'attaquant. Cet \xE9tat peut \xEAtre un des \xE9tats d\xE9finis plus bas, ou un attribut quelconque.
      • +
      • attribut attr val: vrai si l'attaquant poss\xE8de un attribut attr, de valeur val, aux majuscules pr\xE8s. On peut optionnellement pr\xE9ciser qu'il s'agit d'un attribut par token en rajoutant le mot cl\xE9 local, ou encore qu'il sagit d'un attribut de la fiche, avec \xE9ventuellement sa valeur par d\xE9faut, en ajoutant le mot cl\xE9 fiche defaut.
      • +
      • etatCible e : vrai si l'\xE9tat e est actif sur toutes la cible. Cet \xE9tat peut \xEAtre un des \xE9tats d\xE9finis plus bas, ou un attribut quelconque.
      • +
      • attributCible attr val: vrai si la cible poss\xE8de un attribut attr, de valeur val, aux majuscules pr\xE8s. On peut optionnellement pr\xE9ciser qu'il s'agit d'un attribut par token en rajoutant le mot cl\xE9 local, ou encore qu'il sagit d'un attribut de la fiche, avec \xE9ventuellement sa valeur par d\xE9faut, en ajoutant le mot cl\xE9 fiche defaut.
      • +
      • predicatCible predicat: vrai si la cible poss\xE8de un pr\xE9dicat predicat. On peut aussi sp\xE9cifier une valeur auquel le pr\xE9dicat doit \xEAtre \xE9gal.
      • +
      • typeCible type: vrai si la cible est du type sp\xE9cifi\xE9. Les types reconnus sont animal, d\xE9mon, dragon, f\xE9e, insecte, mauvais, mort-vivant, g\xE9ant, gobelin, et si le type n'est pas reconnu, va chercher si la race ou un pr\xE9dicat correspondant.
      • +
      • deAttaque n : vrai si le jet de d\xE9 d'attaque est sup\xE9rieur ou \xE9gal \xE0 n.
      • touche : vrai si l'attaque touche.
      • critique : vrai si l'attaque est un critique.
      • -
      • echecCritique : vrai si l'attaque est un échec critique.
      • +
      • echecCritique : vrai si l'attaque est un \xE9chec critique.
    • -
    • --if condition options --endif: permet de ne prendre en compte des options que si certaines conditions sont réalisées. Il est possible d'utiliser un --else pour activer des options quand les conditions ne sont pas réalisées. Attention, les options qui modifient une option précédente (comme --valeur) doivent apparaître au même niveau que l'option qu'elles modifient. Comme les conditions peuvent dépendre du dé d'attaque, un certain nombre d'options ne sont pas affectées par cette conditionnelle : tempeteDeMana, les options d'aoe (ligne, cone, disque, target), avecd12, avantage, auto, demiAuto, test, pointsVitaux, tempsRecharge, sortilege, bonusCritique, disparition, affute, munition, tirDouble, semonce, tirDeBarrage, poudre, traquenard, feinte, asDeLaGachette, magique, tranchant, percant, contondant, pasDeDmg. Ne pas hésiter à me demander si vous aviez besoin que l'une de ces options puissent être conditionnelle.
    • -
    • --ifSaveFails carac seuil options --endif : comme --if, mais fait réaliser une jet de sauvegarde à la cible (comme avec --save), et si le test est raté, applique les options qui suivent. Un --else permet de choisir des options à appliquer quand le test est réussi. À utiliser seulement si on ne peut pas se contenter d'un --save, car ça marche moins bien.
    • -
    • --decrAttribute nom : l'attaque n'est possible que si l'attribut existe et si sa valeur est strictement positive. L'attaque diminue cette valeur de 1. Si cette option est utilisée à l'intérieur d'un --if, alors l'option se contente de diminuer l'attribut (on peut savoir si la valeur est positive grâce à --if etat nom).
    • -
    • --decrLimitePredicatParTour nom : l'attaque n'est possible que si un prédicat nom existe et si elle n'a pas été utilisée plus de fois dans le tour que la valeur de ce prédicat. L'attaque augmente ce nombre de 1.
    • -
    • --tempsRecharge effet duree : l'attaque n'est possible que si l'effet est inactif sur l'attaquant, et de plus active l'effet sur l'attaquant pour la durée indiquée si l'attaque est possible. Il existe un effet temporaire générique, rechargeGen(desc) que vous pouvez utiliser si aucun effet existant ne correspond pour votre attaque.
    • -
    • --etat e: si l'attaque touche, la cible passe dans l'état e. Il est aussi possible de spécifier une caractéristique et un seuil (comme pour !cof-set-state) pour faire afficher à chaque tour une action permettant de se libérer de l'état.
    • -
    • --effet e duree : ajoute à la cible l'effet temporaire e pour la duree spécifiée. Pour que cela soit automatiquement mis à jour, il faut utiliser le turn tracker. Noter que l'argument de durée peut être omis pour certains effets, comme ceux qui par définition durent tout le combat.
    • -
    • --valeur v : spécifie une valeur au dernier effet mentionné.
    • -
    • --optionEffet opt arg1 arg2 ... : spécifie une option au dernier effet mentionné. L'option opt doit être donnée sans le -- et sera passée telle quelle à l'effet, par exemple pour les dégâts périodiques, si on ne veut pas que la RD s'applique, on pourra ajouter --optionEffet ignoreRD.
    • -
    • --peur seuil duree : fait un effet de peur si l'attaque touche. Le seuil sert pour le test de sagesse de résistance à la peur (tient compte de la capacité sans peur du chevalier).
    • -
    • --affaiblirCarac carac n : l'attaque diminue la caractéristique carac de n. Si carac est random, le script tire une caractéristique au hasard.
    • -
    • --plus dmg : ajoute dmg dégâts. Attention, si dmg est un simple nombre, ces dégâts sont multipliés par les critiques (sauf si de type différent de l'attaque principale). Ainsi, --plus [[1d6]] donnera des dégâts multipliés par les critiques (car la fonction ne voit que le résultat du jet), alors que --plus 1d6 ne le sera pas.
    • -
    • --plusCrit dmg : ajoute dmg dégâts en cas de réussite critique
    • -
    • --test pour voir le résultat du jet d'attaque. On n'applique pas les résultats d'un touché.
    • -
    • --sournoise n : ajoute nd6 de dégâts d'attaque sournoise ou par surprise. Si l'option n'a pas d'argument, le nombre de dés rajoutés sera celui associé à un prédicat attaqueSournoise, et si l'attaquant n'a pas de prédicat attaqueSournoise, l'attaque ajoute juste 1d6. Le script limite le nombre d'attaque sournoise par personnage à 1 par tour. On peut augmenter ce nombre en utilisant un prédicat sournoisesParTour, de valeur la limite au nombre de sournoises pour ce personnage.
    • -
    • --magique : les dégâts sont magiques. On peut passer en argument le niveau de magie. Il est utilisé contre les créatures immunisées aux armes. Le niveau par défaut est 1.
    • -
    • --+k : l'attaque utilise une arme magique +k. Pratique à mettre dans les modificateurs de l'attaque (dans ce cas, on n'a pas les --), cela rajoute les bonus au toucher et aux dégâts, et indique que les dégâts sont magiques. Si un niveau de magie est spécifié, rajoute k à ce niveau.
    • -
    • --feu, --acide, --electrique, --froid, --sonique, --poison, --maladie, --argent, --drain, --energie : les dégâts sont de type feu, acide, électrique, froid, sonique, poison, maladie, argent, drain ou énergie. Le type spécifie uniquement le dernier --plus précédent cette option, ou si il n'y en a pas, celui des dégâts principaux. Seul le dernier type spécifié est pris en compte (pas de type multiple pour l'instant). Le type affecte différents attributs, et aussi la couleur d'affichage des dégâts.
    • -
    • --beni : les dégâts sont d'une source sainte ou bénie. Sert principalement à signaler pour les résistances aux dégâts qui peuvent dépendre de cela (genre RD 5/beni).
    • -
    • --spectral : L'attaque peut toucher les créatures intangibles.
    • -
    • --tranchant, --percant, --contondant : précise le type d'arme (si pertinent), pour pouvoir utiliser les RD spécifiques à un type d'arme.
    • -
    • --ignoreRD : l'attaque ignore les RD et division de DMs. Il est possible de donner en argument une valeur de RD ignorée, de sorte que l'attaque ignore les RD jusqu'à cette valeur. Par exemple on pourra écrire --ignoreRD 5.
    • -
    • --ignoreMoitieRD : l'attaque ignore la moitié de la RD.
    • -
    • --sortilege pour indiquer qu'il s'agit d'un sortilège, de façons à pouvoir appliquer tous les effets spécifiques aux sorts. Cette options devrait être passées pour toutes les capacités suivies d'une étoile dans le livre des règles. En particulier, tout sortilege ignore les malus d'obstacles.
    • -
    • --reroll1 : relance les 1 aux dés de dégats. À noter que cela ne concerne que les dés de base de l'attaque, pas les DM supplémentaire.
    • -
    • --explodeMax : relance les valeurs maximum aux dés de DM de base, et rajoute le nouveau résultat (qui lui-même explose).
    • -
    • --mana n : l'attaque coûte n points de mana. Si l'attaque provoque un effet temporaire, le script essaiera de le supprimer à la mort du lanceur (même avec un coût nul).
    • -
    • --magieRapide : augmente le coût en mana (1 avec la mana normale, 3 avec la mana totale) et affiche un petit message indiquant que le lancement est rapide. Il est possible de préciser un coût en mana différent.
    • -
    • --rang n : indique le rang de la capacité utilisée, si besoin. Utilisé par l'option --tempeteDeMana.
    • -
    • --tempeteDeMana liste : indique des effets de tempête de mana. La liste peut contenir un nombre (pour l'effet intense), duree, rapide, portee et altruiste id. Si le rang du sort est spécifié (par l'option --rang, un message est affichée si le coût en mana est supérieur au rang. Si la liste d'options est vide ou ne contient que altruiste, le script affiche un menu dans le chat pour spécifier les options de tempête de mana. Il est possible d'utiliser les règles de mana totale pour les coûts de tempête de mana (à activer avec !cof-options).
    • -
    • --magieEnArmure : applique un malus à l'attaque égale au rang du sort + le malus d'armure de l'attaquant. On peut ajouter un argument optionnel : soit un nombre qui va remplacer le rang dans cette formule, soit mana qui va augmenter le coût en mana de l'attaque en fonction de l'armure portée.
    • -
    • --frappeDesArcanes n : ajoute +5 à l'attaque et +nd6 aux DM, mais empêche de lancer des sorts pendant 1d6 tours si l'attaque touche. Si le nombre n n'est pas présent, le bonus est de 2d6.
    • -
    • --limiteParJour l : limite le nombre d'utilisations de cette attaque à l fois par jour. On peut préciser un nom après l, qui va correspondre à une ressource pouvant être partagée avec d'autres attaques ou d'autres effets (voir !cof-effet-temp). Par défaut, le nom de cette ressource est le label de l'attaque.
    • -
    • --limiteParCombat : même effet que la limite par jour. Si aucun argument n'est donné, la limite est de une fois par combat.
    • -
    • --limiteParTour : même effet que la limite par jour. Si aucun argument n'est donné, la limite est de une fois par tour.
    • -
    • --munition label : l'attaque utilise les munitions de label label (notées dans l'onglet équipement de la fiche). À chaque attaque portée, une munition est utilisée, et le script teste si elle sera récupérable (en fonction du taux de pertes notée sur la fiche). En fin de combat, on considère que le personnage récupère toutes les munitions récupérables. Si une arme est reconnue comme étant un arc,une arbalète ou une arme à poudre, et que les options de l'attaque ne contiennent pas l'option --munition, alors le script propose automatiquement de choisir parmis les munitions normales (supposées illimitées) et celles encores présentes du bon type. À noter que cette option devrait être inutile pour les armes de jet qui ont déjà leur propre case associée à l'attaque.
    • -
    • --aussiArmeDeJet L : permet d'indiquer que l'arme peut aussi être employée comme arme de jet. L doit être le label de l'attaque avec cette arme en tant qu'arme de jet. Cela permet de tenir compte des cas où l'arme a été lancée et ne peut donc plus être utilisée au corps à corps. Si l'arme est utilisée à distance, le script va automatiquement utiliser l'attaque L.
    • -
    • --arcComposite n : augmente les DM du modificateur de force, (qui peut être négatif), mais sans dépasser n. Si le modificateur est strictement inférieur à n, l'attaque se fait avec un malus de -2.
    • -
    • --seulementDistance : l'attaque ne peut être réalisée que contre un adversaire à distance.
    • -
    • --vampirise : soigne de tous les DM infligés, quel que soit leur type. Il est possible de soigner un pourcentage des dégâts : pour cela, préciser le pourcentage entier après l'option. Par exemple, pour une attaque qui soigne de la moitié des dégâts infligés, on pourra mettre --vampirise 50. À noter que les soins se cumulent avec les dégâts de type drain.
    • +
    • --if condition options --endif: permet de ne prendre en compte des options que si certaines conditions sont r\xE9alis\xE9es. Il est possible d'utiliser un --else pour activer des options quand les conditions ne sont pas r\xE9alis\xE9es. Attention, les options qui modifient une option pr\xE9c\xE9dente (comme --valeur) doivent appara\xEEtre au m\xEAme niveau que l'option qu'elles modifient. Comme les conditions peuvent d\xE9pendre du d\xE9 d'attaque, un certain nombre d'options ne sont pas affect\xE9es par cette conditionnelle : tempeteDeMana, les options d'aoe (ligne, cone, disque, target), avecd12, avantage, auto, demiAuto, test, pointsVitaux, tempsRecharge, sortilege, bonusCritique, disparition, affute, munition, tirDouble, semonce, tirDeBarrage, poudre, traquenard, feinte, asDeLaGachette, magique, tranchant, percant, contondant, pasDeDmg. Ne pas h\xE9siter \xE0 me demander si vous aviez besoin que l'une de ces options puissent \xEAtre conditionnelle.
    • +
    • --ifSaveFails carac seuil options --endif : comme --if, mais fait r\xE9aliser une jet de sauvegarde \xE0 la cible (comme avec --save), et si le test est rat\xE9, applique les options qui suivent. Un --else permet de choisir des options \xE0 appliquer quand le test est r\xE9ussi. \xC0 utiliser seulement si on ne peut pas se contenter d'un --save, car \xE7a marche moins bien.
    • +
    • --decrAttribute nom : l'attaque n'est possible que si l'attribut existe et si sa valeur est strictement positive. L'attaque diminue cette valeur de 1. Si cette option est utilis\xE9e \xE0 l'int\xE9rieur d'un --if, alors l'option se contente de diminuer l'attribut (on peut savoir si la valeur est positive gr\xE2ce \xE0 --if etat nom).
    • +
    • --decrLimitePredicatParTour nom : l'attaque n'est possible que si un pr\xE9dicat nom existe et si elle n'a pas \xE9t\xE9 utilis\xE9e plus de fois dans le tour que la valeur de ce pr\xE9dicat. L'attaque augmente ce nombre de 1.
    • +
    • --tempsRecharge effet duree : l'attaque n'est possible que si l'effet est inactif sur l'attaquant, et de plus active l'effet sur l'attaquant pour la dur\xE9e indiqu\xE9e si l'attaque est possible. Il existe un effet temporaire g\xE9n\xE9rique, rechargeGen(desc) que vous pouvez utiliser si aucun effet existant ne correspond pour votre attaque.
    • +
    • --etat e: si l'attaque touche, la cible passe dans l'\xE9tat e. Il est aussi possible de sp\xE9cifier une caract\xE9ristique et un seuil (comme pour !cof-set-state) pour faire afficher \xE0 chaque tour une action permettant de se lib\xE9rer de l'\xE9tat.
    • +
    • --effet e duree : ajoute \xE0 la cible l'effet temporaire e pour la duree sp\xE9cifi\xE9e. Pour que cela soit automatiquement mis \xE0 jour, il faut utiliser le turn tracker. Noter que l'argument de dur\xE9e peut \xEAtre omis pour certains effets, comme ceux qui par d\xE9finition durent tout le combat.
    • +
    • --valeur v : sp\xE9cifie une valeur au dernier effet mentionn\xE9.
    • +
    • --optionEffet opt arg1 arg2 ... : sp\xE9cifie une option au dernier effet mentionn\xE9. L'option opt doit \xEAtre donn\xE9e sans le -- et sera pass\xE9e telle quelle \xE0 l'effet, par exemple pour les d\xE9g\xE2ts p\xE9riodiques, si on ne veut pas que la RD s'applique, on pourra ajouter --optionEffet ignoreRD.
    • +
    • --peur seuil duree : fait un effet de peur si l'attaque touche. Le seuil sert pour le test de sagesse de r\xE9sistance \xE0 la peur (tient compte de la capacit\xE9 sans peur du chevalier).
    • +
    • --affaiblirCarac carac n : l'attaque diminue la caract\xE9ristique carac de n. Si carac est random, le script tire une caract\xE9ristique au hasard.
    • +
    • --plus dmg : ajoute dmg d\xE9g\xE2ts. Attention, si dmg est un simple nombre, ces d\xE9g\xE2ts sont multipli\xE9s par les critiques (sauf si de type diff\xE9rent de l'attaque principale). Ainsi, --plus [[1d6]] donnera des d\xE9g\xE2ts multipli\xE9s par les critiques (car la fonction ne voit que le r\xE9sultat du jet), alors que --plus 1d6 ne le sera pas.
    • +
    • --plusCrit dmg : ajoute dmg d\xE9g\xE2ts en cas de r\xE9ussite critique
    • +
    • --test pour voir le r\xE9sultat du jet d'attaque. On n'applique pas les r\xE9sultats d'un touch\xE9.
    • +
    • --sournoise n : ajoute nd6 de d\xE9g\xE2ts d'attaque sournoise ou par surprise. Si l'option n'a pas d'argument, le nombre de d\xE9s rajout\xE9s sera celui associ\xE9 \xE0 un pr\xE9dicat attaqueSournoise, et si l'attaquant n'a pas de pr\xE9dicat attaqueSournoise, l'attaque ajoute juste 1d6. Le script limite le nombre d'attaque sournoise par personnage \xE0 1 par tour. On peut augmenter ce nombre en utilisant un pr\xE9dicat sournoisesParTour, de valeur la limite au nombre de sournoises pour ce personnage.
    • +
    • --magique : les d\xE9g\xE2ts sont magiques. On peut passer en argument le niveau de magie. Il est utilis\xE9 contre les cr\xE9atures immunis\xE9es aux armes. Le niveau par d\xE9faut est 1.
    • +
    • --+k : l'attaque utilise une arme magique +k. Pratique \xE0 mettre dans les modificateurs de l'attaque (dans ce cas, on n'a pas les --), cela rajoute les bonus au toucher et aux d\xE9g\xE2ts, et indique que les d\xE9g\xE2ts sont magiques. Si un niveau de magie est sp\xE9cifi\xE9, rajoute k \xE0 ce niveau.
    • +
    • --feu, --acide, --electrique, --froid, --sonique, --poison, --maladie, --argent, --drain, --energie : les d\xE9g\xE2ts sont de type feu, acide, \xE9lectrique, froid, sonique, poison, maladie, argent, drain ou \xE9nergie. Le type sp\xE9cifie uniquement le dernier --plus pr\xE9c\xE9dent cette option, ou si il n'y en a pas, celui des d\xE9g\xE2ts principaux. Seul le dernier type sp\xE9cifi\xE9 est pris en compte (pas de type multiple pour l'instant). Le type affecte diff\xE9rents attributs, et aussi la couleur d'affichage des d\xE9g\xE2ts.
    • +
    • --beni : les d\xE9g\xE2ts sont d'une source sainte ou b\xE9nie. Sert principalement \xE0 signaler pour les r\xE9sistances aux d\xE9g\xE2ts qui peuvent d\xE9pendre de cela (genre RD 5/beni).
    • +
    • --spectral : L'attaque peut toucher les cr\xE9atures intangibles.
    • +
    • --tranchant, --percant, --contondant : pr\xE9cise le type d'arme (si pertinent), pour pouvoir utiliser les RD sp\xE9cifiques \xE0 un type d'arme.
    • +
    • --ignoreRD : l'attaque ignore les RD et division de DMs. Il est possible de donner en argument une valeur de RD ignor\xE9e, de sorte que l'attaque ignore les RD jusqu'\xE0 cette valeur. Par exemple on pourra \xE9crire --ignoreRD 5.
    • +
    • --ignoreMoitieRD : l'attaque ignore la moiti\xE9 de la RD.
    • +
    • --sortilege pour indiquer qu'il s'agit d'un sortil\xE8ge, de fa\xE7ons \xE0 pouvoir appliquer tous les effets sp\xE9cifiques aux sorts. Cette options devrait \xEAtre pass\xE9es pour toutes les capacit\xE9s suivies d'une \xE9toile dans le livre des r\xE8gles. En particulier, tout sortilege ignore les malus d'obstacles.
    • +
    • --reroll1 : relance les 1 aux d\xE9s de d\xE9gats. \xC0 noter que cela ne concerne que les d\xE9s de base de l'attaque, pas les DM suppl\xE9mentaire.
    • +
    • --explodeMax : relance les valeurs maximum aux d\xE9s de DM de base, et rajoute le nouveau r\xE9sultat (qui lui-m\xEAme explose).
    • +
    • --mana n : l'attaque co\xFBte n points de mana. Si l'attaque provoque un effet temporaire, le script essaiera de le supprimer \xE0 la mort du lanceur (m\xEAme avec un co\xFBt nul).
    • +
    • --magieRapide : augmente le co\xFBt en mana (1 avec la mana normale, 3 avec la mana totale) et affiche un petit message indiquant que le lancement est rapide. Il est possible de pr\xE9ciser un co\xFBt en mana diff\xE9rent.
    • +
    • --rang n : indique le rang de la capacit\xE9 utilis\xE9e, si besoin. Utilis\xE9 par l'option --tempeteDeMana.
    • +
    • --tempeteDeMana liste : indique des effets de temp\xEAte de mana. La liste peut contenir un nombre (pour l'effet intense), duree, rapide, portee et altruiste id. Si le rang du sort est sp\xE9cifi\xE9 (par l'option --rang, un message est affich\xE9e si le co\xFBt en mana est sup\xE9rieur au rang. Si la liste d'options est vide ou ne contient que altruiste, le script affiche un menu dans le chat pour sp\xE9cifier les options de temp\xEAte de mana. Il est possible d'utiliser les r\xE8gles de mana totale pour les co\xFBts de temp\xEAte de mana (\xE0 activer avec !cof-options).
    • +
    • --magieEnArmure : applique un malus \xE0 l'attaque \xE9gale au rang du sort + le malus d'armure de l'attaquant. On peut ajouter un argument optionnel : soit un nombre qui va remplacer le rang dans cette formule, soit mana qui va augmenter le co\xFBt en mana de l'attaque en fonction de l'armure port\xE9e.
    • +
    • --frappeDesArcanes n : ajoute +5 \xE0 l'attaque et +nd6 aux DM, mais emp\xEAche de lancer des sorts pendant 1d6 tours si l'attaque touche. Si le nombre n n'est pas pr\xE9sent, le bonus est de 2d6.
    • +
    • --limiteParJour l : limite le nombre d'utilisations de cette attaque \xE0 l fois par jour. On peut pr\xE9ciser un nom apr\xE8s l, qui va correspondre \xE0 une ressource pouvant \xEAtre partag\xE9e avec d'autres attaques ou d'autres effets (voir !cof-effet-temp). Par d\xE9faut, le nom de cette ressource est le label de l'attaque.
    • +
    • --limiteParCombat : m\xEAme effet que la limite par jour. Si aucun argument n'est donn\xE9, la limite est de une fois par combat.
    • +
    • --limiteParTour : m\xEAme effet que la limite par jour. Si aucun argument n'est donn\xE9, la limite est de une fois par tour.
    • +
    • --munition label : l'attaque utilise les munitions de label label (not\xE9es dans l'onglet \xE9quipement de la fiche). \xC0 chaque attaque port\xE9e, une munition est utilis\xE9e, et le script teste si elle sera r\xE9cup\xE9rable (en fonction du taux de pertes not\xE9e sur la fiche). En fin de combat, on consid\xE8re que le personnage r\xE9cup\xE8re toutes les munitions r\xE9cup\xE9rables. Si une arme est reconnue comme \xE9tant un arc,une arbal\xE8te ou une arme \xE0 poudre, et que les options de l'attaque ne contiennent pas l'option --munition, alors le script propose automatiquement de choisir parmis les munitions normales (suppos\xE9es illimit\xE9es) et celles encores pr\xE9sentes du bon type. \xC0 noter que cette option devrait \xEAtre inutile pour les armes de jet qui ont d\xE9j\xE0 leur propre case associ\xE9e \xE0 l'attaque.
    • +
    • --aussiArmeDeJet L : permet d'indiquer que l'arme peut aussi \xEAtre employ\xE9e comme arme de jet. L doit \xEAtre le label de l'attaque avec cette arme en tant qu'arme de jet. Cela permet de tenir compte des cas o\xF9 l'arme a \xE9t\xE9 lanc\xE9e et ne peut donc plus \xEAtre utilis\xE9e au corps \xE0 corps. Si l'arme est utilis\xE9e \xE0 distance, le script va automatiquement utiliser l'attaque L.
    • +
    • --arcComposite n : augmente les DM du modificateur de force, (qui peut \xEAtre n\xE9gatif), mais sans d\xE9passer n. Si le modificateur est strictement inf\xE9rieur \xE0 n, l'attaque se fait avec un malus de -2.
    • +
    • --seulementDistance : l'attaque ne peut \xEAtre r\xE9alis\xE9e que contre un adversaire \xE0 distance.
    • +
    • --vampirise : soigne de tous les DM inflig\xE9s, quel que soit leur type. Il est possible de soigner un pourcentage des d\xE9g\xE2ts : pour cela, pr\xE9ciser le pourcentage entier apr\xE8s l'option. Par exemple, pour une attaque qui soigne de la moiti\xE9 des d\xE9g\xE2ts inflig\xE9s, on pourra mettre --vampirise 50. \xC0 noter que les soins se cumulent avec les d\xE9g\xE2ts de type drain.
    • --seulementVivant : n'affecte que les cibles vivantes
    • --forceMinimum n : l'attaque n'est possible que si l'attaquant a au moins n en force.
    • -
    • --necromancie : l'attaque est de la nécromancie
    • -
    • --ferFroid : multiplie par 2 les dégâts contre les fées et les démons (le script reconnaît certaines races et les prédicats démon et fée).
    • -
    • --adamantium : l'arme utilisée est en adamantium. Reconnu pour la RD.
    • -
    • --tueurDe categorie : bonus de +2 en attaque et +2d6 DM contre les espèces appartenant à la catégorie (voir la condition typeCible.
    • -
    • --tueurDeGrands : bonus de +1d6 DM contre les créatures de taille grande et +2d6 DM contre les créatures de taille énorme ou plus.
    • -
    • --ignoreObstacles : ignore les tokens sur le trajet. Ça semble nécessaire pour les attaques magiques d'après Kegron.
    • -
    • --retourneEnMain : L'arme de jet revient en main après l'attaque.
    • -
    • --puissant : augmente la valeur max des dés de dégâts de 2. Si --puissant est suivi d'un argument effet, on teste la présence d'un attribut effetPuissant pour décider si l'attaque est puissante ou non. Il est aussi possible de donner oui ou non en argument (ce n'est alors pas considéré comme un effet). --puissant portee permet de doubler la portée de l'attaque (utile pour l'option de Magie Puissante)
    • -
    • --attaqueAssuree : implémente une attaque assurée (+5 à l'attaque, dégâts divisés par 2, critique impossible).
    • -
    • --attaqueRisquee : implémente une attaque risquée (+2 à l'attaque au contact, -4 en DEF pendant un tour).
    • -
    • --attaqueDeGroupe n : n est le nombre de créatures qui attaquent ; implémente une attaque de groupe (+2 à l'attaque par attaquant au-delà du premier, x2 DMG si l'attaque dépasse la DEF de 5 ou plus, x3 DMG si critique).
    • -
    • --attaqueAcrobatique : l'attaquant effectue un test d'acrobatie difficulté 15, et s'il réussit, l'attaque bénéficie des effets d'une sournoise. On peut en option préciser le nombre de dés de cette attaque sournoise.
    • -
    • --strigeSuce : option spécifique aux striges. Donne le malus de -3 en DEF et compte la quantite sucée. Quand cette quantité arrive à 6, enlève le malus de DEF et rend la cible affaiblie.
    • -
    • --mainsDEnergie : +2 à +5 à l'attaque, selon l'armure de la cible
    • -
    • --semonce : +5 au touché et +1d6 aux DM (ne change pas les charges de l'arme).
    • -
    • --avantage : lance un dé de plus en attaque et garde le meilleur. plusieurs arguments avantage se cumulent et sont annulés par les désavantages (syntaxe alertnative: (--m2d20)
    • -
    • --desavantage : lance un dé de plus en attaque et garde le moins bon. plusieurs arguments désavantage se cumulent et sont annulés par les avantages.
    • -
    • --avecd12 : lance un d12 au lieu du d20 pour le jet d'attaque. L'attaque est impossible si l'attaquant est déjà affaibli.
    • -
    • --avecd12crit : comme --avecd12, mais le jet peut faire un critique. La plage de critique est divisée par 2, arrondie à l'inférieur. Ainsi si le d20 sevait critiquer sur un 20 seulement, le d12 ne fait pas de critique. Il fait un critique sur un 12 si le d20 devait faire un critique sur un 19 ou un 18, et ainsi de suite.
    • -
    • --incrDmgCoef n : augmente le coefficient des dégâts de base de 1. Les dégâts de base comprennent les dés de dommage de l'arme (ou du sort), plus tous les bonus constants. Le coefficient par défaut est de 1, et une réussite critique augmente ce coefficient de 1.
    • -
    • --incrCritCoef n : augmente le coefficient des dégâts critiques de n (1 si on ne donne pas d'argument).
    • -
    • --diviseDmg n : divise les dégâts de base par n.
    • -
    • --maxDmg : l'attaque inflige le maximum de DM permis par les dés de base.
    • -
    • --runeDePuissance : l'arme est enchantée avec une rune de puissance permanente.
    • -
    • --difficultePVmax : la difficulté du jet d'attaque est le maximum de PVs au lieu de la défense.
    • -
    • --difficultePV : la difficulté du jet d'attaque est la valeur courante des PVs au lieu de la défense.
    • -
    • --difficulteCarac carac : la difficulté du jet d'attaque est une des caractéristiques de la cible (sous forme de code à 3 lettres, FOR, DEX, etc). Il est possible de prendre le meilleur de 2 caractéristiques en écrivant les 2 noms collés. Par exemple, pour viser le meilleur de l'intelligence et du charisme, on écrira --difficuletCarac INTCHA.
    • +
    • --necromancie : l'attaque est de la n\xE9cromancie
    • +
    • --ferFroid : multiplie par 2 les d\xE9g\xE2ts contre les f\xE9es et les d\xE9mons (le script reconna\xEEt certaines races et les pr\xE9dicats d\xE9mon et f\xE9e).
    • +
    • --adamantium : l'arme utilis\xE9e est en adamantium. Reconnu pour la RD.
    • +
    • --tueurDe categorie : bonus de +2 en attaque et +2d6 DM contre les esp\xE8ces appartenant \xE0 la cat\xE9gorie (voir la condition typeCible.
    • +
    • --tueurDeGrands : bonus de +1d6 DM contre les cr\xE9atures de taille grande et +2d6 DM contre les cr\xE9atures de taille \xE9norme ou plus.
    • +
    • --ignoreObstacles : ignore les tokens sur le trajet. Ça semble n\xE9cessaire pour les attaques magiques d'apr\xE8s Kegron.
    • +
    • --retourneEnMain : L'arme de jet revient en main apr\xE8s l'attaque.
    • +
    • --puissant : augmente la valeur max des d\xE9s de d\xE9g\xE2ts de 2. Si --puissant est suivi d'un argument effet, on teste la pr\xE9sence d'un attribut effetPuissant pour d\xE9cider si l'attaque est puissante ou non. Il est aussi possible de donner oui ou non en argument (ce n'est alors pas consid\xE9r\xE9 comme un effet). --puissant portee permet de doubler la port\xE9e de l'attaque (utile pour l'option de Magie Puissante)
    • +
    • --attaqueAssuree : impl\xE9mente une attaque assur\xE9e (+5 \xE0 l'attaque, d\xE9g\xE2ts divis\xE9s par 2, critique impossible).
    • +
    • --attaqueRisquee : impl\xE9mente une attaque risqu\xE9e (+2 \xE0 l'attaque au contact, -4 en DEF pendant un tour).
    • +
    • --attaqueDeGroupe n : n est le nombre de cr\xE9atures qui attaquent ; impl\xE9mente une attaque de groupe (+2 \xE0 l'attaque par attaquant au-del\xE0 du premier, x2 DMG si l'attaque d\xE9passe la DEF de 5 ou plus, x3 DMG si critique).
    • +
    • --attaqueAcrobatique : l'attaquant effectue un test d'acrobatie difficult\xE9 15, et s'il r\xE9ussit, l'attaque b\xE9n\xE9ficie des effets d'une sournoise. On peut en option pr\xE9ciser le nombre de d\xE9s de cette attaque sournoise.
    • +
    • --strigeSuce : option sp\xE9cifique aux striges. Donne le malus de -3 en DEF et compte la quantite suc\xE9e. Quand cette quantit\xE9 arrive \xE0 6, enl\xE8ve le malus de DEF et rend la cible affaiblie.
    • +
    • --mainsDEnergie : +2 \xE0 +5 \xE0 l'attaque, selon l'armure de la cible
    • +
    • --semonce : +5 au touch\xE9 et +1d6 aux DM (ne change pas les charges de l'arme).
    • +
    • --avantage : lance un d\xE9 de plus en attaque et garde le meilleur. plusieurs arguments avantage se cumulent et sont annul\xE9s par les d\xE9savantages (syntaxe alertnative: (--m2d20)
    • +
    • --desavantage : lance un d\xE9 de plus en attaque et garde le moins bon. plusieurs arguments d\xE9savantage se cumulent et sont annul\xE9s par les avantages.
    • +
    • --avecd12 : lance un d12 au lieu du d20 pour le jet d'attaque. L'attaque est impossible si l'attaquant est d\xE9j\xE0 affaibli.
    • +
    • --avecd12crit : comme --avecd12, mais le jet peut faire un critique. La plage de critique est divis\xE9e par 2, arrondie \xE0 l'inf\xE9rieur. Ainsi si le d20 sevait critiquer sur un 20 seulement, le d12 ne fait pas de critique. Il fait un critique sur un 12 si le d20 devait faire un critique sur un 19 ou un 18, et ainsi de suite.
    • +
    • --incrDmgCoef n : augmente le coefficient des d\xE9g\xE2ts de base de 1. Les d\xE9g\xE2ts de base comprennent les d\xE9s de dommage de l'arme (ou du sort), plus tous les bonus constants. Le coefficient par d\xE9faut est de 1, et une r\xE9ussite critique augmente ce coefficient de 1.
    • +
    • --incrCritCoef n : augmente le coefficient des d\xE9g\xE2ts critiques de n (1 si on ne donne pas d'argument).
    • +
    • --diviseDmg n : divise les d\xE9g\xE2ts de base par n.
    • +
    • --maxDmg : l'attaque inflige le maximum de DM permis par les d\xE9s de base.
    • +
    • --runeDePuissance : l'arme est enchant\xE9e avec une rune de puissance permanente.
    • +
    • --difficultePVmax : la difficult\xE9 du jet d'attaque est le maximum de PVs au lieu de la d\xE9fense.
    • +
    • --difficultePV : la difficult\xE9 du jet d'attaque est la valeur courante des PVs au lieu de la d\xE9fense.
    • +
    • --difficulteCarac carac : la difficult\xE9 du jet d'attaque est une des caract\xE9ristiques de la cible (sous forme de code \xE0 3 lettres, FOR, DEX, etc). Il est possible de prendre le meilleur de 2 caract\xE9ristiques en \xE9crivant les 2 noms coll\xE9s. Par exemple, pour viser le meilleur de l'intelligence et du charisme, on \xE9crira --difficuletCarac INTCHA.
    • --affute : augmente de 1 les chances de crit et +1d6 aux DM des crit.
    • --tirDeBarrage : ignore la charge, multiplie les DM par 2 et message pour undo si la cible bouge.
    • --tirAveugle : ignore le malus de tir sur une cible invisible.
    • -
    • --vicieux : ajoute 2d6 DM mais inflige 1d6 DM à l'attaquant.
    • -
    • --enflamme : enflamme la cible, lui infligeant 1d6 DM par tour. Les flammes s'éteindent sur un 1 ou 2. Si l'option --puissant est donnée en conjonction, les DM augmentent de 1.
    • +
    • --vicieux : ajoute 2d6 DM mais inflige 1d6 DM \xE0 l'attaquant.
    • +
    • --enflamme : enflamme la cible, lui infligeant 1d6 DM par tour. Les flammes s'\xE9teindent sur un 1 ou 2. Si l'option --puissant est donn\xE9e en conjonction, les DM augmentent de 1.
    • --malediction : maudit la cible pour 3 jets.
    • -
    • --asDeLaGachette : ajoute 1d6 DM si le jet d'attaque dépasse une DEF de 25.
    • -
    • --armeDArgent : bonus de +2 en attaque et 1d6 aux DM si la cible est un mort-vivant ou un démon (utilise le champ Race de la fiche ou si présent un prédicat mortVivant).
    • -
    • --pietine : si l'attaquant est de taille au moins égale à celle de la cible (ou si la taille de l'un des deux n'est pas connue), fait un test opposé de FOR. En cas d'échec de la cible, elle est renversée et les DM sont doublés.
    • -
    • --percute : comme --pietine, mais la cible est en plus projetée à 1d6+1 mètres et étourdie si elle rate un test de CON difficulté 15, renouvelable chaque tour.
    • -
    • --feinte : L'attaque ne fait pas de dégât, mais un bonus de +5 en attaque est donné sur les attaques du tour suivant sur cette cible (par celui qui a fait la feinte), et +2d6 DM si l'attaque fictive était un succès. Si l'attaquant possède un prédicat bonusFeinte, c'est la valeur de ce prédicat qui est donné en bonus aux attaques, à la place de +5.
    • -
    • --enveloppe difficulte type expr : si l'attaque touche, elle a une chance d'envelopper la cible. Dans ce cas, un bouton apparaît qui lance un test en opposition. Si celui-ci est remporté par l'attaquant, difficulte est la difficulté du test pour se sortir de l'enveloppement, type est soit label, et dans ce cas, expr doit être le label d'une attaque de l'attaquant, soit ability, et dans ce cas, expr est le nom d'une ability de l'attaquant. Cette attaque ou ability est appelée pour les dégâts périodiques. Si les deux derniers arguments sont ommis, le script prend label et le label de l'attaque courante, et si le premier argument est ommis, la difficulté est de 15.
    • -
    • --etreinte difficulte : si l'attaque touche, il y a une chance que l'attaquant puisse s'enrouler autour de la cible. Dans ce cas, un bouton apparaît qui lance un test en opposition. Si celui-ci est remporté par l'attaquant, difficulte est la difficulté du test pour se sortir de l'enveloppement. Cela fera apparaître un bouton pour les dégâts de l'étreinte, par défaut 1d6, mais on peut spécifier une autre expression pour les dégâts (optionelle, juste après la difficulté).
    • -
    • --ouvertureMortelle : touche automatiquement, fait des dégât comme en cas de critique et multiplie par 2 les dégâts d'attaque sournoise (si il y en a).
    • -
    • --rate, --touche, --critique, --echecCritique, --pasDEchecCritique : options pour tricher : le résultat des dés donne toujours le résultat voulu.
    • -
    • --ligne : l'attaque porte sur toutes les cibles à portée, entre l'attaquant et le token ciblé. Si le token ciblé est plus proche que la portée de l'attaque, les tokens derrière le token ciblé sont aussi visés. Pour permettre de viser un point quelconque, on peut utiliser un personnage dédié avec un maximum de 0 pv. À chaque fois qu'un token représentant ce personnage est utilisé comme cible de --ligne, le token est enlevé de la carte.
    • -
    • --disque r : l'attaque porte sur toutes les cibles dans le disque de centre le token ciblé et de rayon r. Comme pour --ligne, on peut utiliser un token cible qui sera supprimé après l'attaque. À noter que l'attaquant lui-même peut prendre des dégâts, sauf si l'attaque a une portée nulle et que l'attaquant se cible lui-même (attaque centrée sur le lanceur). On peut donner en argument optionel le mot souffleDeMort pour ne valider l'attaque que si le centre du disque est un personnage mort depuis moins d'un tour et ne garder que les alliés de ce personnage de niveau inférieur ou égal.
    • -
    • --cone angle : cible toutes les créatures dans un cône de sommet l'attaquant, d'angle angle degrés (90 degrés par défaut), et séparé en deux par le segment joignant l'attaquant et le token visé.
    • -
    • --explosion : si l'attaque n'est pas déjà un disque, considère qu'elle forme un disque de rayon égal à la portée. L'attaquant est automatiquement exclus de la zone.
    • -
    • --dmCible dmg : utilisé conjointement aux options de zone ci-dessus, cette option permet de remplacer les dommages de base de l'attaque spécifiquement sur la cible sélectionnée lors de l'attaque
    • -
    • --saufAllies : ne cible pas les allies dans la zone ou les cibles spécifiées.
    • -
    • --target id : ajoute une cible à l'attaque (s'ajoute à la cible principale et aux options d'aoe).
    • -
    • --ciblesDansDisque n : impose que les différentes cibles soient dans un disque de rayon n.
    • -
    • --ricochets n : l'arme de jet peut faire n ricochets. Une cible ne peut être touchée qu'une fois par attaque.
    • -
    • --message texte : ajoute une ligne avec le message dans la fenêtre de l'attaque. Attention, texte ne doit pas contenir la séquence --.
    • -
    • --secret : affiche les jets et résultats de l'attaque seulement aux joueurs qui contrôlent l'attaquant ou ses cibles, ainsi qu'au MJ.
    • -
    • --allonge n : ajoute n mètres à la portée d'une attaque au contact. L'allonge peut être un nombre à virgule et même négative.
    • -
    • --canaliseParFamilier : le point de départ de l'attaque est le familier s'il est actif sur la carte.
    • -
    • --peutAgripper : l'attaque peut agripper comme si l'attaquant avait le prédicat agripper.
    • -
    • --soundAttack son : joue le son son, à moins qu'une version plus longue de l'option (voir ci-dessous) n'existe et qu'elle soit active.
    • -
    • --soundAttackEchec son : joue le son son lorque l'arme fait un echec, sauf si c'est un échec particulier et une version plus longue existe.
    • +
    • --asDeLaGachette : ajoute 1d6 DM si le jet d'attaque d\xE9passe une DEF de 25.
    • +
    • --armeDArgent : bonus de +2 en attaque et 1d6 aux DM si la cible est un mort-vivant ou un d\xE9mon (utilise le champ Race de la fiche ou si pr\xE9sent un pr\xE9dicat mortVivant).
    • +
    • --pietine : si l'attaquant est de taille au moins \xE9gale \xE0 celle de la cible (ou si la taille de l'un des deux n'est pas connue), fait un test oppos\xE9 de FOR. En cas d'\xE9chec de la cible, elle est renvers\xE9e et les DM sont doubl\xE9s.
    • +
    • --percute : comme --pietine, mais la cible est en plus projet\xE9e \xE0 1d6+1 m\xE8tres et \xE9tourdie si elle rate un test de CON difficult\xE9 15, renouvelable chaque tour.
    • +
    • --feinte : L'attaque ne fait pas de d\xE9g\xE2t, mais un bonus de +5 en attaque est donn\xE9 sur les attaques du tour suivant sur cette cible (par celui qui a fait la feinte), et +2d6 DM si l'attaque fictive \xE9tait un succ\xE8s. Si l'attaquant poss\xE8de un pr\xE9dicat bonusFeinte, c'est la valeur de ce pr\xE9dicat qui est donn\xE9 en bonus aux attaques, \xE0 la place de +5.
    • +
    • --enveloppe difficulte type expr : si l'attaque touche, elle a une chance d'envelopper la cible. Dans ce cas, un bouton appara\xEEt qui lance un test en opposition. Si celui-ci est remport\xE9 par l'attaquant, difficulte est la difficult\xE9 du test pour se sortir de l'enveloppement, type est soit label, et dans ce cas, expr doit \xEAtre le label d'une attaque de l'attaquant, soit ability, et dans ce cas, expr est le nom d'une ability de l'attaquant. Cette attaque ou ability est appel\xE9e pour les d\xE9g\xE2ts p\xE9riodiques. Si les deux derniers arguments sont ommis, le script prend label et le label de l'attaque courante, et si le premier argument est ommis, la difficult\xE9 est de 15.
    • +
    • --etreinte difficulte : si l'attaque touche, il y a une chance que l'attaquant puisse s'enrouler autour de la cible. Dans ce cas, un bouton appara\xEEt qui lance un test en opposition. Si celui-ci est remport\xE9 par l'attaquant, difficulte est la difficult\xE9 du test pour se sortir de l'enveloppement. Cela fera appara\xEEtre un bouton pour les d\xE9g\xE2ts de l'\xE9treinte, par d\xE9faut 1d6, mais on peut sp\xE9cifier une autre expression pour les d\xE9g\xE2ts (optionelle, juste apr\xE8s la difficult\xE9).
    • +
    • --ouvertureMortelle : touche automatiquement, fait des d\xE9g\xE2t comme en cas de critique et multiplie par 2 les d\xE9g\xE2ts d'attaque sournoise (si il y en a).
    • +
    • --rate, --touche, --critique, --echecCritique, --pasDEchecCritique : options pour tricher : le r\xE9sultat des d\xE9s donne toujours le r\xE9sultat voulu.
    • +
    • --ligne : l'attaque porte sur toutes les cibles \xE0 port\xE9e, entre l'attaquant et le token cibl\xE9. Si le token cibl\xE9 est plus proche que la port\xE9e de l'attaque, les tokens derri\xE8re le token cibl\xE9 sont aussi vis\xE9s. Pour permettre de viser un point quelconque, on peut utiliser un personnage d\xE9di\xE9 avec un maximum de 0 pv. \xC0 chaque fois qu'un token repr\xE9sentant ce personnage est utilis\xE9 comme cible de --ligne, le token est enlev\xE9 de la carte.
    • +
    • --disque r : l'attaque porte sur toutes les cibles dans le disque de centre le token cibl\xE9 et de rayon r. Comme pour --ligne, on peut utiliser un token cible qui sera supprim\xE9 apr\xE8s l'attaque. \xC0 noter que l'attaquant lui-m\xEAme peut prendre des d\xE9g\xE2ts, sauf si l'attaque a une port\xE9e nulle et que l'attaquant se cible lui-m\xEAme (attaque centr\xE9e sur le lanceur). On peut donner en argument optionel le mot souffleDeMort pour ne valider l'attaque que si le centre du disque est un personnage mort depuis moins d'un tour et ne garder que les alli\xE9s de ce personnage de niveau inf\xE9rieur ou \xE9gal.
    • +
    • --cone angle : cible toutes les cr\xE9atures dans un c\xF4ne de sommet l'attaquant, d'angle angle degr\xE9s (90 degr\xE9s par d\xE9faut), et s\xE9par\xE9 en deux par le segment joignant l'attaquant et le token vis\xE9.
    • +
    • --explosion : si l'attaque n'est pas d\xE9j\xE0 un disque, consid\xE8re qu'elle forme un disque de rayon \xE9gal \xE0 la port\xE9e. L'attaquant est automatiquement exclus de la zone.
    • +
    • --dmCible dmg : utilis\xE9 conjointement aux options de zone ci-dessus, cette option permet de remplacer les dommages de base de l'attaque sp\xE9cifiquement sur la cible s\xE9lectionn\xE9e lors de l'attaque
    • +
    • --saufAllies : ne cible pas les allies dans la zone ou les cibles sp\xE9cifi\xE9es.
    • +
    • --target id : ajoute une cible \xE0 l'attaque (s'ajoute \xE0 la cible principale et aux options d'aoe).
    • +
    • --ciblesDansDisque n : impose que les diff\xE9rentes cibles soient dans un disque de rayon n.
    • +
    • --ricochets n : l'arme de jet peut faire n ricochets. Une cible ne peut \xEAtre touch\xE9e qu'une fois par attaque.
    • +
    • --message texte : ajoute une ligne avec le message dans la fen\xEAtre de l'attaque. Attention, texte ne doit pas contenir la s\xE9quence --.
    • +
    • --secret : affiche les jets et r\xE9sultats de l'attaque seulement aux joueurs qui contr\xF4lent l'attaquant ou ses cibles, ainsi qu'au MJ.
    • +
    • --allonge n : ajoute n m\xE8tres \xE0 la port\xE9e d'une attaque au contact. L'allonge peut \xEAtre un nombre \xE0 virgule et m\xEAme n\xE9gative.
    • +
    • --canaliseParFamilier : le point de d\xE9part de l'attaque est le familier s'il est actif sur la carte.
    • +
    • --peutAgripper : l'attaque peut agripper comme si l'attaquant avait le pr\xE9dicat agripper.
    • +
    • --soundAttack son : joue le son son, \xE0 moins qu'une version plus longue de l'option (voir ci-dessous) n'existe et qu'elle soit active.
    • +
    • --soundAttackEchec son : joue le son son lorque l'arme fait un echec, sauf si c'est un \xE9chec particulier et une version plus longue existe.
    • --soundAttackEchecCritique son : joue le son n lorque l'arme fait un echec critique
    • --soundAttackEchecClignotement son : joue le son son lorque l'arme fait un echec par clignotement
    • -
    • --soundAttackSucces son : joue le son son lorque l'arme fait un succès
    • -
    • --soundAttackSuccesCritique son : joue le son n lorque l'arme fait un succès critique
    • -
    • --soundAttackSuccesChampion son : joue le son son lorque l'arme fait un succès champion
    • -
    • --imgAttack img : Affiche dans le chat l'image (.jpg/.png/.gif) img, à moins qu'une version plus longue de l'option (voir ci-dessous) n'existe et qu'elle soit active.
    • +
    • --soundAttackSucces son : joue le son son lorque l'arme fait un succ\xE8s
    • +
    • --soundAttackSuccesCritique son : joue le son n lorque l'arme fait un succ\xE8s critique
    • +
    • --soundAttackSuccesChampion son : joue le son son lorque l'arme fait un succ\xE8s champion
    • +
    • --imgAttack img : Affiche dans le chat l'image (.jpg/.png/.gif) img, \xE0 moins qu'une version plus longue de l'option (voir ci-dessous) n'existe et qu'elle soit active.
    • --imgAttackEchecCritique img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec critique
    • --imgAttackEchec img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec
    • --imgAttackEchecClignotement img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec par clignotement
    • -
    • --imgAttackSuccesCritique img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès critique
    • -
    • --imgAttackSucces img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès
    • -
    • --imgAttackSuccesChampion img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès champion
    • +
    • --imgAttackSuccesCritique img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s critique
    • +
    • --imgAttackSucces img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s
    • +
    • --imgAttackSuccesChampion img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s champion
    -

    Réduction des dégâts

    +

    R\xE9duction des d\xE9g\xE2ts

    Fonctionnement de base
      -
    • Le script utilise les cases RD et Casque présentes sur les fiches.
    • -
    • Il est possible d'indiquer plusieurs RD différentes, il suffit de les séparer par une virgule.
    • +
    • Le script utilise les cases RD et Casque pr\xE9sentes sur les fiches.
    • +
    • Il est possible d'indiquer plusieurs RD diff\xE9rentes, il suffit de les s\xE9parer par une virgule.
    • Toutes les RD se cumulent.
    • -
    • Le script se base sur les types de dégâts pour choisir d'appliquer ou non les dégâts.
    • -
    • Pour les armes magiques, il est possible de spécifier à la fois le type de l'arme (par exemple --tranchant) et --magique.
    • +
    • Le script se base sur les types de d\xE9g\xE2ts pour choisir d'appliquer ou non les d\xE9g\xE2ts.
    • +
    • Pour les armes magiques, il est possible de sp\xE9cifier \xE0 la fois le type de l'arme (par exemple --tranchant) et --magique.
    RD simple
    -

    Dans le cas d'une RD simple (résistance à tous les dégâts), il suffit d'indiquer un nombre. Exemple : 3

    -
    RD à un type de dégâts particuliers
    -

    Pour une RD qui ne s'applique qu'à un type de dégâts particuliers, indiquer le type et la valeur séparés par :. Exemple : feu:5. On peut aussi spécifier une RD conte tous les types élémentaires avec le mot clé elementaire. On peut aussi avoir une RD qui ne s'applique qu'aux attaques à distance avec le mot clé distance.

    -
    RD sauf un ou plusieurs types de dégâts particuliers
    -

    Pour une RD qui s'applique tout le temps sauf un ou plusieurs types de dégâts particuliers, indiquer la valeur puis / puis les différents types séparés par _. Exemple /. Exemple : 5/argent_magique
    - Pour une RD qui s'appliquerait à tous les types d'armes sauf une, utiliser à la place une résistance aux 2 autres types d'armes. Exemple, pour 5/tranchant, utiliser percant:5,contondant:5.

    +

    Dans le cas d'une RD simple (r\xE9sistance \xE0 tous les d\xE9g\xE2ts), il suffit d'indiquer un nombre. Exemple : 3

    +
    RD \xE0 un type de d\xE9g\xE2ts particuliers
    +

    Pour une RD qui ne s'applique qu'\xE0 un type de d\xE9g\xE2ts particuliers, indiquer le type et la valeur s\xE9par\xE9s par :. Exemple : feu:5. On peut aussi sp\xE9cifier une RD conte tous les types \xE9l\xE9mentaires avec le mot cl\xE9 elementaire. On peut aussi avoir une RD qui ne s'applique qu'aux attaques \xE0 distance avec le mot cl\xE9 distance.

    +
    RD sauf un ou plusieurs types de d\xE9g\xE2ts particuliers
    +

    Pour une RD qui s'applique tout le temps sauf un ou plusieurs types de d\xE9g\xE2ts particuliers, indiquer la valeur puis / puis les diff\xE9rents types s\xE9par\xE9s par _. Exemple /. Exemple : 5/argent_magique
    + Pour une RD qui s'appliquerait \xE0 tous les types d'armes sauf une, utiliser \xE0 la place une r\xE9sistance aux 2 autres types d'armes. Exemple, pour 5/tranchant, utiliser percant:5,contondant:5.

    RD critique
    -

    Utiliser un prédicat RD_critique avec comme valeur la résistance aux critiques. Se combine avec une éventuelle RD critique fournie par le port d'un casque.

    -
    Résistances
    -

    Pour les effets qui divisent la dégâts subits d'un type donné, utilisez un prédicat resistanceA_type. Une resistance à tous les dégâts non-magiques est possible avec resistanceA_nonMagique.Il est aussi possible d'octroyer une résistance temporaire, par exemple une potion de résistance au feu pourra être simulée par la commande !cof-set-attribute resistanceA_feu true. Cela ne sera pas visible dans les prédicats, local à un mook, et il faut ensuite effacer l'attribut à la fin de l'effet.

    -

    Pour les effets qui divisent par 2 les dégâts ou la durée, utiliser un prédicat diviseEffet_type.

    -

    Pour les effets qui donnent un bonus aux tests pour résister aux effets ou dégâts d'un certain type, utiliser un prédicat bonusSaveContre_type de valeur le bonus accordé. Par exemple, un objet qui donnerait +5 à tous les tests pour résister au poison pourrait être encodé par un prédicat bonusSaveContre_poison de valeur 5.

    +

    Utiliser un pr\xE9dicat RD_critique avec comme valeur la r\xE9sistance aux critiques. Se combine avec une \xE9ventuelle RD critique fournie par le port d'un casque.

    +
    R\xE9sistances
    +

    Pour les effets qui divisent la d\xE9g\xE2ts subits d'un type donn\xE9, utilisez un pr\xE9dicat resistanceA_type. Une resistance \xE0 tous les d\xE9g\xE2ts non-magiques est possible avec resistanceA_nonMagique.Il est aussi possible d'octroyer une r\xE9sistance temporaire, par exemple une potion de r\xE9sistance au feu pourra \xEAtre simul\xE9e par la commande !cof-set-attribute resistanceA_feu true. Cela ne sera pas visible dans les pr\xE9dicats, local \xE0 un mook, et il faut ensuite effacer l'attribut \xE0 la fin de l'effet.

    +

    Pour les effets qui divisent par 2 les d\xE9g\xE2ts ou la dur\xE9e, utiliser un pr\xE9dicat diviseEffet_type.

    +

    Pour les effets qui donnent un bonus aux tests pour r\xE9sister aux effets ou d\xE9g\xE2ts d'un certain type, utiliser un pr\xE9dicat bonusSaveContre_type de valeur le bonus accord\xE9. Par exemple, un objet qui donnerait +5 \xE0 tous les tests pour r\xE9sister au poison pourrait \xEAtre encod\xE9 par un pr\xE9dicat bonusSaveContre_poison de valeur 5.

    Armures/Boucliers de Protection (COF p. 203)
    -

    ajoutez un prédicat armureProtection ou bouclierProtection. Le script détecte si l'équipement est porté ou pas via la fiche, et fonctionne spécifiquement contre les attaques qui utilisent --sournoise. Il est aussi possible de spécifier le port d'un anneau de protection ayant le même effet (prédicat anneauProtection.

    +

    ajoutez un pr\xE9dicat armureProtection ou bouclierProtection. Le script d\xE9tecte si l'\xE9quipement est port\xE9 ou pas via la fiche, et fonctionne sp\xE9cifiquement contre les attaques qui utilisent --sournoise. Il est aussi possible de sp\xE9cifier le port d'un anneau de protection ayant le m\xEAme effet (pr\xE9dicat anneauProtection.

    Manoeuvres

    -

    !cof-action-defensive avec comme argument soit simple, soit totale donne le bonus en défense de l'action défensive (p 71). Cette action est disponible par défaut dans la liste des actions du tour. Alternativement, si vous n'utilisez pas cette méthode, vous pouvez créer une macro accessible à tous les tokens, !cof-action-defensive ?{Action défensive|simple|totale}.

    -

    Les manoeuvres risquées peuvent être lancées avec la commande !cof-manoeuvre @{selected|token_id} @{target|token_id} effet. Liste des manoeuvres : aveugler, bloquer, desarmer, faireDiversion, menacer, renverser, repousser, tenirADistance.

    -

    Il est aussi possible de faire un test d'attaque opposée avec la commande !cof-test-attaque-opposee @{selected|token_id} @{target|token_id}.

    +

    !cof-action-defensive avec comme argument soit simple, soit totale donne le bonus en d\xE9fense de l'action d\xE9fensive (p 71). Cette action est disponible par d\xE9faut dans la liste des actions du tour. Alternativement, si vous n'utilisez pas cette m\xE9thode, vous pouvez cr\xE9er une macro accessible \xE0 tous les tokens, !cof-action-defensive ?{Action d\xE9fensive|simple|totale}.

    +

    Les manoeuvres risqu\xE9es peuvent \xEAtre lanc\xE9es avec la commande !cof-manoeuvre @{selected|token_id} @{target|token_id} effet. Liste des manoeuvres : aveugler, bloquer, desarmer, faireDiversion, menacer, renverser, repousser, tenirADistance.

    +

    Il est aussi possible de faire un test d'attaque oppos\xE9e avec la commande !cof-test-attaque-opposee @{selected|token_id} @{target|token_id}.

    Recharger des armes : !cof-recharger N

    -

    Il faut un prédicat charge dans le champ de prédicat des armes qui ont besoin d'être chargées pour fonctionner. On peut associer un nombre au prédicat, pour indiquer un maximum de charges supérieur à 1. Noter que si on a 2 armes à une charge, il faut utiliser un maximum de 2.
    - Recharge l'arme N (augmente les charges d'un). Les armes sont toutes rechargées à la fin d'un combat.
    - La commande admet un argment optionel --grenaille pour charger (une arme à poudre) avec de la grenaille. +

    Il faut un pr\xE9dicat charge dans le champ de pr\xE9dicat des armes qui ont besoin d'\xEAtre charg\xE9es pour fonctionner. On peut associer un nombre au pr\xE9dicat, pour indiquer un maximum de charges sup\xE9rieur \xE0 1. Noter que si on a 2 armes \xE0 une charge, il faut utiliser un maximum de 2.
    + Recharge l'arme N (augmente les charges d'un). Les armes sont toutes recharg\xE9es \xE0 la fin d'un combat.
    + La commande admet un argment optionel --grenaille pour charger (une arme \xE0 poudre) avec de la grenaille.

    -

    Dégainer une arme : !cof-degainer N

    +

    D\xE9gainer une arme : !cof-degainer N

    -

    Pour certaines capacités, (commme Plus vite que son ombre ou Désarmer), il peut être utile de savoir quelle arme est en main. Pour cela, le script peut utiliser deux méthodes : +

    Pour certaines capacit\xE9s, (commme Plus vite que son ombre ou D\xE9sarmer), il peut \xEAtre utile de savoir quelle arme est en main. Pour cela, le script peut utiliser deux m\xE9thodes :

      -
    • !cof-degainer LL est le label d'une des attaques sur la fiche de personnage : cela fait rengainer l'arme en main et dégainer l'arme correspondant à cette attaque. Si le label ne correspond à aucune attaque (ou qu'on ne donne pas de label), l'action fait rengainer l'arme en main. On peut donner en argument 2 labels d'armes, pour faire dégainer à la fois une arme dans la main droite (le premier label) et une arme dans la main gauche. !cof-degainer l gauche permet de dégainer uniquement une arme dans la main gauche. À noter que si une arme est notée comme arme gauche dans l'attaque, alors elle est toujours portée en main gauche. L'ordre de rengainer fait rengainer les deux armes si le personnage porte une arme en main gauche.
    • -
    • Si on attaque avec !cof-attack tok1 tok2 L, et que l'attaque est de type Arme 1 main, Arme 2 mains ou Arme gauche, alors on considère qu'on doit dégainer cette arme pour pouvoir l'utiliser. Le script envoie le message et considère ensuite l'arme comme étant en main, au MJ de vérifier que le joueur dispose bien d'une action de mouvement pour le faire.
    • -
    • En fin de combat, si le personnage a la capacité frappe du vide, le script va automatiquement lui faire rengainer son arme.
    • -
    • Enfin, en fin de combat, si le personnage possède un prédicat armeParDefaut, le script va lui faire dégainer l'arme dont le label est la valeur du prédicat. Donc si le prédicat n'a pas de label associé, le personnage va rengainer son arme.
    • +
    • !cof-degainer L o\xF9 L est le label d'une des attaques sur la fiche de personnage : cela fait rengainer l'arme en main et d\xE9gainer l'arme correspondant \xE0 cette attaque. Si le label ne correspond \xE0 aucune attaque (ou qu'on ne donne pas de label), l'action fait rengainer l'arme en main. On peut donner en argument 2 labels d'armes, pour faire d\xE9gainer \xE0 la fois une arme dans la main droite (le premier label) et une arme dans la main gauche. !cof-degainer l gauche permet de d\xE9gainer uniquement une arme dans la main gauche. \xC0 noter que si une arme est not\xE9e comme arme gauche dans l'attaque, alors elle est toujours port\xE9e en main gauche. L'ordre de rengainer fait rengainer les deux armes si le personnage porte une arme en main gauche.
    • +
    • Si on attaque avec !cof-attack tok1 tok2 L, et que l'attaque est de type Arme 1 main, Arme 2 mains ou Arme gauche, alors on consid\xE8re qu'on doit d\xE9gainer cette arme pour pouvoir l'utiliser. Le script envoie le message et consid\xE8re ensuite l'arme comme \xE9tant en main, au MJ de v\xE9rifier que le joueur dispose bien d'une action de mouvement pour le faire.
    • +
    • En fin de combat, si le personnage a la capacit\xE9 frappe du vide, le script va automatiquement lui faire rengainer son arme.
    • +
    • Enfin, en fin de combat, si le personnage poss\xE8de un pr\xE9dicat armeParDefaut, le script va lui faire d\xE9gainer l'arme dont le label est la valeur du pr\xE9dicat. Donc si le pr\xE9dicat n'a pas de label associ\xE9, le personnage va rengainer son arme.
    -

    Dans tous les cas, si le personnage dégaine une arme à 2 mains, le script fait enlever le bouclier, et il le fait remettre si on passe d'une arme à 2 mains à une arme à 1 main.

    -

    Il existe un prédicat DEF qui permet d'ajouter sa valeur à la défense d'un personnage. C'est particulièrement utile pour coder une arme de parade. Par exemple avecDEF:2 dans les prédicats de l'arme, elle augmentera la défense de 2 quand elle sera portée.

    +

    Dans tous les cas, si le personnage d\xE9gaine une arme \xE0 2 mains, le script fait enlever le bouclier, et il le fait remettre si on passe d'une arme \xE0 2 mains \xE0 une arme \xE0 1 main.

    +

    Il existe un pr\xE9dicat DEF qui permet d'ajouter sa valeur \xE0 la d\xE9fense d'un personnage. C'est particuli\xE8rement utile pour coder une arme de parade. Par exemple avecDEF:2 dans les pr\xE9dicats de l'arme, elle augmentera la d\xE9fense de 2 quand elle sera port\xE9e.

    Couvert :!cof-bonus-couvert b

    - Pour donner un bonus en DEF contre toutes les attaques à distance, on peut utiliser !cof-bonus-couvert ?{Bonus du couvert?} en sélectionnant les tokens bénéficiant du couvert. La commande accepte un argument --secret permettant de ne pas faire connaître l'action du personnage à tous les joueurs. Pour ne plus être à couvert, il suffit de lancer la commande sans argument. + Pour donner un bonus en DEF contre toutes les attaques \xE0 distance, on peut utiliser !cof-bonus-couvert ?{Bonus du couvert?} en s\xE9lectionnant les tokens b\xE9n\xE9ficiant du couvert. La commande accepte un argument --secret permettant de ne pas faire conna\xEEtre l'action du personnage \xE0 tous les joueurs. Pour ne plus \xEAtre \xE0 couvert, il suffit de lancer la commande sans argument.
    -

    Échecs critiques :

    -

    En cas d'échec critique à une attaque, le script va suggérer des effets d'échec critique inspirés de cette table suggérée par l'auteur du jeu. Le script proposera même dans la plupart des cas un bouton qui automatisera les lancers de dés et l'application de l'effet, si relevant.

    -

    Il est aussi possible d'utiliser une table personnelle, non-automatisée (voir les options d'affichage, !cof-options affichage). La table utilisée (Echec-Critique-Contact) peut être modifiée par le MJ.

    -

    Dégâts directs (sans attaquant, ou aire d'effet trop complexe pour !cof-attack) : !cof-dmg dm

    +

    \xC9checs critiques :

    +

    En cas d'\xE9chec critique \xE0 une attaque, le script va sugg\xE9rer des effets d'\xE9chec critique inspir\xE9s de cette table sugg\xE9r\xE9e par l'auteur du jeu. Le script proposera m\xEAme dans la plupart des cas un bouton qui automatisera les lancers de d\xE9s et l'application de l'effet, si relevant.

    +

    Il est aussi possible d'utiliser une table personnelle, non-automatis\xE9e (voir les options d'affichage, !cof-options affichage). La table utilis\xE9e (Echec-Critique-Contact) peut \xEAtre modifi\xE9e par le MJ.

    +

    D\xE9g\xE2ts directs (sans attaquant, ou aire d'effet trop complexe pour !cof-attack) : !cof-dmg dm

    -

    Applique des dégâts à tous les tokens sélectionnés. L'argument dm peut être un inline roll. Utile par exemple pour les chutes, ou bien les dégâts d'environnement, voire de pièges.
    - Arguments optionels: une partie des options de !cof-attack, dont le type, et par exemple --psave carac seuil (jet de carac, si supérieur au seuil, les dégâts sont divisés par 2). On peut aussi donner un titre aux dégâts en utilisant l'option --titre +

    Applique des d\xE9g\xE2ts \xE0 tous les tokens s\xE9lectionn\xE9s. L'argument dm peut \xEAtre un inline roll. Utile par exemple pour les chutes, ou bien les d\xE9g\xE2ts d'environnement, voire de pi\xE8ges.
    + Arguments optionels: une partie des options de !cof-attack, dont le type, et par exemple --psave carac seuil (jet de carac, si sup\xE9rieur au seuil, les d\xE9g\xE2ts sont divis\xE9s par 2). On peut aussi donner un titre aux d\xE9g\xE2ts en utilisant l'option --titre

    -

    Il est possible d'infliger des dégâts sur la durée en utilisant la commande !cof-effet-temp dotGen(nom) duree --valeur expr type. Les arguments de --valeur donnent l'expression à évaluer, de type lancé de dé, et le type de dégâts. Par défaut, si rien n'est précisé, c'est 1d6 et normal. On peut utiliser les options habituelles de !cof-effet-temp. Ainsi, si on souhaite infliger des dégâts de poison de 1d4+1 par tour, pendant 10 tours, avec un jet de CON difficulté 12 pour arrêter l'effet, on pourra écrire !cof-effet-temp dotGen(monPoison) 10 --saveParTour CON 12 --valeur 1d4+1 poison. +

    Il est possible d'infliger des d\xE9g\xE2ts sur la dur\xE9e en utilisant la commande !cof-effet-temp dotGen(nom) duree --valeur expr type. Les arguments de --valeur donnent l'expression \xE0 \xE9valuer, de type lanc\xE9 de d\xE9, et le type de d\xE9g\xE2ts. Par d\xE9faut, si rien n'est pr\xE9cis\xE9, c'est 1d6 et normal. On peut utiliser les options habituelles de !cof-effet-temp. Ainsi, si on souhaite infliger des d\xE9g\xE2ts de poison de 1d4+1 par tour, pendant 10 tours, avec un jet de CON difficult\xE9 12 pour arr\xEAter l'effet, on pourra \xE9crire !cof-effet-temp dotGen(monPoison) 10 --saveParTour CON 12 --valeur 1d4+1 poison.

    Sortir du combat : !cof-fin-combat

    -

    Ferme aussi le tracker de tour. Encore à mettre en macro dans la barre du MJ (macro automatiquement générée par !cof-set-macros). Permet de tenir compte de pleins de capacités qui durent un combat, ou utilisables une seule fois par combat,...

    +

    Ferme aussi le tracker de tour. Encore \xE0 mettre en macro dans la barre du MJ (macro automatiquement g\xE9n\xE9r\xE9e par !cof-set-macros). Permet de tenir compte de pleins de capacit\xE9s qui durent un combat, ou utilisables une seule fois par combat,...

    -

    Utilisation spéciale des images et son des armes

    +

    Utilisation sp\xE9ciale des images et son des armes

    -

    Les images des armes et les sons peuvent être redéfinis dans le champ détail de l'arme.

    +

    Les images des armes et les sons peuvent \xEAtre red\xE9finis dans le champ d\xE9tail de l'arme.

    Pour ce faire vous devez ajouter les urls des images au format suivant dans la description de l'arme :

    -

    [Type de réussite] url de l'image [Type de réussite]

    +

    [Type de r\xE9ussite] url de l'image [Type de r\xE9ussite]

    Par exemple : [img-attack-echec-critique]https://media0.giphy.com/media/3og0INyCmHlNylks9O/giphy.gif[img-attack-echec-critique]

    -

    Les types de réussite que vous pouvez mettre en image sont :

    +

    Les types de r\xE9ussite que vous pouvez mettre en image sont :

    • [img-attack-echec-critique] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec critique
    • [img-attack-echec] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec
    • [img-attack-echec-clignotement] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec par clignotement
    • -
    • [img-attack-succes-critique] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès critique
    • -
    • [img-attack-succes] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès
    • -
    • [img-attack-succes-champion] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès champion
    • +
    • [img-attack-succes-critique] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s critique
    • +
    • [img-attack-succes] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s
    • +
    • [img-attack-succes-champion] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s champion
    -

    De la même manière vous pouvez ajouter des sons :

    -

    [Type de réussite] Nom du son dans votre jukebox [Type de réussite]

    +

    De la m\xEAme mani\xE8re vous pouvez ajouter des sons :

    +

    [Type de r\xE9ussite] Nom du son dans votre jukebox [Type de r\xE9ussite]

    • [sound-attack-echec-critique] son : joue le son n lorque l'arme fait un echec critique
    • [sound-attack-echec] son : joue le son son lorque l'arme fait un echec
    • [sound-attack-echec-clignotement] son : joue le son son lorque l'arme fait un echec par clignotement
    • -
    • [sound-attack-succes-critique] son : joue le son n lorque l'arme fait un succès critique
    • -
    • [sound-attack-succes] son : joue le son son lorque l'arme fait un succès
    • -
    • [sound-attack-succes-champion] son : joue le son son lorque l'arme fait un succès champion
    • +
    • [sound-attack-succes-critique] son : joue le son n lorque l'arme fait un succ\xE8s critique
    • +
    • [sound-attack-succes] son : joue le son son lorque l'arme fait un succ\xE8s
    • +
    • [sound-attack-succes-champion] son : joue le son son lorque l'arme fait un succ\xE8s champion

    Par exemple : [sound-attack-echec-critique]bang[sound-attack-echec-critique]

    -

    Dans cette exemple le son nomé "bang" dans votre jutbox serra joué a chaque echec critique de cette arme

    +

    Dans cette exemple le son nom\xE9 "bang" dans votre jutbox serra jou\xE9 a chaque echec critique de cette arme

    2.2 Soins :

    !cof-soin @{selected|token_id} @{target|token_id} x

    -

    x peut être un nombre, un jet de dé ou leger, modere, groupe ou secondSouffle.

    -

    Les deux premiers arguments sont optionnels. Si !cof-soin n'a qu'un seul argument, c'est interprété comme le montant des soins, et les tokens soignés sont ceux sélectionnés. Si !cof-soin n'a que 2 arguments, le premier argument est le token du soigneur, et les cibles doivent être désignées avec une option de sélection de groupe.

    +

    x peut \xEAtre un nombre, un jet de d\xE9 ou leger, modere, groupe ou secondSouffle.

    +

    Les deux premiers arguments sont optionnels. Si !cof-soin n'a qu'un seul argument, c'est interpr\xE9t\xE9 comme le montant des soins, et les tokens soign\xE9s sont ceux s\xE9lectionn\xE9s. Si !cof-soin n'a que 2 arguments, le premier argument est le token du soigneur, et les cibles doivent \xEAtre d\xE9sign\xE9es avec une option de s\xE9lection de groupe.

    Options (en plus de options normales de commandes):
      -
    • --portee n : permet de spécifier une distance maximum entre le soigneur et le soigné (au-delà, le soin échoue)
    • -
    • --transfer : le soin est payé avec les PV du soigneur
    • +
    • --portee n : permet de sp\xE9cifier une distance maximum entre le soigneur et le soign\xE9 (au-del\xE0, le soin \xE9choue)
    • +
    • --transfer : le soin est pay\xE9 avec les PV du soigneur
    • --mana n : demande au lanceur de payer n points de mana
    • -
    • --depasseLimite n : permet de lancer les sorts de soins léger, modéré ou de groupe quand la limite journalière est dépassée, mais en augmentant le coût en mana de n à chaque nouveau dépassement.
    • -
    • --limiteSoinsParJour n : limite le nombre total de PVs soignés par jour. Cette limite peut être associée à une ressource (spécifier en deuxième argument de l'option, peut contenir des espaces), de sorte que seuls les soins qui mentionnent cette ressource sont concernés par cette limitation. Cette option n'a de sens que si un soigneur est précisé.
    • -
    • --sacrifierPV : le soigneur doit sacrifier autant de PV que le montant des soins (que ces soins soient utilisés ou non).
    • +
    • --depasseLimite n : permet de lancer les sorts de soins l\xE9ger, mod\xE9r\xE9 ou de groupe quand la limite journali\xE8re est d\xE9pass\xE9e, mais en augmentant le co\xFBt en mana de n \xE0 chaque nouveau d\xE9passement.
    • +
    • --limiteSoinsParJour n : limite le nombre total de PVs soign\xE9s par jour. Cette limite peut \xEAtre associ\xE9e \xE0 une ressource (sp\xE9cifier en deuxi\xE8me argument de l'option, peut contenir des espaces), de sorte que seuls les soins qui mentionnent cette ressource sont concern\xE9s par cette limitation. Cette option n'a de sens que si un soigneur est pr\xE9cis\xE9.
    • +
    • --sacrifierPV : le soigneur doit sacrifier autant de PV que le montant des soins (que ces soins soient utilis\xE9s ou non).
    @@ -615,33 +616,33 @@

    2.3 Repos et changement de jour

    Changement de jour

    -

    !cof-nouveau-jour : remise à zéro de toutes les limites journalières.

    +

    !cof-nouveau-jour : remise \xE0 z\xE9ro de toutes les limites journali\xE8res.

    Repos de plus de 8 h

    -

    Fait récupérer 1 PR ou les points de vie correspondant à 1 PR, plus les points de mana.

    +

    Fait r\xE9cup\xE9rer 1 PR ou les points de vie correspondant \xE0 1 PR, plus les points de mana.

      -
    • !cof-nouveau-jour --repos : Pour une nuit qui se passe bien : fait l'effet d'un nouveau jour sur le monde, et, si aucun token n'est sélectionné, applique un repos de 8 h à tous les tokens de la page, sinon applique ce repos uniquement aux tokens sélectionnés.
    • -
    • !cof-recuperation --reposLong : applique le repos aux tokens selectionnés, sans remettre à zéro les limites journalières. +
    • !cof-nouveau-jour --repos : Pour une nuit qui se passe bien : fait l'effet d'un nouveau jour sur le monde, et, si aucun token n'est s\xE9lectionn\xE9, applique un repos de 8 h \xE0 tous les tokens de la page, sinon applique ce repos uniquement aux tokens s\xE9lectionn\xE9s.
    • +
    • !cof-recuperation --reposLong : applique le repos aux tokens selectionn\xE9s, sans remettre \xE0 z\xE9ro les limites journali\xE8res.

    Repos de 10 minutes

    -

    !cof-recuperation : dépense 1 PR pour se soigner. À mettre en macro associée aux tokens, car tous les joueurs en ont besoin (généré par !cof-set-macros.

    +

    !cof-recuperation : d\xE9pense 1 PR pour se soigner. \xC0 mettre en macro associ\xE9e aux tokens, car tous les joueurs en ont besoin (g\xE9n\xE9r\xE9 par !cof-set-macros.

    -

    2.4 Statut et états

    +

    2.4 Statut et \xE9tats

    -

    !cof-statut affiche l'état courant de tous les tokens sélectionnés. Utile pour connaître facilement les états qui ne sont pas directement visibles sur un token (points de récupération, armes chargées, ...). Il est possible de rajouter l'affichage d'autres attributs que ceux sélectionnés par défaut par le script. Pour cela, utiliser un prédicat attributsDeStatut, de valeur la liste des noms d'attributs à afficher, séparés par des virgules. Attention, si vous avez besoin de séparer vos attributs par des virgules, pensez à utiliser la syntaxe avec ::. Si vous le souhaitez, vous pouvez utiliser plusieurs prédicats nommés attributsDeStatut.

    -

    États gérés en utilisant le statut des tokens

    +

    !cof-statut affiche l'\xE9tat courant de tous les tokens s\xE9lectionn\xE9s. Utile pour conna\xEEtre facilement les \xE9tats qui ne sont pas directement visibles sur un token (points de r\xE9cup\xE9ration, armes charg\xE9es, ...). Il est possible de rajouter l'affichage d'autres attributs que ceux s\xE9lectionn\xE9s par d\xE9faut par le script. Pour cela, utiliser un pr\xE9dicat attributsDeStatut, de valeur la liste des noms d'attributs \xE0 afficher, s\xE9par\xE9s par des virgules. Attention, si vous avez besoin de s\xE9parer vos attributs par des virgules, pensez \xE0 utiliser la syntaxe avec ::. Si vous le souhaitez, vous pouvez utiliser plusieurs pr\xE9dicats nomm\xE9s attributsDeStatut.

    +

    \xC9tats g\xE9r\xE9s en utilisant le statut des tokens

    -

    !cof-set-state etat [true|false] permet de changer l'état des tokens sélectionnés. Si cet état concerne un personnage avec tokens liés (en liant la barre 1 aux points de vie), alors l'état persiste si on change de carte (utilisation d'un attribut hors fiche).

    -

    Liste des états et markers correspondants :

    +

    !cof-set-state etat [true|false] permet de changer l'\xE9tat des tokens s\xE9lectionn\xE9s. Si cet \xE9tat concerne un personnage avec tokens li\xE9s (en liant la barre 1 aux points de vie), alors l'\xE9tat persiste si on change de carte (utilisation d'un attribut hors fiche).

    +

    Liste des \xE9tats et markers correspondants :

    - + @@ -652,40 +653,40 @@

    États gérés en utilisant le statut des

    - + - - - - - @@ -699,14 +700,14 @@

    États gérés en utilisant le statut des

    - - @@ -715,19 +716,19 @@

    États gérés en utilisant le statut des

    - + - + - @@ -741,7 +742,7 @@

    États gérés en utilisant le statut des

    - @@ -755,7 +756,7 @@

    États gérés en utilisant le statut des

    - @@ -763,391 +764,393 @@

    États gérés en utilisant le statut des

    LdB : Livre de Base, Comp : Compagnon
    État\xC9tat Source Remarque Marker Std.
    Affaibli LdB p70Apparaît sur la fiche persoAppara\xEEt sur la fiche perso half-heart cof-affaibli
    Apeuré + Apeur\xE9 Victime d'un sort de Peur screaming cof-apeure
    Assommé + Assomm\xE9 LdB p72 pummeled cof-assomme
    Aveuglé + Aveugl\xE9 LdB p70 Change aussi la vision du token bleeding-eye cof-aveugle
    Blessé + Bless\xE9 LdB p177 arrowed cof-blesse
    Encombré + Encombr\xE9 Comp p103 frozen-orbcof-endormi
    Étourdi + \xC9tourdi LdB p70 half-haze cof-etourdi
    Immobilisé + Immobilis\xE9 LdB p70 cobweb
    Invisible Sort d'invisibilitéSort d'invisibilit\xE9 ninja-mask cof-invisible
    Mort LdB p73Même état pour un PJ juste inconscient à 0 PVM\xEAme \xE9tat pour un PJ juste inconscient \xE0 0 PV dead dead
    Paralysé + Paralys\xE9 LdB p70 fishing-netcof-ralenti
    Renversé + Renvers\xE9 LdB p70 back-paincof-surpris
    Pénombre + P\xE9nombre LdB p71 archery-target
    -

    Pour faciliter la gestion des états, on peut deux macros dans la barre du GM, !cof-set-state ?{État|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blessé|encombre} true, et la même avec false. (N'oubliez pas que la commande !cof-set-macros permet de générer automatiquement les macros utiles au script). Une fois qu'on connaît bien les icônes, on peut directement les changer sur les tokens pour le même effet (et même faire un undo de ces changements si besoin).

    -

    À noter qu'un personnage ayant un prédicat nommé immunite_etat ne pourra pas être mis dans l'état etat.

    -

    Enfin, il est possible de faire réaliser un jet pour se libérer d'un état, en utilisant la commande !cof-save-state etat carac seuil. Il est possible de remplacer seuil par une id de token pour faire faire un test en opposition avec ce token. On peut aussi passer la caractéristique et le seuil en argument à !cof-set-state pour proposer le jet à chaque fois qu'on affiche les actions du tour ou qu'on affiche le statut du personnage.

    +

    Pour faciliter la gestion des \xE9tats, on peut deux macros dans la barre du GM, !cof-set-state ?{\xC9tat|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|bless\xE9|encombre} true, et la m\xEAme avec false. (N'oubliez pas que la commande !cof-set-macros permet de g\xE9n\xE9rer automatiquement les macros utiles au script). Une fois qu'on conna\xEEt bien les ic\xF4nes, on peut directement les changer sur les tokens pour le m\xEAme effet (et m\xEAme faire un undo de ces changements si besoin).

    +

    \xC0 noter qu'un personnage ayant un pr\xE9dicat nomm\xE9 immunite_etat ne pourra pas \xEAtre mis dans l'\xE9tat etat.

    +

    Enfin, il est possible de faire r\xE9aliser un jet pour se lib\xE9rer d'un \xE9tat, en utilisant la commande !cof-save-state etat carac seuil. Il est possible de remplacer seuil par une id de token pour faire faire un test en opposition avec ce token. On peut aussi passer la caract\xE9ristique et le seuil en argument \xE0 !cof-set-state pour proposer le jet \xE0 chaque fois qu'on affiche les actions du tour ou qu'on affiche le statut du personnage.

    -

    Affaiblissements de caractéristiques

    +

    Affaiblissements de caract\xE9ristiques

    - !cof-affaiblir-carac carac valeur permet d'affaiblir temporairement une caractéristique (force, dextérité, constitution, intelligence, sagesse, charisme ou random) d'une valeur positive. Il existe aussi une option pour les attaques, --affaiblirCarac, qui permet de n'affaiblir une caractéristique que si une attaque est réussie. + !cof-affaiblir-carac carac valeur permet d'affaiblir temporairement une caract\xE9ristique (force, dext\xE9rit\xE9, constitution, intelligence, sagesse, charisme ou random) d'une valeur positive. Il existe aussi une option pour les attaques, --affaiblirCarac, qui permet de n'affaiblir une caract\xE9ristique que si une attaque est r\xE9ussie.

    -

    Une caractéristique affaiblie remonte de 1 après chaque nuit de repos. Le sort de régénération permet de récupérer 1d4 points d'une seule caractéristique physique (d'abord constitution, puis force puis dextérité). Le sort délivrance permet de récupérer 1d4 point d'une seule caractéristique, et comme indiqué dans les règles, le sort de guérison annule tous les affaiblissements de caractéritiques. Enfin le script propose une commande dédiée, !cof-soigner-affaiblissement carac valeur pour soigner les affaiblissements. +

    Une caract\xE9ristique affaiblie remonte de 1 apr\xE8s chaque nuit de repos. Le sort de r\xE9g\xE9n\xE9ration permet de r\xE9cup\xE9rer 1d4 points d'une seule caract\xE9ristique physique (d'abord constitution, puis force puis dext\xE9rit\xE9). Le sort d\xE9livrance permet de r\xE9cup\xE9rer 1d4 point d'une seule caract\xE9ristique, et comme indiqu\xE9 dans les r\xE8gles, le sort de gu\xE9rison annule tous les affaiblissements de caract\xE9ritiques. Enfin le script propose une commande d\xE9di\xE9e, !cof-soigner-affaiblissement carac valeur pour soigner les affaiblissements.

    -

    À noter que la diminution de constitution fait baisser les points de vie maximum, et qu'une constitution de 0 conduit à la mort.

    +

    \xC0 noter que la diminution de constitution fait baisser les points de vie maximum, et qu'une constitution de 0 conduit \xE0 la mort.

    -

    Conditions hostiles et extrêmes

    +

    Conditions hostiles et extr\xEAmes

    -

    Pour des conditions hostiles, faire !cof-effet conditionsHostiles oui en sélectionnant les personnages concernés. Pour des conditions extrêmes, !cof-effet conditionsHostiles 5. À noter que le script permet de passer en argument n'importe quel nombre, qui sera appliqué en malus à la DEX, FOR, DEF et attaque.

    +

    Pour des conditions hostiles, faire !cof-effet conditionsHostiles oui en s\xE9lectionnant les personnages concern\xE9s. Pour des conditions extr\xEAmes, !cof-effet conditionsHostiles 5. \xC0 noter que le script permet de passer en argument n'importe quel nombre, qui sera appliqu\xE9 en malus \xE0 la DEX, FOR, DEF et attaque.

    Autres bufs et debufs

    !cof-buf-def n : buf ou debuf de la DEF.

    -

    !cof-remove-buf-def : enlève tout buf ou debuf de la def.

    -

    !cof-effet-temp effet duree : ajoute l'effet effet à la cible pour la durée, !cof-effet-combat effet ajoute l'effet pour le combat, et !cof-effet effet ajoute ou enlève un effet à durée indéterminée. À noter que si la durée est 0 ou fin, alors la commande met fin à l'effet (utile pour des effets temporaires qui ont une action en fin d'effet, comme agrandissement ou formeDArbre). Un personnage ayant un prédicat nommé immunite_effetTemp est immunisé à l'effet temporaire de nom effetTemp.

    +

    !cof-remove-buf-def : enl\xE8ve tout buf ou debuf de la def.

    +

    !cof-effet-temp effet duree : ajoute l'effet effet \xE0 la cible pour la dur\xE9e, !cof-effet-combat effet ajoute l'effet pour le combat, et !cof-effet effet ajoute ou enl\xE8ve un effet \xE0 dur\xE9e ind\xE9termin\xE9e. \xC0 noter que si la dur\xE9e est 0 ou fin, alors la commande met fin \xE0 l'effet (utile pour des effets temporaires qui ont une action en fin d'effet, comme agrandissement ou formeDArbre). Un personnage ayant un pr\xE9dicat nomm\xE9 immunite_effetTemp est immunis\xE9 \xE0 l'effet temporaire de nom effetTemp.

    • --lanceur id : indique quel est le lanceur. Utile pour un certain nombre d'autres options.
    • -
    • --mana id cout : impose au token id de dépenser cout mana. Si --lanceur est donné, id est inutile. La présence de cette option, même avec un coût de 0, indique au script que l'effet devrait être supprimé à la mort du lanceur.
    • -
    • --limiteParJour l : limite le nombre d'utilisations de cette effet à l fois par jour. On peut préciser un nom après l, qui va correspondre à une ressource pouvant être partagée avec d'autres attaques ou d'autres effets (voir !cof-attack). Par défaut, le nom de cette ressource est effet. Attention, il faut un lanceur auquel appliquer la limite par jour !
    • -
    • --limiteParCombat : même effet que la limite par jour. Si aucun argument n'est donné, la limite est de une fois par combat. Attention, il faut un lanceur auquel appliquer la limite par combat !
    • -
    • --tempsRecharge effet duree : l'action n'est possible que si l'effet est inactif sur le personnage qui génère l'effet, et de plus active l'effet sur celui-ci pour la durée indiquée. Il existe un effet temporaire générique, rechargeGen(desc) que vous pouvez utiliser si aucun effet existant ne correspond.
    • -
    • --dose nom: définie une ressource nommée dose_nom, dont la valeur doit être positive. Utile par exemple pour les parchemins, les potions ou les baguettes.
    • -
    • --portee id d : impose aux cibles de l'effet d'être à moins de d mètres du token id. Si --lanceur est précisé, inutile de donner id.
    • +
    • --mana id cout : impose au token id de d\xE9penser cout mana. Si --lanceur est donn\xE9, id est inutile. La pr\xE9sence de cette option, m\xEAme avec un co\xFBt de 0, indique au script que l'effet devrait \xEAtre supprim\xE9 \xE0 la mort du lanceur.
    • +
    • --limiteParJour l : limite le nombre d'utilisations de cette effet \xE0 l fois par jour. On peut pr\xE9ciser un nom apr\xE8s l, qui va correspondre \xE0 une ressource pouvant \xEAtre partag\xE9e avec d'autres attaques ou d'autres effets (voir !cof-attack). Par d\xE9faut, le nom de cette ressource est effet. Attention, il faut un lanceur auquel appliquer la limite par jour !
    • +
    • --limiteParCombat : m\xEAme effet que la limite par jour. Si aucun argument n'est donn\xE9, la limite est de une fois par combat. Attention, il faut un lanceur auquel appliquer la limite par combat !
    • +
    • --tempsRecharge effet duree : l'action n'est possible que si l'effet est inactif sur le personnage qui g\xE9n\xE8re l'effet, et de plus active l'effet sur celui-ci pour la dur\xE9e indiqu\xE9e. Il existe un effet temporaire g\xE9n\xE9rique, rechargeGen(desc) que vous pouvez utiliser si aucun effet existant ne correspond.
    • +
    • --dose nom: d\xE9finie une ressource nomm\xE9e dose_nom, dont la valeur doit \xEAtre positive. Utile par exemple pour les parchemins, les potions ou les baguettes.
    • +
    • --portee id d : impose aux cibles de l'effet d'\xEAtre \xE0 moins de d m\xE8tres du token id. Si --lanceur est pr\xE9cis\xE9, inutile de donner id.
    • --puissant : lance la version puissante de l'effet
    • --puissant oui : idem
    • --puissant non : lance la version non puissante (efface le dernier effet puissant)
    • -
    • --puissant duree : multiplie la durée par 2
    • -
    • --puissant portee : multiplie la portée par 2
    • -
    • --saveParTour carac seuil : la cible peut se sortir de l'effet chaque tour grâce à un test de carac de difficulte seuil.
    • -
    • --saveActifParTour carac seuil : la cible peut se sortir de l'effet à tour grâce à un test de carac de difficulte seuil (utilisation dans bouton dans la liste d'actions).
    • -
    • --save carac seuil : la cible peut faire un jet pour échapper à l'effet. Si on ajoute l'argument demiDuree, alors réussir la sauvegarde ne fait que diviser la durée.
    • +
    • --puissant duree : multiplie la dur\xE9e par 2
    • +
    • --puissant portee : multiplie la port\xE9e par 2
    • +
    • --saveParTour carac seuil : la cible peut se sortir de l'effet chaque tour gr\xE2ce \xE0 un test de carac de difficulte seuil.
    • +
    • --saveActifParTour carac seuil : la cible peut se sortir de l'effet \xE0 tour gr\xE2ce \xE0 un test de carac de difficulte seuil (utilisation dans bouton dans la liste d'actions).
    • +
    • --save carac seuil : la cible peut faire un jet pour \xE9chapper \xE0 l'effet. Si on ajoute l'argument demiDuree, alors r\xE9ussir la sauvegarde ne fait que diviser la dur\xE9e.
    • --seulementVivant : l'effet ne peut s'appliquer qu'aux personnages vivants.
    • -
    • --tempeteDeMana liste : indique des effets de tempête de mana. La liste peut contenir un nombre (pour l'effet intense), duree, rapide et portee. Si le rang du sort est spécifié (par l'option --rang, un message est affichée si le coût en mana est supérieur au rang. Si la liste d'options est vide, le script affiche un menu dans le chat pour spécifier les options de tempête de mana.
    • -
    • --magieEnArmure : indique d'appliquer les règles pour la magie en armure pour un profil hybride. Il faut pour cela un lanceur défini. Par defaut, va faire test l'intelligence par un jet de difficulté 10 + rang + malus d'armure. Le rang est obtenu par l'option --rang. J'utilise le malus d'armure car il n'y a pas moyen de distinguer la DEF intrinsèque de l'armure de ses bonus de DEF dûs à un bonus magique. Enfin, on peut utiliser la règle de dépense supplémentaire de mana à la place du jet d'INT en utilisant l'option --magieEnarmure mana. Encore une fois, je prends le malus d'armure, divisé par 3 et arrondi au supérieur pour les règles de mana de base.
    • -
    • --accumuleDuree n : l'effet peut être accumulé : chaque fois qu'on applique à nouveau l'effet avec une durée donnée, on ajoute cette durée à la durée courante de l'effet sur la cible. On ne peut cumuler ainsi que n instances de l'effet.
    • -
    • --valeur n : pour certains effet, permet de spécifier une valeur qui remplace la valeur par défaut de l'effet.
    • -
    • --optionEffet opt arg1 arg2 ... : spécifie une option à l'effet. L'option opt doit être donnée sans le -- et sera passée telle quelle à l'effet, par exemple pour les dégâts périodiques. Si on a besoin de plusieurs options, il faut utiliser plusieurs fois --optionEffet.
    • -
    • --secret : le résultat de l'effet est chuchoté au joueur qui lance la commande.
    • -
    • --fx effet : affiche l'effet spécial entre le lanceur et ses cibles. Il est possible d'utiliser un effet que vous avez défini vous-même en utilisant l'option --fx custom nom, où nom est le nom de votre effet.
    • -
    • --targetFx effet : affiche l'effet spécial sur toutes les cibles (l'effet ne doit pas être directionnel).
    • +
    • --tempeteDeMana liste : indique des effets de temp\xEAte de mana. La liste peut contenir un nombre (pour l'effet intense), duree, rapide et portee. Si le rang du sort est sp\xE9cifi\xE9 (par l'option --rang, un message est affich\xE9e si le co\xFBt en mana est sup\xE9rieur au rang. Si la liste d'options est vide, le script affiche un menu dans le chat pour sp\xE9cifier les options de temp\xEAte de mana.
    • +
    • --magieEnArmure : indique d'appliquer les r\xE8gles pour la magie en armure pour un profil hybride. Il faut pour cela un lanceur d\xE9fini. Par defaut, va faire test l'intelligence par un jet de difficult\xE9 10 + rang + malus d'armure. Le rang est obtenu par l'option --rang. J'utilise le malus d'armure car il n'y a pas moyen de distinguer la DEF intrins\xE8que de l'armure de ses bonus de DEF d\xFBs \xE0 un bonus magique. Enfin, on peut utiliser la r\xE8gle de d\xE9pense suppl\xE9mentaire de mana \xE0 la place du jet d'INT en utilisant l'option --magieEnarmure mana. Encore une fois, je prends le malus d'armure, divis\xE9 par 3 et arrondi au sup\xE9rieur pour les r\xE8gles de mana de base.
    • +
    • --accumuleDuree n : l'effet peut \xEAtre accumul\xE9 : chaque fois qu'on applique \xE0 nouveau l'effet avec une dur\xE9e donn\xE9e, on ajoute cette dur\xE9e \xE0 la dur\xE9e courante de l'effet sur la cible. On ne peut cumuler ainsi que n instances de l'effet.
    • +
    • --valeur n : pour certains effet, permet de sp\xE9cifier une valeur qui remplace la valeur par d\xE9faut de l'effet.
    • +
    • --optionEffet opt arg1 arg2 ... : sp\xE9cifie une option \xE0 l'effet. L'option opt doit \xEAtre donn\xE9e sans le -- et sera pass\xE9e telle quelle \xE0 l'effet, par exemple pour les d\xE9g\xE2ts p\xE9riodiques. Si on a besoin de plusieurs options, il faut utiliser plusieurs fois --optionEffet.
    • +
    • --secret : le r\xE9sultat de l'effet est chuchot\xE9 au joueur qui lance la commande.
    • +
    • --fx effet : affiche l'effet sp\xE9cial entre le lanceur et ses cibles. Il est possible d'utiliser un effet que vous avez d\xE9fini vous-m\xEAme en utilisant l'option --fx custom nom, o\xF9 nom est le nom de votre effet.
    • +
    • --targetFx effet : affiche l'effet sp\xE9cial sur toutes les cibles (l'effet ne doit pas \xEAtre directionnel).
    • --son son : joue le son (normalement compatible avec Roll20AM)
    • --image img : affiche l'image dans le texte d'activation de l'effet.
    • -
    • --tokenSide n : utilisable seulement pour les tokens à plusieurs faces. Dans ce cas, va changer la face du token en n (à noter que les faces sont numérotées à partir de 0). Quand l'effet se termine, le token retrouve la face qu'il avait au moment où on avait appliqué l'effet.
    • -
    • --type : il est possible d'associer un type à l'effet. L'utilisation la plus courante est le type poison ou maladie, qui vont permettre de tenir compte des bonus ou immunités contre les effets de ce type.
    • -
    • --montreActions : affiche les actions du tours de la cible après avoir appliqué l'effet. Utile si les actions du tours dépendent de cet effet, pour afficher une liste à jour.
    • -
    • --degainer L : le lanceur dégaine l'arme de label L.
    • +
    • --tokenSide n : utilisable seulement pour les tokens \xE0 plusieurs faces. Dans ce cas, va changer la face du token en n (\xE0 noter que les faces sont num\xE9rot\xE9es \xE0 partir de 0). Quand l'effet se termine, le token retrouve la face qu'il avait au moment o\xF9 on avait appliqu\xE9 l'effet.
    • +
    • --type : il est possible d'associer un type \xE0 l'effet. L'utilisation la plus courante est le type poison ou maladie, qui vont permettre de tenir compte des bonus ou immunit\xE9s contre les effets de ce type.
    • +
    • --montreActions : affiche les actions du tours de la cible apr\xE8s avoir appliqu\xE9 l'effet. Utile si les actions du tours d\xE9pendent de cet effet, pour afficher une liste \xE0 jour.
    • +
    • --degainer L : le lanceur d\xE9gaine l'arme de label L.
    -

    !cof-boire-alcool et !cof-desaouler permettent de faire varier le niveau d'ébriété. Par exemple, pour tester si le niveau d'ébriété augmente après avoir bu un certain nombre de verres, on peut utiliser la macro !cof-boire-alcool --save CON [[10+?{Nombre de verres}]]. +

    !cof-boire-alcool et !cof-desaouler permettent de faire varier le niveau d'\xE9bri\xE9t\xE9. Par exemple, pour tester si le niveau d'\xE9bri\xE9t\xE9 augmente apr\xE8s avoir bu un certain nombre de verres, on peut utiliser la macro !cof-boire-alcool --save CON [[10+?{Nombre de verres}]].

    -

    Effets retardés

    +

    Effets retard\xE9s

    -

    On peut utiliser l'effet temporaire générique messageRetarde(nom) pour programmer un message qui sera affiché après un certain nombre de tours. Au bout de ce nombre de tours, le nom est affiché, ainsi que le texte de valeur (avec --valeur si besoin). La syntaxe est !cof-effet-temp messageRetarde(nom) duree --valeur message. Si vous avez besoin d'un message qui contienne des espaces, remplacez les espaces par des _.

    -

    On peut aussi déclencher un effet après un certain nombre de tour avec l'effet temporaire générique effetRetarde(effet). Après la durée de l'effet retardé, si effet est un état, la cible est mise dans cet état, si c'est un effet temporaire, on lui applique cet effet pour une durée de 1 tour, ou si un argument --valeur a été donné, il sera utilisé comme durée. Enfin si ce n'est ni l'un ni l'autre, un attribut avec le nom effet sera créé, de valeur courante true, ou bien si un argument --valeur a été donné, cette valeur sera utilisée comme valeur courante de l'attribut effet.

    +

    On peut utiliser l'effet temporaire g\xE9n\xE9rique messageRetarde(nom) pour programmer un message qui sera affich\xE9 apr\xE8s un certain nombre de tours. Au bout de ce nombre de tours, le nom est affich\xE9, ainsi que le texte de valeur (avec --valeur si besoin). La syntaxe est !cof-effet-temp messageRetarde(nom) duree --valeur message. Si vous avez besoin d'un message qui contienne des espaces, remplacez les espaces par des _.

    +

    On peut aussi d\xE9clencher un effet apr\xE8s un certain nombre de tour avec l'effet temporaire g\xE9n\xE9rique effetRetarde(effet). Apr\xE8s la dur\xE9e de l'effet retard\xE9, si effet est un \xE9tat, la cible est mise dans cet \xE9tat, si c'est un effet temporaire, on lui applique cet effet pour une dur\xE9e de 1 tour, ou si un argument --valeur a \xE9t\xE9 donn\xE9, il sera utilis\xE9 comme dur\xE9e. Enfin si ce n'est ni l'un ni l'autre, un attribut avec le nom effet sera cr\xE9\xE9, de valeur courante true, ou bien si un argument --valeur a \xE9t\xE9 donn\xE9, cette valeur sera utilis\xE9e comme valeur courante de l'attribut effet.

    -

    Prédicats : !cof-set-predicate

    +

    Pr\xE9dicats : !cof-set-predicate

    -

    Il est possible d'ajouter ou de retirer un prédicat avec la fonction !cof-set-predicate nom, optionellement suivi de true ou false.

    +

    Il est possible d'ajouter ou de retirer un pr\xE9dicat avec la fonction !cof-set-predicate nom, optionellement suivi de true ou false.

    Autres attributs : !cof-set-attribute

    - Il est possible de changer ou créer n'importe quel attribut avec la fonction !cof-set-attribute nom val. Optionellement, on peut spécifier en troisième argument une valeur maximale de l'attribut (comme dans !cof-set-attribute nom val max). Attention, ça peut interragir de façon imprévue avec le script ou la fiche, si on écrit dans un attribut utilisé par la fiche. + Il est possible de changer ou cr\xE9er n'importe quel attribut avec la fonction !cof-set-attribute nom val. Optionellement, on peut sp\xE9cifier en troisi\xE8me argument une valeur maximale de l'attribut (comme dans !cof-set-attribute nom val max). Attention, \xE7a peut interragir de fa\xE7on impr\xE9vue avec le script ou la fiche, si on \xE9crit dans un attribut utilis\xE9 par la fiche.

    2.5 Sorts

    -

    !cof-attaque-magique @{selected|token_id} @{target|token_id} : fait un jet d'attaque magique opposé entre le lanceur et sa cible, et dit juste si le sort est raté ou réussi. Options disponibles : --portee et --mana.

    -

    !cof-lancer-sort texte : le token sélectionné lance un sort sans support particulier du script (seul un whisper est envoyé au joueur et au MJ). Options disponibles : --manapour indiquer un coût en mana et --son pour jouer un son. Pour un sort sur plusieurs cibles, utiliser l'option --lanceur @{selected|token_id}.

    -

    !cof-peur difficulté durée : effet de peur (nécromant, dragon, etc). Tant que la peur est active, statut screaming. difficulté est la difficulté du jet de SAG.

    +

    !cof-attaque-magique @{selected|token_id} @{target|token_id} : fait un jet d'attaque magique oppos\xE9 entre le lanceur et sa cible, et dit juste si le sort est rat\xE9 ou r\xE9ussi. Options disponibles : --portee et --mana.

    +

    !cof-lancer-sort texte : le token s\xE9lectionn\xE9 lance un sort sans support particulier du script (seul un whisper est envoy\xE9 au joueur et au MJ). Options disponibles : --manapour indiquer un co\xFBt en mana et --son pour jouer un son. Pour un sort sur plusieurs cibles, utiliser l'option --lanceur @{selected|token_id}.

    +

    !cof-peur difficult\xE9 dur\xE9e : effet de peur (n\xE9cromant, dragon, etc). Tant que la peur est active, statut screaming. difficult\xE9 est la difficult\xE9 du jet de SAG.

    Options :
      -
    • --resisteAvecForce : on prend le max de FOR et SAG pour résister
    • -
    • --etourdi : la peur fait fuir ou rend étourdi
    • +
    • --resisteAvecForce : on prend le max de FOR et SAG pour r\xE9sister
    • +
    • --etourdi : la peur fait fuir ou rend \xE9tourdi
    • --ralenti : la peur ralenti
    • -
    • --secoue : la peur ne donne qu'un malus de -2 aux tests. Mais un autre effet de peur de même type fait fuir.
    • +
    • --paralyse : la peur paralyse
    • +
    • --secoue : la peur ne donne qu'un malus de -2 aux tests. Mais un autre effet de peur de m\xEAme type fait fuir.
    • --effroi : la peur est passive (pas un sort)
    • -
    • --portee n : limite la portée du sort à n metres.
    • -
    • --lanceur id : le lanceur de l'effet de peur (si il y en a un). Nécessaire pour la portée, par exemple.
    • -
    • --titre message : spécifie un titre pour la fenêtre affichant les jets de résistance à la peur.
    • -
    • --immuniseSiResiste nom : la personne qui résiste à cet effet de peur est ensuite immunisé pour la journée aux effets de peur ayant la même option (avec le même nom).
    • +
    • --portee n : limite la port\xE9e du sort \xE0 n metres.
    • +
    • --lanceur id : le lanceur de l'effet de peur (si il y en a un). N\xE9cessaire pour la port\xE9e, par exemple.
    • +
    • --titre message : sp\xE9cifie un titre pour la fen\xEAtre affichant les jets de r\xE9sistance \xE0 la peur.
    • +
    • --immuniseSiResiste nom : la personne qui r\xE9siste \xE0 cet effet de peur est ensuite immunis\xE9 pour la journ\xE9e aux effets de peur ayant la m\xEAme option (avec le m\xEAme nom).
    - Noter qu'un prédicat courage permet d'obtenir un bonus (égal à la valeur du prédicat) au jet pour résister à la peur. + Noter qu'un pr\xE9dicat courage permet d'obtenir un bonus (\xE9gal \xE0 la valeur du pr\xE9dicat) au jet pour r\xE9sister \xE0 la peur.

    2.6 Consommables !cof-consommables

    -

    Cette fonction affiche une liste de consommables, avec la possibilité de cliquer sur un élément de la liste pour le consommer (et activer son effet) ou l'échanger avec un autre personnage (via le symbole d'échange).

    -

    Pour cela, la fonction utilise la liste des consommables sur la fiche (onglet "Équipement"). Elle ne va afficher que les consommables qui ont un effet (décrit dans la ligne Effet sous le nom du consommable).

    +

    Cette fonction affiche une liste de consommables, avec la possibilit\xE9 de cliquer sur un \xE9l\xE9ment de la liste pour le consommer (et activer son effet) ou l'\xE9changer avec un autre personnage (via le symbole d'\xE9change).

    +

    Pour cela, la fonction utilise la liste des consommables sur la fiche (onglet "\xC9quipement"). Elle ne va afficher que les consommables qui ont un effet (d\xE9crit dans la ligne Effet sous le nom du consommable).

    Exemple d'une liste de consommable.
    - +

    Pour l'instant, seules les commandes !cof-effet-temp, !cof-effet-combat, !cof-effet, !cof-enduire-poison, !cof-attack, !cof-lancer-sort et !cof-soin diminuent correctement le nombre de consommables.

    Attention :

      -
    • Pour la commande !cof-attack, il est vivemement recommandé de ne pas utiliser de label, mais uniquement un nom et des options si vous voulez faciliter l'échange du consommable.
    • -
    • De manière générale, faites attention avec les références utilisé dans le consommable du personnage qui utilise le consommable.
      +
    • Pour la commande !cof-attack, il est vivemement recommand\xE9 de ne pas utiliser de label, mais uniquement un nom et des options si vous voulez faciliter l'\xE9change du consommable.
    • +
    • De mani\xE8re g\xE9n\xE9rale, faites attention avec les r\xE9f\xE9rences utilis\xE9 dans le consommable du personnage qui utilise le consommable.
    -

    L'échange via le symbole vous permettra de sélectionner un token destinataire qui recevra le consommable dans sa liste. Si le consommable existe déjà pour le destinataire, sa quantité sera augmenté de 1, sinon le consommable sera créé.

    +

    L'\xE9change via le symbole vous permettra de s\xE9lectionner un token destinataire qui recevra le consommable dans sa liste. Si le consommable existe d\xE9j\xE0 pour le destinataire, sa quantit\xE9 sera augment\xE9 de 1, sinon le consommable sera cr\xE9\xE9.

    -

    Cette fonction peut-être très utile pour que les PJ échangent entre eux un consommable, mais aussi pour faciliter la vente d'objet entre PNJ et PJ.

    -

    Pour cette dernière, il vous suffira de préparer un personnage avec un token qui contient, dans son équipement, les consommables à échanger/vendre.

    +

    Cette fonction peut-\xEAtre tr\xE8s utile pour que les PJ \xE9changent entre eux un consommable, mais aussi pour faciliter la vente d'objet entre PNJ et PJ.

    +

    Pour cette derni\xE8re, il vous suffira de pr\xE9parer un personnage avec un token qui contient, dans son \xE9quipement, les consommables \xE0 \xE9changer/vendre.

    -

    2.7 Déplacements

    +

    2.7 D\xE9placements

    Retrouver un personnage

    -

    Pour centrer la vue d'un joueur sur un token particulier, on peut utiliser !cof-centrer-sur-token suivi du nom du token. Généralement, c'est une bonne idée pour un joueur d'avoir une macro avec le nom de son token pour le retrouver facilement quand il arrive sur une nouvelle carte.

    +

    Pour centrer la vue d'un joueur sur un token particulier, on peut utiliser !cof-centrer-sur-token suivi du nom du token. G\xE9n\xE9ralement, c'est une bonne id\xE9e pour un joueur d'avoir une macro avec le nom de son token pour le retrouver facilement quand il arrive sur une nouvelle carte.

    -

    Personnages immobilisés

    +

    Personnages immobilis\xE9s

    -

    Le script bloque automatiquement personnages immobilisés (paralysé, étourdi, etc...). Pour permettre de déplacer ces personnages vous pouvez simplement enlever le blockage (click droit sur le token, propriétés avancées). Si vous souhaitez être le seul à pouvoir le bouger, sélectionner le (ou les) token et cliquer sur la macro Bouger. Cela crée un token non bloqué associé au personnage. Bien penser à supprimer ce token après utilisation.

    +

    Le script bloque automatiquement personnages immobilis\xE9s (paralys\xE9, \xE9tourdi, etc...). Pour permettre de d\xE9placer ces personnages vous pouvez simplement enlever le blockage (click droit sur le token, propri\xE9t\xE9s avanc\xE9es). Si vous souhaitez \xEAtre le seul \xE0 pouvoir le bouger, s\xE9lectionner le (ou les) token et cliquer sur la macro Bouger. Cela cr\xE9e un token non bloqu\xE9 associ\xE9 au personnage. Bien penser \xE0 supprimer ce token apr\xE8s utilisation.

    Il est possible de mettre le jeu en pause (les joueurs ne peuvent plus bouger leurs tokens) en utilisant la macro ⏸. La macro change alors de nom et devient ⏵, que vous pouvez utiliser pour enlever la pause.

    Escaliers

    -

    Pour gérer les escaliers sur les cartes, vous pouvez utiliser la méthode suivante, inspirée du script Teleport : placez dans le layer "GM Info Overlay", au niveau des escaliers, des tokens qui prennent exactement la place des escaliers. Nommez ces escaliers avec un nom, suivi d'une lettre majuscule. Par exemple EscalierA.

    -

    Chaque escalier de la même colonne doit avoir le même nom, et différer seulement par la lettre finale. Ensuite, si un ensemble de tokens est sur un escalier, utilisez !cof-escalier pour téléporter les tokens à l'emplacement de l'escalier suivant dans l'ordre des lettres. Si vous utilisez l'argument haut, alors les tokens n'iront pas plus loin que le dernier étage, et avec l'argument bas, il iront dans l'ordre inverse.

    -

    Dans l'exemple précédent, il serait téléporté à l'emplacement du token nommé EscalierB. Cela ne fonctionne que si les bouts de l'escalier sont sur la même carte. À vous de choisir sir vous préférez révéler cette fonctionalité à vos joueurs, ou si vous le faites vous-même.

    -

    La limite au nombre d'escaliers est de 12 étages, donc pas de lettre après L.

    -

    Il est possible d'avoir des escaliers qui mènent à d'autres cartes (ce qui fait alors changer la carte vue par le joueur). Il suffit que le nom de l'escalier commence par tmap_. Attention, à cause de limitations de Roll20, cela ne peut fonctionner que si l'image du token est dans une lirary personnelle d'un joueur : si elle vient du marketplace, il fait d'abord la copier dans sa library, puis utiliser l'image qui est dans la library pour le token.

    +

    Pour g\xE9rer les escaliers sur les cartes, vous pouvez utiliser la m\xE9thode suivante, inspir\xE9e du script Teleport : placez dans le layer "GM Info Overlay", au niveau des escaliers, des tokens qui prennent exactement la place des escaliers. Nommez ces escaliers avec un nom, suivi d'une lettre majuscule. Par exemple EscalierA.

    +

    Chaque escalier de la m\xEAme colonne doit avoir le m\xEAme nom, et diff\xE9rer seulement par la lettre finale. Ensuite, si un ensemble de tokens est sur un escalier, utilisez !cof-escalier pour t\xE9l\xE9porter les tokens \xE0 l'emplacement de l'escalier suivant dans l'ordre des lettres. Si vous utilisez l'argument haut, alors les tokens n'iront pas plus loin que le dernier \xE9tage, et avec l'argument bas, il iront dans l'ordre inverse.

    +

    Dans l'exemple pr\xE9c\xE9dent, il serait t\xE9l\xE9port\xE9 \xE0 l'emplacement du token nomm\xE9 EscalierB. Cela ne fonctionne que si les bouts de l'escalier sont sur la m\xEAme carte. \xC0 vous de choisir sir vous pr\xE9f\xE9rez r\xE9v\xE9ler cette fonctionalit\xE9 \xE0 vos joueurs, ou si vous le faites vous-m\xEAme.

    +

    La limite au nombre d'escaliers est de 12 \xE9tages, donc pas de lettre apr\xE8s L.

    +

    Il est possible d'avoir des escaliers qui m\xE8nent \xE0 d'autres cartes (ce qui fait alors changer la carte vue par le joueur). Il suffit que le nom de l'escalier commence par tmap_. Attention, \xE0 cause de limitations de Roll20, cela ne peut fonctionner que si l'image du token est dans une lirary personnelle d'un joueur : si elle vient du marketplace, il fait d'abord la copier dans sa library, puis utiliser l'image qui est dans la library pour le token.

    Montures

    -

    Pour qu'un personnage puisse monter sur une monture, il faut que cette monture soit associée à une fiche de personnage et qu'il possède un prédicat monture. La commande pour monter sur la monture est !cof-en-selle @{selected|token_id} @{target|token_id}, à lancer en sélectionnant le cavalier.

    -

    On peut ensuite bouger la monture, cela déplace le cavalier. Le mieux est de lancer la commander alors que le token du cavalier est sur le token de la monture. Si on déplace le cavalier, cela fait aussi bouger sa monture.

    +

    Pour qu'un personnage puisse monter sur une monture, il faut que cette monture soit associ\xE9e \xE0 une fiche de personnage et qu'il poss\xE8de un pr\xE9dicat monture. La commande pour monter sur la monture est !cof-en-selle @{selected|token_id} @{target|token_id}, \xE0 lancer en s\xE9lectionnant le cavalier.

    +

    On peut ensuite bouger la monture, cela d\xE9place le cavalier. Le mieux est de lancer la commander alors que le token du cavalier est sur le token de la monture. Si on d\xE9place le cavalier, cela fait aussi bouger sa monture.

    Suivre un autre personnages

    - Le principe est le suivant : on sélectionne un token, dans les abilities qui s'affichent en haut de la map, on clique sur Suivre, puis on sélectionne le token à suivre. À partir de ce moment, le script déplace le premier token à chaque fois qu'on déplace le second (en tenant compte des états qui empêchent le mouvement et des obstacles sur le layer de lumière, si ils doivent empêcher le mouvement). On peut aussi suivre un token qui en suit un autre. Et pour arrêter de suivre un token, il suffit de déplacer manuellement le premier token. + Le principe est le suivant : on s\xE9lectionne un token, dans les abilities qui s'affichent en haut de la map, on clique sur Suivre, puis on s\xE9lectionne le token \xE0 suivre. \xC0 partir de ce moment, le script d\xE9place le premier token \xE0 chaque fois qu'on d\xE9place le second (en tenant compte des \xE9tats qui emp\xEAchent le mouvement et des obstacles sur le layer de lumi\xE8re, si ils doivent emp\xEAcher le mouvement). On peut aussi suivre un token qui en suit un autre. Et pour arr\xEAter de suivre un token, il suffit de d\xE9placer manuellement le premier token. - Ça permet donc d'avoir un familier qui suit un personnage, ou bien de faire automatiquement bouger un groupe de perosnnage dont l'ordre de marche est déterminé. + Ça permet donc d'avoir un familier qui suit un personnage, ou bien de faire automatiquement bouger un groupe de perosnnage dont l'ordre de marche est d\xE9termin\xE9.
    -

    Déplacer un personnage sur plusieurs cartes

    +

    D\xE9placer un personnage sur plusieurs cartes

    -

    Il est possible de synchroniser des tokens de même nom (représentant le même personnage) sur plusieurs cartes. Ainsi, déplacer le token sur une carte déplace aussi les token sur les autres cartes. Cela peut servir par exemple si tous les joueurs ne doivent pas voir la même chose sur une carte : chaque joueur est alors sur la carte qui lui montre ce qu'il doit voir, et tous les tokens des joueurs sont synchronisés entre les cartes.

    -

    La commande pour activer la synchonisation d'un (ou plusieurs) tokens séléctionnés est !cof-multi-cartes. Pour mettre fin à la synchronisation, on peut sélectionner ces tokens et faire !cof-multi-cartes false. Enfin, cette même commande sans selectionner aucun token met fin à toutes les synchronisations.

    +

    Il est possible de synchroniser des tokens de m\xEAme nom (repr\xE9sentant le m\xEAme personnage) sur plusieurs cartes. Ainsi, d\xE9placer le token sur une carte d\xE9place aussi les token sur les autres cartes. Cela peut servir par exemple si tous les joueurs ne doivent pas voir la m\xEAme chose sur une carte : chaque joueur est alors sur la carte qui lui montre ce qu'il doit voir, et tous les tokens des joueurs sont synchronis\xE9s entre les cartes.

    +

    La commande pour activer la synchonisation d'un (ou plusieurs) tokens s\xE9l\xE9ctionn\xE9s est !cof-multi-cartes. Pour mettre fin \xE0 la synchronisation, on peut s\xE9lectionner ces tokens et faire !cof-multi-cartes false. Enfin, cette m\xEAme commande sans selectionner aucun token met fin \xE0 toutes les synchronisations.

    -

    2.8 Lumière

    +

    2.8 Lumi\xE8re

    -

    Pour faire de la lumière, on peut utiliser !cof-lumiere token_id portee. Cela va faire en sorte que le token fasse de la lumière jusqu'à portee mètres. Il est possible d'avoir plusieurs sources de lumière, et la commande est compatible avec la vision dans le noir. La commande admet un troisième argument qui est la distance à laquelle la lumière devient moins brillante, et un quatrième argument qui est le nom du type de lumière (par défaut, lumiere), utilisé quand on éteint les lumières.

    -

    Pour éteindre des lumières, utiliser !cof-eteindre-lumiere en sélectionnant le ou les tokens désirés. Il est possible de prendre un argument optionnel qui est le nom du groupe de lumières que l'on souhaite éteindre. Par exemple, on peut ainsi éteindre toutes les torches et laisser les effets de lumière magique actifs.

    -

    Pour les torches, le script propose d'automatiser la gestion en utilisant la commande !cof-torche token_id. Si le token tient une torche allumée, cela éteint la torche (et propose au MJ d'indiquer combien de temps la torche est restée allumée), et sinon, si le token possède des torches, cela allume une torche. Le nombre de torche et leur état est stocké dans un attribut torches, dont la valeur courante contient le nombre de torches dans l'inventaire, et la valeur max le temps restant pour la torche en cours d'utilisation (60 minutes pour une torche neuve). Si aucun attribut de ce nom n'existe, le script se contente d'allumer ou d'éteindre une torche, sans gérer leur nombre.

    -

    Pour les armes qui font de la lumière, on peut préciser un prédicat eclaire dans le champ de prédicats de l'arme. La valeur du prédicat doit être la distance à laquelle l'arme éclaire. On peut préciser dans un prédicat eclaireFaible (toujours dans le champ de l'arme) le début de la lumière faible, si besoin. Ça peut aussi être une façon de gérer les torches.

    -

    Quand les personnages sont dans le brouillard, je mets la carte sans lumière, et je sélectionne les tokens et lance la commande !cof-vision-nocturne 6 pour qu'ils voient à 6 m.

    +

    Pour faire de la lumi\xE8re, on peut utiliser !cof-lumiere token_id portee. Cela va faire en sorte que le token fasse de la lumi\xE8re jusqu'\xE0 portee m\xE8tres. Il est possible d'avoir plusieurs sources de lumi\xE8re, et la commande est compatible avec la vision dans le noir. La commande admet un troisi\xE8me argument qui est la distance \xE0 laquelle la lumi\xE8re devient moins brillante, et un quatri\xE8me argument qui est le nom du type de lumi\xE8re (par d\xE9faut, lumiere), utilis\xE9 quand on \xE9teint les lumi\xE8res.

    +

    Pour \xE9teindre des lumi\xE8res, utiliser !cof-eteindre-lumiere en s\xE9lectionnant le ou les tokens d\xE9sir\xE9s. Il est possible de prendre un argument optionnel qui est le nom du groupe de lumi\xE8res que l'on souhaite \xE9teindre. Par exemple, on peut ainsi \xE9teindre toutes les torches et laisser les effets de lumi\xE8re magique actifs.

    +

    Pour les torches, le script propose d'automatiser la gestion en utilisant la commande !cof-torche token_id. Si le token tient une torche allum\xE9e, cela \xE9teint la torche (et propose au MJ d'indiquer combien de temps la torche est rest\xE9e allum\xE9e), et sinon, si le token poss\xE8de des torches, cela allume une torche. Le nombre de torche et leur \xE9tat est stock\xE9 dans un attribut torches, dont la valeur courante contient le nombre de torches dans l'inventaire, et la valeur max le temps restant pour la torche en cours d'utilisation (60 minutes pour une torche neuve). Si aucun attribut de ce nom n'existe, le script se contente d'allumer ou d'\xE9teindre une torche, sans g\xE9rer leur nombre.

    +

    Pour les armes qui font de la lumi\xE8re, on peut pr\xE9ciser un pr\xE9dicat eclaire dans le champ de pr\xE9dicats de l'arme. La valeur du pr\xE9dicat doit \xEAtre la distance \xE0 laquelle l'arme \xE9claire. On peut pr\xE9ciser dans un pr\xE9dicat eclaireFaible (toujours dans le champ de l'arme) le d\xE9but de la lumi\xE8re faible, si besoin. Ça peut aussi \xEAtre une fa\xE7on de g\xE9rer les torches.

    +

    Quand les personnages sont dans le brouillard, je mets la carte sans lumi\xE8re, et je s\xE9lectionne les tokens et lance la commande !cof-vision-nocturne 6 pour qu'ils voient \xE0 6 m.

    -

    2.9 Jet de caractéristiques

    +

    2.9 Jet de caract\xE9ristiques

    -

    !cof-jet ?{Faire un jet de |Charisme, CHA|Constitution, CON|Dextérité, DEX|Force, FOR|Intelligence, INT|Sagesse, SAG} : fait un simple jet pour la caractérisique sélectionnée.

    -

    Il est aussi possible de donner en argument une difficulté au jet. Par exemple en faisant !cof-jet INT ?{difficulté}.

    -

    Si on ne donne aucun argument (en dehors des options), la commande demande de préciser la caractéristique à tester. Pour chaque caractéristique, le script va proposer d'utiliser une des compétences définies sur la fiche (liste sous les capacités). Si il existe un handout nommé Compétences, celui-ci sera aussi utilisé pour proposer pour chaque caractéristique un choix de compétences à tester. Le handout doit contenir dans ses notes des lignes commençant par une caractéristique (FOR, DEX, ...), suivi de :, puis des noms de compétences, séparés par des blancs, des retours à la ligne, des virgules ou des /.

    +

    !cof-jet ?{Faire un jet de |Charisme, CHA|Constitution, CON|Dext\xE9rit\xE9, DEX|Force, FOR|Intelligence, INT|Sagesse, SAG} : fait un simple jet pour la caract\xE9risique s\xE9lectionn\xE9e.

    +

    Il est aussi possible de donner en argument une difficult\xE9 au jet. Par exemple en faisant !cof-jet INT ?{difficult\xE9}.

    +

    Si on ne donne aucun argument (en dehors des options), la commande demande de pr\xE9ciser la caract\xE9ristique \xE0 tester. Pour chaque caract\xE9ristique, le script va proposer d'utiliser une des comp\xE9tences d\xE9finies sur la fiche (liste sous les capacit\xE9s). Si il existe un handout nomm\xE9 Comp\xE9tences, celui-ci sera aussi utilis\xE9 pour proposer pour chaque caract\xE9ristique un choix de comp\xE9tences \xE0 tester. Le handout doit contenir dans ses notes des lignes commen\xE7ant par une caract\xE9ristique (FOR, DEX, ...), suivi de :, puis des noms de comp\xE9tences, s\xE9par\xE9s par des blancs, des retours \xE0 la ligne, des virgules ou des /.

    La fonction accepte les arguments suivants:

      -
    • --bonus pour spécifier un bonus numérique au jet.
    • -
    • --attribut pour spécifier un attribut dont la valeur doit être ajoutée au jet. Il est possible de spécifier plusieurs attributs, comme par exemple --attribut perception --attribut vigilance pour un jet de vigilance.
    • -
    • --predicat pour spécifier un prédicat dont la valeur doit être ajoutée au jet. Il est possible de spécifier plusieurs pédicats.
    • -
    • --nom précise le nom du jet à afficher. De plus, cela va aussi faire rechercher une compétence de même nom (sans tenir compte des majuscules) pour une fiche de PJ et un attribut ou un prédicat pour une fiche de PNJ. Par exemple !cof-jet DEX --nom Discrétion va lancer un jet de DEX, qui sera affiché comme un jet de Discrétion, et qui va ajouter au jet le bonus d'une compétence discrétion ou d'un éventuel prédicat discrétion.
    • -
    • --secret : le jet n'est visible que par les personnes qui contrôlent le personnage, plus le MJ. Si la personne qui a lancé la commande est MJ, il sera le seul à voir le résultat.
    • -
    • --competences : si la commande n'a pas déjà d'option --nom, invite l'utilisateur à choisir une compétence parmis une liste correspondant à la caractéristique (incluant celles provenant du handout Compétences tel que défini plus haut).
    • -
    • --plageEchecCritique c : permet de considérer tout jet de dé inférieur ou égal à c comme un échec critique.
    • +
    • --bonus pour sp\xE9cifier un bonus num\xE9rique au jet.
    • +
    • --attribut pour sp\xE9cifier un attribut dont la valeur doit \xEAtre ajout\xE9e au jet. Il est possible de sp\xE9cifier plusieurs attributs, comme par exemple --attribut perception --attribut vigilance pour un jet de vigilance.
    • +
    • --predicat pour sp\xE9cifier un pr\xE9dicat dont la valeur doit \xEAtre ajout\xE9e au jet. Il est possible de sp\xE9cifier plusieurs p\xE9dicats.
    • +
    • --nom pr\xE9cise le nom du jet \xE0 afficher. De plus, cela va aussi faire rechercher une comp\xE9tence de m\xEAme nom (sans tenir compte des majuscules) pour une fiche de PJ et un attribut ou un pr\xE9dicat pour une fiche de PNJ. Par exemple !cof-jet DEX --nom Discr\xE9tion va lancer un jet de DEX, qui sera affich\xE9 comme un jet de Discr\xE9tion, et qui va ajouter au jet le bonus d'une comp\xE9tence discr\xE9tion ou d'un \xE9ventuel pr\xE9dicat discr\xE9tion.
    • +
    • --secret : le jet n'est visible que par les personnes qui contr\xF4lent le personnage, plus le MJ. Si la personne qui a lanc\xE9 la commande est MJ, il sera le seul \xE0 voir le r\xE9sultat.
    • +
    • --competences : si la commande n'a pas d\xE9j\xE0 d'option --nom, invite l'utilisateur \xE0 choisir une comp\xE9tence parmis une liste correspondant \xE0 la caract\xE9ristique (incluant celles provenant du handout Comp\xE9tences tel que d\xE9fini plus haut).
    • +
    • --plageEchecCritique c : permet de consid\xE9rer tout jet de d\xE9 inf\xE9rieur ou \xE9gal \xE0 c comme un \xE9chec critique.
    • +
    • --succes message : affiche message en cas de succ\xE8s au jet. N'a pas d'effet si la difficult\xE9 du jet n'est pas d\xE9finie.
    -

    Si le personnage possède un attribut numérique modificateurTests, ce modificateur sera pris en compte pour tous les tests.

    -

    Dans les options de jeu (affichés en utilisant !cof-options, dans le menu des options d'affichage, il est possible de choisir de ne faire afficher les résultats qu'au MJ, qui peut alors en cliquant sur un bouton le montrer aux joueurs (ou pas).

    +

    Si le personnage poss\xE8de un attribut num\xE9rique modificateurTests, ce modificateur sera pris en compte pour tous les tests.

    +

    Dans les options de jeu (affich\xE9s en utilisant !cof-options, dans le menu des options d'affichage, il est possible de choisir de ne faire afficher les r\xE9sultats qu'au MJ, qui peut alors en cliquant sur un bouton le montrer aux joueurs (ou pas).

    -

    2.10 Anonymat et fausses identités

    +

    2.10 Anonymat et fausses identit\xE9s

    -

    La fiche de personnage propose deux noms par personnage : le nom principal (appelé simplement "nom") et un alias. Le nom principal est celui visible dans la liste des personnages de l'interface Roll20. C'est aussi celui qui est montré quand on montre une fiche aux joueurs. La fiche propose de choisir le nom affiché lors des jets (champ "connu") : soit le nom principal, soit l'alias. Le script part toujours de l'hypothèse que c'est ce nom qui est connu des joueurs, et que le second est le "vrai" nom. Je laisse le choix au MJ de décider lequel est quoi, car les deux méthodes ont leurs avantages et leurs inconvénients : si on choisit d'avoir l'alias en nom caché, on peut montrer la fiche aux joueurs, sans dévoiler le vrai nom. En revanche, dans la liste des personnages, il peut être plus difficile de s'y retrouver, car le MJ ne verra pas le vrai nom. Si on choisit d'avoir le vrai nom caché, tout est bien clair pour le MJ, mais il doit faire attention à ne pas montrer la fiche aux joueurs.

    +

    La fiche de personnage propose deux noms par personnage : le nom principal (appel\xE9 simplement "nom") et un alias. Le nom principal est celui visible dans la liste des personnages de l'interface Roll20. C'est aussi celui qui est montr\xE9 quand on montre une fiche aux joueurs. La fiche propose de choisir le nom affich\xE9 lors des jets (champ "connu") : soit le nom principal, soit l'alias. Le script part toujours de l'hypoth\xE8se que c'est ce nom qui est connu des joueurs, et que le second est le "vrai" nom. Je laisse le choix au MJ de d\xE9cider lequel est quoi, car les deux m\xE9thodes ont leurs avantages et leurs inconv\xE9nients : si on choisit d'avoir l'alias en nom cach\xE9, on peut montrer la fiche aux joueurs, sans d\xE9voiler le vrai nom. En revanche, dans la liste des personnages, il peut \xEAtre plus difficile de s'y retrouver, car le MJ ne verra pas le vrai nom. Si on choisit d'avoir le vrai nom cach\xE9, tout est bien clair pour le MJ, mais il doit faire attention \xE0 ne pas montrer la fiche aux joueurs.

    Concernant les tokens, le script suppose que vous mettez en "connu" le nom visible par les joueurs.

    -

    Révéler le vrai nom d'un personnage

    +

    R\xE9v\xE9ler le vrai nom d'un personnage

    -

    Pour révéler le vrai nom d'un personnage au joueurs, vous pourrez utiliser !cof-reveler-nom. L'effet s'applique à tous les personnages sélectionnés (voir les méthodes de sélection). L'effet est le suivant :

    +

    Pour r\xE9v\xE9ler le vrai nom d'un personnage au joueurs, vous pourrez utiliser !cof-reveler-nom. L'effet s'applique \xE0 tous les personnages s\xE9lectionn\xE9s (voir les m\xE9thodes de s\xE9lection). L'effet est le suivant :

      -
    • Si le personnage était connu par son nom, et que l'alias était non vide, alors on copie l'alias à la place du nom, et on efface l'alias.
    • -
    • Si le personnage était connu par son alias, alors on le passe en connu par son nom et on efface l'alias.
    • -
    • Si on a fait un des deux changements ci-dessus, alors on change aussi les noms des tokens : si on a passé un nom en argument à !cof-reveler-nom, alors on utilise ce nom. Sinon, on utilise le nouveau nom public. Tous les tokens liés prennent ce nom, et tous les tokens non liés gardent leur numéro et changent juste la partie avant le numéro en ce nom. On n'applique cette transformation qu'aux tokens dont les noms n'ont pas été modifiés (par rapport au token par défaut défini sur la fiche).
    • -
    • Et on change aussi le nom du token par défaut.
    • +
    • Si le personnage \xE9tait connu par son nom, et que l'alias \xE9tait non vide, alors on copie l'alias \xE0 la place du nom, et on efface l'alias.
    • +
    • Si le personnage \xE9tait connu par son alias, alors on le passe en connu par son nom et on efface l'alias.
    • +
    • Si on a fait un des deux changements ci-dessus, alors on change aussi les noms des tokens : si on a pass\xE9 un nom en argument \xE0 !cof-reveler-nom, alors on utilise ce nom. Sinon, on utilise le nouveau nom public. Tous les tokens li\xE9s prennent ce nom, et tous les tokens non li\xE9s gardent leur num\xE9ro et changent juste la partie avant le num\xE9ro en ce nom. On n'applique cette transformation qu'aux tokens dont les noms n'ont pas \xE9t\xE9 modifi\xE9s (par rapport au token par d\xE9faut d\xE9fini sur la fiche).
    • +
    • Et on change aussi le nom du token par d\xE9faut.

    2.11 Autres aspects du jeu

    Annuler une action : !cof-undo

    -

    Fait partie des fonctions que je met en macro dans la barre du MJ, ça peut servir très souvent. Elle est d'ailleurs générée par la commande !cof-set-macros.

    +

    Fait partie des fonctions que je met en macro dans la barre du MJ, \xE7a peut servir tr\xE8s souvent. Elle est d'ailleurs g\xE9n\xE9r\xE9e par la commande !cof-set-macros.

    Chance

    -

    Le script essaie de détecter les cas où un point de chance peut être utile, et dans ce cas fournit un bouton (utilisable par les joueurs contrôlant le perosnnage ou le GM), permettant de dépenser un point de chance. Attention, pour l'instant, il n'est pas possible de faire juste un undo de la dépense de point de chnce. Le undo après la dépense de point de chance annule toute l'action. Il faut ensuite faire un undo par point de chance dépensé.

    +

    Le script essaie de d\xE9tecter les cas o\xF9 un point de chance peut \xEAtre utile, et dans ce cas fournit un bouton (utilisable par les joueurs contr\xF4lant le perosnnage ou le GM), permettant de d\xE9penser un point de chance. Attention, pour l'instant, il n'est pas possible de faire juste un undo de la d\xE9pense de point de chnce. Le undo apr\xE8s la d\xE9pense de point de chance annule toute l'action. Il faut ensuite faire un undo par point de chance d\xE9pens\xE9.

    Surprise : !cof-surprise ?difficulte

    -

    Fait un test de surprise sur tous les tokens sélectionné. Si la difficulté n'est pas présente, ils sont automatiquement surpris. Les valeurs des compétences vigilance et perception sont ajoutés au test de sagesse.

    -

    Si vous souhaitez préciser que la surprise est le fait d'un personnage ou effet non vivant (pour ne pas faire bénéficier du bonus de la capacité Radar mental), vous pouvez rajouter l'option --nonVivant.

    +

    Fait un test de surprise sur tous les tokens s\xE9lectionn\xE9. Si la difficult\xE9 n'est pas pr\xE9sente, ils sont automatiquement surpris. Les valeurs des comp\xE9tences vigilance et perception sont ajout\xE9s au test de sagesse.

    +

    Si vous souhaitez pr\xE9ciser que la surprise est le fait d'un personnage ou effet non vivant (pour ne pas faire b\xE9n\xE9ficier du bonus de la capacit\xE9 Radar mental), vous pouvez rajouter l'option --nonVivant.

    Gestion de la bourse : !cof-bourse

    -

    La gestion de la bourse peut se faire sans ouvrir la fiche à l'aide de la commande !cof-bourse. Si un seul token est sélectionné (quelle que soit la méthode de sélection), la commande affiche le montant de la bourse, avec la possibilité de modifier directement les nombres de pièces ou de dépenser ou gagner un certain nombre de pièces.

    -

    !cof-bourse depenser n permet de faire dépenser de l'argent aux tokens sélectionnés. On peut préciser le type de pièces (pc, pa, po ou pp) après le montant, par défaut le script utilise les pièces d'argent. De même, on peut utiliser !cof-bourse gagner n pour ajouter de l'argent.

    +

    La gestion de la bourse peut se faire sans ouvrir la fiche \xE0 l'aide de la commande !cof-bourse. Si un seul token est s\xE9lectionn\xE9 (quelle que soit la m\xE9thode de s\xE9lection), la commande affiche le montant de la bourse, avec la possibilit\xE9 de modifier directement les nombres de pi\xE8ces ou de d\xE9penser ou gagner un certain nombre de pi\xE8ces.

    +

    !cof-bourse depenser n permet de faire d\xE9penser de l'argent aux tokens s\xE9lectionn\xE9s. On peut pr\xE9ciser le type de pi\xE8ces (pc, pa, po ou pp) apr\xE8s le montant, par d\xE9faut le script utilise les pi\xE8ces d'argent. De m\xEAme, on peut utiliser !cof-bourse gagner n pour ajouter de l'argent.

    Jouer un son

    -

    Les fonctions d'attaque peuvent jouer un son (options commençant par --soundAttack). Une partie des actions admet aussi une option --son pour jouer un son. Finalement, il est aussi possible de simplement jouer un son en utilisant !cof-jouer-son son. Il est possible d'arrêter tous les sons avec la commande !cof-jouer-son, sans argument.

    +

    Les fonctions d'attaque peuvent jouer un son (options commen\xE7ant par --soundAttack). Une partie des actions admet aussi une option --son pour jouer un son. Finalement, il est aussi possible de simplement jouer un son en utilisant !cof-jouer-son son. Il est possible d'arr\xEAter tous les sons avec la commande !cof-jouer-son, sans argument.

    -

    Le script est compatible avec Roll20AM, et si ce script est installé, il fera appel à lui. Mais si il n'est pas installé (et seulement dans ce cas !), il va simplement utiliser les sons dans le jukebox.

    +

    Le script est compatible avec Roll20AM, et si ce script est install\xE9, il fera appel \xE0 lui. Mais si il n'est pas install\xE9 (et seulement dans ce cas !), il va simplement utiliser les sons dans le jukebox.

    Changer la taille d'une page : !cof-agrandir-page

    - !cof-agrandir-carte coef permet de multiplier par coef les dimensions de tout ce qui se trouve sur la carte et le layer de la lumière. Les tokens sont déplacés pour se retrouver à la même position relative sur la carte. Je l'utilise pour les cartes que je trouve trop petites pour des groupes de 5-6 joueurs. + !cof-agrandir-carte coef permet de multiplier par coef les dimensions de tout ce qui se trouve sur la carte et le layer de la lumi\xE8re. Les tokens sont d\xE9plac\xE9s pour se retrouver \xE0 la m\xEAme position relative sur la carte. Je l'utilise pour les cartes que je trouve trop petites pour des groupes de 5-6 joueurs.

    Retarder l'affichage de la mort

    -

    Pour retarder l'affichage de la mort d'un personnage, ajoutez à ce personnage un prédicat mortDemandeConfirmation. Ainsi, si le personnage meurt à la suite d'une attaque, les PVs finaux ne seront pas enlevés, et la croix rouge indiquant la mort ne sera pas dessinée. À la place, le MJ verra au bout de 2 secondes un bouton lui-demandant de confirmer la mort (par exemple le temps de décrire comment la mort advient).

    +

    Pour retarder l'affichage de la mort d'un personnage, ajoutez \xE0 ce personnage un pr\xE9dicat mortDemandeConfirmation. Ainsi, si le personnage meurt \xE0 la suite d'une attaque, les PVs finaux ne seront pas enlev\xE9s, et la croix rouge indiquant la mort ne sera pas dessin\xE9e. \xC0 la place, le MJ verra au bout de 2 secondes un bouton lui-demandant de confirmer la mort (par exemple le temps de d\xE9crire comment la mort advient).

    -

    3. Capacités par Classe

    +

    3. Capacit\xE9s par Classe

    Arquebusier

    Voie de l'artilleur

      -
    1. Mécanismes : ajouter les bonus sur la fiche
    2. -
    3. Tir de semonce : utiliser le modificateur semonce aux attaques. On laisse le MJ vérifier si la dernière attaque du personnage était bien un échec (devrait être facile à voir dans le chat). Le plus pratique pour l'utilisation avec differentes armes, est de créer une action Tir de barrage dans les actions du tour, avec comme code #Attaque -1 --semonce. -
    4. Tir de barrage : Utiliser l'option --tirDeBarrage. Ça multiplie les dégâts par 2, ignore la charge, et laisse un message demandant le undo si la cible décide de ne pas bouger.
    5. -
    6. Couleuvrine : ajouter une attaque à distance, avec dans les modificateurs, poudre, limiteParCombat (ou en ligne de commande, avec l'option --limiteParCombat)
    7. -
    8. Feu nourri : faire les attaques comme pour le tirde barrage. Le script ne va pas vérifier que les cibles ne sont pas trop loin les unes des autres.
    9. +
    10. M\xE9canismes : ajouter les bonus sur la fiche
    11. +
    12. Tir de semonce : utiliser le modificateur semonce aux attaques. On laisse le MJ v\xE9rifier si la derni\xE8re attaque du personnage \xE9tait bien un \xE9chec (devrait \xEAtre facile \xE0 voir dans le chat). Le plus pratique pour l'utilisation avec differentes armes, est de cr\xE9er une action Tir de barrage dans les actions du tour, avec comme code #Attaque -1 --semonce. +
    13. Tir de barrage : Utiliser l'option --tirDeBarrage. Ça multiplie les d\xE9g\xE2ts par 2, ignore la charge, et laisse un message demandant le undo si la cible d\xE9cide de ne pas bouger.
    14. +
    15. Couleuvrine : ajouter une attaque \xE0 distance, avec dans les modificateurs, poudre, limiteParCombat (ou en ligne de commande, avec l'option --limiteParCombat)
    16. +
    17. Feu nourri : faire les attaques comme pour le tirde barrage. Le script ne va pas v\xE9rifier que les cibles ne sont pas trop loin les unes des autres.

    Voie des explosifs

      -
    1. Chimiste : ajoutez un prédicat chimiste, ainsi que les compétences de chimie et alchimie sur la fiche. Si vous utilisez la capacité alternative Grenaille, vous pouvez soit gérer les charges de grenaille avec !cof-recharger L --grenaille, soit (si vous ne voulez pas faire gérer les charges) utiliser l'option --grenaille. Si vous utilisez la même attaque pour plusieurs armes et que seule une partie est chargée de grenaille, il faudra aussi utiliser cette option pour utiliser l'arme chargée de grenaille.
    2. -
    3. Démolition : pas de support particulier
    4. +
    5. Chimiste : ajoutez un pr\xE9dicat chimiste, ainsi que les comp\xE9tences de chimie et alchimie sur la fiche. Si vous utilisez la capacit\xE9 alternative Grenaille, vous pouvez soit g\xE9rer les charges de grenaille avec !cof-recharger L --grenaille, soit (si vous ne voulez pas faire g\xE9rer les charges) utiliser l'option --grenaille. Si vous utilisez la m\xEAme attaque pour plusieurs armes et que seule une partie est charg\xE9e de grenaille, il faudra aussi utiliser cette option pour utiliser l'arme charg\xE9e de grenaille.
    6. +
    7. D\xE9molition : pas de support particulier
    8. Poudre puissante : ajuster les attaques
    9. -
    10. Piège explosif :
    11. -
    12. Boulet explosif : ajouter une attaque de type Arme de jet, dégâts 5d6 de type contondant (ou feu ?), portée 20, modificateurs auto, options --disque 5 --psave DEX [[12+@{selected|DEX}]]
    13. +
    14. Pi\xE8ge explosif :
    15. +
    16. Boulet explosif : ajouter une attaque de type Arme de jet, d\xE9g\xE2ts 5d6 de type contondant (ou feu ?), port\xE9e 20, modificateurs auto, options --disque 5 --psave DEX [[12+@{selected|DEX}]]

    Voie du champ de bataille

      -
    1. Action concertée : utiliser !cof-echange-init @{selected|token_id} @{target|token_id} nn peut valoir 0, 1 ou 2 selon le rang dans la voie.
    2. -
    3. À couvert : !cof-a-couvert @{selected|token_id} @{target|token_id} le target est l'allié qui se déplace avec l'arquebusier. Se sélectionner soi-même si pas d'allié.
    4. -
    5. Combattant aguerri : se reporter à la capacité choisie
    6. -
    7. Combat de masse : pas de support particulier, effectuer les actions supplémentaires en fonction des situations.
    8. -
    9. Constitution héroïque : reporter le bonus sur la fiche
    10. +
    11. Action concert\xE9e : utiliser !cof-echange-init @{selected|token_id} @{target|token_id} n o\xF9 n peut valoir 0, 1 ou 2 selon le rang dans la voie.
    12. +
    13. \xC0 couvert : !cof-a-couvert @{selected|token_id} @{target|token_id} le target est l'alli\xE9 qui se d\xE9place avec l'arquebusier. Se s\xE9lectionner soi-m\xEAme si pas d'alli\xE9.
    14. +
    15. Combattant aguerri : se reporter \xE0 la capacit\xE9 choisie
    16. +
    17. Combat de masse : pas de support particulier, effectuer les actions suppl\xE9mentaires en fonction des situations.
    18. +
    19. Constitution h\xE9ro\xEFque : reporter le bonus sur la fiche

    Voie du Pistolero

    1. - Plus vite que son ombre : ajouter un prédicat plusViteQueSonOmbre. On peut associer un nombre à ce prédicat pour modifier le bonus à l'initiative, ou bien lui donner la valeur arbalete pour activer le bonus sur les arbalètes au lieu des armes à poudre. + Plus vite que son ombre : ajouter un pr\xE9dicat plusViteQueSonOmbre. On peut associer un nombre \xE0 ce pr\xE9dicat pour modifier le bonus \xE0 l'initiative, ou bien lui donner la valeur arbalete pour activer le bonus sur les arbal\xE8tes au lieu des armes \xE0 poudre.
    2. Cadence de tir : pas de support
    3. -
    4. Tir double : utiliser l'option --tirDouble si deux tirs sur une même cible. Si les deux armes sont différentes, rajouter le label de la deuxième arme après l'option (si le label est l2, cela donne --tirDouble l2).
    5. -
    6. As de la gâchette : utiliser l'option --asDeLaGachette pour les attaques avec des armes à poudre ou des arbalètes.
    7. -
    8. Dextérité héroïque : reporter le bonus sur la fiche
    9. +
    10. Tir double : utiliser l'option --tirDouble si deux tirs sur une m\xEAme cible. Si les deux armes sont diff\xE9rentes, rajouter le label de la deuxi\xE8me arme apr\xE8s l'option (si le label est l2, cela donne --tirDouble l2).
    11. +
    12. As de la g\xE2chette : utiliser l'option --asDeLaGachette pour les attaques avec des armes \xE0 poudre ou des arbal\xE8tes.
    13. +
    14. Dext\xE9rit\xE9 h\xE9ro\xEFque : reporter le bonus sur la fiche
    -

    Voie de la précision

    +

    Voie de la pr\xE9cision

      -
    1. Joli coup ! : ajouter un prédicat joliCoup sur la fiche.
    2. -
    3. Tir précis : ajouter un prédicat tirPrecis, valeur 1 ou 2 (le bonus apporté par la capacité)
    4. -
    5. Défaut dans la cuirasse : utiliser !cof-defaut-dans-la-cuirasse @{selected|token_id} @{target|token_id}
    6. -
    7. Tir parabolique : ajouter un prédicat tirParabolique. Surtout ne pas changer la portée des armes, pour que le script gère correctement les distances entre portéex2 et portéex3.
    8. -
    9. Tir mortel : Ajouter ?{Tir mortel ?|Oui, --avecd12crit --plus 2d6|Non,} aux attaques à distance du personnage
    10. +
    11. Joli coup ! : ajouter un pr\xE9dicat joliCoup sur la fiche.
    12. +
    13. Tir pr\xE9cis : ajouter un pr\xE9dicat tirPrecis, valeur 1 ou 2 (le bonus apport\xE9 par la capacit\xE9)
    14. +
    15. D\xE9faut dans la cuirasse : utiliser !cof-defaut-dans-la-cuirasse @{selected|token_id} @{target|token_id}
    16. +
    17. Tir parabolique : ajouter un pr\xE9dicat tirParabolique. Surtout ne pas changer la port\xE9e des armes, pour que le script g\xE8re correctement les distances entre port\xE9ex2 et port\xE9ex3.
    18. +
    19. Tir mortel : Ajouter ?{Tir mortel ?|Oui, --avecd12crit --plus 2d6|Non,} aux attaques \xE0 distance du personnage

    Barbare

    Voie de la brute

      -
    1. Argument de taille : ajouter le bonus de PV sur la fiche. Ajouter un prédicat argumentDeTaille. Le script devrait automatiquement tenir compte de cette capacité pour les tests de négociation, persuasion et intimidation. Pour s'assurer que la bonne compétence est utilisée, vous pouvez ajouter ces noms au handout de compétence (voir la partie sur les jet de caractéristiques, le handout Compétences) ou sur les fiches de personnages.
    2. -
    3. Tour de force : ajouter un prédicat tourDeForce. Le script ajoutera systématique un bouton lors de tous les tests de FOR du personnage. Au MJ de décider s'il peut être utilisé ou non.
    4. +
    5. Argument de taille : ajouter le bonus de PV sur la fiche. Ajouter un pr\xE9dicat argumentDeTaille. Le script devrait automatiquement tenir compte de cette capacit\xE9 pour les tests de n\xE9gociation, persuasion et intimidation. Pour s'assurer que la bonne comp\xE9tence est utilis\xE9e, vous pouvez ajouter ces noms au handout de comp\xE9tence (voir la partie sur les jet de caract\xE9ristiques, le handout Comp\xE9tences) ou sur les fiches de personnages.
    6. +
    7. Tour de force : ajouter un pr\xE9dicat tourDeForce. Le script ajoutera syst\xE9matique un bouton lors de tous les tests de FOR du personnage. Au MJ de d\xE9cider s'il peut \xEAtre utilis\xE9 ou non.
    8. Attaque brutale : faire l'attaque avec les options --bonusAttaque -2 --plus 1d6
    9. -
    10. Briseur d'os : ajouter un prédicat briseurDOs. Cela va automatiquement affecter les chances de coups critique au contact.
    11. -
    12. Force héroïque : reporter sur la fiche.
    13. +
    14. Briseur d'os : ajouter un pr\xE9dicat briseurDOs. Cela va automatiquement affecter les chances de coups critique au contact.
    15. +
    16. Force h\xE9ro\xEFque : reporter sur la fiche.

    Voie du pagne

      -
    1. Vigueur : ajouter les compétences avec leurs bonus sur la fiche
    2. -
    3. Peau de pierre : ajouter un prédicat peauDePierre. La nouvelle DEF sera calculée automatiquement.
    4. +
    5. Vigueur : ajouter les comp\xE9tences avec leurs bonus sur la fiche
    6. +
    7. Peau de pierre : ajouter un pr\xE9dicat peauDePierre. La nouvelle DEF sera calcul\xE9e automatiquement.
    8. Tatouages : ajouter le bonus choisi sur la fiche
    9. Peau d'acier : ajouter dans la partie RD de la fiche, 3/1
    10. -
    11. Constitution héroïque : reporter les bonus sur la fiche
    12. +
    13. Constitution h\xE9ro\xEFque : reporter les bonus sur la fiche

    Voie du pourfendeur

      -
    1. Réflexes félins : ajouter un prédicat reflexesFelins, avec comme valeur le bonus aux saves et à l'initiative.
    2. -
    3. Charge : faire une attaque avec les options --bonusAttaque 2 --plus 1d6. Pour gérer plusieurs armes, vous pouvez utiliser la commande #Attaque -1.
    4. -
    5. Enchaînement : ajouter un prédicat enchainement.
    6. -
    7. Déchaînement d'acier : !cof-attack-line @{selected|token_id} --distanceMax 10. L'attaque va être faite avec l'arme en main, mais on peut spécifier un label d'attaque (avant les options) et toutes les options supportées par !cof-attack.
    8. +
    9. R\xE9flexes f\xE9lins : ajouter un pr\xE9dicat reflexesFelins, avec comme valeur le bonus aux saves et \xE0 l'initiative.
    10. +
    11. Charge : faire une attaque avec les options --bonusAttaque 2 --plus 1d6. Pour g\xE9rer plusieurs armes, vous pouvez utiliser la commande #Attaque -1.
    12. +
    13. Encha\xEEnement : ajouter un pr\xE9dicat enchainement.
    14. +
    15. D\xE9cha\xEEnement d'acier : !cof-attack-line @{selected|token_id} --distanceMax 10. L'attaque va \xEAtre faite avec l'arme en main, mais on peut sp\xE9cifier un label d'attaque (avant les options) et toutes les options support\xE9es par !cof-attack.
    16. Attaque tourbillon : Faite une action avec le code !cof-explosion -1 --auto --disque 5 --saufAllies --limiteParCombat 1 tourbillon.

    Voie du primitif

      -
    1. Proche de la nature : ajouter le rang à une compétence perception
    2. -
    3. Armure de vent : Ajouter un prédicat armureDeVent avec comme valeur le rang dans la voie du primitif. Cela augmente la DEF, mais seulement lorsque le barbare ne porte pas d'armure (ne se voit pas sur le total de DEF de la fiche)
    4. -
    5. Vigilance : ajouter 5 à une compétence vigilance et ajouter un prédicat immuniteAuxSournoises
    6. -
    7. Résistance à la magie : ajouter un prédicat resistanceALaMagieBarbare.
    8. -
    9. Vitalité débordante : faire une ability de type token action, avec le code !cof-soin ?{Nombre d'heures écoulées}d6 --message guérit à une vitesse surnaturelle
    10. +
    11. Proche de la nature : ajouter le rang \xE0 une comp\xE9tence perception
    12. +
    13. Armure de vent : Ajouter un pr\xE9dicat armureDeVent avec comme valeur le rang dans la voie du primitif. Cela augmente la DEF, mais seulement lorsque le barbare ne porte pas d'armure (ne se voit pas sur le total de DEF de la fiche)
    14. +
    15. Vigilance : ajouter 5 \xE0 une comp\xE9tence vigilance et ajouter un pr\xE9dicat immuniteAuxSournoises
    16. +
    17. R\xE9sistance \xE0 la magie : ajouter un pr\xE9dicat resistanceALaMagieBarbare.
    18. +
    19. Vitalit\xE9 d\xE9bordante : faire une ability de type token action, avec le code !cof-soin ?{Nombre d'heures \xE9coul\xE9es}d6 --message gu\xE9rit \xE0 une vitesse surnaturelle

    Voie de la rage

    1. Cri de guerre : !cof-effet-combat criDeGuerre
    2. -
    3. Défier la mort : ajouter un prédicat defierLaMort.
    4. -
    5. Rage du berserk : utiliser !cof-rage-du-berserk, à la fois pour entrer en rage et pour tenter d'en sortir avant la fin du combat.
    6. -
    7. Même pas mal : ajouter un prédicat memePasMal. Le joueur doit lui-même activer la rage ou le furie si il souhaite en profiter.
    8. -
    9. Furie du berserk : utiliser !cof-rage-du-berserk --furie pour entrer en rage et pour tenter d'en sortir avant la fin du combat. Pour sortir de la rage, l'option --furie peut être omise.
    10. +
    11. D\xE9fier la mort : ajouter un pr\xE9dicat defierLaMort.
    12. +
    13. Rage du berserk : utiliser !cof-rage-du-berserk, \xE0 la fois pour entrer en rage et pour tenter d'en sortir avant la fin du combat.
    14. +
    15. M\xEAme pas mal : ajouter un pr\xE9dicat memePasMal. Le joueur doit lui-m\xEAme activer la rage ou le furie si il souhaite en profiter.
    16. +
    17. Furie du berserk : utiliser !cof-rage-du-berserk --furie pour entrer en rage et pour tenter d'en sortir avant la fin du combat. Pour sortir de la rage, l'option --furie peut \xEAtre omise.
    - Note: en option, il est possible de diviser par 2 la pénalité de défense infligée par la Rage ou la Furie en ajoutant un prédicat rageDuBerserkAmelioree au personnage (par exemple pour la ceinture d'Anathazerïn p. 341) + Note: en option, il est possible de diviser par 2 la p\xE9nalit\xE9 de d\xE9fense inflig\xE9e par la Rage ou la Furie en ajoutant un pr\xE9dicat rageDuBerserkAmelioree au personnage (par exemple pour la ceinture d'Anathazer\xEFn p. 341)

    Barde

    Voie de l'escrime

      -
    1. Précision : simplement utiliser le bon score sur la fiche.
    2. -
    3. Intelligence du combat : ajouter un prédicat intelligenceDuCombat.
    4. -
    5. Feinte : faire une attaque avec l'option --feinte pour profiter des effets de feinte au tour suivant. Par défaut, le bonus à l'attaque suivante est de +5 (règles de base), mais vous pouvez spécifier un bonus différent (par exemple 10 pour les règles de la boîte d'initiation) avec un prédicat bonusFeinte (la valeur du prédicat remplace le bonus de +5 par défaut). Il est aussi possible de changer le nombre de dés de dégât bonus en utilisant un prédicatnbDesFeinte.
    6. -
    7. Attaque flamboyante : faire une attaque avec le modificateur attaqueFlamboyante. Le plus pratique pour l'utilisation avec différentes armes, est d'ajouter à la liste des actions du tour une action de titre Attaque flamboyante et de code #Attaque -1 --attaqueFlamboyante. Attention, afin de garder un intérêt à la feinte quand on dispose de cette attaque, j'ai choisi de rajouter encore le mod. de charisme aux DM en cas d'attaque flamboyante suivant une feinte réussie. Si cela ne vous convient pas, vous pouvez à la place de cette option ajouter --bonusAttaque [[@{selected|CHA}]] --plus [[@{selected|CHA}]].
    8. -
    9. Botte mortelle : ajoutez un prédicat botteMortelle.
    10. +
    11. Pr\xE9cision : simplement utiliser le bon score sur la fiche.
    12. +
    13. Intelligence du combat : ajouter un pr\xE9dicat intelligenceDuCombat.
    14. +
    15. Feinte : faire une attaque avec l'option --feinte pour profiter des effets de feinte au tour suivant. Par d\xE9faut, le bonus \xE0 l'attaque suivante est de +5 (r\xE8gles de base), mais vous pouvez sp\xE9cifier un bonus diff\xE9rent (par exemple 10 pour les r\xE8gles de la bo\xEEte d'initiation) avec un pr\xE9dicat bonusFeinte (la valeur du pr\xE9dicat remplace le bonus de +5 par d\xE9faut). Il est aussi possible de changer le nombre de d\xE9s de d\xE9g\xE2t bonus en utilisant un pr\xE9dicatnbDesFeinte.
    16. +
    17. Attaque flamboyante : faire une attaque avec le modificateur attaqueFlamboyante. Le plus pratique pour l'utilisation avec diff\xE9rentes armes, est d'ajouter \xE0 la liste des actions du tour une action de titre Attaque flamboyante et de code #Attaque -1 --attaqueFlamboyante. Attention, afin de garder un int\xE9r\xEAt \xE0 la feinte quand on dispose de cette attaque, j'ai choisi de rajouter encore le mod. de charisme aux DM en cas d'attaque flamboyante suivant une feinte r\xE9ussie. Si cela ne vous convient pas, vous pouvez \xE0 la place de cette option ajouter --bonusAttaque [[@{selected|CHA}]] --plus [[@{selected|CHA}]].
    18. +
    19. Botte mortelle : ajoutez un pr\xE9dicat botteMortelle.

    Voie du musicien

      -
    1. Chant des héros : !cof-effet-temp chantDesHeros [[5+@{selected|CHA}]] --allies. Il faut avoir défini une équipe avec le barde.
    2. +
    3. Chant des h\xE9ros : !cof-effet-temp chantDesHeros [[5+@{selected|CHA}]] --allies. Il faut avoir d\xE9fini une \xE9quipe avec le barde.
    4. Attaque sonore :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, DM 1d6+CHA, de portée 10, type Sortilège, dégâts soniques, options --mana 0 --cone --fx breath-smoke.
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, DM 1d6+CHA, de port\xE9e 10, type Sortil\xE8ge, d\xE9g\xE2ts soniques, options --mana 0 --cone --fx breath-smoke.
      • Objet de sort : #Attaque Attaque sonore --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|CHA}]] --portee 10 --sortilege --sonique --cone --fx breath-smoke
    5. -
    6. Zone de silence : !cof-effet-temp zoneDeSilence [[1d6+@{selected|CHA}]] --lanceur @{selected|token_id} --portee 35 --disque @{target|token_id} 3 --mana 1. Le script ne gère pas le moment où les cibles sortent de la zone. Si cela arrive, le MJ doit enlever à la main l'attribut zoneDeSilence créé par le script pour le personnage concerné.
    7. -
    8. Danse irrésisitible : +
    9. Zone de silence : !cof-effet-temp zoneDeSilence [[1d6+@{selected|CHA}]] --lanceur @{selected|token_id} --portee 35 --disque @{target|token_id} 3 --mana 1. Le script ne g\xE8re pas le moment o\xF9 les cibles sortent de la zone. Si cela arrive, le MJ doit enlever \xE0 la main l'attribut zoneDeSilence cr\xE9\xE9 par le script pour le personnage concern\xE9.
    10. +
    11. Danse irr\xE9sisitible :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateur pasDeDmg, options --mana 2 --effet danseIrresistible [[1d4+@{selected|CHA]].
      • -
      • Objet de sort : #Attaque Danse irrésisitible --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet danseIrresistible [[1d4+@{selected|CHA]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateur pasDeDmg, options --mana 2 --effet danseIrresistible [[1d4+@{selected|CHA]].
      • +
      • Objet de sort : #Attaque Danse irr\xE9sisitible --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet danseIrresistible [[1d4+@{selected|CHA]]
    12. -
    13. Musique fascinante : !cof-lancer-sort joue une musique fascinante qui contrôle toutes les créatures de son choix de moins de [[5+@{selected|CHA}]] PV --mana 3
    14. +
    15. Musique fascinante : !cof-lancer-sort joue une musique fascinante qui contr\xF4le toutes les cr\xE9atures de son choix de moins de [[5+@{selected|CHA}]] PV --mana 3

    Voie du saltimbanque

      -
    1. Acrobate : ajouter les compétences sur la fiche
    2. -
    3. Grâce féline : ajouter un prédicat graceFeline. Cela va affecter l'initiative et la DEF, mais sans se voir sur la fiche.
    4. +
    5. Acrobate : ajouter les comp\xE9tences sur la fiche
    6. +
    7. Gr\xE2ce f\xE9line : ajouter un pr\xE9dicat graceFeline. Cela va affecter l'initiative et la DEF, mais sans se voir sur la fiche.
    8. Lanceur de couteau : faire normalement l'attaque.
    9. -
    10. Esquive acrobatique : ajouter un prédicat esquiveAcrobatique.
    11. -
    12. Liberté d'action : ajouter un prédicat liberteDAction.
    13. +
    14. Esquive acrobatique : ajouter un pr\xE9dicat esquiveAcrobatique.
    15. +
    16. Libert\xE9 d'action : ajouter un pr\xE9dicat liberteDAction.
    -

    Voie de la séduction

    +

    Voie de la s\xE9duction

      -
    1. Charmant : ajouter les compétences sur la fiche
    2. -
    3. Dentelles et rapière : Ajouter un prédicat dentellesEtRapiere avec comme valeur le rang dans la voie de la séduction. Cela augmente la DEF, mais seulement lorsque le barde ne porte pas d'armure et seulement contre les attaques au contact. (ne se voit pas sur le total de DEF de la fiche)
    4. -
    5. Arme secrète : !cof-arme-secrete @{selected|token_id} @{target|token_id}
    6. +
    7. Charmant : ajouter les comp\xE9tences sur la fiche
    8. +
    9. Dentelles et rapi\xE8re : Ajouter un pr\xE9dicat dentellesEtRapiere avec comme valeur le rang dans la voie de la s\xE9duction. Cela augmente la DEF, mais seulement lorsque le barde ne porte pas d'armure et seulement contre les attaques au contact. (ne se voit pas sur le total de DEF de la fiche)
    10. +
    11. Arme secr\xE8te : !cof-arme-secrete @{selected|token_id} @{target|token_id}
    12. Suggestion :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg, options --mana 2 --difficultePVmax --attaqueMentale --if touche --message la cible doit faire l'action suggérée --endif.
      • -
      • Objet de sort : #Attaque Suggestion --toucher [[@{selected|ATKMAG}]] --portee 20 --pasDeDmg --difficultePVmax --sortilege --attaqueMentale --if touche --message la cible doit faire l'action suggérée --endif
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg, options --mana 2 --difficultePVmax --attaqueMentale --if touche --message la cible doit faire l'action sugg\xE9r\xE9e --endif.
      • +
      • Objet de sort : #Attaque Suggestion --toucher [[@{selected|ATKMAG}]] --portee 20 --pasDeDmg --difficultePVmax --sortilege --attaqueMentale --if touche --message la cible doit faire l'action sugg\xE9r\xE9e --endif
    13. -
    14. Charisme héroïque : Reporter le bonus sur la fiche.
    15. +
    16. Charisme h\xE9ro\xEFque : Reporter le bonus sur la fiche.

    Voie du vagabond

      -
    1. Rumeurs et légendes : ajouter les compétences sur la fiche
    2. -
    3. Compréhension des langues : !cof-lancer-sort lance un sort de compréhension des langues. --messageMJ la compréhension des langues va durer [[1d6+@{selected|CHA}]] minutes --mana 0
    4. -
    5. Débrouillard : pas de support particulier. Ajouter le bonus aux compétences que vous souhaitez noter.
    6. -
    7. Déguisement :!cof-lancer-sort lance un sort de déguisement --mana 2
    8. -
    9. Touche à tout : se reporter aux capacités choisies
    10. +
    11. Rumeurs et l\xE9gendes : ajouter les comp\xE9tences sur la fiche
    12. +
    13. Compr\xE9hension des langues : !cof-lancer-sort lance un sort de compr\xE9hension des langues. --messageMJ la compr\xE9hension des langues va durer [[1d6+@{selected|CHA}]] minutes --mana 0
    14. +
    15. D\xE9brouillard : pas de support particulier. Ajouter le bonus aux comp\xE9tences que vous souhaitez noter.
    16. +
    17. D\xE9guisement :!cof-lancer-sort lance un sort de d\xE9guisement --mana 2
    18. +
    19. Touche \xE0 tout : se reporter aux capacit\xE9s choisies

    Chevalier

    Voie du cavalier

      -
    1. Fidèle monture : Faire un personnage pour la monture, avec un prédicat monture. Pour monter sur la monture, on peut utiliser une ability de type token action, avec !cof-en-selle @{selected|token_id} nom_de_la_monture. Pour en descendre, il suffit de cliquer à nouveau sur le bouton de l'ability. Si vous souhaitez éviter que la monture apparaisse dans le turn tracker, vous pouvez ajouter un prédicat aucuneActionCombat à la monture.
    2. -
    3. Cavalier émérite : Ajouter au chevalier un prédicat cavalierEmerite:2. Pour la défense de la monture, ajouter à cellle-ci un prédicat defDeriveeDe de valeur le nom du chevalier (exactement tel qu'il apparaît sur la fiche, il est possible que cela demande d'utiliser la syntaxe avec ::).
    4. -
    5. Monture magique : pour les soins automatiques de la nuit, ajouter un prédicat montureMagique.
    6. +
    7. Fid\xE8le monture : Faire un personnage pour la monture, avec un pr\xE9dicat monture. Pour monter sur la monture, on peut utiliser une ability de type token action, avec !cof-en-selle @{selected|token_id} nom_de_la_monture. Pour en descendre, il suffit de cliquer \xE0 nouveau sur le bouton de l'ability. Si vous souhaitez \xE9viter que la monture apparaisse dans le turn tracker, vous pouvez ajouter un pr\xE9dicat aucuneActionCombat \xE0 la monture.
    8. +
    9. Cavalier \xE9m\xE9rite : Ajouter au chevalier un pr\xE9dicat cavalierEmerite:2. Pour la d\xE9fense de la monture, ajouter \xE0 cellle-ci un pr\xE9dicat defDeriveeDe de valeur le nom du chevalier (exactement tel qu'il appara\xEEt sur la fiche, il est possible que cela demande d'utiliser la syntaxe avec ::).
    10. +
    11. Monture magique : pour les soins automatiques de la nuit, ajouter un pr\xE9dicat montureMagique.
    12. - Charge : pas de support pour le déplacement, mais + Charge : pas de support pour le d\xE9placement, mais
      • Pour l'attaque : utiliser --m2d20 --plus 1d6
      • -
      • Pour les créatures sur la trajectoire, utiliser !cof-jet FOR 18, et en cas de succès, infliger les DM.
      • +
      • Pour les cr\xE9atures sur la trajectoire, utiliser !cof-jet FOR 18, et en cas de succ\xE8s, infliger les DM.
    13. -
    14. Monture fantastique : Faire un personnage pour la monture, avec un prédicat monture.
    15. +
    16. Monture fantastique : Faire un personnage pour la monture, avec un pr\xE9dicat monture.

    Voie de la guerre

      @@ -1155,38 +1158,38 @@

      Voie de la guerre

    1. Encaisser un coup :
      • utiliser !cof-effet-temp encaisserUnCoup 1 pour se mettre en position
      • -
      • Le script proposera un bouton à activer en cas d'attaque réussie alors que le chevalier est en position.
      • +
      • Le script proposera un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le chevalier est en position.
    2. -
    3. Coup de bouclier : faire une attaque de bouclier, de type Arme gauche, avec le modificateur avecd12crit. Pour que cette attaque soit proposée dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un prédicat attaqueAuBouclier de valeur le label de l'attaque.
    4. +
    5. Coup de bouclier : faire une attaque de bouclier, de type Arme gauche, avec le modificateur avecd12crit. Pour que cette attaque soit propos\xE9e dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un pr\xE9dicat attaqueAuBouclier de valeur le label de l'attaque.
    6. Frappe lourde : faire l'attaque avec les options --avecd12crit --plus 2d6 --ignoreMoitieRD --seulementContact
    7. -
    8. Force héroïque : reporter les bonus sur la fiche
    9. +
    10. Force h\xE9ro\xEFque : reporter les bonus sur la fiche
    -

    Voie du héro

    +

    Voie du h\xE9ro

      -
    1. Ignorer la douleur : Ajouter un prédicat ignorerLaDouleur. Normalement, le script affiche un bouton quand cela est utilisable, mais on peut aussi le déclencher avec !cof-ignorer-la-douleur juste après le coup.
    2. -
    3. Piqures d'insectes : ajouter un prédicat piquresDInsectes, avec comme valeur le rang dans la voie.
    4. -
    5. Laissez-le-moi ! : Ajouter un prédicat laissezLeMoi. Le bonus sera accordé contre tous les tokens ayant le statut de chef (donnés avec !cof-set-state chef true, ou alors simplement en activant le marker sur le token).
    6. -
    7. Seul contre tous : Utiliser !cof-effet-temp seulContreTous 1 pour se mettre en position. Les actions affichées en cas de riposte seront normalement une attaque avec l'arme en main si il y en a, plus les attaques naturelles cochées sur la liste d'attaque. Si ça ne convient pas, vous pouvez écrire une liste d'actions nomméeRipostes (voir les actions du tour).
    8. -
    9. Charisme héroïque : reporter sur la fiche.
    10. +
    11. Ignorer la douleur : Ajouter un pr\xE9dicat ignorerLaDouleur. Normalement, le script affiche un bouton quand cela est utilisable, mais on peut aussi le d\xE9clencher avec !cof-ignorer-la-douleur juste apr\xE8s le coup.
    12. +
    13. Piqures d'insectes : ajouter un pr\xE9dicat piquresDInsectes, avec comme valeur le rang dans la voie.
    14. +
    15. Laissez-le-moi ! : Ajouter un pr\xE9dicat laissezLeMoi. Le bonus sera accord\xE9 contre tous les tokens ayant le statut de chef (donn\xE9s avec !cof-set-state chef true, ou alors simplement en activant le marker sur le token).
    16. +
    17. Seul contre tous : Utiliser !cof-effet-temp seulContreTous 1 pour se mettre en position. Les actions affich\xE9es en cas de riposte seront normalement une attaque avec l'arme en main si il y en a, plus les attaques naturelles coch\xE9es sur la liste d'attaque. Si \xE7a ne convient pas, vous pouvez \xE9crire une liste d'actions nomm\xE9eRipostes (voir les actions du tour).
    18. +
    19. Charisme h\xE9ro\xEFque : reporter sur la fiche.

    Voie du meneur d'hommes

      -
    1. Sans peur : Ajouter un prédicat sansPeur, utilisé quand on essaiera de faire peur à un allié.
    2. -
    3. Intercepter : Ajouter un prédicat intercepter, et un autre voieDuMeneurDHomme de valeur le rang dans la voie, s'il est différent de 2.
    4. -
    5. Exemplaire : !cof-exemplaire, juste après l'attaque ratée.
    6. +
    7. Sans peur : Ajouter un pr\xE9dicat sansPeur, utilis\xE9 quand on essaiera de faire peur \xE0 un alli\xE9.
    8. +
    9. Intercepter : Ajouter un pr\xE9dicat intercepter, et un autre voieDuMeneurDHomme de valeur le rang dans la voie, s'il est diff\xE9rent de 2.
    10. +
    11. Exemplaire : !cof-exemplaire, juste apr\xE8s l'attaque rat\xE9e.
    12. Ordre de bataille : pas de support
    13. Charge fantastique : !cof-charge-fantastique @{selected|token_id} --alliesEnVue --self --limiteParCombat 1

    Voie de la noblesse

      -
    1. Éduqué : pas de support particulier, juste reporter les bonus sur la fiche.
    2. -
    3. Autorité naturelle : simplement reporter sur la fiche les bonus d'init et de DEF, et ajouter la capacité intimider.
    4. -
    5. Écuyer : +
    6. \xC9duqu\xE9 : pas de support particulier, juste reporter les bonus sur la fiche.
    7. +
    8. Autorit\xE9 naturelle : simplement reporter sur la fiche les bonus d'init et de DEF, et ajouter la capacit\xE9 intimider.
    9. +
    10. \xC9cuyer :
        -
      • Pour le bonus au critique, ajouter un prédicat ecuyer.
      • -
      • Pour les soins de nuit, ajouter à l'écuyer un prédicat ecuyerDe, avec comme valeur le nom du chevalier (attention à utiliser la syntaxe avec :: si ce nom contient des espaces). L'écuyer pourra soigner chaque nuit le chevalier et certains alliés, mais pour qu'il soigne les alliés, il ne faut pas oublier de le mettre dans la liste de l'équipe du chevalier.
      • -
      • Si on souhaite que l'écuyer puisse soigner gratuitement la monture, il faut aussi que celle-ci ait un prédicat montureDe, avec comme valeur le nom du chevalier.
      • +
      • Pour le bonus au critique, ajouter un pr\xE9dicat ecuyer.
      • +
      • Pour les soins de nuit, ajouter \xE0 l'\xE9cuyer un pr\xE9dicat ecuyerDe, avec comme valeur le nom du chevalier (attention \xE0 utiliser la syntaxe avec :: si ce nom contient des espaces). L'\xE9cuyer pourra soigner chaque nuit le chevalier et certains alli\xE9s, mais pour qu'il soigne les alli\xE9s, il ne faut pas oublier de le mettre dans la liste de l'\xE9quipe du chevalier.
      • +
      • Si on souhaite que l'\xE9cuyer puisse soigner gratuitement la monture, il faut aussi que celle-ci ait un pr\xE9dicat montureDe, avec comme valeur le nom du chevalier.
    @@ -1196,52 +1199,52 @@

    Druide

    Voie des animaux

    1. Langage des animaux : pas de support particulier
    2. -
    3. Nuée d'insectes : Pas de support particulier pour les DM de zone qui détruisent la nuée (enlever l'attribut nueeDInsecte sur la cible dans ce cas). +
    4. Nu\xE9e d'insectes : Pas de support particulier pour les DM de zone qui d\xE9truisent la nu\xE9e (enlever l'attribut nueeDInsecte sur la cible dans ce cas).
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateur pasDeDmg, options --mana 0 --effet nueeDInsectes [[5+@{selected|SAG}]].
      • -
      • Objet de sort : #Attaque Nuée d'insectes --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet nueeDInsectes [[5+@{selected|SAG}]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateur pasDeDmg, options --mana 0 --effet nueeDInsectes [[5+@{selected|SAG}]].
      • +
      • Objet de sort : #Attaque Nu\xE9e d'insectes --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet nueeDInsectes [[5+@{selected|SAG}]]
    5. -
    6. Le guetteur : Si elle n'est pas déjà présente dans votre handout de compétences, ajouter au druide une compétence perception (valeur 0 pour le moment). Créer un personnage et un token pour l'oiseau. Ajouter au druide un prédicat guetteur de valeur le nom exact de l'oiseau (sur la fiche, attention à utiliser la symtaxe avec :: si le nom comporte des espaces). Ajouter de même un prédicat PVPartagesAvec de valeur le nom de l'oiseau. Ajouter aussi à l'oiseau un prédicat PVPartagesAvec de valeur le nom du druide. Pour le faire agir en même temps que le druide, ajoutez aussi à l'oiseau un prédicat initiativeDeriveeDe de valeur le nom du druide. Pour l'attaque, ajouter sur la fiche une attaque de contact faisant 1d4 DM, avec dans les options --attaqueMagiqueDe nom de personnage du druide. Si vous souhaitez que le guetteur rentre en combat en même temps que le druide, ajoutez au druide un prédicat nommé entrerEnCombatAvec, de valeur le nom du token de l'oiseau.
    7. -
    8. Masque du prédateur : !cof-effet-temp masqueDuPredateur [[5+@{selected|SAG}]] --mana 2
    9. +
    10. Le guetteur : Si elle n'est pas d\xE9j\xE0 pr\xE9sente dans votre handout de comp\xE9tences, ajouter au druide une comp\xE9tence perception (valeur 0 pour le moment). Cr\xE9er un personnage et un token pour l'oiseau. Ajouter au druide un pr\xE9dicat guetteur de valeur le nom exact de l'oiseau (sur la fiche, attention \xE0 utiliser la symtaxe avec :: si le nom comporte des espaces). Ajouter de m\xEAme un pr\xE9dicat PVPartagesAvec de valeur le nom de l'oiseau. Ajouter aussi \xE0 l'oiseau un pr\xE9dicat PVPartagesAvec de valeur le nom du druide. Pour le faire agir en m\xEAme temps que le druide, ajoutez aussi \xE0 l'oiseau un pr\xE9dicat initiativeDeriveeDe de valeur le nom du druide. Pour l'attaque, ajouter sur la fiche une attaque de contact faisant 1d4 DM, avec dans les options --attaqueMagiqueDe nom de personnage du druide. Si vous souhaitez que le guetteur rentre en combat en m\xEAme temps que le druide, ajoutez au druide un pr\xE9dicat nomm\xE9 entrerEnCombatAvec, de valeur le nom du token de l'oiseau.
    11. +
    12. Masque du pr\xE9dateur : !cof-effet-temp masqueDuPredateur [[5+@{selected|SAG}]] --mana 2
    13. Forme animale : pas d'autre support que !cof-lancer-sort se transforme en ?{Transformation en ?} --mana 3

    Voie du fauve

      -
    1. Vitesse du félin : ajouter un prédicat vitesseDuFelin, de valeur le rang dans la voie. Pensez à ajouter des compétences de saut, escalade et course sur la fiche (sans les bonus !) s'ils ne sont pas déjà présent dans votre handout de compétences.
    2. -
    3. Panthère : ajouter un personnage pour la panthère, qui sera contrôlé par le joueur. Si vous souhaitez que la panthère rentre en combat à chaque fois que le druide entre en combat, ajoutez au druide un prédicat nommé entrerEnCombatAvec, de valeur le nom du token de la panthère (il peut y avoir plusieurs prédicats avec ce nom).
    4. -
    5. Attaque bondissante : faire l'attaque avec les options --bonusAttaque 5 --plus 1d6. Les conditions d'utilisation sont à vérifier par le MJ.
    6. -
    7. Grand félin : ajuster la fiche de la panthère, et pour le soin, utiliser !cof-soin @{selected|token_id} nom_familier ?{Montant des soins} --transfer.
    8. -
    9. Les sept vies du chat : pas de support particulier, la commande Undo peut être utilisée pour annuler l'action qui a mené le Druide à 0 PV.
    10. +
    11. Vitesse du f\xE9lin : ajouter un pr\xE9dicat vitesseDuFelin, de valeur le rang dans la voie. Pensez \xE0 ajouter des comp\xE9tences de saut, escalade et course sur la fiche (sans les bonus !) s'ils ne sont pas d\xE9j\xE0 pr\xE9sent dans votre handout de comp\xE9tences.
    12. +
    13. Panth\xE8re : ajouter un personnage pour la panth\xE8re, qui sera contr\xF4l\xE9 par le joueur. Si vous souhaitez que la panth\xE8re rentre en combat \xE0 chaque fois que le druide entre en combat, ajoutez au druide un pr\xE9dicat nomm\xE9 entrerEnCombatAvec, de valeur le nom du token de la panth\xE8re (il peut y avoir plusieurs pr\xE9dicats avec ce nom).
    14. +
    15. Attaque bondissante : faire l'attaque avec les options --bonusAttaque 5 --plus 1d6. Les conditions d'utilisation sont \xE0 v\xE9rifier par le MJ.
    16. +
    17. Grand f\xE9lin : ajuster la fiche de la panth\xE8re, et pour le soin, utiliser !cof-soin @{selected|token_id} nom_familier ?{Montant des soins} --transfer.
    18. +
    19. Les sept vies du chat : pas de support particulier, la commande Undo peut \xEAtre utilis\xE9e pour annuler l'action qui a men\xE9 le Druide \xE0 0 PV.

    Voie de la nature

      -
    1. Maître de la survie : Ajouter +2 par rang à une compétence vigilance
    2. -
    3. Marche sylvestre : ajouter un prédicat marcheSylvestre. Pour indiquer un terrain difficile, on peut utiliser les objets graphiques sur le layer des cartes (map en anglais). Pour cela, éditer l'objet, et ajouter dans les notes pour MJ une ligne terrainDifficile. Tout le dessin est considéré comme un terrain difficile. On peut restreindre la partie considérée comme difficile à un disque en écrivant terrainDifficile: disque nn est le diamètre du disque en pixels. À noter que la zone d'une prison végétale est considérée difficile par le script. Le druide est considéré en terrain difficile si vous le mettez dans l'état conditionsHostiles (pour des valeurs inférieures à 5). Alternativement, si vous n'avez pas ajouté le type de terrain vous pouvez taper !cof-effet marcheSylvestre oui quand le druide entre dans un terrain que vous considérez difficile. Dans ce cas, faire !cof-effet marcheSylvestre non quand il sort de cette zone.
    4. -
    5. Résistant : ajouter dans la RD sur la fiche, nature:v, avec comme valeur v la RD (donc deux fois le rang dans la voie). Cette RD s'applique à toute attaque ou dommages avec l'option --nature ou --naturel. Il s'applique aussi à toute attaque venant d'un personnage avec un prédicat animal, ou insecte ou bien avec un profil animal ou insecte, ou avec une race reconnue comme étant un animal ou un insecte. Dans ce cas, si on souhaite qu'une attaque d'une telle créature ne soit pas considérée comme naturelle, on peut utiliser l'option --artificiel à l'attaque.
    6. -
    7. Bâton de druide : Simplement créer l'attaque correspondante et permettre les deux attaques en action limitée.
    8. -
    9. Constitution héroïque : reporter sur la fiche
    10. +
    11. Ma\xEEtre de la survie : Ajouter +2 par rang \xE0 une comp\xE9tence vigilance
    12. +
    13. Marche sylvestre : ajouter un pr\xE9dicat marcheSylvestre. Pour indiquer un terrain difficile, on peut utiliser les objets graphiques sur le layer des cartes (map en anglais). Pour cela, \xE9diter l'objet, et ajouter dans les notes pour MJ une ligne terrainDifficile. Tout le dessin est consid\xE9r\xE9 comme un terrain difficile. On peut restreindre la partie consid\xE9r\xE9e comme difficile \xE0 un disque en \xE9crivant terrainDifficile: disque n o\xF9 n est le diam\xE8tre du disque en pixels. \xC0 noter que la zone d'une prison v\xE9g\xE9tale est consid\xE9r\xE9e difficile par le script. Le druide est consid\xE9r\xE9 en terrain difficile si vous le mettez dans l'\xE9tat conditionsHostiles (pour des valeurs inf\xE9rieures \xE0 5). Alternativement, si vous n'avez pas ajout\xE9 le type de terrain vous pouvez taper !cof-effet marcheSylvestre oui quand le druide entre dans un terrain que vous consid\xE9rez difficile. Dans ce cas, faire !cof-effet marcheSylvestre non quand il sort de cette zone.
    14. +
    15. R\xE9sistant : ajouter dans la RD sur la fiche, nature:v, avec comme valeur v la RD (donc deux fois le rang dans la voie). Cette RD s'applique \xE0 toute attaque ou dommages avec l'option --nature ou --naturel. Il s'applique aussi \xE0 toute attaque venant d'un personnage avec un pr\xE9dicat animal, ou insecte ou bien avec un profil animal ou insecte, ou avec une race reconnue comme \xE9tant un animal ou un insecte. Dans ce cas, si on souhaite qu'une attaque d'une telle cr\xE9ature ne soit pas consid\xE9r\xE9e comme naturelle, on peut utiliser l'option --artificiel \xE0 l'attaque.
    16. +
    17. B\xE2ton de druide : Simplement cr\xE9er l'attaque correspondante et permettre les deux attaques en action limit\xE9e.
    18. +
    19. Constitution h\xE9ro\xEFque : reporter sur la fiche

    Voie du protecteur

      -
    1. Baies magiques : Pour simplement créer les baies, on peut utiliser !cof-creer-baies, avec éventuellement des arguments pour la dépense de mana. Si le sort ne demande pas de dépense et que le temps passé n'est pas important, il peut être plus simple de directement utiliser !cof-distribuer-baies avec option --allies --self ou --target pour créer et donner des baies (en ayant sélectionné le druide, le mieux est d'utiliser une ability). Pour consommer ensuite une baie, il faut utiliser !cof-consommables.
    2. -
    3. Forêt vivante : on peut mettre un effet (avec !cof-effet) foretVivanteEnnemie aux personnages affectés. Par exemple, si on veut donner l'effet aux personnages non alliés du druide, on peut faire !cof-effet foretVivanteEnnemie oui --disque @{selected|token_id} 2000 --saufAllies --mana 0. Attention, l'effet ne disparaît que si on fait un !cof-effet foretVivanteEnnemie non sur les personnages.
    4. -
    5. Régénération : !cof-effet-temp regeneration [[@{selected|niveau} + @{selected|SAG}]] --lanceur @{selected|token_id} --target @{target|token_id} --limiteCibleParJour 1 --portee 0 --mana 1.
    6. -
    7. Forme d'arbre : !cof-effet-temp formeDArbre [[5+@{selected|SAG}]] --mana 2. J'ai choisi de donner comme pouvoir supplémentaire à cette forme d'avoir ses propres PVs, et le druide récupère ses PVs originaux à la fin de l'effet. La transformation est annulée aussi si l'arbre perd tous ses PVs. Le nombre de PVs par défaut est de niveau x 5, mais il peut être modifié en ajoutant au argument --valeur pv. Pour augmenter un peu l'intérêt de ce sort, je lui fais aussi augmenter de 50% le bonus de peau d'écorce. Si vous utilisez les actions à afficher à chaque tour, vous pouvez aussi créer une liste d'actions nommée Forme d'arbre contenant les sorts et actions possibles en forme d'arbre. Si une telle liste existe, elle va toujours afficher au moins les actions défensive, d'attente et d'attaque sous forme d'arbre (pas besoin de créer une attaque dédiée sur la fiche). Il est possible de spécifier une image pour le token en forme d'arbre, en utilisant le valeur d'un prédicat tokenFormeDArbre.
    8. -
    9. Sagesse héroïque : reporter sur la fiche
    10. +
    11. Baies magiques : Pour simplement cr\xE9er les baies, on peut utiliser !cof-creer-baies, avec \xE9ventuellement des arguments pour la d\xE9pense de mana. Si le sort ne demande pas de d\xE9pense et que le temps pass\xE9 n'est pas important, il peut \xEAtre plus simple de directement utiliser !cof-distribuer-baies avec option --allies --self ou --target pour cr\xE9er et donner des baies (en ayant s\xE9lectionn\xE9 le druide, le mieux est d'utiliser une ability). Pour consommer ensuite une baie, il faut utiliser !cof-consommables.
    12. +
    13. For\xEAt vivante : on peut mettre un effet (avec !cof-effet) foretVivanteEnnemie aux personnages affect\xE9s. Par exemple, si on veut donner l'effet aux personnages non alli\xE9s du druide, on peut faire !cof-effet foretVivanteEnnemie oui --disque @{selected|token_id} 2000 --saufAllies --mana 0. Attention, l'effet ne dispara\xEEt que si on fait un !cof-effet foretVivanteEnnemie non sur les personnages.
    14. +
    15. R\xE9g\xE9n\xE9ration : !cof-effet-temp regeneration [[@{selected|niveau} + @{selected|SAG}]] --lanceur @{selected|token_id} --target @{target|token_id} --limiteCibleParJour 1 --portee 0 --mana 1.
    16. +
    17. Forme d'arbre : !cof-effet-temp formeDArbre [[5+@{selected|SAG}]] --mana 2. J'ai choisi de donner comme pouvoir suppl\xE9mentaire \xE0 cette forme d'avoir ses propres PVs, et le druide r\xE9cup\xE8re ses PVs originaux \xE0 la fin de l'effet. La transformation est annul\xE9e aussi si l'arbre perd tous ses PVs. Le nombre de PVs par d\xE9faut est de niveau x 5, mais il peut \xEAtre modifi\xE9 en ajoutant au argument --valeur pv. Pour augmenter un peu l'int\xE9r\xEAt de ce sort, je lui fais aussi augmenter de 50% le bonus de peau d'\xE9corce. Si vous utilisez les actions \xE0 afficher \xE0 chaque tour, vous pouvez aussi cr\xE9er une liste d'actions nomm\xE9e Forme d'arbre contenant les sorts et actions possibles en forme d'arbre. Si une telle liste existe, elle va toujours afficher au moins les actions d\xE9fensive, d'attente et d'attaque sous forme d'arbre (pas besoin de cr\xE9er une attaque d\xE9di\xE9e sur la fiche). Il est possible de sp\xE9cifier une image pour le token en forme d'arbre, en utilisant le valeur d'un pr\xE9dicat tokenFormeDArbre.
    18. +
    19. Sagesse h\xE9ro\xEFque : reporter sur la fiche
    -

    Voie des végétaux

    +

    Voie des v\xE9g\xE9taux

      -
    1. Peau d'écorce : !cof-effet-temp peauDEcorce [[5+@{selected|SAG}]] --mana 0. Par défaut, utilise la valeur d'un prédicat voieDesVegetaux (qui devrait avoir comme valeur le rang dans la voie). Il est possible de choisir une autre valeur en utilisant l'option --valeur, et si aucune des deux méthodes n'est utilisée, le bonus de DEF est de 1.
    2. -
    3. Prison végétale : !cof-effet-temp prisonVegetale [[5+@{selected|SAG}]] --saveActifParTour FOR [[10+@{selected|SAG}]] --lanceur @{selected|token_id} --disque @{target|token_id} 5 20 --saufAllies --mana 0.
    4. -
    5. Animation d'un arbre : !cof-animer-arbre @{selected|token_id} @{target|token_id} --portee 0 --mana 1. Cela implique d'avoir un token représentant l'arbre sur la carte. Ce que je fais, c'est de passer un token d'arbre du layer map au layer tokens, puis je laisse le joueur faire le sort. Si c'est trop compliqué, vous pouvez aussi préparer un personnage arbre, avec les caractéristiques décrites, et le faire arriver sur la carte à la main (ne pas oublier sa RD 10/feu_hache, dans ce cas).
    6. +
    7. Peau d'\xE9corce : !cof-effet-temp peauDEcorce [[5+@{selected|SAG}]] --mana 0. Par d\xE9faut, utilise la valeur d'un pr\xE9dicat voieDesVegetaux (qui devrait avoir comme valeur le rang dans la voie). Il est possible de choisir une autre valeur en utilisant l'option --valeur, et si aucune des deux m\xE9thodes n'est utilis\xE9e, le bonus de DEF est de 1.
    8. +
    9. Prison v\xE9g\xE9tale : !cof-effet-temp prisonVegetale [[5+@{selected|SAG}]] --saveActifParTour FOR [[10+@{selected|SAG}]] --lanceur @{selected|token_id} --disque @{target|token_id} 5 20 --saufAllies --mana 0.
    10. +
    11. Animation d'un arbre : !cof-animer-arbre @{selected|token_id} @{target|token_id} --portee 0 --mana 1. Cela implique d'avoir un token repr\xE9sentant l'arbre sur la carte. Ce que je fais, c'est de passer un token d'arbre du layer map au layer tokens, puis je laisse le joueur faire le sort. Si c'est trop compliqu\xE9, vous pouvez aussi pr\xE9parer un personnage arbre, avec les caract\xE9ristiques d\xE9crites, et le faire arriver sur la carte \xE0 la main (ne pas oublier sa RD 10/feu_hache, dans ce cas).
    12. Gland de pouvoir :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateur pasDeDmg, options --mana 2 --effet statueDeBois [[2d6+@{selected|SAG}]] --valeur 10 10. À noter qu'un prédicat immunite_petrification permet d'être immunisé à cet effet.
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateur pasDeDmg, options --mana 2 --effet statueDeBois [[2d6+@{selected|SAG}]] --valeur 10 10. \xC0 noter qu'un pr\xE9dicat immunite_petrification permet d'\xEAtre immunis\xE9 \xE0 cet effet.
      • Objet de sort : #Attaque Gland de pouvoir --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --effet statueDeBois [[2d6+@{selected|SAG}]] --valeur 10 10
    13. -
    14. Porte végétale : Pas de support au niveau du script, à part !cof-lancer-sort lance un sort de porte végétale --mana 3.
    15. +
    16. Porte v\xE9g\xE9tale : Pas de support au niveau du script, \xE0 part !cof-lancer-sort lance un sort de porte v\xE9g\xE9tale --mana 3.

    Ensorceleur

    @@ -1252,225 +1255,225 @@

    Voie de l'air

  • Sous tension :
    1. !cof-effet-temp sousTension [[5+@{selected|CHA}]] --mana 0 pour lancer le sort et mettre l'ensorceleur sous tension
    2. -
    3. Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+CHA, portée 10, type Sortilège, dégâts électriques, options --si etat sousTension --fx beam-holy.
    4. -
    5. Pour les objets de sorts, on peut mettre l'attaque directement sous la forme #Attaque Décharge électrique --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|CHA}]] --electrique --portee 10 --sortilege --si etat sousTension --fx beam-holy
    6. +
    7. Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+CHA, port\xE9e 10, type Sortil\xE8ge, d\xE9g\xE2ts \xE9lectriques, options --si etat sousTension --fx beam-holy.
    8. +
    9. Pour les objets de sorts, on peut mettre l'attaque directement sous la forme #Attaque D\xE9charge \xE9lectrique --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|CHA}]] --electrique --portee 10 --sortilege --si etat sousTension --fx beam-holy
  • - Note : Il est possible de spécifier une autre valeur pour les DM automatiques quand le lanceur est touché en contact, en rajoutant --valeur X à la première ability. + Note : Il est possible de sp\xE9cifier une autre valeur pour les DM automatiques quand le lanceur est touch\xE9 en contact, en rajoutant --valeur X \xE0 la premi\xE8re ability. -
  • Télékinésie : Pas de support autre que !cof-lancer-sort lance un sort de télékinésie --mana 1
  • +
  • T\xE9l\xE9kin\xE9sie : Pas de support autre que !cof-lancer-sort lance un sort de t\xE9l\xE9kin\xE9sie --mana 1
  • Foudre :
      -
    • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, 4d6+CHA, portée 10, type Sortilège, options --mana 2 --psave DEX [[12+@{selected|DEX}]] --ligne --fx beam-holy.
    • +
    • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, 4d6+CHA, port\xE9e 10, type Sortil\xE8ge, options --mana 2 --psave DEX [[12+@{selected|DEX}]] --ligne --fx beam-holy.
    • Objet de sort : #Attaque Foudre --toucher [[@{selected|ATKMAG}]] --dm 4d6+[[@{selected|CHA}]] --portee 10 --sortilege --psave DEX [[12+@{selected|DEX}]] --ligne --fx beam-holy
  • -
  • Forme éthérée : !cof-effet-temp intangible [[5 + @{selected|CHA}]] --mana 3. Pour implémentaer des variantes, il existe aussi un effet intangibleInvisible qui cumule les états intangible et invisible, et l'option --puissant donne la possibilité au personnage de passer entre l'état tangible et intangible à chaque tour, tant que dure l'effet.
  • +
  • Forme \xE9th\xE9r\xE9e : !cof-effet-temp intangible [[5 + @{selected|CHA}]] --mana 3. Pour impl\xE9mentaer des variantes, il existe aussi un effet intangibleInvisible qui cumule les \xE9tats intangible et invisible, et l'option --puissant donne la possibilit\xE9 au personnage de passer entre l'\xE9tat tangible et intangible \xE0 chaque tour, tant que dure l'effet.
  • Voie de la divination

      -
    1. 6eme sens : ajouter le bonus en DEF divers et initiative diver, ajouter une compétence vigilance, de valeur 2*rang (le bonus aux jet de surprise).
    2. -
    3. Détection de l'invisible : !cof-effet-temp detectionDeLInvisible [[5+@{selected|CHA}]] --mana 0.
    4. -
    5. Clairvoyance : !cof-lancer-sort peut voir et entendre à distance --mana 1
    6. -
    7. Prescience : ajouter un prédicat prescience (on peut y associer un nombre pour avoir plus d'une prescience par tour). Si le personnage était sur la carte au moment de lancer le combat, il se verra proposer un bouton pour utiliser sa prescience à la fin de chaque tour. Attention, en l'état, il est impossible d'annuler l'utilisation de ce bouton. De plus, ce bouton ne fera rien si le script a été interrompu depuis le début du tour (interruption de la partie, redémarrage du script, etc...).
    8. +
    9. 6eme sens : ajouter le bonus en DEF divers et initiative diver, ajouter une comp\xE9tence vigilance, de valeur 2*rang (le bonus aux jet de surprise).
    10. +
    11. D\xE9tection de l'invisible : !cof-effet-temp detectionDeLInvisible [[5+@{selected|CHA}]] --mana 0.
    12. +
    13. Clairvoyance : !cof-lancer-sort peut voir et entendre \xE0 distance --mana 1
    14. +
    15. Prescience : ajouter un pr\xE9dicat prescience (on peut y associer un nombre pour avoir plus d'une prescience par tour). Si le personnage \xE9tait sur la carte au moment de lancer le combat, il se verra proposer un bouton pour utiliser sa prescience \xE0 la fin de chaque tour. Attention, en l'\xE9tat, il est impossible d'annuler l'utilisation de ce bouton. De plus, ce bouton ne fera rien si le script a \xE9t\xE9 interrompu depuis le d\xE9but du tour (interruption de la partie, red\xE9marrage du script, etc...).
    16. Hyperconscience : reporter sur la fiche.
    -

    Voie de l'envoûteur

    +

    Voie de l'envo\xFBteur

    1. Injonction : utiliser !cof-injonction @{selected|token_id} @{target|token_id} --portee 20 --mana 0
    2. -
    3. Sommeil : !cof-sommeil @{selected|token_id} --disque @{target|token_id} 5 20 --mana 0. Pour sélectionner le centre de la zone, on peut utiliser un personnage fictif (avec un token représentant une cible, par exemple) ayant 0 de max de PV.
    4. +
    5. Sommeil : !cof-sommeil @{selected|token_id} --disque @{target|token_id} 5 20 --mana 0. Pour s\xE9lectionner le centre de la zone, on peut utiliser un personnage fictif (avec un token repr\xE9sentant une cible, par exemple) ayant 0 de max de PV.
    6. Confusion:
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg options --mana 1 --attaqueMentale --effet confusion [[3+@{selected|CHA}]] --saveParTour SAG [[10+@{selected|CHA}]].
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg options --mana 1 --attaqueMentale --effet confusion [[3+@{selected|CHA}]] --saveParTour SAG [[10+@{selected|CHA}]].
      • Objet de sort : #Attaque Confusion --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --attaqueMentale --effet confusion [[3+@{selected|CHA}]] --saveParTour SAG [[10+@{selected|CHA}]]
    7. -
    8. Amitié: +
    9. Amiti\xE9:
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg options --mana 2 --attaqueMentale --difficultePVmax --effet charme --save SAG [[12+@{selected|CHA}]] --saveParJour SAG [[12+@{selected|CHA}]].
      • -
      • Objet de sort : #Attaque Amitié --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --attaqueMentale --difficultePVmax --effet charme --save SAG [[12+@{selected|CHA}]] --saveParJour SAG [[12+@{selected|CHA}]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg options --mana 2 --attaqueMentale --difficultePVmax --effet charme --save SAG [[12+@{selected|CHA}]] --saveParJour SAG [[12+@{selected|CHA}]].
      • +
      • Objet de sort : #Attaque Amiti\xE9 --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --attaqueMentale --difficultePVmax --effet charme --save SAG [[12+@{selected|CHA}]] --saveParJour SAG [[12+@{selected|CHA}]]
    10. Domination : utiliser !cof-attaque-magique @{selected|token_id} @{target|token_id} --portee 20 --attaqueMentale

    Voie des illusions

      -
    1. Image décalée : !cof-effet-temp imageDecalee [[5+@{selected|CHA}]] --mana 0.
    2. +
    3. Image d\xE9cal\xE9e : !cof-effet-temp imageDecalee [[5+@{selected|CHA}]] --mana 0.
    4. Mirage : pas de support autre que !cof-lancer-sort lance un sort de mirage ([[5+@{selected|CHA}]] minutes) --mana 0
    5. Imitation : pas de support autre que !cof-lancer-sort lance un sort d'imitation ([[5+@{selected|CHA}]] minutes) --mana 1
    6. -
    7. Dédoublement : +
    8. D\xE9doublement :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg options --mana 2 --effet dedoublement [[5+@{selected|CHA}]].
      • -
      • Objet de sort : #Attaque Dédoublement --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet dedoublement [[5+@{selected|CHA}]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg options --mana 2 --effet dedoublement [[5+@{selected|CHA}]].
      • +
      • Objet de sort : #Attaque D\xE9doublement --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet dedoublement [[5+@{selected|CHA}]]
    9. -
    10. Tueur fantasmagorique : !cof-tueur-fantasmagorique @{selected|token_id} @{target|token_id} --portee 20 --mana 3. Attention, j'en ai fait une interprétation un peu personnelle : au lieu de ne pas pouvoir toucher les cibles de niveau supérieur au lanceur, les cible de niveau supérieur gagnent un bonus de 5 par niveau au dessus de celui du lanceur pour résister au tueur fantasmagorique. Et ceux de niveau inférieur un malus de 1 par niveau de différence. Si cette interprétation ne vous convient pas, n'hésitez pas à me demander des changements.
    11. +
    12. Tueur fantasmagorique : !cof-tueur-fantasmagorique @{selected|token_id} @{target|token_id} --portee 20 --mana 3. Attention, j'en ai fait une interpr\xE9tation un peu personnelle : au lieu de ne pas pouvoir toucher les cibles de niveau sup\xE9rieur au lanceur, les cible de niveau sup\xE9rieur gagnent un bonus de 5 par niveau au dessus de celui du lanceur pour r\xE9sister au tueur fantasmagorique. Et ceux de niveau inf\xE9rieur un malus de 1 par niveau de diff\xE9rence. Si cette interpr\xE9tation ne vous convient pas, n'h\xE9sitez pas \xE0 me demander des changements.

    Voie de l'invocation

      -
    1. Familier : créer un personnage (de type PNJ) pour le familier, controlé par le joueur et avec un token lié ayant la capacité de voir. +
    2. Familier : cr\xE9er un personnage (de type PNJ) pour le familier, control\xE9 par le joueur et avec un token li\xE9 ayant la capacit\xE9 de voir.
        -
      • Pour le bonus en initiative, ajouter un prédicat familier au personnage, avec comme valeur le nom du compagnon (doit être exactement le même que celui du token du compagnon). Cela automatise l'initiative quand le familier est présent.
      • -
      • Pour les points de vie partagés avec le familier, il faut mettre un prédicat PVPartagesAvec de valeur le nom du familier (celui de la fiche, pas forcément le même que le token) pour le personnage, et un prédicat similaire chez le familier, de valeur le nom du personnage. Le partage de PVs ne fonctionne pas avec des mooks, et il ne fait pas le partage de dégâts temporaires. En revanche, le script devrait gérer correctement les dégâts de zone.
      • -
      • Pour la défense du familier, lui ajouter un prédicat defDeriveeDe, de valeur le nom du personnage (nom complet sur la fiche, attention à bien utiliser la syntaxe avec :: si ce nom contient des espaces ou autres caractères spéciaux).
      • -
      • L'initiative ne devrait pas être très utile, mais si besoin, ajoutez un prédicat initiativeDeriveeDe de valeur le nom du personnage. En fait, pour les familiers normaux, je préfères même qu'ils n'apparaissent pas sur le turn tracker, et je leur met donc un prédicat aucuneActionCombat.
      • +
      • Pour le bonus en initiative, ajouter un pr\xE9dicat familier au personnage, avec comme valeur le nom du compagnon (doit \xEAtre exactement le m\xEAme que celui du token du compagnon). Cela automatise l'initiative quand le familier est pr\xE9sent.
      • +
      • Pour les points de vie partag\xE9s avec le familier, il faut mettre un pr\xE9dicat PVPartagesAvec de valeur le nom du familier (celui de la fiche, pas forc\xE9ment le m\xEAme que le token) pour le personnage, et un pr\xE9dicat similaire chez le familier, de valeur le nom du personnage. Le partage de PVs ne fonctionne pas avec des mooks, et il ne fait pas le partage de d\xE9g\xE2ts temporaires. En revanche, le script devrait g\xE9rer correctement les d\xE9g\xE2ts de zone.
      • +
      • Pour la d\xE9fense du familier, lui ajouter un pr\xE9dicat defDeriveeDe, de valeur le nom du personnage (nom complet sur la fiche, attention \xE0 bien utiliser la syntaxe avec :: si ce nom contient des espaces ou autres caract\xE8res sp\xE9ciaux).
      • +
      • L'initiative ne devrait pas \xEAtre tr\xE8s utile, mais si besoin, ajoutez un pr\xE9dicat initiativeDeriveeDe de valeur le nom du personnage. En fait, pour les familiers normaux, je pr\xE9f\xE8res m\xEAme qu'ils n'apparaissent pas sur le turn tracker, et je leur met donc un pr\xE9dicat aucuneActionCombat.
    3. -
    4. Serviteur invisible : pas de support autre que !cof-lancer-sort crée une force invisible pour ([[5+@{selected|CHA}]] minutes) --mana 0
    5. -
    6. Mur de force : !cof-mur-de-force ?{Spherique?|Oui,&#32;|Non,mur} --mana 1. Cela affiche une image d'un champ de force, mais seulement si il est sphérique. Il est possible de ne pas afficher d'image avec la commande !cof-mur-de-force noImage. Il est possible d'utiliser une autre image que l'image par défaut en utilisant la commande !cof-mur-de-force pathpath est l'adresse url d'une image de la librairie Roll20 qui représente un mur de force sphérique. On peut aussi changer l'image par défaut dans les options de jeu.
    7. -
    8. Épée dansante : +
    9. Serviteur invisible : pas de support autre que !cof-lancer-sort cr\xE9e une force invisible pour ([[5+@{selected|CHA}]] minutes) --mana 0
    10. +
    11. Mur de force : !cof-mur-de-force ?{Spherique?|Oui,&#32;|Non,mur} --mana 1. Cela affiche une image d'un champ de force, mais seulement si il est sph\xE9rique. Il est possible de ne pas afficher d'image avec la commande !cof-mur-de-force noImage. Il est possible d'utiliser une autre image que l'image par d\xE9faut en utilisant la commande !cof-mur-de-force path o\xF9 path est l'adresse url d'une image de la librairie Roll20 qui repr\xE9sente un mur de force sph\xE9rique. On peut aussi changer l'image par d\xE9faut dans les options de jeu.
    12. +
    13. \xC9p\xE9e dansante :
      • !cof-effet-temp epeeDansante [[5+@{selected|CHA}]] --mana 2 pour lancer le sort
      • -
      • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+CHA, portée 20, type Sortilège, dégâts magiques, options --si etat epeeDansante --ignoreObstacles.
      • -
      • Pour les objets de sort, on peut utiliser une action #Attaque Épée dansante --toucher [[@{selected|ATKMAG}]] --dm 1d8+[[@{selected|CHA}]] --magique --portee 20 --sortilege --si etat epeeDansante --ignoreObstacles
      • +
      • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+CHA, port\xE9e 20, type Sortil\xE8ge, d\xE9g\xE2ts magiques, options --si etat epeeDansante --ignoreObstacles.
      • +
      • Pour les objets de sort, on peut utiliser une action #Attaque \xC9p\xE9e dansante --toucher [[@{selected|ATKMAG}]] --dm 1d8+[[@{selected|CHA}]] --magique --portee 20 --sortilege --si etat epeeDansante --ignoreObstacles
      - Pour une rapière dansante, il existe aussi un effet temporaire rapiereDansante. + Pour une rapi\xE8re dansante, il existe aussi un effet temporaire rapiereDansante.
    14. -
    15. Charisme héroïque : reporter sur la fiche
    16. +
    17. Charisme h\xE9ro\xEFque : reporter sur la fiche

    Forgesort

    Voie des artefacts

      -
    1. Bâton de mage : simplement adapter l'attaque, avec aussi le modificateur magique. Pour l'éclair d'énergie, ajoutez dans les options ?{Attaque|Normale,--magieRapide 2|Éclair d'énergie (L),--eclairDEnergie}. Si vous autorisez les règles de mana pour cette attaque, remplacez par ?{Attaque|Normale,&#32;|Éclair d'énergie (L),--eclairDEnergie|Éclair d'énergie rapide, --eclairDEnergie --magieRapide|Éclair d'énergie puissant (L), --eclairDEnergie --tempeteDeMana 1}.
    2. -
    3. Blocage : pas de support autre que !cof-lancer-sort scelle une porte ou un coffre (+5 solidité & RD) pour [[@{selected|INT}]] minutes --mana 0
    4. +
    5. B\xE2ton de mage : simplement adapter l'attaque, avec aussi le modificateur magique. Pour l'\xE9clair d'\xE9nergie, ajoutez dans les options ?{Attaque|Normale,--magieRapide 2|\xC9clair d'\xE9nergie (L),--eclairDEnergie}. Si vous autorisez les r\xE8gles de mana pour cette attaque, remplacez par ?{Attaque|Normale,&#32;|\xC9clair d'\xE9nergie (L),--eclairDEnergie|\xC9clair d'\xE9nergie rapide, --eclairDEnergie --magieRapide|\xC9clair d'\xE9nergie puissant (L), --eclairDEnergie --tempeteDeMana 1}.
    6. +
    7. Blocage : pas de support autre que !cof-lancer-sort scelle une porte ou un coffre (+5 solidit\xE9 & RD) pour [[@{selected|INT}]] minutes --mana 0
    8. Sac sans fond : pas de support particulier
    9. -
    10. Frappe des arcanes : le plus simple est d'utiliser la même ligne d'attaque (disons que son label est E) que pour l'attaque d'énergie (mais si besoin, rien n'empêche d'en utiliser une autre). La commande sera alors !cof-explosion E --auto --magique --sortilege --portee 10 --etat renverse --save FOR [[10+@{selected|INT}]].
    11. +
    12. Frappe des arcanes : le plus simple est d'utiliser la m\xEAme ligne d'attaque (disons que son label est E) que pour l'attaque d'\xE9nergie (mais si besoin, rien n'emp\xEAche d'en utiliser une autre). La commande sera alors !cof-explosion E --auto --magique --sortilege --portee 10 --etat renverse --save FOR [[10+@{selected|INT}]].
    13. Artefact majeur : pas de support particulier
    -

    Voie des élixirs

    -

    Pour créer ou juste voir ses élixirs, utiliser la commande !cof-elixirs. Pour cela, il faut aussi un prédicat voieDesElixirs avec comme valeur le rang dans la voie. Noter que la commande !cof-elixirs affiche une liste d'élixirs, et que pour effectivement créer un élixir, il faut cliquer sur le bouton correspondant dans cette liste. Le script propose les élixirs par défaut du jeu, mais vous pouvez modifier cette liste : pour changer un élixir de rang k (k<4), ajouter un attribut de nom Elixir k, de valeur courante le nom et de valeur maximale l'effet.

    +

    Voie des \xE9lixirs

    +

    Pour cr\xE9er ou juste voir ses \xE9lixirs, utiliser la commande !cof-elixirs. Pour cela, il faut aussi un pr\xE9dicat voieDesElixirs avec comme valeur le rang dans la voie. Noter que la commande !cof-elixirs affiche une liste d'\xE9lixirs, et que pour effectivement cr\xE9er un \xE9lixir, il faut cliquer sur le bouton correspondant dans cette liste. Le script propose les \xE9lixirs par d\xE9faut du jeu, mais vous pouvez modifier cette liste : pour changer un \xE9lixir de rang k (k<4), ajouter un attribut de nom Elixir k, de valeur courante le nom et de valeur maximale l'effet.

      -
    1. Fortifiant : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables. Si vous souhaitez avoir une potion de fortifiant indépendament de cette Voie (par exemple achetée dans une échope), vous pouvez ajouter un consommable avec l'effet !cof-fortifiant n, où n est le rang dans la Voie du forgesort qui a créé la potion.
    2. -
    3. Feu grégeois : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
    4. -
    5. Élixir de guérison : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
    6. -
    7. Potion magique : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
    8. -
    9. Élixirs magiques : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
    10. +
    11. Fortifiant : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables. Si vous souhaitez avoir une potion de fortifiant ind\xE9pendament de cette Voie (par exemple achet\xE9e dans une \xE9chope), vous pouvez ajouter un consommable avec l'effet !cof-fortifiant n, o\xF9 n est le rang dans la Voie du forgesort qui a cr\xE9\xE9 la potion.
    12. +
    13. Feu gr\xE9geois : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
    14. +
    15. \xC9lixir de gu\xE9rison : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
    16. +
    17. Potion magique : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
    18. +
    19. \xC9lixirs magiques : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
    -

    Voie du métal

    +

    Voie du m\xE9tal

      -
    1. Forgeron : Il faut un prédicat voieDuMetal pour connaître le rang (ou utiliser l'option --valeur). Lancer le sort avec !cof-effet-temp forgeron(L) [[5+@{selected|INT}]]L est le label d'une attaque. Ensuite, chaque fois que cette attaque sera utilisée, les dégâts seront ajoutés. Limitations : si deux attaques utilisent la même arme, il faut faire deux fois l'action, une pour chaque attaque.
    2. -
    3. Métal brûlant : +
    4. Forgeron : Il faut un pr\xE9dicat voieDuMetal pour conna\xEEtre le rang (ou utiliser l'option --valeur). Lancer le sort avec !cof-effet-temp forgeron(L) [[5+@{selected|INT}]] o\xF9 L est le label d'une attaque. Ensuite, chaque fois que cette attaque sera utilis\xE9e, les d\xE9g\xE2ts seront ajout\xE9s. Limitations : si deux attaques utilisent la m\xEAme arme, il faut faire deux fois l'action, une pour chaque attaque.
    5. +
    6. M\xE9tal br\xFBlant :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg options --mana 0 --effet ?{Chauffer|une arme,armeBrulante|une armure,armureBrulante} [[5+@{selected|INT}]].
      • -
      • Objet de sort : #Attaque Métal brûlant --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet ?{Chauffer|une arme,armeBrulante|une armure,armureBrulante} [[5+@{selected|INT}]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg options --mana 0 --effet ?{Chauffer|une arme,armeBrulante|une armure,armureBrulante} [[5+@{selected|INT}]].
      • +
      • Objet de sort : #Attaque M\xE9tal br\xFBlant --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet ?{Chauffer|une arme,armeBrulante|une armure,armureBrulante} [[5+@{selected|INT}]]
      - Pour mettre fin à l'effet (si la cible lâche son arme ou enlève son armure), vous pouvez utiliser la macro !cof-effet-temp ?{Se débarrasser d'une |arme,armeBrulante|armure,armureBrulante} 0 + Pour mettre fin \xE0 l'effet (si la cible l\xE2che son arme ou enl\xE8ve son armure), vous pouvez utiliser la macro !cof-effet-temp ?{Se d\xE9barrasser d'une |arme,armeBrulante|armure,armureBrulante} 0
    7. -
    8. Magnétisme : !cof-effet-temp magnetisme [[3+@{selected|INT}]] --mana 1. L'effet n'est actif que contre les attaques ayant l'option --metal. Il est possible de changer le bonus de DEF apporté avec l'option --valeur.
    9. -
    10. Métal hurlant :
    11. +
    12. Magn\xE9tisme : !cof-effet-temp magnetisme [[3+@{selected|INT}]] --mana 1. L'effet n'est actif que contre les attaques ayant l'option --metal. Il est possible de changer le bonus de DEF apport\xE9 avec l'option --valeur.
    13. +
    14. M\xE9tal hurlant :
    15. Endurer : reporter les bonus sur la fiche

    Voie du golem

      -
    1. Grosse tête : Vous pouvez ajouter un prédicat grosseTete. Normalement, le bonus devrait dépendre des actions du forgesort. Si vous souhaitez le faire, vous pouvez ne pas mettre le prédicat, mais juste avant un jet de force pour lequel vous pensez que la grosse tête s'applique, faire !cof-set-predicate grosseTete true (en sélectionnant le token du forgesort), puis après le jet faire !cof-set-predicate grosseTete false. Si vous voulez l'ajout de grosse tête par défaut, vous pouvez aussi faire l'opération dans l'ordre inverse pour les jets pour lesquels vous pensez que le bonus ne peut pas s'appliquer.
    2. -
    3. Golem : ajouter un personnage et un token pour le golem (ne pas oublier le prédicat nonVivant pour le golem). Pour les réparations, utiliser !cof-soin @{selected|token_id} nom_du_golem rangd6+@{selected|INT}. Bien remplacer rang par le rang dans la voie, dans cette commande. Attention, le nom du golem est celui du token représentant le golem, et il ne doit pas contenir de blanc.
    4. -
    5. Protecteur : !cof-interposer permet de s'interposer à la place de la cible de la dernière attaque. (Attention, pas de undo pour cette action)
    6. -
    7. Golem supérieur : reporter les avantages sur la fiche du golem.
    8. -
    9. Intelligence héroïque : reporter sur la fiche
    10. +
    11. Grosse t\xEAte : Vous pouvez ajouter un pr\xE9dicat grosseTete. Normalement, le bonus devrait d\xE9pendre des actions du forgesort. Si vous souhaitez le faire, vous pouvez ne pas mettre le pr\xE9dicat, mais juste avant un jet de force pour lequel vous pensez que la grosse t\xEAte s'applique, faire !cof-set-predicate grosseTete true (en s\xE9lectionnant le token du forgesort), puis apr\xE8s le jet faire !cof-set-predicate grosseTete false. Si vous voulez l'ajout de grosse t\xEAte par d\xE9faut, vous pouvez aussi faire l'op\xE9ration dans l'ordre inverse pour les jets pour lesquels vous pensez que le bonus ne peut pas s'appliquer.
    12. +
    13. Golem : ajouter un personnage et un token pour le golem (ne pas oublier le pr\xE9dicat nonVivant pour le golem). Pour les r\xE9parations, utiliser !cof-soin @{selected|token_id} nom_du_golem rangd6+@{selected|INT}. Bien remplacer rang par le rang dans la voie, dans cette commande. Attention, le nom du golem est celui du token repr\xE9sentant le golem, et il ne doit pas contenir de blanc.
    14. +
    15. Protecteur : !cof-interposer permet de s'interposer \xE0 la place de la cible de la derni\xE8re attaque. (Attention, pas de undo pour cette action)
    16. +
    17. Golem sup\xE9rieur : reporter les avantages sur la fiche du golem.
    18. +
    19. Intelligence h\xE9ro\xEFque : reporter sur la fiche

    Voie des runes

    -

    Ajouter un prédicat voieDesRunes pour le personnage avec comme valeur le niveau dans la voie des Runes.

    +

    Ajouter un pr\xE9dicat voieDesRunes pour le personnage avec comme valeur le niveau dans la voie des Runes.

      -
    1. Runes de défense : Rien à faire, le prédicat voieDesRunes est pris en compte dans le calcule de la DEF.
    2. -
    3. Rune d'énergie : La fabrication des runes de combat est gérée par la commande !cof-runes (il est fortement conseillé de créer une ability pour le forgesort). Le script tente de détecter quand les runes peuvent être utilisées en combat et propose un bouton (à la manière des points de chance). Lors de chaque nuit (utilisation de la commande !cof-nouveau-jour) toutes les runes sont retirées, mais le script va suggérer des raccourcis au forgesort pour les restaurer facilement à tous les tokens présents sur la page des joueurs (par personnage, type de rune, et aussi un bouton "Tout renouveler"). Les points de mana sont automatiquement décomptés.
    4. -
    5. Rune de protection : cf. ci-dessus. Le script implémente par défaut un maximum de dommages absorbés par la rune équivalent au rang du forgesort dans la voie des Runes multiplié par 10. Il est possible de désactiver cette limitation via !cof-options.
    6. -
    7. Rune de puissance : cf. ci-dessus. Créer une rune de puissance vous demandera d'indiquer en plus le numéro de l'arme sur la fiche du propriétaire.
    8. -
    9. Rune de pouvoir : pas de support particulier, créer l'objet de pouvoir approprié.
    10. +
    11. Runes de d\xE9fense : Rien \xE0 faire, le pr\xE9dicat voieDesRunes est pris en compte dans le calcule de la DEF.
    12. +
    13. Rune d'\xE9nergie : La fabrication des runes de combat est g\xE9r\xE9e par la commande !cof-runes (il est fortement conseill\xE9 de cr\xE9er une ability pour le forgesort). Le script tente de d\xE9tecter quand les runes peuvent \xEAtre utilis\xE9es en combat et propose un bouton (\xE0 la mani\xE8re des points de chance). Lors de chaque nuit (utilisation de la commande !cof-nouveau-jour) toutes les runes sont retir\xE9es, mais le script va sugg\xE9rer des raccourcis au forgesort pour les restaurer facilement \xE0 tous les tokens pr\xE9sents sur la page des joueurs (par personnage, type de rune, et aussi un bouton "Tout renouveler"). Les points de mana sont automatiquement d\xE9compt\xE9s.
    14. +
    15. Rune de protection : cf. ci-dessus. Le script impl\xE9mente par d\xE9faut un maximum de dommages absorb\xE9s par la rune \xE9quivalent au rang du forgesort dans la voie des Runes multipli\xE9 par 10. Il est possible de d\xE9sactiver cette limitation via !cof-options.
    16. +
    17. Rune de puissance : cf. ci-dessus. Cr\xE9er une rune de puissance vous demandera d'indiquer en plus le num\xE9ro de l'arme sur la fiche du propri\xE9taire.
    18. +
    19. Rune de pouvoir : pas de support particulier, cr\xE9er l'objet de pouvoir appropri\xE9.

    Guerrier

    Voie du bouclier

      -
    1. Protéger un allié : !cof-proteger-un-allie @{selected|token_id} @{target|token_id}. Fonctionne aussi si on remplace le target par un nom de token. Le script ne vérifie pas que le guerrier ne change pas d'allié plus d'une fois par tour.
    2. +
    3. Prot\xE9ger un alli\xE9 : !cof-proteger-un-allie @{selected|token_id} @{target|token_id}. Fonctionne aussi si on remplace le target par un nom de token. Le script ne v\xE9rifie pas que le guerrier ne change pas d'alli\xE9 plus d'une fois par tour.
    4. Absorber un coup :
        -
      • utiliser !cof-effet-temp absorberUnCoup 1 pour se mettre en position. Attention, ça ne vérifie pas si le guerrier porte son bouclier.
      • -
      • le script propose un bouton à activer en cas d'attaque réussie alors que le guerrier est en position.
      • +
      • utiliser !cof-effet-temp absorberUnCoup 1 pour se mettre en position. Attention, \xE7a ne v\xE9rifie pas si le guerrier porte son bouclier.
      • +
      • le script propose un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le guerrier est en position.
    5. Absorber un sort :
        -
      • utiliser !cof-effet-temp absorberUnSort 1 pour se mettre en position. Attention, ça ne vérifie pas si le guerrier porte son bouclier.
      • -
      • le script propose un bouton à activer en cas d'attaque réussie alors que le guerrier est en position.
      • +
      • utiliser !cof-effet-temp absorberUnSort 1 pour se mettre en position. Attention, \xE7a ne v\xE9rifie pas si le guerrier porte son bouclier.
      • +
      • le script propose un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le guerrier est en position.
    6. -
    7. Armure lourde : Noter l'armure sur la feuille du personnage, et ajouter un prédicat armureLourdeGuerrier au personnage. L'annulation du critique ne se produira que si l'armure est portée et que la valeur totale du bonus de défense supérieure ou égale à 7 (le bonus de DEF d'une armure de plaques complète).
    8. +
    9. Armure lourde : Noter l'armure sur la feuille du personnage, et ajouter un pr\xE9dicat armureLourdeGuerrier au personnage. L'annulation du critique ne se produira que si l'armure est port\xE9e et que la valeur totale du bonus de d\xE9fense sup\xE9rieure ou \xE9gale \xE0 7 (le bonus de DEF d'une armure de plaques compl\xE8te).

    Voie du combat

      -
    1. Vivacité : simplement augmenter l'init sur la fiche.
    2. -
    3. Désarmer : !cof-desarmer @{selected|token_id} @{target|token_id}. On peut utiliser un troisième argument optionnel, qui est le label d'une arme par défaut, au cas où le guerrier n'aurait pas d'arme en main.
    4. -
    5. Double attaque : faire deux attaques, avec l'option supplémentaire --bonusAttaque -2.
    6. -
    7. Attaque circulaire : faire les attaques normalement, ce n'est pas considéré comme une aoe.
    8. +
    9. Vivacit\xE9 : simplement augmenter l'init sur la fiche.
    10. +
    11. D\xE9sarmer : !cof-desarmer @{selected|token_id} @{target|token_id}. On peut utiliser un troisi\xE8me argument optionnel, qui est le label d'une arme par d\xE9faut, au cas o\xF9 le guerrier n'aurait pas d'arme en main.
    12. +
    13. Double attaque : faire deux attaques, avec l'option suppl\xE9mentaire --bonusAttaque -2.
    14. +
    15. Attaque circulaire : faire les attaques normalement, ce n'est pas consid\xE9r\xE9 comme une aoe.
    16. Attaque puissante : #Attaque -1 --avecd12crit --plus 2d6 --seulementContact.
    -

    Voie du maître d'armes

    +

    Voie du ma\xEEtre d'armes

      -
    1. Arme de prédilection : il est possible de préciser une famille d'armes de prédilection (un peu plus large que dans les règles), parmis arc, arbalete, hache, epee, marteau, masse, epieu, poudre, baton et rapiere. Si cela vous convient, ajoutez un prédicat armeDePredilection de valeur une de ces familles. Sinon, simplement ajouter le bonus sur les attaques dans la fiche.
    2. -
    3. Science du critique : pour ne pas avoir à modifier les chances de critique pour toutes les attaques, utiliser un prédicat scienceDuCritique. Attention à ne pas faire ça ET modifier les chances de critiques de l'attaque, car ça s'additionne.
    4. -
    5. Spécialisation : reporter le bonus aux DM sur la fiche.
    6. +
    7. Arme de pr\xE9dilection : il est possible de pr\xE9ciser une famille d'armes de pr\xE9dilection (un peu plus large que dans les r\xE8gles), parmis arc, arbalete, hache, epee, marteau, masse, epieu, poudre, baton et rapiere. Si cela vous convient, ajoutez un pr\xE9dicat armeDePredilection de valeur une de ces familles. Sinon, simplement ajouter le bonus sur les attaques dans la fiche.
    8. +
    9. Science du critique : pour ne pas avoir \xE0 modifier les chances de critique pour toutes les attaques, utiliser un pr\xE9dicat scienceDuCritique. Attention \xE0 ne pas faire \xE7a ET modifier les chances de critiques de l'attaque, car \xE7a s'additionne.
    10. +
    11. Sp\xE9cialisation : reporter le bonus aux DM sur la fiche.
    12. Attaque parfaite : utiliser les options --m2d20 --plus 1d6.
    13. -
    14. Riposte : ajouter un prédicat riposteGuerrier. Les actions affichées en cas de riposte seront normalement une attaque avec l'arme en main, et les attaques naturelles cochées du personnage. Si cela ne convient pas, écrivez une liste d'actions nommée Ripostes.
    15. +
    16. Riposte : ajouter un pr\xE9dicat riposteGuerrier. Les actions affich\xE9es en cas de riposte seront normalement une attaque avec l'arme en main, et les attaques naturelles coch\xE9es du personnage. Si cela ne convient pas, \xE9crivez une liste d'actions nomm\xE9e Ripostes.
    -

    Voie de la résistance

    +

    Voie de la r\xE9sistance

    1. Robustesse : rajouter les PV sur la fiche.
    2. Armure naturelle : rajouter la DEF sur la fiche.
    3. -
    4. Second souffle : Ajouter un prédicat secondSouffle permet de faire apparaître un bouton pour utiliser le second souffle quand le guerrier a perdu des PVs en combat, limite le gain de PVs à ceux perdus dans le combat en cours, et utilise automatiquement la capacité en fin de combat si elle n'a pas été utilisée. Si cette automatisation ne vous convient pas, vous pouvez utiliser la commande !cof-soin @{selected|token_id} secondSouffle à la place. Enfin, on peut préciser une valeur pour ce prédicat, pour remplacer le niveau + CON (par exemple pour un PNJ).
    5. -
    6. Dur à cuire : rajouter un prédicat durACuire sur la fiche.
    7. -
    8. Constitution héroïque : reporter les bonus sur la fiche.
    9. +
    10. Second souffle : Ajouter un pr\xE9dicat secondSouffle permet de faire appara\xEEtre un bouton pour utiliser le second souffle quand le guerrier a perdu des PVs en combat, limite le gain de PVs \xE0 ceux perdus dans le combat en cours, et utilise automatiquement la capacit\xE9 en fin de combat si elle n'a pas \xE9t\xE9 utilis\xE9e. Si cette automatisation ne vous convient pas, vous pouvez utiliser la commande !cof-soin @{selected|token_id} secondSouffle \xE0 la place. Enfin, on peut pr\xE9ciser une valeur pour ce pr\xE9dicat, pour remplacer le niveau + CON (par exemple pour un PNJ).
    11. +
    12. Dur \xE0 cuire : rajouter un pr\xE9dicat durACuire sur la fiche.
    13. +
    14. Constitution h\xE9ro\xEFque : reporter les bonus sur la fiche.

    Voie du soldat

      -
    1. Posture de combat : !cof-posture-de-combat bonus attr1 attr2, où les deux attr peuvent être soit DEF soit ATT soit DM, et le bonus est retiré au premier attribut pour être ajouté au second. Le bonus peut être limité si le guerrier a un prédicat voieDuSoldat qui indique son rang dans la voie. Exemple d'utilisation : !cof-posture-de-combat ?{Bonus} ?{Baisser|Défense,DEF|Attaque,ATT|Dégâts,DM} ?{Augmenter|Défense,DEF|Attaque,ATT|Dégâts,DM}. Normalement, la règle fait décider de sa posture au guerrier à chaque tour, mais en pratique, il en change assez rarement. Une posture de combat reste donc active jusqu'à la fin du combat ou jusqu'à ce qu'on en change (elle est neutre si on a le même attribut à buffer et débuffer).
    2. -
    3. Combat en phalange : ajouter un prédicat combatEnPhalange. Les bonus seront ajoutés automatiquement en fonctions des alliés définis selon cette méthode.
    4. -
    5. Prouesse : ajouter un prédicat prouesse (on peut y associer un nombre, si on souhaite plus d'une utilisation par tour). Le script générera automatiquement les boutons Prouesse sur les test appropriés.
    6. -
    7. Dernier rempart : pas de support particulier, le MJ doit gérer les attaques supplémentaires.
    8. -
    9. Force héroïque : reporter sur la fiche.
    10. +
    11. Posture de combat : !cof-posture-de-combat bonus attr1 attr2, o\xF9 les deux attr peuvent \xEAtre soit DEF soit ATT soit DM, et le bonus est retir\xE9 au premier attribut pour \xEAtre ajout\xE9 au second. Le bonus peut \xEAtre limit\xE9 si le guerrier a un pr\xE9dicat voieDuSoldat qui indique son rang dans la voie. Exemple d'utilisation : !cof-posture-de-combat ?{Bonus} ?{Baisser|D\xE9fense,DEF|Attaque,ATT|D\xE9g\xE2ts,DM} ?{Augmenter|D\xE9fense,DEF|Attaque,ATT|D\xE9g\xE2ts,DM}. Normalement, la r\xE8gle fait d\xE9cider de sa posture au guerrier \xE0 chaque tour, mais en pratique, il en change assez rarement. Une posture de combat reste donc active jusqu'\xE0 la fin du combat ou jusqu'\xE0 ce qu'on en change (elle est neutre si on a le m\xEAme attribut \xE0 buffer et d\xE9buffer).
    12. +
    13. Combat en phalange : ajouter un pr\xE9dicat combatEnPhalange. Les bonus seront ajout\xE9s automatiquement en fonctions des alli\xE9s d\xE9finis selon cette m\xE9thode.
    14. +
    15. Prouesse : ajouter un pr\xE9dicat prouesse (on peut y associer un nombre, si on souhaite plus d'une utilisation par tour). Le script g\xE9n\xE9rera automatiquement les boutons Prouesse sur les test appropri\xE9s.
    16. +
    17. Dernier rempart : pas de support particulier, le MJ doit g\xE9rer les attaques suppl\xE9mentaires.
    18. +
    19. Force h\xE9ro\xEFque : reporter sur la fiche.

    Invocateur

    Voie de la conjuration

      -
    1. Conjuration de prédateur : !cof-conjuration-de-predateur --mana 0.
    2. -
    3. Conjuration renforcée : vous pouvez soit utiliser un prédicat voieDeLaConjuration, de valeur le rang dans la voie, soit ajouter ce rang en premier argument de !cof-conjuration-de-predateur.
    4. -
    5. Conjuration d'armée : !cof-conjuration-armee --limiteParJour 1 --mana 1. Le niveau de puissance de l'armée et déterminé par la valeur d'un prédicat voieDeLaConjuration, ou sinon par un argument optionnel qui donne les DMs infligés par l'armée (par exemple, !cof-conjuration-armee 2d6). L'armée va apparaître comme un token normal, mais avec une aura de 20m de coté qui représente la place qu'elle occupe. Pour les dégâts qu'elle inflige, utiliser son attaque sur toutes les cibles désignées par l'invocateur. Pour faire disparaître l'armée, il suffit de la tuer (par exemple en utilisant !cof-set-state mort true). Tous les personnages dans la zone de l'armée et qui ne sont pas alliés de l'invocateurs ont automatiquement une nouvelle action dans leur liste pour attaquer l'armée. Cette action leur permet aussi de bénéficier d'une division des DM par 2 lorsque l'armée les attaque.
    6. +
    7. Conjuration de pr\xE9dateur : !cof-conjuration-de-predateur --mana 0.
    8. +
    9. Conjuration renforc\xE9e : vous pouvez soit utiliser un pr\xE9dicat voieDeLaConjuration, de valeur le rang dans la voie, soit ajouter ce rang en premier argument de !cof-conjuration-de-predateur.
    10. +
    11. Conjuration d'arm\xE9e : !cof-conjuration-armee --limiteParJour 1 --mana 1. Le niveau de puissance de l'arm\xE9e et d\xE9termin\xE9 par la valeur d'un pr\xE9dicat voieDeLaConjuration, ou sinon par un argument optionnel qui donne les DMs inflig\xE9s par l'arm\xE9e (par exemple, !cof-conjuration-armee 2d6). L'arm\xE9e va appara\xEEtre comme un token normal, mais avec une aura de 20m de cot\xE9 qui repr\xE9sente la place qu'elle occupe. Pour les d\xE9g\xE2ts qu'elle inflige, utiliser son attaque sur toutes les cibles d\xE9sign\xE9es par l'invocateur. Pour faire dispara\xEEtre l'arm\xE9e, il suffit de la tuer (par exemple en utilisant !cof-set-state mort true). Tous les personnages dans la zone de l'arm\xE9e et qui ne sont pas alli\xE9s de l'invocateurs ont automatiquement une nouvelle action dans leur liste pour attaquer l'arm\xE9e. Cette action leur permet aussi de b\xE9n\xE9ficier d'une division des DM par 2 lorsque l'arm\xE9e les attaque.
    -

    Voie de l'entité

    +

    Voie de l'entit\xE9

      -
    1. Invocation d'une entité : ajouter la fiche correspondante.
    2. -
    3. Lien magique : pour l'instant, gérer à la main le transfert de dégâts.
    4. -
    5. Amélioration : ajuster la fiche de l'entité.
    6. +
    7. Invocation d'une entit\xE9 : ajouter la fiche correspondante.
    8. +
    9. Lien magique : pour l'instant, g\xE9rer \xE0 la main le transfert de d\xE9g\xE2ts.
    10. +
    11. Am\xE9lioration : ajuster la fiche de l'entit\xE9.

    Voie du familier

      -
    1. Familier : créer un token pour le familier, avec vue et controlé par le joueur. Le partage des PV n'est pas géré. Pour le bonus en initiative, ajouter un prédicat familier, avec comme valeur le nom du compagnon (doit être exactement le même que celui du token du compagnon). Cela automatise l'initiative quand le familier est présent.
    2. -
    3. Résistance : ajouter la valeur de RD sur la fiche du familier.
    4. -
    5. Sens développés : ajouter un prédicat perception de valeur 5 (ou augmenter ce prédicat, si il existe déjà), et ajouter un prédicat visionDansLeNoir de valeur 20 (40 si le personnage dispose déjà de la vision dans le noir).
    6. +
    7. Familier : cr\xE9er un token pour le familier, avec vue et control\xE9 par le joueur. Le partage des PV n'est pas g\xE9r\xE9. Pour le bonus en initiative, ajouter un pr\xE9dicat familier, avec comme valeur le nom du compagnon (doit \xEAtre exactement le m\xEAme que celui du token du compagnon). Cela automatise l'initiative quand le familier est pr\xE9sent.
    8. +
    9. R\xE9sistance : ajouter la valeur de RD sur la fiche du familier.
    10. +
    11. Sens d\xE9velopp\xE9s : ajouter un pr\xE9dicat perception de valeur 5 (ou augmenter ce pr\xE9dicat, si il existe d\xE9j\xE0), et ajouter un pr\xE9dicat visionDansLeNoir de valeur 20 (40 si le personnage dispose d\xE9j\xE0 de la vision dans le noir).

    Voie des mutations

    1. Mutation offensive :
      • !cof-effet-temp mutationOffensive [[5+@{selected|CHA}]] --mana 0 pour lancer le sort
      • -
      • Ajouter une attaque sur la fiche utilisant l'attaque au contact, dommages 1d6+FOR+3, type Naturel, dégâts magiques, options --si etat mutationOffensive
      • +
      • Ajouter une attaque sur la fiche utilisant l'attaque au contact, dommages 1d6+FOR+3, type Naturel, d\xE9g\xE2ts magiques, options --si etat mutationOffensive
      • Pour un objet de sort, vous pouvez utiliser une action avec le code #Attaque Mutation offensive --toucher [[@{selected|ATKCAC}]] --dm 1d6+[[3+@{selected|FOR}]] --magique --naturel --si etat mutationOffensive
    2. -
    3. Mutation protectrice : !cof-effet ?{Mutation protectrice|Cuirasse,mutationCuirasse|Écailles rouges,mutationEcaillesRouges|Fourrure violette,mutationFourrureViolette|Ouïes,mutationOuies|Sang noir,mutationSangNoir} true --classeEffet mutationProtectrice --mana 0. Pour la valeur de protection de la cuirasse, vous pouvez soit utiliser un prédicat voieDesMutations, de valeur le rang dans la voie, soit remplacer mutationCuirasse par mutationCuirasse --valeur rang. Pour enlever la mutation, le MJ peut ensuite simplement sélectionner le personnage et utiliser !cof-fin-classe-effet mutationProtectrice.
    4. -
    5. Surpuissance physique : !cof-effet ?{Surpuissance physique|Muscles hypertrophiés,mutationMusclesHypertrophies|Silhouette filiforme,mutationSilhouetteFiliforme|Silhouette massive,mutationSilhouetteMassive} true --classeEffet surpuissancePhysique --mana 1. Pour enlever la mutation, le MJ peut ensuite simplement sélectionner le personnage et utiliser !cof-fin-classe-effet surpuissancePhysique.
    6. -
    7. Adaptation motrice : pas d'autre support que !cof-lancer-sort --message se fait pousser ?{Adaptation motrice ?|Ailes|des ailes|Pattes demesurées,des pattes demesurées|Queue de poisson,une queue de poisson} --mana 2
    8. +
    9. Mutation protectrice : !cof-effet ?{Mutation protectrice|Cuirasse,mutationCuirasse|\xC9cailles rouges,mutationEcaillesRouges|Fourrure violette,mutationFourrureViolette|Ou\xEFes,mutationOuies|Sang noir,mutationSangNoir} true --classeEffet mutationProtectrice --mana 0. Pour la valeur de protection de la cuirasse, vous pouvez soit utiliser un pr\xE9dicat voieDesMutations, de valeur le rang dans la voie, soit remplacer mutationCuirasse par mutationCuirasse --valeur rang. Pour enlever la mutation, le MJ peut ensuite simplement s\xE9lectionner le personnage et utiliser !cof-fin-classe-effet mutationProtectrice.
    10. +
    11. Surpuissance physique : !cof-effet ?{Surpuissance physique|Muscles hypertrophi\xE9s,mutationMusclesHypertrophies|Silhouette filiforme,mutationSilhouetteFiliforme|Silhouette massive,mutationSilhouetteMassive} true --classeEffet surpuissancePhysique --mana 1. Pour enlever la mutation, le MJ peut ensuite simplement s\xE9lectionner le personnage et utiliser !cof-fin-classe-effet surpuissancePhysique.
    12. +
    13. Adaptation motrice : pas d'autre support que !cof-lancer-sort --message se fait pousser ?{Adaptation motrice ?|Ailes|des ailes|Pattes demesur\xE9es,des pattes demesur\xE9es|Queue de poisson,une queue de poisson} --mana 2

    Voie des portes

    1. Raccourci : pas de support autre que !cof-lancer-sort lance un sort de Raccourci --mana 0
    2. -
    3. Porte artificielle : pas de support autre que !cof-lancer-sort lance un sort de Porte artificielle --mana 0. Un jour, je compte lui faire créer une porte.
    4. +
    5. Porte artificielle : pas de support autre que !cof-lancer-sort lance un sort de Porte artificielle --mana 0. Un jour, je compte lui faire cr\xE9er une porte.
    6. Manoir d'outre-tombe : pas d'autre support que !cof-lancer-sort enchante une porte --mana 1
    7. Enkystement lointain : !cof-enkystement-lointain @{selected|token_id} @{target|token_id} --portee 20 --mana 2 --limiteParCombat 1 enkystement.
    8. Porte dimensionnelle : pas de support pour l'instant.
    9. @@ -1480,14 +1483,14 @@

      Magicien

      Voie de la magie des arcanes

        -
      1. Agrandissement : !cof-effet-temp agrandissement [[5+@{selected|INT}]] --target @{target|token_id} --lanceur @{selected|token_id} --portee 0 --mana 0. Si vous souhaitez qu'une arme puisse être tenue à une main quand le personnage est agrandi, ajoutez à l'arme le prédicat armeDeGrand.
      2. -
      3. Forme gazeuse : !cof-effet-temp formeGazeuse [[1d4 + @{selected|INT}]] --mana 0. Au MJ de faire attention que sous cette forme, toutes les capacités sont interdites.
      4. -
      5. Hâte : !cof-effet-temp hate [[1d6+@{selected|INT}]] --mana 1, au MJ de gérer ensuite les actions possibles chaque tour.
      6. -
      7. Téléportation : Pas de support autre que !cof-lancer-sort se téléporte (à [[@{selected|INTELLIGENCE}*10]] m maximum) --mana 2.
      8. -
      9. Désintégration : +
      10. Agrandissement : !cof-effet-temp agrandissement [[5+@{selected|INT}]] --target @{target|token_id} --lanceur @{selected|token_id} --portee 0 --mana 0. Si vous souhaitez qu'une arme puisse \xEAtre tenue \xE0 une main quand le personnage est agrandi, ajoutez \xE0 l'arme le pr\xE9dicat armeDeGrand.
      11. +
      12. Forme gazeuse : !cof-effet-temp formeGazeuse [[1d4 + @{selected|INT}]] --mana 0. Au MJ de faire attention que sous cette forme, toutes les capacit\xE9s sont interdites.
      13. +
      14. H\xE2te : !cof-effet-temp hate [[1d6+@{selected|INT}]] --mana 1, au MJ de g\xE9rer ensuite les actions possibles chaque tour.
      15. +
      16. T\xE9l\xE9portation : Pas de support autre que !cof-lancer-sort se t\xE9l\xE9porte (\xE0 [[@{selected|INTELLIGENCE}*10]] m maximum) --mana 2.
      17. +
      18. D\xE9sint\xE9gration :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 5D6+INT, portée 20, type Sortilège, dégâts magiques, options --mana 3.
        • -
        • Objet de sort : #Attaque Désintégration --toucher [[@{selected|ATKMAG}]] --dm 5d6+[[@{selected|INT}]] --magique --portee 20 --sortilege
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 5D6+INT, port\xE9e 20, type Sortil\xE8ge, d\xE9g\xE2ts magiques, options --mana 3.
        • +
        • Objet de sort : #Attaque D\xE9sint\xE9gration --toucher [[@{selected|ATKMAG}]] --dm 5d6+[[@{selected|INT}]] --magique --portee 20 --sortilege
      @@ -1495,518 +1498,519 @@

      Voie de la magie destructrice

      1. Projectile magique :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4, portée 50, type Sortilège, modificateurs auto dégâts magiques, options --mana 0 --fx beam-magic.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4, port\xE9e 50, type Sortil\xE8ge, modificateurs auto d\xE9g\xE2ts magiques, options --mana 0 --fx beam-magic.
        • Objet de sort : #Attaque Projectile Magique --auto --dm 1d4 --magique --portee 50 --sortilege --fx beam-magic
      2. Rayon affaiblissant :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateurs pasDeDmg dégâts magiques, options --mana 0 --effet rayonAffaiblissant [[1d6+@{selected|INT}]] --fx splatter-magic.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateurs pasDeDmg d\xE9g\xE2ts magiques, options --mana 0 --effet rayonAffaiblissant [[1d6+@{selected|INT}]] --fx splatter-magic.
        • Objet de sort : #Attaque Rayon affaiblissant --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --effet rayonAffaiblissant [[1d6+@{selected|INT}]] --fx splatter-magic
      3. -
      4. Flèche enflammée : +
      5. Fl\xE8che enflamm\xE9e :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, portée 30, type Sortilège, dégâts feu, options --mana 1 --fx beam-fire --feu --enflamme.
        • -
        • Objet de sort : #Attaque Flèche enflammée --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --feu --portee 30 --sortilege --fx beam-fire --enflamme
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, port\xE9e 30, type Sortil\xE8ge, d\xE9g\xE2ts feu, options --mana 1 --fx beam-fire --feu --enflamme.
        • +
        • Objet de sort : #Attaque Fl\xE8che enflamm\xE9e --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --feu --portee 30 --sortilege --fx beam-fire --enflamme
      6. Boule de feu :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 4d6+INT, portée 30, type Sortilège, dégâts feu, options --mana 2 --demiAuto --disque 6 --psave DEX [[10+@{selected|INT}]] --targetFx explode-fire.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 4d6+INT, port\xE9e 30, type Sortil\xE8ge, d\xE9g\xE2ts feu, options --mana 2 --demiAuto --disque 6 --psave DEX [[10+@{selected|INT}]] --targetFx explode-fire.
        • Objet de sort : #Attaque Boule de feu --toucher [[@{selected|ATKMAG}]] --dm 4d6+[[@{selected|INT}]] --feu --magique --portee 30 --sortilege --demiAuto --disque 6 --psave DEX [[10+@{selected|INT}]] --targetFx explode-fire
      7. -
      8. Rituel de puissance : faire l'appel aux attaques avec --avecd12crit --plus 2d6. On peut par exemple ajouter ceci dans les options des attaques lorsque le Rituel peut être utilisé :?{Rituel de puissance?|Non,&#32;|Oui,--avecd12crit --plus 2d6}
      9. +
      10. Rituel de puissance : faire l'appel aux attaques avec --avecd12crit --plus 2d6. On peut par exemple ajouter ceci dans les options des attaques lorsque le Rituel peut \xEAtre utilis\xE9 :?{Rituel de puissance?|Non,&#32;|Oui,--avecd12crit --plus 2d6}
      -

      Voie de la magie élémentaire

      +

      Voie de la magie \xE9l\xE9mentaire

      1. Asphyxie :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège,modificateurs pasDeDmg, options --mana 0 --effet asphyxie [[1+@{selected|INT}]].
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge,modificateurs pasDeDmg, options --mana 0 --effet asphyxie [[1+@{selected|INT}]].
        • Objet de sort : #Attaque Asphyxie --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet asphyxie [[1+@{selected|INT}]]
      2. -
      3. Protection contre les éléments : ajouter un prédicat voieDeLaMagieElementaire avec comme valeur le rang dans la voie. Pour lancer le sort, faire !cof-effet-temp protectionContreLesElements [[5+@{selected|INT}]] --mana 0. Notez que si vous utilisez une option --valeur à la place d'utiliser le prédicat, la RD sera cette valeur multipliée par 2.
      4. -
      5. Arme enflammée : Lancer le sort avec !cof-effet-temp armeEnflammee [[5+@{selected|INT}]] --lanceur @{selected|token_id} --target @{target|token_id} --portee 0 --mana 1. Il faut que la cible tienne une arme en main (voir !cof-degainer). Limitations : si deux attaques utilisent la même arme, il faut faire deux fois l'action, une pour chaque attaque. Si vous souhaitez faire le même effet mais avec des dégâts de froid, vous pouvez utiliser armeGlacee à la place.
      6. -
      7. Respiration aquatique : pas de support autre que !cof-lancer-sort lance un sort de respiration aquatique (durée 10 minutes, sur soi plus [[@{selected|INT}]] compagnons) --mana 2.
      8. -
      9. Peau de pierre : !cof-effet-temp peauDePierreMag [[5+@{selected|INT}]] --mana 3. Le script va appliquer une RD de [5+Mod. d'INT] en dernier lieu, et compter le maximum des 40 dégâts par défaut. Il est possible de changer la valeur de la RD et le nombre de points de dégâts absorbés en ajoutant l'option --valeur rd absorbe. À noter que le script rajoute +1 à la RD et +5 au total de dégâts absorbés en cas de magie puissante, ou par point de mana depensé en magie intense.
      10. +
      11. Protection contre les \xE9l\xE9ments : ajouter un pr\xE9dicat voieDeLaMagieElementaire avec comme valeur le rang dans la voie. Pour lancer le sort, faire !cof-effet-temp protectionContreLesElements [[5+@{selected|INT}]] --mana 0. Notez que si vous utilisez une option --valeur \xE0 la place d'utiliser le pr\xE9dicat, la RD sera cette valeur multipli\xE9e par 2.
      12. +
      13. Arme enflamm\xE9e : Lancer le sort avec !cof-effet-temp armeEnflammee [[5+@{selected|INT}]] --lanceur @{selected|token_id} --target @{target|token_id} --portee 0 --mana 1. Il faut que la cible tienne une arme en main (voir !cof-degainer). Limitations : si deux attaques utilisent la m\xEAme arme, il faut faire deux fois l'action, une pour chaque attaque. Si vous souhaitez faire le m\xEAme effet mais avec des d\xE9g\xE2ts de froid, vous pouvez utiliser armeGlacee \xE0 la place.
      14. +
      15. Respiration aquatique : pas de support autre que !cof-lancer-sort lance un sort de respiration aquatique (dur\xE9e 10 minutes, sur soi plus [[@{selected|INT}]] compagnons) --mana 2.
      16. +
      17. Peau de pierre : !cof-effet-temp peauDePierreMag [[5+@{selected|INT}]] --mana 3. Le script va appliquer une RD de [5+Mod. d'INT] en dernier lieu, et compter le maximum des 40 d\xE9g\xE2ts par d\xE9faut. Il est possible de changer la valeur de la RD et le nombre de points de d\xE9g\xE2ts absorb\xE9s en ajoutant l'option --valeur rd absorbe. \xC0 noter que le script rajoute +1 \xE0 la RD et +5 au total de d\xE9g\xE2ts absorb\xE9s en cas de magie puissante, ou par point de mana depens\xE9 en magie intense.

      Voie de la magie protectrice

      1. Armure du mage : !cof-effet-combat armureDuMage --mana 0.
      2. Chute ralentie : pas de support autre que !cof-lancer-sort lance un sort de Chute ralentie --mana 0
      3. Flou : !cof-effet-temp flou [[1d4+@{selected|INT}]] --mana 1.
      4. -
      5. Cercle de protection : Le script ne gère pas le cercle en lui-même, mais vous pouvez créer deux abilities. +
      6. Cercle de protection : Le script ne g\xE8re pas le cercle en lui-m\xEAme, mais vous pouvez cr\xE9er deux abilities.
        • !cof-effet-temp cercleDeProtection 100 --target @{target|token_id} --lanceur @{selected|token_id} --valeur @{selected|token_id} et cibler un personnage pour lui appliquer l'effet.
        • !cof-effet-temp cercleDeProtection fin --target @{target|token_id} --lanceur @{selected|token_id} pour supprimer l'effet sur un personnage.
        - Le script proposera alors automatiquement à ces personnages un bouton avec le nom du magicien si une cible protégée est ciblée par une attaque magique. Le jet d'attaque magique opposé sera automatisé. Si vous utilisez les options de mana, rajoutez --mana {Coût ?} à la première ability. Indiquer le coût au lancement, et 0 pour les autres applications. + Le script proposera alors automatiquement \xE0 ces personnages un bouton avec le nom du magicien si une cible prot\xE9g\xE9e est cibl\xE9e par une attaque magique. Le jet d'attaque magique oppos\xE9 sera automatis\xE9. Si vous utilisez les options de mana, rajoutez --mana {Co\xFBt ?} \xE0 la premi\xE8re ability. Indiquer le co\xFBt au lancement, et 0 pour les autres applications.
      7. -
      8. Arrêt du temps : pas de support autre que !cof-lancer-sort arrête le temps pour [[1d6+@{selected|INT}]] tours --mana 3
      9. +
      10. Arr\xEAt du temps : pas de support autre que !cof-lancer-sort arr\xEAte le temps pour [[1d6+@{selected|INT}]] tours --mana 3

      Voie de la magie universelle

        -
      1. Lumière : !cof-lumiere @{target|token_id} 20 --mana 0. On peut utiliser une cible qui ne soit qu'un personnage sans PV, et dans ce cas le token disparaît, et pour éteindre la lumière, le MJ doit supprimer le token dans le layer de l'éclairage dynamique. Si la cible est un personnage avec des PV, alors la lumière se déplacera avec lui, et pour éteindre la lumière, il faut séclectionner le ou les tokens et lancer !cof-eteindre-lumiere lumiere.
      2. -
      3. Détection de la magie : pas de support autre que !cof-lancer-sort lance un sort de Détection de la Magie --mana 0.
      4. -
      5. Invisibilité : utiliser !cof-set-state invisible true --message se rend invisible --messageMJ l'invisibilité va durer [[1d6+@{selected|INT}]] minutes --mana 1. Pour les ennemis, mettre dans le layer gm, pour les joueurs, ne pas les cibler. Reste le problème des AOE...
      6. +
      7. Lumi\xE8re : !cof-lumiere @{target|token_id} 20 --mana 0. On peut utiliser une cible qui ne soit qu'un personnage sans PV, et dans ce cas le token dispara\xEEt, et pour \xE9teindre la lumi\xE8re, le MJ doit supprimer le token dans le layer de l'\xE9clairage dynamique. Si la cible est un personnage avec des PV, alors la lumi\xE8re se d\xE9placera avec lui, et pour \xE9teindre la lumi\xE8re, il faut s\xE9clectionner le ou les tokens et lancer !cof-eteindre-lumiere lumiere.
      8. +
      9. D\xE9tection de la magie : pas de support autre que !cof-lancer-sort lance un sort de D\xE9tection de la Magie --mana 0.
      10. +
      11. Invisibilit\xE9 : utiliser !cof-set-state invisible true --message se rend invisible --messageMJ l'invisibilit\xE9 va durer [[1d6+@{selected|INT}]] minutes --mana 1. Pour les ennemis, mettre dans le layer gm, pour les joueurs, ne pas les cibler. Reste le probl\xE8me des AOE...
      12. Vol : pas de support autre que !cof-lancer-sort vole --messageMJ le vol va durer [[1d6+@{selected|INT}]] minutes --mana 2
      13. -
      14. Intelligence héroïque : reporter sur la fiche
      15. +
      16. Intelligence h\xE9ro\xEFque : reporter sur la fiche

      Moine

      -

      Voie de l’énergie vitale

      +

      Voie de l\x2019\xE9nergie vitale

        -
      1. Main d'énergie : utiliser l'attaque à mains nues avec l'option --mainsDEnergie. D'autre part, ajouter l'option --magique à toutes les attaques à mains nues.
      2. -
      3. Pression mortelle : utiliser l'option --pointsVitaux pour ne pas infliger immédiatement les dégâts, et l'option --pressionMortelle pour libérer les dégâts.
      4. -
      5. Invulnérable: utiliser un prédicat invulnerable
      6. -
      7. Projection du ki : ajouter simplement l'attaque sur la fiche, et utiliser le type d'attaque Sortilege et le type de dégâts magique.
      8. -
      9. Ascétisme : noter la constitution comme une caractéristique supérieure sur la fiche.
      10. +
      11. Main d'\xE9nergie : utiliser l'attaque \xE0 mains nues avec l'option --mainsDEnergie. D'autre part, ajouter l'option --magique \xE0 toutes les attaques \xE0 mains nues.
      12. +
      13. Pression mortelle : utiliser l'option --pointsVitaux pour ne pas infliger imm\xE9diatement les d\xE9g\xE2ts, et l'option --pressionMortelle pour lib\xE9rer les d\xE9g\xE2ts.
      14. +
      15. Invuln\xE9rable: utiliser un pr\xE9dicat invulnerable
      16. +
      17. Projection du ki : ajouter simplement l'attaque sur la fiche, et utiliser le type d'attaque Sortilege et le type de d\xE9g\xE2ts magique.
      18. +
      19. Asc\xE9tisme : noter la constitution comme une caract\xE9ristique sup\xE9rieure sur la fiche.
      -

      Voie de la maîtrise

      +

      Voie de la ma\xEEtrise

        -
      1. Esquive du singe : mettre à jour la défense sur la fiche, et ajouter une compétence acrobatie avec le bonus donné par la capacité.
      2. -
      3. Morsure du serpent : pour ne pas avoir à modifier les chances de critique pour toutes les attaques au contact, utiliser un prédicat morsureDuSerpent. Attention à ne pas faire ça ET modifier les chances de critiques de l'attaque, car ça s'additionne. (En revanche, pas de soucis avec la science du critique).
      4. -
      5. Griffes du tigre : rajouter l'option --explodeMax aux attaques à mains nues.
      6. -
      7. Fureur du dragon : Créer une action : !cof-explosion Fureur du dragon --auto --portee 0 --disque 1 --saufAllies --dm 2D6+[[@{selected|FOR}]] --etat renverse --save FOR 10 --limiteParCombat 1 fureurDuDragon
      8. +
      9. Esquive du singe : mettre \xE0 jour la d\xE9fense sur la fiche, et ajouter une comp\xE9tence acrobatie avec le bonus donn\xE9 par la capacit\xE9.
      10. +
      11. Morsure du serpent : pour ne pas avoir \xE0 modifier les chances de critique pour toutes les attaques au contact, utiliser un pr\xE9dicat morsureDuSerpent. Attention \xE0 ne pas faire \xE7a ET modifier les chances de critiques de l'attaque, car \xE7a s'additionne. (En revanche, pas de soucis avec la science du critique).
      12. +
      13. Griffes du tigre : rajouter l'option --explodeMax aux attaques \xE0 mains nues.
      14. +
      15. Fureur du dragon : Cr\xE9er une action : !cof-explosion Fureur du dragon --auto --portee 0 --disque 1 --saufAllies --dm 2D6+[[@{selected|FOR}]] --etat renverse --save FOR 10 --limiteParCombat 1 fureurDuDragon
      16. Moment de perfection : !cof-effet-temp momentDePerfection 1 --limiteParCombat 1
      -

      Voie de la méditation

      +

      Voie de la m\xE9ditation

        -
      1. Pacifisme : ajouter un prédicat pacifisme. Il est possible d'y associer une valeur pour appliquer un bonus à la défense différent de 5.
      2. -
      3. Transe de guérison : !cof-transe-guerison
      4. -
      5. Maîtrise du ki : adapter les valeurs de DEF et init
      6. +
      7. Pacifisme : ajouter un pr\xE9dicat pacifisme. Il est possible d'y associer une valeur pour appliquer un bonus \xE0 la d\xE9fense diff\xE9rent de 5.
      8. +
      9. Transe de gu\xE9rison : !cof-transe-guerison
      10. +
      11. Ma\xEEtrise du ki : adapter les valeurs de DEF et init
      12. Projection mentale : aucun support
      13. -
      14. Sagesse héroïque : reporter sur la fiche
      15. +
      16. Sagesse h\xE9ro\xEFque : reporter sur la fiche

      Voie du poing

        -
      1. Poings de fer : simplement enlever le --tempDmg et ajuster les dégâts
      2. -
      3. Parade de projectiles : ajouter un prédicat paradeDeProjectiles. Le script proposera automatiquement un bouton pour parer l'attaque dans les cas appropriés.
      4. +
      5. Poings de fer : simplement enlever le --tempDmg et ajuster les d\xE9g\xE2ts
      6. +
      7. Parade de projectiles : ajouter un pr\xE9dicat paradeDeProjectiles. Le script proposera automatiquement un bouton pour parer l'attaque dans les cas appropri\xE9s.
      8. Peau de fer : ajuster la DEF sur la fiche.
      9. -
      10. Déluge de coups : le MJ gère le nombre d'attaques. Pour les attaques au d12, utiliser l'option --avecd12.
      11. +
      12. D\xE9luge de coups : le MJ g\xE8re le nombre d'attaques. Pour les attaques au d12, utiliser l'option --avecd12.
      13. Puissance du ki : utiliser les options --avecd12crit --plus 2d6.

      Voie du vent

        -
      1. Pas du vent : un prédicat pasDuVent avec comme valeur le rang dans la voie permet d'augmenter automatiquement l'initiative. Pour le reste, il n'y a pas de support particulier.
      2. -
      3. Course du vent : géré par le MJ.
      4. +
      5. Pas du vent : un pr\xE9dicat pasDuVent avec comme valeur le rang dans la voie permet d'augmenter automatiquement l'initiative. Pour le reste, il n'y a pas de support particulier.
      6. +
      7. Course du vent : g\xE9r\xE9 par le MJ.
      8. Course des airs : pas de support.
      9. -
      10. Lévitation : pas de support.
      11. +
      12. L\xE9vitation : pas de support.
      13. Passe-muraille : pas de support.
      -

      Nécromancien

      +

      N\xE9cromancien

      -

      Voie du démon

      +

      Voie du d\xE9mon

        -
      1. Malédiction : +
      2. Mal\xE9diction :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg malediction, options --mana 0.
        • -
        • Objet de sort : #Attaque Malédiction --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --malediction
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg malediction, options --mana 0.
        • +
        • Objet de sort : #Attaque Mal\xE9diction --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --malediction
      3. Aspect de la succube :
        • !cof-effet-temp aspectDeLaSuccube [[5+@{selected|INT}]] --mana 0 pour lancer le sort
        • -
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4+CHA, portée 0, type Sortilège, dégâts de drain, options --si etat aspectDeLaSuccube.
        • +
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4+CHA, port\xE9e 0, type Sortil\xE8ge, d\xE9g\xE2ts de drain, options --si etat aspectDeLaSuccube.
        • Pour un objet de sort, le code sera #Attaque Attaque de la succube --toucher [[@{selected|ATKMAG}]] --dm 1d4+[[@{selected|CHA}]] --magique --portee 0 --sortilege --si etat aspectDeLaSuccube --drain
      4. -
      5. Pacte sanglant : créer un prédicat pacteSanglant de valeur 3 (rang 3) ou 5 (rang 5). Le script va automatiser l'ajout de boutons sur tous les tests a posteriori, y compris sur les attaques qui ciblent le personnage. Aux joueurs de s'accorder sur la nécessité d'une déclaration a priori nécessaire pour l'utilisation de la capacité.
      6. -
      7. Aspect du démon : +
      8. Pacte sanglant : cr\xE9er un pr\xE9dicat pacteSanglant de valeur 3 (rang 3) ou 5 (rang 5). Le script va automatiser l'ajout de boutons sur tous les tests a posteriori, y compris sur les attaques qui ciblent le personnage. Aux joueurs de s'accorder sur la n\xE9cessit\xE9 d'une d\xE9claration a priori n\xE9cessaire pour l'utilisation de la capacit\xE9.
      9. +
      10. Aspect du d\xE9mon :
        • !cof-effet-temp aspectDuDemon [[5+@{selected|INT}]] --mana 2 pour lancer le sort
        • -
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+4, portée 0, type Sortilège, dégâts magiques, options --si etat aspectDuDemon
        • -
        • Pour un objet de sort, l'attaque pourra avoir le code #Attaque Attaque du démon --toucher [[@{selected|ATKMAG}]] --dm 1d6+4 --magique --portee 0 --sortilege --si etat aspectDuDemon
        • +
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+4, port\xE9e 0, type Sortil\xE8ge, d\xE9g\xE2ts magiques, options --si etat aspectDuDemon
        • +
        • Pour un objet de sort, l'attaque pourra avoir le code #Attaque Attaque du d\xE9mon --toucher [[@{selected|ATKMAG}]] --dm 1d6+4 --magique --portee 0 --sortilege --si etat aspectDuDemon
      11. -
      12. Invocation d'un démon : !cof-invoquer-demon @{selected|token_id} --mana 3
      13. +
      14. Invocation d'un d\xE9mon : !cof-invoquer-demon @{selected|token_id} --mana 3

      Voie de la mort

        -
      1. Siphon des âmes : ajouter un prédicat siphonDesAmes. Par défaut, si il y a plusieurs personnages avec ce pouvoir, tous vont siphoner les âmes sans interaction. Mais il est possible de déclarer un ordre de priorité, telle que si les personnages de plus haute priorité ont siphoné tous les points de vie qu'ils pouvaient, il ne reste rien à siphoner pour les autre. Pour se faire, utilisez un prédicat siphonDesAmesPrioritaire avec la valeur numérique de la priorité (0 par défaut, plus la valeur est grande, plus le personnage est prioritaire).
      2. +
      3. Siphon des \xE2mes : ajouter un pr\xE9dicat siphonDesAmes. Par d\xE9faut, si il y a plusieurs personnages avec ce pouvoir, tous vont siphoner les \xE2mes sans interaction. Mais il est possible de d\xE9clarer un ordre de priorit\xE9, telle que si les personnages de plus haute priorit\xE9 ont siphon\xE9 tous les points de vie qu'ils pouvaient, il ne reste rien \xE0 siphoner pour les autre. Pour se faire, utilisez un pr\xE9dicat siphonDesAmesPrioritaire avec la valeur num\xE9rique de la priorit\xE9 (0 par d\xE9faut, plus la valeur est grande, plus le personnage est prioritaire).
      4. Masque mortuaire : !cof-effet-temp masqueMortuaire [[5+@{selected|INT}]] --mana 0
      5. Baiser du vampire :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+INT, portée 50, type Sortilège, dégâts de drain, options --mana 1 --seulementVivant.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+INT, port\xE9e 50, type Sortil\xE8ge, d\xE9g\xE2ts de drain, options --mana 1 --seulementVivant.
        • Objet de sort : #Attaque Baiser du vampire --toucher [[@{selected|ATKMAG}]] --dm 1d8+[[@{selected|INT}]] --portee 50 --sortilege --drain --seulementVivant
      6. Briser les coeurs :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 5d6+INT, portée 20, type Sortilège, modificateurs seulementVivant necromancie, options --mana 2 --psave CON [[10+@{selected|INT}]] tempete 2.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 5d6+INT, port\xE9e 20, type Sortil\xE8ge, modificateurs seulementVivant necromancie, options --mana 2 --psave CON [[10+@{selected|INT}]] tempete 2.
        • Objet de sort : #Attaque Briser les coeurs --toucher [[@{selected|ATKMAG}]] --dm 5d6+[[@{selected|INT}]] --portee 20 --sortilege --psave CON [[10+@{selected|INT}]] tempete 2 --seulementVivant --necromancie
        - À noter que la partie tempete 2 implémente une chose qui n'est pas dans les règles, à savoir augmenter la difficulté du test de constitution de 2 par point de mana investi en tempête de mana intense. Je trouvais en effet que sans cet ajout, à mana égale, le sort était moins intéressant que le baiser du vampire. Il reste moins fort et plus situationnel que la désintégration du magicien (à mana égale), même avec ce changement. + \xC0 noter que la partie tempete 2 impl\xE9mente une chose qui n'est pas dans les r\xE8gles, \xE0 savoir augmenter la difficult\xE9 du test de constitution de 2 par point de mana investi en temp\xEAte de mana intense. Je trouvais en effet que sans cet ajout, \xE0 mana \xE9gale, le sort \xE9tait moins int\xE9ressant que le baiser du vampire. Il reste moins fort et plus situationnel que la d\xE9sint\xE9gration du magicien (\xE0 mana \xE9gale), m\xEAme avec ce changement.
      7. Mot de mort :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateurs pasDeDmg necromancie difficultePV, options --mana 3 --etat mort --save CON [[10+@{selected|INT}]] tempete 2.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateurs pasDeDmg necromancie difficultePV, options --mana 3 --etat mort --save CON [[10+@{selected|INT}]] tempete 2.
        • Objet de sort : #Attaque Mot de mort --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --necromancie --difficultePV --etat mort --save CON [[10+@{selected|INT}]] tempete 2
        - Comme pour Briser les coeurs, je pense qu'on peut augmenter la difficulté du jet de résistance avec la puissance de la tempête de mana. + Comme pour Briser les coeurs, je pense qu'on peut augmenter la difficult\xE9 du jet de r\xE9sistance avec la puissance de la temp\xEAte de mana.

      Voie de l'outre-tombe

      1. Peur :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg, options --mana 0 --peur [[10+@{selected|INT}]] [[1d4+r]]r est le rang dans la voie
        • -
        • Objet de sort : #Attaque Peur --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --peur [[10+@{selected|INT}]] [[1d4+r]]r est le niveau de l'objet
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg, options --mana 0 --peur [[10+@{selected|INT}]] [[1d4+r]]o\xF9 r est le rang dans la voie
        • +
        • Objet de sort : #Attaque Peur --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --peur [[10+@{selected|INT}]] [[1d4+r]]o\xF9 r est le niveau de l'objet
      2. -
      3. Animation d'un mort-vivant : !cof-animer-mort @{selected|token_id} --mana 0. Cela met directement le nécromant et le zombie en combat. Les Zombies perdent automatiquement 1 PV tous les 6 rounds. Lorsqu'ils atteignent 0 PV (quelle qu'en soit la raison) ou à la fin du combat, ils sont automatiquement détruits et supprimés. Si le lanceur a un prédicat voieOutreTombe, le script gère le maximum de zombies qu'il peut invoquer. Mana, consommables et limites sont gérées, mais pas Tempête de Mana.
      4. -
      5. Putréfaction : +
      6. Animation d'un mort-vivant : !cof-animer-mort @{selected|token_id} --mana 0. Cela met directement le n\xE9cromant et le zombie en combat. Les Zombies perdent automatiquement 1 PV tous les 6 rounds. Lorsqu'ils atteignent 0 PV (quelle qu'en soit la raison) ou \xE0 la fin du combat, ils sont automatiquement d\xE9truits et supprim\xE9s. Si le lanceur a un pr\xE9dicat voieOutreTombe, le script g\xE8re le maximum de zombies qu'il peut invoquer. Mana, consommables et limites sont g\xE9r\xE9es, mais pas Temp\xEAte de Mana.
      7. +
      8. Putr\xE9faction :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, portée 10, type Sortilège, modificateurs necromancie, options --mana 1 --effet putrefactionOutreTombe --save CON [[12+@{selected|INT}]]
        • -
        • Objet de sort : #Attaque Putréfaction --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --portee 10 --sortilege --necromancie --effet putrefactionOutreTombe --save CON [[12+@{selected|INT}]]
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, port\xE9e 10, type Sortil\xE8ge, modificateurs necromancie, options --mana 1 --effet putrefactionOutreTombe --save CON [[12+@{selected|INT}]]
        • +
        • Objet de sort : #Attaque Putr\xE9faction --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --portee 10 --sortilege --necromancie --effet putrefactionOutreTombe --save CON [[12+@{selected|INT}]]
      9. Ensevelissement :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg necromancie, options --mana 2 --etat enseveli FORDEX [[13+@{selected|INT}]]
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg necromancie, options --mana 2 --etat enseveli FORDEX [[13+@{selected|INT}]]
        • Objet de sort : #Attaque Ensevelissement --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --necromancie --etat enseveli FORDEX [[13+@{selected|INT}]]
        - Les dégâts sont infligés au début de chaque tour, et la cible recevra à son initiative un bouton lui permettant d'effectuer le jet pour sortir. Elle pourra également ajouter un bonus manuel au jet, en fonction des actions réalisées pour l'aider à sortir. + Les d\xE9g\xE2ts sont inflig\xE9s au d\xE9but de chaque tour, et la cible recevra \xE0 son initiative un bouton lui permettant d'effectuer le jet pour sortir. Elle pourra \xE9galement ajouter un bonus manuel au jet, en fonction des actions r\xE9alis\xE9es pour l'aider \xE0 sortir.
      10. -
      11. Armée des morts : !cof-effet-temp armeeDesMorts @{selected|niveau} --limiteParJour 1 --mana 3. La zone couverte est symbolisée par l'activation d'une aura sur le token du lanceur. Le script utilisera pour cela l'aura 2 du token, donc attention si vous l'utilisez déjà sur le token du lanceur, elle sera écrasée. Toute cible (le script ignore les alliés du lanceur) qui s'active dans une zone couverte par une armée recevra dans ses actions un bouton spécial pour se défendre. Les dégâts sont infligés automatiquement en début de tour. En option, le script support l'argument --puissant des règles de Mana de base, qui doublent la surface couverte (rayon 28m). Il est aussi possible d'utiliser l'option de Tempête de Mana ; la surface couverte sera multipliée par le nombre de PM investis en Magie Intense. Les adversaires avec un prédicat volant ne seront pas affectés.
      12. +
      13. Arm\xE9e des morts : !cof-effet-temp armeeDesMorts @{selected|niveau} --limiteParJour 1 --mana 3. La zone couverte est symbolis\xE9e par l'activation d'une aura sur le token du lanceur. Le script utilisera pour cela l'aura 2 du token, donc attention si vous l'utilisez d\xE9j\xE0 sur le token du lanceur, elle sera \xE9cras\xE9e. Toute cible (le script ignore les alli\xE9s du lanceur) qui s'active dans une zone couverte par une arm\xE9e recevra dans ses actions un bouton sp\xE9cial pour se d\xE9fendre. Les d\xE9g\xE2ts sont inflig\xE9s automatiquement en d\xE9but de tour. En option, le script support l'argument --puissant des r\xE8gles de Mana de base, qui doublent la surface couverte (rayon 28m). Il est aussi possible d'utiliser l'option de Temp\xEAte de Mana ; la surface couverte sera multipli\xE9e par le nombre de PM investis en Magie Intense. Les adversaires avec un pr\xE9dicat volant ne seront pas affect\xE9s.

      Voie du sang

      1. Saignements :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateurs pasDeDmg necromancie, options --mana 0 --effet saignementsSang rang, où rang est le rang dans la Voie
        • -
        • Objet de sort : #Attaque Saignements --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --necromancie --effet saignementsSang rang, où rang est le niveau de l'objet
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateurs pasDeDmg necromancie, options --mana 0 --effet saignementsSang rang, o\xF9 rang est le rang dans la Voie
        • +
        • Objet de sort : #Attaque Saignements --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --necromancie --effet saignementsSang rang, o\xF9 rang est le niveau de l'objet
        - Si vous souhaitez que le saignement ne puisse pas être appliqué à certains personnages (comme des golems ou des squelettes), vous pouvez leur ajouter un prédicat immuniteSaignement. + Si vous souhaitez que le saignement ne puisse pas \xEAtre appliqu\xE9 \xE0 certains personnages (comme des golems ou des squelettes), vous pouvez leur ajouter un pr\xE9dicat immuniteSaignement.
      2. Sang mordant : !cof-effet-temp sangMordant [[5+@{selected|INT}]] --mana 0.
      3. -
      4. Exsangue : ajouter un prédicat exsangue.
      5. -
      6. Hémorragie : +
      7. Exsangue : ajouter un pr\xE9dicat exsangue.
      8. +
      9. H\xE9morragie :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateurs pasDeDmg necromancie, options --mana 2 --effet hemorragie [[5+@{selected|INT}]]
        • -
        • Objet de sort : #Attaque Hémorragie --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --necromancie --effet hemorragie [[5+@{selected|INT}]]
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateurs pasDeDmg necromancie, options --mana 2 --effet hemorragie [[5+@{selected|INT}]]
        • +
        • Objet de sort : #Attaque H\xE9morragie --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --necromancie --effet hemorragie [[5+@{selected|INT}]]
      10. Lien de sang :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg necromancie, options --mana 3 --effet lienDeSang [[5+@{selected|INT}]]
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg necromancie, options --mana 3 --effet lienDeSang [[5+@{selected|INT}]]
        • Objet de sort : #Attaque Lien de sang --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --necromancie --effet lienDeSang [[5+@{selected|INT}]]
        Pas de support pour le lancement de sort sans ligne de vue.

      Voie de la sombre magie

      -

      Ajouter sur la fiche une compétence Occultisme avec en bonus 2 fois le rang dans cette voie.

      +

      Ajouter sur la fiche une comp\xE9tence Occultisme avec en bonus 2 fois le rang dans cette voie.

        -
      1. Ténèbres : !cof-tenebres @{selected|token_id} @{target|token_id} --mana 0. La commande pose un token transparent avec une aura noire visible par les joueurs pour visualiser la zone, et une petite aura jaune visible uniquement par le MJ (pour sélectionner le token si nécessaire). Tous les tokens présents dans la zone au lancement du sort sont automatiquement aveuglés. Au MJ ensuite d'enlever l'état aveuglé quand les cibles sortent de la zone. A la fin de la durée du sort, ou à la fin du combat, la zone et les états aveuglés restant disparaissent automatiquement. Il est aussi possible de changer les valeurs par défaut du sort (portée 20m, rayon 5m) avec les options --portee X et --rayon X. En règle custom, l'option puissant permet de doubler la superficie couverte (le script calcule le rayon approprié si custom).
      2. -
      3. Pattes d'araignées : !cof-lancer-sort peut se déplacer sur les murs pendants [[5+@{selected|INT}]] tours --mana 0
      4. -
      5. Strangulation : Le script va vérifier que la cible est bien vivante, en se basant sur la race, et sinon sur la présence éventuelle d'un prédicat nonVivant. +
      6. T\xE9n\xE8bres : !cof-tenebres @{selected|token_id} @{target|token_id} --mana 0. La commande pose un token transparent avec une aura noire visible par les joueurs pour visualiser la zone, et une petite aura jaune visible uniquement par le MJ (pour s\xE9lectionner le token si n\xE9cessaire). Tous les tokens pr\xE9sents dans la zone au lancement du sort sont automatiquement aveugl\xE9s. Au MJ ensuite d'enlever l'\xE9tat aveugl\xE9 quand les cibles sortent de la zone. A la fin de la dur\xE9e du sort, ou \xE0 la fin du combat, la zone et les \xE9tats aveugl\xE9s restant disparaissent automatiquement. Il est aussi possible de changer les valeurs par d\xE9faut du sort (port\xE9e 20m, rayon 5m) avec les options --portee X et --rayon X. En r\xE8gle custom, l'option puissant permet de doubler la superficie couverte (le script calcule le rayon appropri\xE9 si custom).
      7. +
      8. Pattes d'araign\xE9es : !cof-lancer-sort peut se d\xE9placer sur les murs pendants [[5+@{selected|INT}]] tours --mana 0
      9. +
      10. Strangulation : Le script va v\xE9rifier que la cible est bien vivante, en se basant sur la race, et sinon sur la pr\xE9sence \xE9ventuelle d'un pr\xE9dicat nonVivant.
          -
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, portée 20, type Sortilège, dégâts magiques, modificateurs necromancie, options --mana 1 --effet strangulation rang
        • +
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, port\xE9e 20, type Sortil\xE8ge, d\xE9g\xE2ts magiques, modificateurs necromancie, options --mana 1 --effet strangulation rang
        • !cof-strangulation @{selected|token_id} @{target|token_id} pour maintenir la strangulation
        • Pour un objet de sort, le code de l'attaque sera #Attaque Strangulation --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --magique --portee 20 --sortilege --effet strangulation rang
      11. -
      12. Ombre mortelle : !cof-ombre-mortelle @{selected|token_id} @{target|token_id} [[3+@{selected|INT}]] --portee 20 --mana 2 va créer un double de la cible, (à condition de disposer de 2 points de mana) et ajouter ce double à l'initiative. Au MJ ensuite de la faire attaquer à son tour (pas d'aoe, juste attaquer le token dont elle est l'ombre). Le token disparaît lorsque le nombre de tours est écoulé. Il est possible de choisir l'image utilisée pour représenter l'ombre en passant l'url de l'image avec l'option --image.
      13. -
      14. Intelligence héroïque : utiliser la fiche
      15. +
      16. Ombre mortelle : !cof-ombre-mortelle @{selected|token_id} @{target|token_id} [[3+@{selected|INT}]] --portee 20 --mana 2 va cr\xE9er un double de la cible, (\xE0 condition de disposer de 2 points de mana) et ajouter ce double \xE0 l'initiative. Au MJ ensuite de la faire attaquer \xE0 son tour (pas d'aoe, juste attaquer le token dont elle est l'ombre). Le token dispara\xEEt lorsque le nombre de tours est \xE9coul\xE9. Il est possible de choisir l'image utilis\xE9e pour repr\xE9senter l'ombre en passant l'url de l'image avec l'option --image.
      17. +
      18. Intelligence h\xE9ro\xEFque : utiliser la fiche
      -

      Prêtre

      +

      Pr\xEAtre

      Voie de la foi

        -
      1. Parole divine : ajouter une compétence convaincre, de valeur 2 fois le rang dans la voie, et ajouter cette compétence dans la liste.
      2. +
      3. Parole divine : ajouter une comp\xE9tence convaincre, de valeur 2 fois le rang dans la voie, et ajouter cette comp\xE9tence dans la liste.
      4. Arme d'argent :
          -
        • Pour attaquer avec l'arme d'argent, faire l'attaque avec les DM appropriés, les modificateurs armeDArgent, magique et l'option --si etat armeDArgent.
        • -
        • !cof-effet-combat armeDArgent --mana 0 pour lancer le sort. Vous pouvez ajouter l'option --degainer L (où L est le label de l'attaque avec l'arme d'argent) si vous souhaitez que le prêtre puisse prendre l'arme en main dans le même tour.
        • +
        • Pour attaquer avec l'arme d'argent, faire l'attaque avec les DM appropri\xE9s, les modificateurs armeDArgent, magique et l'option --si etat armeDArgent.
        • +
        • !cof-effet-combat armeDArgent --mana 0 pour lancer le sort. Vous pouvez ajouter l'option --degainer L (o\xF9 L est le label de l'attaque avec l'arme d'argent) si vous souhaitez que le pr\xEAtre puisse prendre l'arme en main dans le m\xEAme tour.
      5. -
      6. Ailes célestes : !cof-effet-temp ailesCelestes [[5+@{selected|SAG}]] --mana 1.
      7. +
      8. Ailes c\xE9lestes : !cof-effet-temp ailesCelestes [[5+@{selected|SAG}]] --mana 1.
      9. Foudres divines :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+SAG, portée 10, type Sortilège, dégâts électrique, modificateur saufAllies, option --mana 2. Décochez cette attaque, car elle sera appelée de manière spéciale : si le label de ce sort est L, il ne vous reste plus qu'à faire une action avec !cof-explosion L.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+SAG, port\xE9e 10, type Sortil\xE8ge, d\xE9g\xE2ts \xE9lectrique, modificateur saufAllies, option --mana 2. D\xE9cochez cette attaque, car elle sera appel\xE9e de mani\xE8re sp\xE9ciale : si le label de ce sort est L, il ne vous reste plus qu'\xE0 faire une action avec !cof-explosion L.
        • Objet de sort : !cof-explosion Foudres divines --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|SAG}]] --electrique --sortilege --portee 10 --saufAllies
      10. -
      11. Charisme héroïque : reporter les bonus sur la fiche
      12. +
      13. Charisme h\xE9ro\xEFque : reporter les bonus sur la fiche

      Voie de la guerre sainte

        -
      1. Arme bénie : utiliser les modificateurs reroll1, beni et magique à l'attaque
      2. -
      3. Bouclier de la foi : ajuster le bonus de DEF du bouclier
      4. +
      5. Arme b\xE9nie : utiliser les modificateurs reroll1, beni et magique \xE0 l'attaque
      6. +
      7. Bouclier de la foi : ajouter un pr\xE9dicat bouclierDeLaFoi, de valeur le bonus en DEF. Ce bonus sera automatiquement ajout\xE9 quand le pr\xEAtre porte son bouclier.
      8. Marteau sprirituel :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+SAG, portée 30, type Sortilège, options --mana 1
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+SAG, port\xE9e 30, type Sortil\xE8ge, options --mana 1
        • Objet de sort : #Attaque Marteau sprirituel --toucher [[@{selected|ATKMAG}]] --dm 1d8+[[@{selected|SAG}]] --portee 30 --sortilege
      9. -
      10. Châtiment divin : Ajoutez dans la actions du tour une action nommée Châtiment divin, de code #Attaque -1 --bonusAttaque [[@{selected|SAG}]] --plus [[@{selected|SAG}]].
      11. +
      12. Ch\xE2timent divin : Ajoutez dans la actions du tour une action nomm\xE9e Ch\xE2timent divin, de code #Attaque -1 --bonusAttaque [[@{selected|SAG}]] --plus [[@{selected|SAG}]].
      13. Mot de pouvoir : !cof-effet-temp etourdi 1 --lanceur @{selected|token_id} --enVue --saufAllies --message @{selected|token_name} prononce un mot avec la voix de son dieu --mana 3
      -

      Voie de la prière

      +

      Voie de la pri\xE8re

        -
      1. Bénédiction : !cof-effet-temp benediction [[3+@{selected|SAG}]] --alliesEnVue --self --mana 0. Il faut avoir défini une équipe avec le prêtre.
      2. -
      3. Destruction des morts-vivants : !cof-destruction-des-morts-vivants 2d6 --mana 0. Au rang 4 dans la voie, ajuster les dégâts. Notez que le script considère comme mort-vivant tout personnage avec le champ race à squelette, zombie, momie, goule,vampire ou mort-vivant, ou alors qui possède un prédicat mortVivant. Pour éviter la répétition abusive du sort, vous pouvez augmenter la difficulté à chaque fois que le sort est réussi pendant un même combat, avec l'option --malusRepetition m. Un mort-vivant ayant le prédicat immunite_destruction ne sera pas affecté par ce sort.
      4. +
      5. B\xE9n\xE9diction : !cof-effet-temp benediction [[3+@{selected|SAG}]] --alliesEnVue --self --mana 0. Il faut avoir d\xE9fini une \xE9quipe avec le pr\xEAtre.
      6. +
      7. Destruction des morts-vivants : !cof-destruction-des-morts-vivants 2d6 --mana 0. Au rang 4 dans la voie, ajuster les d\xE9g\xE2ts. Notez que le script consid\xE8re comme mort-vivant tout personnage avec le champ race \xE0 squelette, zombie, momie, goule,vampire ou mort-vivant, ou alors qui poss\xE8de un pr\xE9dicat mortVivant. Pour \xE9viter la r\xE9p\xE9tition abusive du sort, vous pouvez augmenter la difficult\xE9 \xE0 chaque fois que le sort est r\xE9ussi pendant un m\xEAme combat, avec l'option --malusRepetition m. Un mort-vivant ayant le pr\xE9dicat immunite_destruction ne sera pas affect\xE9 par ce sort.
      8. Sanctuaire : !cof-effet-temp sanctuaire [[5+@{selected|SAG}]] --mana 1.
      9. -
      10. Intervention Divine : ajouter au personnage un prédicat interventionDivine. Ensuite, utiliser !cof-intervention-divine ?{Type ?|rate|touche} juste après l'attaque en sélectionnant le token du Prêtre pour modifier le résultat selon le choix. Il est très pratique de mettre cette commande dans une Ability à afficher en Token Action. Ne supporte que le jet de touche de la dernière attaque effectuée.
      11. -
      12. Sagesse héroïque : Reporter les bonus sur la fiche.
      13. +
      14. Intervention Divine : ajouter au personnage un pr\xE9dicat interventionDivine. Ensuite, utiliser !cof-intervention-divine ?{Type ?|rate|touche} juste apr\xE8s l'attaque en s\xE9lectionnant le token du Pr\xEAtre pour modifier le r\xE9sultat selon le choix. Il est tr\xE8s pratique de mettre cette commande dans une Ability \xE0 afficher en Token Action. Ne supporte que le jet de touche de la derni\xE8re attaque effectu\xE9e.
      15. +
      16. Sagesse h\xE9ro\xEFque : Reporter les bonus sur la fiche.

      Voie des soins

      -

      Ajouter un prédicat voieDesSoins avec comme valeur le rang dans la voie.

      +

      Ajouter un pr\xE9dicat voieDesSoins avec comme valeur le rang dans la voie.

        -
      1. Soins légers : !cof-soin @{selected|token_id} @{target|token_id} leger --mana 0. Vous pouvez rajouter un petit effet visuel, par exemple avec --targetFx bubbling-holy. À titre personnel, j'ajoute --depasseLimite 1 pour permettre de lancer plus de sorts de soins léger en une journée (mais avec une augmentation cumulative du coût en mana de 1 à chaque dépassement).
      2. -
      3. Soins modérés : !cof-soin @{selected|token_id} @{target|token_id} modere --mana 0.
      4. -
      5. Soins de groupe : !cof-soin @{selected|token_id} groupe --mana 1 (ne pas oublier de définir des alliés). Attention, toutefois, le sort ne va pas automatiquement soigner les personnages notés comme morts, ce qui est le cas général si ils sont tombés à 0 PV. Si certains alliés notés morts ne sont pas vraiment morts, mais juste inconscient, il faudra que le MJ fasse la mise à jour de l'état et des PV lui-même.
      6. -
      7. Guérison : !cof-guerison @{selected|token_id} @{target|token_id} --portee 0 --limiteParJour 1 --mana 2. Pour l'instant ça ne fait que remettre les points de vie au maximum.
      8. +
      9. Soins l\xE9gers : !cof-soin @{selected|token_id} @{target|token_id} leger --mana 0. Vous pouvez rajouter un petit effet visuel, par exemple avec --targetFx bubbling-holy. \xC0 titre personnel, j'ajoute --depasseLimite 1 pour permettre de lancer plus de sorts de soins l\xE9ger en une journ\xE9e (mais avec une augmentation cumulative du co\xFBt en mana de 1 \xE0 chaque d\xE9passement).
      10. +
      11. Soins mod\xE9r\xE9s : !cof-soin @{selected|token_id} @{target|token_id} modere --mana 0.
      12. +
      13. Soins de groupe : !cof-soin @{selected|token_id} groupe --mana 1 (ne pas oublier de d\xE9finir des alli\xE9s). Attention, toutefois, le sort ne va pas automatiquement soigner les personnages not\xE9s comme morts, ce qui est le cas g\xE9n\xE9ral si ils sont tomb\xE9s \xE0 0 PV. Si certains alli\xE9s not\xE9s morts ne sont pas vraiment morts, mais juste inconscient, il faudra que le MJ fasse la mise \xE0 jour de l'\xE9tat et des PV lui-m\xEAme.
      14. +
      15. Gu\xE9rison : !cof-guerison @{selected|token_id} @{target|token_id} --portee 0 --limiteParJour 1 --mana 2. Pour l'instant \xE7a ne fait que remettre les points de vie au maximum.
      16. +
      17. Rappel \xE0 la vie : pas de suport, simplement faire !cof-lancer-sort Rappel \xE0 la vie --mana 3 --limiteParJour 1 rappelALaVie.
      -

      Voie de la spiritualité

      +

      Voie de la spiritualit\xE9

        -
      1. Vêtements sacrés : Ajouter un prédicat vetementsSacres avec comme valeur le rang dans la voie de la spiritualité. Cela augmente la DEF, mais seulement lorsque le prêtre ne porte pas d'armure (ne se voit pas sur le total de DEF de la fiche)
      2. -
      3. Protection contre le mal : !cof-effet-combat protectionContreLeMal --lanceur @{selected|token_id} --target @{target|token_id} --portee 0 --mana 0. Donne le bonus contre toute créature dont l'attribut race est squelette, zombie, démon, élémentaire, ou bien qui possède un prédicat mauvais.
      4. -
      5. Délivrance : !cof-delivrance @{selected|token_id} @{target|token_id} --portee 0 --mana 1
      6. -
      7. Marche des plans : !cof-lancer-sort marche entre les plans (il peut se déplacer de [[(3+@{selected|SAG})*10]] km) --mana 2.
      8. -
      9. Messie : pas d'autre support que !cof-lancer-sort entre directement en contact avec son dieu pour réaliser un miracle --mana 3
      10. +
      11. V\xEAtements sacr\xE9s : Ajouter un pr\xE9dicat vetementsSacres avec comme valeur le rang dans la voie de la spiritualit\xE9. Cela augmente la DEF, mais seulement lorsque le pr\xEAtre ne porte pas d'armure (ne se voit pas sur le total de DEF de la fiche)
      12. +
      13. Protection contre le mal : !cof-effet-combat protectionContreLeMal --lanceur @{selected|token_id} --target @{target|token_id} --portee 0 --mana 0. Donne le bonus contre toute cr\xE9ature dont l'attribut race est squelette, zombie, d\xE9mon, \xE9l\xE9mentaire, ou bien qui poss\xE8de un pr\xE9dicat mauvais.
      14. +
      15. D\xE9livrance : !cof-delivrance @{selected|token_id} @{target|token_id} --portee 0 --mana 1
      16. +
      17. Marche des plans : !cof-lancer-sort marche entre les plans (il peut se d\xE9placer de [[(3+@{selected|SAG})*10]] km) --mana 2.
      18. +
      19. Messie : pas d'autre support que !cof-lancer-sort entre directement en contact avec son dieu pour r\xE9aliser un miracle --mana 3

      Psionique

      Voie de l'attaque mentale

        -
      1. Attaque mentale : faire 2 attaques, une pour les DMs létaux, avec les options --sortilege --attaqueMentale --mana 0 et l'autre avec l'option supplémentaire --tempDmg (et en ajustant les DM).
      2. -
      3. Bouclier psi : ajouter un prédicat bouclierPsi.
      4. -
      5. Attaque étourdissante : faire une attaque mentale, avec les options --avecd12 --if moins niveau --if etatCible bouclierPsi --effet etourdi 1 --save CHA [[8+@{selected|CHA}]] --else --effet etourdi 1 --endif --endif --mana 1.
      6. +
      7. Attaque mentale : faire 2 attaques, une pour les DMs l\xE9taux, avec les options --sortilege --attaqueMentale --mana 0 et l'autre avec l'option suppl\xE9mentaire --tempDmg (et en ajustant les DM).
      8. +
      9. Bouclier psi : ajouter un pr\xE9dicat bouclierPsi.
      10. +
      11. Attaque \xE9tourdissante : faire une attaque mentale, avec les options --avecd12 --if moins niveau --if etatCible bouclierPsi --effet etourdi 1 --save CHA [[8+@{selected|CHA}]] --else --effet etourdi 1 --endif --endif --mana 1.
      12. Vague psionique : faire les attaques mentales sur toutes les cibles. En cas d'utilisation avec la Mana, le plus simple est de faire deux ability :
          -
        • !cof-lancer-sort lance une vague psychique --mana 2 qui lance le sort (pratique pour y mettre votre dépense de Mana unique)
        • -
        • Une ability qui permet de faire une attaque mentale (sans dépense de Mana)
        • +
        • !cof-lancer-sort lance une vague psychique --mana 2 qui lance le sort (pratique pour y mettre votre d\xE9pense de Mana unique)
        • +
        • Une ability qui permet de faire une attaque mentale (sans d\xE9pense de Mana)
      13. -
      14. Ego héroïque : reporter les bonus sur la fiche
      15. +
      16. Ego h\xE9ro\xEFque : reporter les bonus sur la fiche
      -

      Voie du contrôle corporel

      +

      Voie du contr\xF4le corporel

        -
      1. Proprioception : ajouter les PVs sur la fiche, et ajouter un prédicat proprioception.
      2. -
      3. Transe de régénération : ajoutez une ability !cof-soin @{selected|token_id} 1d6+[[@{selected|niveau} + @{selected|CHA}]] --limiteParJour rang --mana 0 --message entre en transe de régénération pour [[2d6]] tours.
      4. -
      5. Contrôle du métabolisme : ajouter un prédicat controleDuMetabolisme. Ne pas modifier l'initiative, le bonus de charisme sera pris en compte par le script.
      6. -
      7. Contrôle sanguin : ajouter un prédicat controleSanguin. Le script immunise aux poison, aux effets saignements automatisés, et divise par deux les dommages des attaques avec --vampirise.
      8. +
      9. Proprioception : ajouter les PVs sur la fiche, et ajouter un pr\xE9dicat proprioception.
      10. +
      11. Transe de r\xE9g\xE9n\xE9ration : ajoutez une ability !cof-soin @{selected|token_id} 1d6+[[@{selected|niveau} + @{selected|CHA}]] --limiteParJour rang --mana 0 --message entre en transe de r\xE9g\xE9n\xE9ration pour [[2d6]] tours.
      12. +
      13. Contr\xF4le du m\xE9tabolisme : ajouter un pr\xE9dicat controleDuMetabolisme. Ne pas modifier l'initiative, le bonus de charisme sera pris en compte par le script.
      14. +
      15. Contr\xF4le sanguin : ajouter un pr\xE9dicat controleSanguin. Le script immunise aux poison, aux effets saignements automatis\xE9s, et divise par deux les dommages des attaques avec --vampirise.

      Voie de l'empathie

        -
      1. Perception extra-sensorielle : ajuster l'initiative et ajouter le bonus à une compétence perception (pour les jets).
      2. -
      3. Défense intuitive : ajouter un prédicat defenseIntuitive. Ne pas modifier la DEF sur la fiche, la sagesse sera automatiquement prise en compte.
      4. -
      5. Perception du passé : !cof-lancer-sort tente de percevoir le passé --mana 1 pour lancer le sort. On peut faire le jet en utilisant !cof-jet SAG 15.
      6. -
      7. Vision lointaine : pas de support autre que !cof-lancer-sort projette son esprit à grande distance --mana 2. Utiliser !cof-jet SAG pour les jets de sagesse.
      8. -
      9. Perception héroïque : reporter les bonus sur la fiche
      10. +
      11. Perception extra-sensorielle : ajuster l'initiative et ajouter le bonus \xE0 une comp\xE9tence perception (pour les jets).
      12. +
      13. D\xE9fense intuitive : ajouter un pr\xE9dicat defenseIntuitive. Ne pas modifier la DEF sur la fiche, la sagesse sera automatiquement prise en compte.
      14. +
      15. Perception du pass\xE9 : !cof-lancer-sort tente de percevoir le pass\xE9 --mana 1 pour lancer le sort. On peut faire le jet en utilisant !cof-jet SAG 15.
      16. +
      17. Vision lointaine : pas de support autre que !cof-lancer-sort projette son esprit \xE0 grande distance --mana 2. Utiliser !cof-jet SAG pour les jets de sagesse.
      18. +
      19. Perception h\xE9ro\xEFque : reporter les bonus sur la fiche
      -

      Voie de la télékinésie

      +

      Voie de la t\xE9l\xE9kin\xE9sie

        -
      1. Manipulation à distance : pour les attaques à distance, le plus simple est d'utiliser une autre attaque en utilisant le score d'attaque magique et le bon modificateur de DMs.
      2. -
      3. Champ de protection : pour l'effet de base, si vous suivez les règles, ajustez simplement la DEF sur la fiche. Si vous préférez en faire un sort, vous pouvez utiliser la commande !cof-effet-temp champDeProtection [[5+@{selected|CHA}]]. La valeur par défaut est celle d'un prédicat voieDeLaTelekinesie, et pour utiliser une autre valeur, on peut utiliser l'option --valeur. Pour le champ à distance, faire !cof-effet-temp champDeProtection 1 --lanceur @{selected|token_id} --portee 10 --valeur n --target @{target|token_id}.
      4. +
      5. Manipulation \xE0 distance : pour les attaques \xE0 distance, le plus simple est d'utiliser une autre attaque en utilisant le score d'attaque magique et le bon modificateur de DMs.
      6. +
      7. Champ de protection : pour l'effet de base, si vous suivez les r\xE8gles, ajustez simplement la DEF sur la fiche. Si vous pr\xE9f\xE9rez en faire un sort, vous pouvez utiliser la commande !cof-effet-temp champDeProtection [[5+@{selected|CHA}]]. La valeur par d\xE9faut est celle d'un pr\xE9dicat voieDeLaTelekinesie, et pour utiliser une autre valeur, on peut utiliser l'option --valeur. Pour le champ \xE0 distance, faire !cof-effet-temp champDeProtection 1 --lanceur @{selected|token_id} --portee 10 --valeur n --target @{target|token_id}.
      8. Onde de choc :
          -
        • Sort : Ajouter une attaque sur la fiche dommages 1d8+CHA, portée 0, type Sortilège, modificateurs auto, options --mana 1 --disque ?{Portée (max 10) ?|10} --etat renverse --save FOR [[10+@{selected|CHA}]] --targetFx explode-magic. Décochez cette attaque, et appelez la dans une action qui fait !cof-explosion li est le label de l'attaque.
        • -
        • Objet de sort : !cof-explosion Onde de choc --auto --dm 1d8+[[@{selected|SAG}]] --portee 0 --sortilege --disque ?{Portée (max 10) ?|10} --etat renverse --save FOR [[10+@{selected|CHA}]] --targetFx explode-magic
        • +
        • Sort : Ajouter une attaque sur la fiche dommages 1d8+CHA, port\xE9e 0, type Sortil\xE8ge, modificateurs auto, options --mana 1 --disque ?{Port\xE9e (max 10) ?|10} --etat renverse --save FOR [[10+@{selected|CHA}]] --targetFx explode-magic. D\xE9cochez cette attaque, et appelez la dans une action qui fait !cof-explosion l o\xF9 i est le label de l'attaque.
        • +
        • Objet de sort : !cof-explosion Onde de choc --auto --dm 1d8+[[@{selected|SAG}]] --portee 0 --sortilege --disque ?{Port\xE9e (max 10) ?|10} --etat renverse --save FOR [[10+@{selected|CHA}]] --targetFx explode-magic
      9. -
      10. Combat kinétique : créer un prédicat combatKinetique. Cela appliquera automatiquement la RD dans tous les cas où le personnage est attaqué par un adversaire et qu'il est conscient. Pour l'augmentation des dommages, reporter sur les attaques sur la fiche.
      11. -
      12. Psychoportation : !cof-lancer-sort s'élève dans les airs pendant [[5+@{selected|INT}]] tours --mana 3. Passer la FOR en caractéristique supérieure via la fiche.
      13. +
      14. Combat kin\xE9tique : cr\xE9er un pr\xE9dicat combatKinetique. Cela appliquera automatiquement la RD dans tous les cas o\xF9 le personnage est attaqu\xE9 par un adversaire et qu'il est conscient. Pour l'augmentation des dommages, reporter sur les attaques sur la fiche.
      15. +
      16. Psychoportation : !cof-lancer-sort s'\xE9l\xE8ve dans les airs pendant [[5+@{selected|INT}]] tours --mana 3. Passer la FOR en caract\xE9ristique sup\xE9rieure via la fiche.
      -

      Voie de la télépathie

      +

      Voie de la t\xE9l\xE9pathie

        -
      1. Télépathie : pas de support autre que !cof-lancer-sort communique par télépathie pendant [[5+@{selected|SAG}]] tours --mana 0
      2. -
      3. Radar mental : ajouter un prédicat radarMental, de valeur le bonus procuré par le radar mental (2 fois le rang dans la voie). En cas de surprise provoquée par quelque chose de non-vivant penser à utiliser l'option --nonVivant dans !cof-surprise.
      4. -
      5. Suggestion : utiliser !cof-attaque-magique-contre-pv @{selected|token_id} @{target|token_id} --limiteParJour 1 suggestion --mana 1 (attention, ça ne teste pas si la cible a un niveau inférieur au psionique, ni si la cible est pensante).
      6. -
      7. Lire les pensées: faire une attaque de type sortilège, portée 10 m, avec l'option --difficulteCarac SAG --if touche --message lit les pensées de @{target|token_name} pendant [[1d6+@{selected|SAG}]] tours --endif.
      8. -
      9. Domination psy : faire une attaque de type sortilège, portée 20 m, avec les modificateurs dominationPsy, attaqueMentale et pasDeDmg.
      10. +
      11. T\xE9l\xE9pathie : pas de support autre que !cof-lancer-sort communique par t\xE9l\xE9pathie pendant [[5+@{selected|SAG}]] tours --mana 0
      12. +
      13. Radar mental : ajouter un pr\xE9dicat radarMental, de valeur le bonus procur\xE9 par le radar mental (2 fois le rang dans la voie). En cas de surprise provoqu\xE9e par quelque chose de non-vivant penser \xE0 utiliser l'option --nonVivant dans !cof-surprise.
      14. +
      15. Suggestion : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg, difficultePVmax, attaqueMentale, options --si moins niveau --if touche --message la cible doit faire l'action sugg\xE9r\xE9e --endif.
      16. +
      17. Lire les pens\xE9es: faire une attaque de type sortil\xE8ge, port\xE9e 10 m, avec l'option --difficulteCarac SAG --if touche --message lit les pens\xE9es de @{target|token_name} pendant [[1d6+@{selected|SAG}]] tours --endif.
      18. +
      19. Domination psy : faire une attaque de type sortil\xE8ge, port\xE9e 20 m, avec les modificateurs dominationPsy, attaqueMentale et pasDeDmg.
      -

      Rôdeur

      +

      R\xF4deur

      Voie de l'archer

        -
      1. Sens affutés : Créez un prédicat sensAffutes. Cela va ajuster l'initiative (ne se voit pas sur la fiche), ainsi que les dégâts des arcs (attention à ne pas en plus le rajouter sur la fiche !). Ajoutez ensuite le bonus aux compétences perception et vigilance (ou créez-les).
      2. +
      3. Sens affut\xE9s : Cr\xE9ez un pr\xE9dicat sensAffutes. Cela va ajuster l'initiative (ne se voit pas sur la fiche), ainsi que les d\xE9g\xE2ts des arcs (attention \xE0 ne pas en plus le rajouter sur la fiche !). Ajoutez ensuite le bonus aux comp\xE9tences perception et vigilance (ou cr\xE9ez-les).
      4. Tir aveugle : utiliser une attaque avec l'option --tirAveugle.
      5. Tir rapide : faire simplement deux attaques dans le tour
      6. -
      7. Flèche de mort : faire l'attaque avec les options --m2d20 --incrDmgCoef
      8. +
      9. Fl\xE8che de mort : faire l'attaque avec les options --m2d20 --incrDmgCoef
      10. Dans le mille : faire l'attaque avec les options --avecd12crit --plus 2d6

      Voie du compagnon animal

        -
      1. Odorat : ajouter une compétence pistage, de valeur 5 (ou augmentée de 5)
      2. -
      3. Surveillance : ajouter un prédicat surveillance, avec comme valeur le nom du compagnon (doit être exactement le même que celui du token du compagnon). Cela automatise l'initiative et le bonus aux jets de surprise, le reste se gère manuellement
      4. -
      5. Combat : ajouter le loup sous contrôle du joueur. Si vous souhaitez que le loup rentre en combat à chaque fois que le rôdeur entre en combat, ajoutez au rôdeur un prédicat nommé entrerEnCombatAvec, de valeur le nom du token du loup.
      6. +
      7. Odorat : ajouter une comp\xE9tence pistage, de valeur 5 (ou augment\xE9e de 5)
      8. +
      9. Surveillance : ajouter un pr\xE9dicat surveillance, avec comme valeur le nom du compagnon (doit \xEAtre exactement le m\xEAme que celui du token du compagnon). Cela automatise l'initiative et le bonus aux jets de surprise, le reste se g\xE8re manuellement
      10. +
      11. Combat : ajouter le loup sous contr\xF4le du joueur. Si vous souhaitez que le loup rentre en combat \xE0 chaque fois que le r\xF4deur entre en combat, ajoutez au r\xF4deur un pr\xE9dicat nomm\xE9 entrerEnCombatAvec, de valeur le nom du token du loup.
      12. Empathie animale : pour soigner, utiliser !cof-soin @{selected|token_id} nom_familier ?{Montant des soins} --transfer
      13. -
      14. Animal fabuleux : ajuster les caractéristiques du loup
      15. +
      16. Animal fabuleux : ajuster les caract\xE9ristiques du loup

      Voie de l'escarmouche

        -
      1. Chasseur émérite : ajouter un prédicat chasseurEmerite. Puis, si dans le profil (attribut profil) de la cible, il y a animal (ou si la cible a un prédicat animal), le bonus s'applique. Ajouter aussi le bonus à une compétence pistage.
      2. -
      3. Traquenard : ajouter un prédicat traquenard, puis option --traquenard pour l'attaque. Pour une utilisation pratique, le mieux est de faire une attaque d'arme en main avec l'option : #Attaque -1 --traquenard.
      4. -
      5. Attaque éclair : --plus [[@{selected|DEX}]] --bonusAttaque [[@{selected|DEX}]]
      6. -
      7. Repli : simplement faire un jet en utilisant par exemple !cof-jet DEX 10, et décrire le résultat.
      8. -
      9. Dextérité héroïque : reporter sur la fiche.
      10. +
      11. Chasseur \xE9m\xE9rite : ajouter un pr\xE9dicat chasseurEmerite. Puis, si dans le profil (attribut profil) de la cible, il y a animal (ou si la cible a un pr\xE9dicat animal), le bonus s'applique. Ajouter aussi le bonus \xE0 une comp\xE9tence pistage.
      12. +
      13. Traquenard : ajouter un pr\xE9dicat traquenard, puis option --traquenard pour l'attaque. Pour une utilisation pratique, le mieux est de faire une attaque d'arme en main avec l'option : #Attaque -1 --traquenard.
      14. +
      15. Attaque \xE9clair : --plus [[@{selected|DEX}]] --bonusAttaque [[@{selected|DEX}]]
      16. +
      17. Repli : simplement faire un jet en utilisant par exemple !cof-jet DEX 10, et d\xE9crire le r\xE9sultat.
      18. +
      19. Dext\xE9rit\xE9 h\xE9ro\xEFque : reporter sur la fiche.

      Voie de la survie

        -
      1. Endurant : ajouter une compétence survie, de caractéristique CON, avec le bonus 2xrang dans la Voie.
      2. -
      3. Nature nourricière : pour la recherche d'herbes, ajouter un prédicat voieDeLaSurvie avec comme valeur le rang du personnage dans la voie. On peut utiliser !cof-nature-nourriciere pour lancer la recherche. Cela crée automatiquement les doses de plantes médicinales dans les consommables du personnage. Ces doses sont supprimées toutes les nuits. Pour les besoins d'un personnage, j'ai aussi donné la possibilité de trouver des baies magiques à la place des herbes médicinales. Pour cela, il faut un prédicat natureNourriciereBaies.
      4. -
      5. Grand pas : ajouter les compétences natation et escalade, de valeur 5.
      6. -
      7. Increvable : ajouter un prédicat increvable.
      8. -
      9. Constitution héroïque : reporter les bonus sur la fiche
      10. +
      11. Endurant : ajouter une comp\xE9tence survie, de caract\xE9ristique CON, avec le bonus 2xrang dans la Voie.
      12. +
      13. Nature nourrici\xE8re : pour la recherche d'herbes, ajouter un pr\xE9dicat voieDeLaSurvie avec comme valeur le rang du personnage dans la voie. On peut utiliser !cof-nature-nourriciere pour lancer la recherche. Cela cr\xE9e automatiquement les doses de plantes m\xE9dicinales dans les consommables du personnage. Ces doses sont supprim\xE9es toutes les nuits. Pour les besoins d'un personnage, j'ai aussi donn\xE9 la possibilit\xE9 de trouver des baies magiques \xE0 la place des herbes m\xE9dicinales. Pour cela, il faut un pr\xE9dicat natureNourriciereBaies.
      14. +
      15. Grand pas : ajouter les comp\xE9tences natation et escalade, de valeur 5.
      16. +
      17. Increvable : ajouter un pr\xE9dicat increvable.
      18. +
      19. Constitution h\xE9ro\xEFque : reporter les bonus sur la fiche

      Voie du traqueur

        -
      1. Pas de loup : ajouter le bonus à une compétence discrétion.
      2. -
      3. Ennemi juré : ajouter un prédicat ennemiJure avec comme valeur la race des ennemis. Cette race doit se retrouver dans le champ race de l'ennemi. Le script reconnait aussi le type mort-vivant (tout en minuscules) et dans ce cas va déterminer si la cible est un mort-vivant (prédicat mortVivant ou race reconnue comme mort-vivant), ainsi que le type géant (pour les géants, ogres, trolls, etc.) et le type gobelin.
      4. +
      5. Pas de loup : ajouter le bonus \xE0 une comp\xE9tence discr\xE9tion.
      6. +
      7. Ennemi jur\xE9 : ajouter un pr\xE9dicat ennemiJure avec comme valeur la race des ennemis. Cette race doit se retrouver dans le champ race de l'ennemi. Le script reconnait aussi le type mort-vivant (tout en minuscules) et dans ce cas va d\xE9terminer si la cible est un mort-vivant (pr\xE9dicat mortVivant ou race reconnue comme mort-vivant), ainsi que le type g\xE9ant (pour les g\xE9ants, ogres, trolls, etc.) et le type gobelin.
      8. Embuscade : en cas d'attaque sur les ennemis, les mettre tous surpris avec la commande !cof-set-state surpris true
      9. -
      10. Second ennemi juré : on peut renseigner une seconde race dans un nouveau prédicat ennemiJure, ou alors le rajouter au prédicat ennemiJure précédant, en la séparant de la première par une virgule (exemple : ennemiJure:: orque, araignée, sans rien ensuite sur la ligne)
      11. -
      12. Perception héroïque : reporter les bonus sur la fiche
      13. +
      14. Second ennemi jur\xE9 : on peut renseigner une seconde race dans un nouveau pr\xE9dicat ennemiJure, ou alors le rajouter au pr\xE9dicat ennemiJure pr\xE9c\xE9dant, en la s\xE9parant de la premi\xE8re par une virgule (exemple : ennemiJure:: orque, araign\xE9e, sans rien ensuite sur la ligne)
      15. +
      16. Perception h\xE9ro\xEFque : reporter les bonus sur la fiche
      -

      Samouraï

      +

      Samoura\xEF

      Voie de l'arc et du cheval

        -
      1. Monture loyale : ajouter un prédicat montureLoyale. Pour la monture, il faut faire un personnage avec un prédicat monture. Pour monter sur la monture, utiliser !cof-en-selle @{selected|token_id} nom_de_la_monture, et pour en descendre, il suffit de faire la même commande (utiliser une ability "token action" rend cela assez facile à l'usage).
      2. +
      3. Monture loyale : ajouter un pr\xE9dicat montureLoyale. Pour la monture, il faut faire un personnage avec un pr\xE9dicat monture. Pour monter sur la monture, utiliser !cof-en-selle @{selected|token_id} nom_de_la_monture, et pour en descendre, il suffit de faire la m\xEAme commande (utiliser une ability "token action" rend cela assez facile \xE0 l'usage).
      4. Tir en mouvement : pas de support particulier.
      5. -
      6. Tir fatal : ajouter un prédicat tirFatal. Pour tenir compte du bonus supplémentaire avec le rang dans la voie, ajouter un prédicat voieDeLArcEtDuCheval de valeur le rang atteint dans cette voie. Si vous souhaitez que cette capacité s'applique à une autre classe d'arme que les arcs, vous pouvez associer ce nom au prédicat tirfatal (attention, sans accent). Par exemple, pour les arbalètes, tirFatal:arbalete.
      7. +
      8. Tir fatal : ajouter un pr\xE9dicat tirFatal. Pour tenir compte du bonus suppl\xE9mentaire avec le rang dans la voie, ajouter un pr\xE9dicat voieDeLArcEtDuCheval de valeur le rang atteint dans cette voie. Si vous souhaitez que cette capacit\xE9 s'applique \xE0 une autre classe d'arme que les arcs, vous pouvez associer ce nom au pr\xE9dicat tirfatal (attention, sans accent). Par exemple, pour les arbal\xE8tes, tirFatal:arbalete.

      Voie du dirigeant

        -
      1. Éduqué : simplement noter les bonus et compétences sur la fiche.
      2. -
      3. Homme de cour : ajouter une compétence étiquette, de valeur 5.
      4. -
      5. Lame de lignée : pas de support particulier pour l'arme, mais quand le samouraï perd l'arme, vous pouvez utiliser la commande !cof-effet lameDeLigneePerdue true (avec le samouraï sélectionné). Quand il la retrouve, utilisez !cof-effet lameDeLigneePerdue false.
      6. +
      7. \xC9duqu\xE9 : simplement noter les bonus et comp\xE9tences sur la fiche.
      8. +
      9. Homme de cour : ajouter une comp\xE9tence \xE9tiquette, de valeur 5.
      10. +
      11. Lame de lign\xE9e : pas de support particulier pour l'arme, mais quand le samoura\xEF perd l'arme, vous pouvez utiliser la commande !cof-effet lameDeLigneePerdue true (avec le samoura\xEF s\xE9lectionn\xE9). Quand il la retrouve, utilisez !cof-effet lameDeLigneePerdue false.

      Voie de l'honneur

        -
      1. Chef né : ajouter un prédicat immunite_peur, et des compétences pour l'intimidation et commander.
      2. -
      3. Défi : !cof-defi-samourai @{selected|token_id} @{target|token_id} bonus. Le bonus en argument est optionnel. S'il n'est pas présent, le script utilise la valeur d'un prédicat voieDeLHonneur.
      4. +
      5. Chef n\xE9 : ajouter un pr\xE9dicat immunite_peur, et des comp\xE9tences pour l'intimidation et commander.
      6. +
      7. D\xE9fi : !cof-defi-samourai @{selected|token_id} @{target|token_id} bonus. Le bonus en argument est optionnel. S'il n'est pas pr\xE9sent, le script utilise la valeur d'un pr\xE9dicat voieDeLHonneur.
      8. Honorable : pas de support particulier.

      Voie du ki

        -
      1. Esprit vide : ajouter un prédicat espritVide. Si vous voulez un boonus différent (par exemple à partir du rang 4 dans la voie), associez les bonus au prédicat.
      2. -
      3. Main vide : faire l'attaque à mains nues correspondant à la capacité.
      4. -
      5. Kiai : ajouter un prédicat kiai, de valeur 1. Au rang 5, mettre cette valeur à 2, le script se charge d'attendre 1d6 tours avant de proposer le deuxième kiai.
      6. -
      7. Course mortelle : !cof-attack-line @{selected|token_id} --distanceMax 10. L'attaque va être faite avec l'arme en main, mais on peut spécifier un label d'attaque (avant les options) et toutes les options supportées par !cof-attack.
      8. +
      9. Esprit vide : ajouter un pr\xE9dicat espritVide. Si vous voulez un boonus diff\xE9rent (par exemple \xE0 partir du rang 4 dans la voie), associez les bonus au pr\xE9dicat.
      10. +
      11. Main vide : faire l'attaque \xE0 mains nues correspondant \xE0 la capacit\xE9.
      12. +
      13. Kiai : ajouter un pr\xE9dicat kiai, de valeur 1. Au rang 5, mettre cette valeur \xE0 2, le script se charge d'attendre 1d6 tours avant de proposer le deuxi\xE8me kiai.
      14. +
      15. Course mortelle : !cof-attack-line @{selected|token_id} --distanceMax 10. L'attaque va \xEAtre faite avec l'arme en main, mais on peut sp\xE9cifier un label d'attaque (avant les options) et toutes les options support\xE9es par !cof-attack.
      16. Puissance du ki : #Attaque -1 --avecd12crit --plus 2d6 --seulementContact.

      Voie du sabre

        -
      1. Technique du sabre : ajouter un prédicat techniqueDuSabre, de valeur le rang dans la Voie.
      2. -
      3. Frappe du vide : ajouter un prédicat frappeDuVide.
      4. -
      5. Lames Jumelles : faire les attaques avec le modificateur lamesJumelles permet de prendre en compte la force courante de l'attaquant pour les malus éventuels à l'attaque. Comme le samouraï va par défaut commencer le combat les mains vides, et qu'avec cette capacité il voudra certainement dégainer à la fois le katana et le wakizachi, on peut utiliser un prédicat pour lui faciliter la tâche : si le label du katana est 5 et celui du wakizachi par exemple 3, ajouter un prédicat actionDegainer1:5-3 (de cette façon, le fait de dégainer le katana et le wakizachi sera en tête de liste).
      6. +
      7. Technique du sabre : ajouter un pr\xE9dicat techniqueDuSabre, de valeur le rang dans la Voie.
      8. +
      9. Frappe du vide : ajouter un pr\xE9dicat frappeDuVide.
      10. +
      11. Lames Jumelles : faire les attaques avec le modificateur lamesJumelles permet de prendre en compte la force courante de l'attaquant pour les malus \xE9ventuels \xE0 l'attaque. Comme le samoura\xEF va par d\xE9faut commencer le combat les mains vides, et qu'avec cette capacit\xE9 il voudra certainement d\xE9gainer \xE0 la fois le katana et le wakizachi, on peut utiliser un pr\xE9dicat pour lui faciliter la t\xE2che : si le label du katana est 5 et celui du wakizachi par exemple 3, ajouter un pr\xE9dicat actionDegainer1:5-3 (de cette fa\xE7on, le fait de d\xE9gainer le katana et le wakizachi sera en t\xEAte de liste).

      Voleur

      Voie de l'assassin

        -
      1. Discrétion : ajouter une compétence discrétion sur la fiche, avec le bon bonus.
      2. -
      3. Attaque sournoise : Ajouter un prédicat attaqueSournoise, de valeur le nombre de dés de l'attaque sournoise. Ensuite, faire des versions des attaques avec --sournoise. Au MJ de vérifier que les conditions de l'attaque sournoise sont remplies. Le plus pratique pour l'utilisation avec différentes armes, est d'ajouter à la liste des actions du tour une action de titre Attaque sournoise et de code #Attaque -1 --sournoise.
      4. -
      5. Ombre mouvante : utiliser la commande !cof-ombre-mouvante --fx burst-smoke (la partie --fx burst-smoke peut être omise ou changée, bien sûr). Le script ne gère pas encore l'attaque sournoise qui peut suivre, au MJ de surveiller l'initiative du voleur par rapport à sa cible.
      6. -
      7. Surprise : ajouter un prédicat immunite_surpris. Pour le reste, à gérer par le MJ.
      8. -
      9. Ouverture mortelle : ajouter les options --ouvertureMortelle --limiteParCombat 1 ouvertureMortelle --sournoise. Selon les indications de Kegron, ne mettre la partie --sournoise que si les conditions s'y prêtent (dans le dos, surprise, acrobatie, etc).
      10. +
      11. Discr\xE9tion : ajouter une comp\xE9tence discr\xE9tion sur la fiche, avec le bon bonus.
      12. +
      13. Attaque sournoise : Ajouter un pr\xE9dicat attaqueSournoise, de valeur le nombre de d\xE9s de l'attaque sournoise. Ensuite, faire des versions des attaques avec --sournoise. Au MJ de v\xE9rifier que les conditions de l'attaque sournoise sont remplies. Le plus pratique pour l'utilisation avec diff\xE9rentes armes, est d'ajouter \xE0 la liste des actions du tour une action de titre Attaque sournoise et de code #Attaque -1 --sournoise.
      14. +
      15. Ombre mouvante : utiliser la commande !cof-ombre-mouvante --fx burst-smoke (la partie --fx burst-smoke peut \xEAtre omise ou chang\xE9e, bien s\xFBr). Le script ne g\xE8re pas encore l'attaque sournoise qui peut suivre, au MJ de surveiller l'initiative du voleur par rapport \xE0 sa cible.
      16. +
      17. Surprise : ajouter un pr\xE9dicat immunite_surpris. Pour le reste, \xE0 g\xE9rer par le MJ.
      18. +
      19. Ouverture mortelle : ajouter les options --ouvertureMortelle --limiteParCombat 1 ouvertureMortelle --sournoise. Selon les indications de Kegron, ne mettre la partie --sournoise que si les conditions s'y pr\xEAtent (dans le dos, surprise, acrobatie, etc).

      Voie de l'aventurier

        -
      1. Sprint : Pour vérifier que ce n'est bien utilisé qu'une fois par combat, on pourra utiliser !cof-lancer-sort pousse un sprint --limiteParCombat 1 sprint.
      2. -
      3. Provocation : !cof-provocation @{selected|token_id} @{target|token_id}. Au joueur ensuite de faire son attaque gratuite si la provocation est réussie et que l'adversaire l'attaque.
      4. -
      5. Grâce féline : ajouter un prédicat graceFeline. Cela va affecter l'initiative et la DEF, mais sans se voir sur la fiche. Pour les tests de déplacement, ajouter un prédicat graceFelineVoleur (penser à proposer l'utilisation de compétences, en ajoutant les compétences course, saut, acrobatie et escalade au voleur ou sur le handout de compétences).
      6. +
      7. Sprint : Pour v\xE9rifier que ce n'est bien utilis\xE9 qu'une fois par combat, on pourra utiliser !cof-lancer-sort pousse un sprint --limiteParCombat 1 sprint.
      8. +
      9. Provocation : !cof-provocation @{selected|token_id} @{target|token_id}. Au joueur ensuite de faire son attaque gratuite si la provocation est r\xE9ussie et que l'adversaire l'attaque.
      10. +
      11. Gr\xE2ce f\xE9line : ajouter un pr\xE9dicat graceFeline. Cela va affecter l'initiative et la DEF, mais sans se voir sur la fiche. Pour les tests de d\xE9placement, ajouter un pr\xE9dicat graceFelineVoleur (penser \xE0 proposer l'utilisation de comp\xE9tences, en ajoutant les comp\xE9tences course, saut, acrobatie et escalade au voleur ou sur le handout de comp\xE9tences).
      -

      Voie du déplacement

      +

      Voie du d\xE9placement

        -
      1. Esquive : Ajouter un prédicat esquiveVoleur, de valeur le rang dans la voie. Ne pas modifier la DEF sur la fiche, le script fera les ajustements (et montrera le total avec !cof-statut).
      2. +
      3. Esquive : Ajouter un pr\xE9dicat esquiveVoleur, de valeur le rang dans la voie. Ne pas modifier la DEF sur la fiche, le script fera les ajustements (et montrera le total avec !cof-statut).
      4. Chute : pas de support particulier.
      5. -
      6. Acrobaties : faire !cof-jet DEX 15 --nom acrobatie pour le jet de dextérité, le reste est géré par le MJ. Il est possible d'automatiser quand le personnage décide de faire une attaque quel que soit le résultat du jet d'acrobatie grace à la commande #Attaque -1 --attaqueAcrobatique.
      7. -
      8. Esquive de la magie : ajouter un prédicat esquiveDeLaMagie.
      9. -
      10. Dextérité héroïque : ajouter les bonus sur la fiche
      11. +
      12. Acrobaties : faire !cof-jet DEX 15 --nom acrobatie pour le jet de dext\xE9rit\xE9, le reste est g\xE9r\xE9 par le MJ. Il est possible d'automatiser quand le personnage d\xE9cide de faire une attaque quel que soit le r\xE9sultat du jet d'acrobatie grace \xE0 la commande #Attaque -1 --attaqueAcrobatique.
      13. +
      14. Esquive de la magie : ajouter un pr\xE9dicat esquiveDeLaMagie.
      15. +
      16. Dext\xE9rit\xE9 h\xE9ro\xEFque : ajouter les bonus sur la fiche

      Voie du roublard

        -
      1. Doigts agiles : utiliser des compétences sur la fiche de personnage
      2. -
      3. Détecter les pièges : faire le jet avec !cof-jet INT ?{Piège normal?|Oui,10|Magique,15} --secret
      4. -
      5. Croc-en-jambe : ajouter un prédicat crocEnJambe. Pour distinguer les adversaires quadrupèdes qui ne seraient pas connues du script, lui ajouter un prédicat quadrupede. Les adversaires avec un prédicat volant ne seront pas affectés.
      6. +
      7. Doigts agiles : utiliser des comp\xE9tences sur la fiche de personnage
      8. +
      9. D\xE9tecter les pi\xE8ges : faire le jet avec !cof-jet INT ?{Pi\xE8ge normal?|Oui,10|Magique,15} --secret
      10. +
      11. Croc-en-jambe : ajouter un pr\xE9dicat crocEnJambe. Pour distinguer les adversaires quadrup\xE8des qui ne seraient pas connues du script, lui ajouter un pr\xE9dicat quadrupede. Les adversaires avec un pr\xE9dicat volant ne seront pas affect\xE9s.
      12. Attaque paralysante : lancer une des attaques de contact du voleur en rajoutant les options --limiteParCombat 1 attaqueParalysante --pasDeDmg --effet paralysieRoublard [[1d4]].
      13. -
      14. Attaque en traître : Ajouter un prédicat attaqueEnTraitre. Les actions affichées en cas d'attaque en traître seront par défaut une attaque avec l'arme en main et les attaques naturelles de la fiche cochées. Si cela ne convient pas, vous pouvez créer une liste d'actions nommée Attaques en traitre contenant les attaques possibles pour l'attaque en traître.
      15. +
      16. Attaque en tra\xEEtre : Ajouter un pr\xE9dicat attaqueEnTraitre. Les actions affich\xE9es en cas d'attaque en tra\xEEtre seront par d\xE9faut une attaque avec l'arme en main et les attaques naturelles de la fiche coch\xE9es. Si cela ne convient pas, vous pouvez cr\xE9er une liste d'actions nomm\xE9e Attaques en traitre contenant les attaques possibles pour l'attaque en tra\xEEtre.

      Voie du spadassin

      1. Attaque en finesse : faire les modifications sur la fiche
      2. -
      3. Esquive fatale : Ajouter un prédicat esquiveFatale (on peut y associer un nombre pour permettre plus d'une utilisation par combat). En combat, si la situation s'y prête, un bouton permettre d'utiliser l'esquive. Ne pas oublier de définir les alliés du voleur pour que la vérification des cibles soit correcte.
      4. -
      5. Frappe chirurgicale : ajouter un prédicat frappeChirurgicale.
      6. -
      7. Ambidextrie : pas géré par le script.
      8. -
      9. Botte secrète : ajouter un prédicat botteSecrete. Ne pas oublier le prédicat attaqueSournoise qui doit être associé au nombre de dés des attaques sournoises du voleur.
      10. +
      11. Esquive fatale : Ajouter un pr\xE9dicat esquiveFatale (on peut y associer un nombre pour permettre plus d'une utilisation par combat). En combat, si la situation s'y pr\xEAte, un bouton permettre d'utiliser l'esquive. Ne pas oublier de d\xE9finir les alli\xE9s du voleur pour que la v\xE9rification des cibles soit correcte.
      12. +
      13. Frappe chirurgicale : ajouter un pr\xE9dicat frappeChirurgicale.
      14. +
      15. Ambidextrie : pas g\xE9r\xE9 par le script.
      16. +
      17. Botte secr\xE8te : ajouter un pr\xE9dicat botteSecrete. Ne pas oublier le pr\xE9dicat attaqueSournoise qui doit \xEAtre associ\xE9 au nombre de d\xE9s des attaques sournoises du voleur.
    -

    4. Autres capacités

    +

    4. Autres capacit\xE9s

    -

    4.1 Voies et capacités raciales

    +

    4.1 Voies et capacit\xE9s raciales

    - Quelques capacités communes à plusieurs races : + Quelques capacit\xE9s communes \xE0 plusieurs races :
      -
    • Vision dans le noir : ajoutez un prédicat visionDansLeNoir de valeur le nombre de metres à laquelle le personnage peut voir dans le noir. Le script va adapter la vison dans le noir à l'unité de mesure utilisée sur la page où le token du personnage est créé.
    • +
    • Vision dans le noir : ajoutez un pr\xE9dicat visionDansLeNoir de valeur le nombre de metres \xE0 laquelle le personnage peut voir dans le noir. Le script va adapter la vison dans le noir \xE0 l'unit\xE9 de mesure utilis\xE9e sur la page o\xF9 le token du personnage est cr\xE9\xE9.
    -

    Âme forgée

    -

    Pour les capacités raciales, un prédicat vieArtificielle permet de diviser tous les soins par 2. Pour la résistance aux effets de drains, au feu et au froid, ajouter dans la RD sur la fiche drain:5, feu:5, froid:5. Pour l'immunité aux poisons et maladies, utiliser un prédicat creatureArtificielle. Enfin pour le saignement, ajouter un prédicat immuniteSaignement.

    +

    \xC2me forg\xE9e

    +

    Pour les capacit\xE9s raciales, un pr\xE9dicat vieArtificielle permet de diviser tous les soins par 2. Pour la r\xE9sistance aux effets de drains, au feu et au froid, ajouter dans la RD sur la fiche drain:5, feu:5, froid:5. Pour l'immunit\xE9 aux poisons et maladies, utiliser un pr\xE9dicat creatureArtificielle. Enfin pour le saignement, ajouter un pr\xE9dicat immuniteSaignement.

      -
    1. Main lourde : ajuster les DM, et enlever l'option --tempDmg pour l'attaque à mains nues.
    2. +
    3. Main lourde : ajuster les DM, et enlever l'option --tempDmg pour l'attaque \xE0 mains nues.

    Demi-ogre

    • Vision dans le noir.
    • -
    • Énorme : pas de support, ajuster les attaques
    • -
    • Grande taille : quand le demi-ogre rentre dans une construction de taille humaine, utiliser !cof-effet constructionTailleHumaine true. À la sortie du bâtiment, !cof-effet constructionTailleHumaine false. Pour les espaces exigus, de même avec l'effet espaceExigu.
    • -
    • Réaction violente : en cas de provocation, exécuter !cof-effet-temp reactionViolente [[1d6]] --save SAG 10. On peut par exemple mettre ce code en ability liée au token. Au MJ et au joueur de gérer les actions qui s'ensuivent. Le script propose une action à l'ogre pour prendre sur lui à chaque tour.
    • +
    • \xC9norme : pas de support, ajuster les attaques
    • +
    • Grande taille : quand le demi-ogre rentre dans une construction de taille humaine, utiliser !cof-effet constructionTailleHumaine true. \xC0 la sortie du b\xE2timent, !cof-effet constructionTailleHumaine false. Pour les espaces exigus, de m\xEAme avec l'effet espaceExigu.
    • +
    • R\xE9action violente : en cas de provocation, ex\xE9cuter !cof-effet-temp reactionViolente [[1d6]] --save SAG 10. On peut par exemple mettre ce code en ability li\xE9e au token. Au MJ et au joueur de g\xE9rer les actions qui s'ensuivent. Le script propose une action \xE0 l'ogre pour prendre sur lui \xE0 chaque tour.
      -
    1. Sang-froid : ajouter un prédicat sangFroid. Modifier la commande pour les provocations en !cof-effet-temp reactionViolente [[1d4]] --save SAG 5.
    2. -
    3. Violence ciblée : ajouter un prédicat violenceCiblee.
    4. +
    5. Sang-froid : ajouter un pr\xE9dicat sangFroid. Modifier la commande pour les provocations en !cof-effet-temp reactionViolente [[1d4]] --save SAG 5.
    6. +
    7. Violence cibl\xE9e : ajouter un pr\xE9dicat violenceCiblee.

    Demi-orque

    Vision dans le noir.
    1. Force de la nature : ajouter les bonus sur la fiche
    2. -
    3. Talent pour la violence : voir les capacités choisies
    4. +
    5. Talent pour la violence : voir les capacit\xE9s choisies
    6. Critique brutal : pour l'instant, ajouter le modificateur incrCritCoef pour toutes les attaques au contact.
    7. Attaque sanglante : faire une attaque (ou liste d'attaques) avec les options --effet blessureQuiSaigne --saveParTour CON [[12 + @{selected|FOR}]]
    8. -
    9. Colosse : augmenter les caractéristiques sur la fiche.
    10. +
    11. Colosse : augmenter les caract\xE9ristiques sur la fiche.

    Elfe sylvain

      -
    1. Grâce elfique : simplement reporter sur la fiche
    2. -
    3. Enfant de la forêt : voir les capacités choisies
    4. -
    5. Archer émérite : ajuster les chances de critique sur les attaques à l'arc
    6. -
    7. Flèche sanglante : faire une attaque (ou liste d'attaques) avec les options --effet blessureQuiSaigne --saveParTour CON [[12 + @{selected|DEX}]]
    8. -
    9. Supériorité elfique : augmenter les caractéristiques sur la fiche.
    10. +
    11. Gr\xE2ce elfique : simplement reporter sur la fiche
    12. +
    13. Enfant de la for\xEAt : voir les capacit\xE9s choisies
    14. +
    15. Archer \xE9m\xE9rite : ajuster les chances de critique sur les attaques \xE0 l'arc
    16. +
    17. Fl\xE8che sanglante : faire une attaque (ou liste d'attaques) avec les options --effet blessureQuiSaigne --saveParTour CON [[12 + @{selected|DEX}]]
    18. +
    19. Sup\xE9riorit\xE9 elfique : augmenter les caract\xE9ristiques sur la fiche.
    -

    Fée et lutin

    +

    F\xE9e et lutin

    • Vision dans le noir.
    • -
    • Tout petit : ajouter un prédicat toutPetit qui va automatiquement ajuster la défense et les jets de discrétion.
    • -
    • Vol et Téléportation : pas de support.
    • -
    • Trop petit : ajouter un prédicat tropPetit. Cela va aussi changer les dégâts de base des armes (il vaut mieux laisser les vrais DM pour que la capacité Grande taille fonctionne).
    • +
    • Tout petit : ajouter un pr\xE9dicat toutPetit qui va automatiquement ajuster la d\xE9fense et les jets de discr\xE9tion.
    • +
    • Vol et T\xE9l\xE9portation : pas de support.
    • +
    • Trop petit : ajouter un pr\xE9dicat tropPetit. Cela va aussi changer les d\xE9g\xE2ts de base des armes (il vaut mieux laisser les vrais DM pour que la capacit\xE9 Grande taille fonctionne).
    1. Langage des animaux : aucun support
    2. -
    3. Invisibilité : !cof-set-state invisible true --message se rend invisible --messageMJ l'invisibilité va durer [[1d6+@{selected|INT}]] minutes --limiteParJour rr est le rang dans la Voie.
    4. -
    5. Monture féérique : ajouter un ersonnage pour la monture. Ajoutez-lui le prédicat monture. Pour monter sur la monture, utiliser !cof-en-selle @{selected|token_id} nom_de_la_monture, et pour en descendre, il suffit de faire la même commande (utiliser une ability "token action" rend cela assez facile à l'usage). Si vous souhaitez que la monture rentre en combat à chaque fois que l'être féérique entre en combat, ajoutez à l'être féérique un prédicat nommé entrerEnCombatAvec, de valeur le nom du token de la monture (pensez à utiliser la syntaxe avec :: si ce nom contient des caractères spéciaux).
    6. -
    7. Grande taille : !cof-effet grandeTaille oui --lanceur @{selected|token_id} --limiteParJour 3 --messageMJ La taille humaine durera [[1d6+@{selected|CHA}]] minutes. Le script ne gère pas les durées en minutes, le MJ devra penser à supprimer l'effet, par exemple depuis le statut (!cof-statut).
    8. +
    9. Invisibilit\xE9 : !cof-set-state invisible true --message se rend invisible --messageMJ l'invisibilit\xE9 va durer [[1d6+@{selected|INT}]] minutes --limiteParJour r o\xF9 r est le rang dans la Voie.
    10. +
    11. Monture f\xE9\xE9rique : ajouter un ersonnage pour la monture. Ajoutez-lui le pr\xE9dicat monture. Pour monter sur la monture, utiliser !cof-en-selle @{selected|token_id} nom_de_la_monture, et pour en descendre, il suffit de faire la m\xEAme commande (utiliser une ability "token action" rend cela assez facile \xE0 l'usage). Si vous souhaitez que la monture rentre en combat \xE0 chaque fois que l'\xEAtre f\xE9\xE9rique entre en combat, ajoutez \xE0 l'\xEAtre f\xE9\xE9rique un pr\xE9dicat nomm\xE9 entrerEnCombatAvec, de valeur le nom du token de la monture (pensez \xE0 utiliser la syntaxe avec :: si ce nom contient des caract\xE8res sp\xE9ciaux).
    12. +
    13. Grande taille : !cof-effet grandeTaille oui --lanceur @{selected|token_id} --limiteParJour 3 --messageMJ La taille humaine durera [[1d6+@{selected|CHA}]] minutes. Le script ne g\xE8re pas les dur\xE9es en minutes, le MJ devra penser \xE0 supprimer l'effet, par exemple depuis le statut (!cof-statut).
    -

    Félis

    +

    F\xE9lis

      -
    1. Âme féline : ajouter un prédicat ameFeline, de valeur le rang dans la voie. Pensez à ajouter des compétences pour le mouvement sur la fiche si ils ne sont pas déjà présent dans votre handout de compétences.
    2. +
    3. \xC2me f\xE9line : ajouter un pr\xE9dicat ameFeline, de valeur le rang dans la voie. Pensez \xE0 ajouter des comp\xE9tences pour le mouvement sur la fiche si ils ne sont pas d\xE9j\xE0 pr\xE9sent dans votre handout de comp\xE9tences.
    4. Armes naturelles :
        -
      • Créez une attaque "Griffes et crocs" naturelle de contact avec en DM 1d6 + Mod de FOR et les options --si etat armesNaturelles --message Attaque de ses griffes et crocs !.
      • +
      • Cr\xE9ez une attaque "Griffes et crocs" naturelle de contact avec en DM 1d6 + Mod de FOR et les options --si etat armesNaturelles --message Attaque de ses griffes et crocs !.
      • Pour faire sortir les griffes, dans l'onglet script, ajouter une action "Sortir/rentrer les griffes" faisant !cof-effet armesNaturelles.
    5. @@ -2014,49 +2018,49 @@

      Félis

      Gnome

      1. Petit pote : ajouter le bonus de CHA sur la fiche
      2. -
      3. Don occulte : se reporter aux capacités choisies.
      4. -
      5. Insignifiant : ajouter un prédicat insignifiant. +
      6. Don occulte : se reporter aux capacit\xE9s choisies.
      7. +
      8. Insignifiant : ajouter un pr\xE9dicat insignifiant.

      Halfelin

      -

      Petite taille : ajouter le bonus de DEF sur la ficher, et ajouter 2 à une compétence discrétion.

      +

      Petite taille : ajouter le bonus de DEF sur la ficher, et ajouter 2 \xE0 une comp\xE9tence discr\xE9tion.

        -
      1. Petit veinard : ajouter un prédicat petitVeinard (on peut y associer un nombre si on veut plus d'une utilisation par combat). Le script ne va automatiser que les relancer de dés d'attaque ou de jets de caractéristiques (et encore, pas tous). Il propose d'utiliser la chance à chaque attaque, même réussie, mais dans ce cas, c'est au joueur de relancer le dé concerné, et au MJ d'en appliquer les conséquences.
      2. -
      3. Résistance légendaire : ajouter le bonus en CON sur la fiche, et ajouter un prédicat DEF_magie avec comme valeur 5.
      4. +
      5. Petit veinard : ajouter un pr\xE9dicat petitVeinard (on peut y associer un nombre si on veut plus d'une utilisation par combat). Le script ne va automatiser que les relancer de d\xE9s d'attaque ou de jets de caract\xE9ristiques (et encore, pas tous). Il propose d'utiliser la chance \xE0 chaque attaque, m\xEAme r\xE9ussie, mais dans ce cas, c'est au joueur de relancer le d\xE9 concern\xE9, et au MJ d'en appliquer les cons\xE9quences.
      6. +
      7. R\xE9sistance l\xE9gendaire : ajouter le bonus en CON sur la fiche, et ajouter un pr\xE9dicat DEF_magie avec comme valeur 5.

      Haut elfe

        -
      1. Grâce elfique : ajouter les bonus sur la fiche
      2. -
      3. Talent pour la magie : voir les capacités choisies
      4. -
      5. Force d'âme : ajouter des prédicat immunite_peur et immunite_endormi. Ajouter aussi des prédicats DEF_magie et bonusSagesseMagie de valeur 5.
      6. +
      7. Gr\xE2ce elfique : ajouter les bonus sur la fiche
      8. +
      9. Talent pour la magie : voir les capacit\xE9s choisies
      10. +
      11. Force d'\xE2me : ajouter des pr\xE9dicat immunite_peur et immunite_endormi. Ajouter aussi des pr\xE9dicats DEF_magie et bonusSagesseMagie de valeur 5.

      Humain

      -

      Instinct de survie : créer un prédicat instinctDeSurvieHumain.

      +

      Instinct de survie : cr\xE9er un pr\xE9dicat instinctDeSurvieHumain.

        -
      1. Adaptable : ajouter un prédicat adaptable, de valeur le bonus en cas de test raté. Le script ne va appliquer le bonus que pour les tests avec difficulté identifiée. Le MJ devra l'appliquer dans les cas ratés par le script.
      2. -
      3. Loup parmi les loups : ajouter un prédicat loupParmiLesLoups avec comme valeur 1 ou 2 selon le rang dans la voie. Une créature sera considérée comme humanoïde si elle a un prédicat humanoide, ou si sa race est reconnue comme humanoïde.
      4. -
      5. Versatile : se reporter à la capacité choisie.
      6. -
      7. Increvable : ajouter un prédicat increvableHumain.
      8. +
      9. Adaptable : ajouter un pr\xE9dicat adaptable, de valeur le bonus en cas de test rat\xE9. Le script ne va appliquer le bonus que pour les tests avec difficult\xE9 identifi\xE9e. Le MJ devra l'appliquer dans les cas rat\xE9s par le script.
      10. +
      11. Loup parmi les loups : ajouter un pr\xE9dicat loupParmiLesLoups avec comme valeur 1 ou 2 selon le rang dans la voie. Une cr\xE9ature sera consid\xE9r\xE9e comme humano\xEFde si elle a un pr\xE9dicat humanoide, ou si sa race est reconnue comme humano\xEFde.
      12. +
      13. Versatile : se reporter \xE0 la capacit\xE9 choisie.
      14. +
      15. Increvable : ajouter un pr\xE9dicat increvableHumain.

      Drakonide

        -
      1. Souffle : ajouter une attaque naturelle cochée, faisant des dégâts du type du drakonide, de portée 10 m, avec comme option --cone 30 --psave DEX 12 --tempsRecharge rechargeSouffle [[1d4]].
      2. -
      3. Intimidant : ajouter la compétence intimidation sur la fiche, avec un bonus de +5.
      4. -
      5. Écailles robustes : ajouter le bonus sur la fiche.
      6. -
      7. Fureur drakonide : ajouter un prédicat fureurDrakonide.
      8. -
      9. Héritage draconique : ajuster les caractéristiques sur la fiche.
      10. +
      11. Souffle : ajouter une attaque naturelle coch\xE9e, faisant des d\xE9g\xE2ts du type du drakonide, de port\xE9e 10 m, avec comme option --cone 30 --psave DEX 12 --tempsRecharge rechargeSouffle [[1d4]].
      12. +
      13. Intimidant : ajouter la comp\xE9tence intimidation sur la fiche, avec un bonus de +5.
      14. +
      15. \xC9cailles robustes : ajouter le bonus sur la fiche.
      16. +
      17. Fureur drakonide : ajouter un pr\xE9dicat fureurDrakonide.
      18. +
      19. H\xE9ritage draconique : ajuster les caract\xE9ristiques sur la fiche.

      Lutin

      - Voir les fées. + Voir les f\xE9es.

      Minotaure

      • Vision dans le noir.
      • Coup de corne : ajouter simplement l'attaque.
      • -
      • Sens de l'orientation : utiliser une compétence/
      • -
      • Grande taille : quand le minotaure rentre dans une construction de taille humaine, utiliser !cof-effet constructionTailleHumaine true. À la sortie du bâtiment, !cof-effet constructionTailleHumaine false. Pour les espaces exigus, de même avec l'effet espaceExigu. Si on veut un seul bouton, enlever simplement l'argument true.
      • +
      • Sens de l'orientation : utiliser une comp\xE9tence/
      • +
      • Grande taille : quand le minotaure rentre dans une construction de taille humaine, utiliser !cof-effet constructionTailleHumaine true. \xC0 la sortie du b\xE2timent, !cof-effet constructionTailleHumaine false. Pour les espaces exigus, de m\xEAme avec l'effet espaceExigu. Si on veut un seul bouton, enlever simplement l'argument true.
        -
      1. Charge : #Attaque -1 --bonusAttaque 2 --plus 1d6. Le déplacement n'est pas encore géré. Modifier les bonus si le minotaure possède la capacité Charge du barbare.
      2. -
      3. Frénésie : On peut faire passer en frénésie avec la commande !cof-effet-temp frenesieMinotaure [[1d6]]. Quand j'aurai le temps, il devrait être possible de faire apparaître un bouton quand le minotaure est blessé.
      4. +
      5. Charge : #Attaque -1 --bonusAttaque 2 --plus 1d6. Le d\xE9placement n'est pas encore g\xE9r\xE9. Modifier les bonus si le minotaure poss\xE8de la capacit\xE9 Charge du barbare.
      6. +
      7. Fr\xE9n\xE9sie : On peut faire passer en fr\xE9n\xE9sie avec la commande !cof-effet-temp frenesieMinotaure [[1d6]]. Quand j'aurai le temps, il devrait \xEAtre possible de faire appara\xEEtre un bouton quand le minotaure est bless\xE9.
      8. Orientation infaillible : pas de support particulier.
      9. Encorner : pas de support particulier.
      10. Colosse : reporter sur la fiche.
      11. @@ -2066,137 +2070,137 @@

        Nain

      12. Vision dans le noir.
        1. -
        2. Résistance : ajouter les bonus sur la fiche
        3. +
        4. R\xE9sistance : ajouter les bonus sur la fiche
        5. Solide comme un roc : ajouter le texte 2/1 dans la RD sur la fiche.
        6. -
        7. Haches et marteaux : ajouter un prédicat hachesEtMarteaux. Ne pas oublier de mettre le modificateur hache ou marteau pour les attaques qui sont concernées.
        8. +
        9. Haches et marteaux : ajouter un pr\xE9dicat hachesEtMarteaux. Ne pas oublier de mettre le modificateur hache ou marteau pour les attaques qui sont concern\xE9es.

        Tieflin

        • Vision dans le noir.
        • -
        • Résistance aux éléments : ajouter dans la RD sur la fiche feu:5, electrique:5, froid:5
        • +
        • R\xE9sistance aux \xE9l\xE9ments : ajouter dans la RD sur la fiche feu:5, electrique:5, froid:5
          -
        1. Se faire discret : ajouter les jets sur la fiche, ou bien des compétences mentir et deguisement de valeur 5, à utiliser avec !cof-jet.
        2. +
        3. Se faire discret : ajouter les jets sur la fiche, ou bien des comp\xE9tences mentir et deguisement de valeur 5, \xE0 utiliser avec !cof-jet.
    -

    4.2 Voies de prestige et capacités épiques

    +

    4.2 Voies de prestige et capacit\xE9s \xE9piques

    -

    Voie d'Arwendée

    +

    Voie d'Arwend\xE9e

      -
    1. Sens affutés : Créez un prédicat sensAffutes. Cela va ajuster l'initiative (ne se voit pas sur la fiche), ainsi que les dégâts des arcs. Ajoutez ensuite le bonus aux compétences perception et vigilance (ou créez-les).
    2. -
    3. Arc de maître : Créez un prédicat arcDeMaitre pour automatiquement augmenter la portée des arcs de 20 m.
    4. +
    5. Sens affut\xE9s : Cr\xE9ez un pr\xE9dicat sensAffutes. Cela va ajuster l'initiative (ne se voit pas sur la fiche), ainsi que les d\xE9g\xE2ts des arcs. Ajoutez ensuite le bonus aux comp\xE9tences perception et vigilance (ou cr\xE9ez-les).
    6. +
    7. Arc de ma\xEEtre : Cr\xE9ez un pr\xE9dicat arcDeMaitre pour automatiquement augmenter la port\xE9e des arcs de 20 m.
    8. Carquois magique : !cof-effet-temp carquoisMagique [[5+@{selected|SAG}]] --valeur ?{Type de DM?|feu|froid|foudre} --mana 1.
    9. -
    10. Protection contre les projectiles : Créez un prédicat protectionContreLesProjectiles de valeur 10. Puis, pour lancer le sort, utilisez !cof-effet-temp protectionContreLesProjectiles [[6*(5+@{selected|SAG})]] --lanceur @{selected|token_id} --target @{target|token_id} --mana 2.
    11. -
    12. Pluie de flèches : lancer l'attaque avec les options --limiteParCombat 1 pluieDeFleches --disque 5 --toucheDoubleDmg --mana 3.
    13. +
    14. Protection contre les projectiles : Cr\xE9ez un pr\xE9dicat protectionContreLesProjectiles de valeur 10. Puis, pour lancer le sort, utilisez !cof-effet-temp protectionContreLesProjectiles [[6*(5+@{selected|SAG})]] --lanceur @{selected|token_id} --target @{target|token_id} --mana 2.
    15. +
    16. Pluie de fl\xE8ches : lancer l'attaque avec les options --limiteParCombat 1 pluieDeFleches --disque 5 --toucheDoubleDmg --mana 3.

    Voie de l'archange

      -
    1. Forme d'ange : !cof-effet-temp formeDAnge [[5+@{selected|SAG}]] --mana 0. Le MJ devra gérer l'aspect en vol.
    2. -
    3. Soins améliorés : utiliser un prédicat voieDeLArchange avec comme valeur le rang dans la voie.
    4. -
    5. Épée céleste : rien à faire si le prédicat voieDeLArchange a la bonne valeur. Si le personnage n'a pas déjà la capacité Arme d'argent, ajouter une attaque pour cette arme, avec le modificateur armeDArgent et l'option --si etat armeDArgent.
    6. +
    7. Forme d'ange : !cof-effet-temp formeDAnge [[5+@{selected|SAG}]] --mana 0. Le MJ devra g\xE9rer l'aspect en vol.
    8. +
    9. Soins am\xE9lior\xE9s : utiliser un pr\xE9dicat voieDeLArchange avec comme valeur le rang dans la voie.
    10. +
    11. \xC9p\xE9e c\xE9leste : rien \xE0 faire si le pr\xE9dicat voieDeLArchange a la bonne valeur. Si le personnage n'a pas d\xE9j\xE0 la capacit\xE9 Arme d'argent, ajouter une attaque pour cette arme, avec le modificateur armeDArgent et l'option --si etat armeDArgent.

    Voie de l'archer arcanique

      -
    1. Flèche magique : vous pouvez ajouter une munition de type flèche, avec les modificateurs magique, reroll1.
    2. -
    3. Flèche tueuse : ajouter une munition dédiée, avec les modificateurs magique, reroll1 et les options --bonusAttaque 3 --plus rd6. Au Mj et au joueur de vérifier que cette flèche n'est utilisée que contre la bonne cible...
    4. -
    5. Flèche intangible : ajouter une action avec le code #Attaque -1 --difficulteCarac DEX --ignoreObstacles. Attention, pour l'instant le script ne vérifie pas que l'arme utilisée est bien un arc.
    6. -
    7. Flèches vivantes : ajoutez aux munitions du rang 1 et 2 l'option --if deAttaque 15 --plus 2d6 --message la flèche prend vie au contact du sang --endif.
    8. -
    9. Flèche chercheuse : faire une action avec le code #Attaque -1 --plus 2d6 --portee 1000 --limiteParJour 1 flecheChercheuse.
    10. +
    11. Fl\xE8che magique : vous pouvez ajouter une munition de type fl\xE8che, avec les modificateurs magique, reroll1.
    12. +
    13. Fl\xE8che tueuse : ajouter une munition d\xE9di\xE9e, avec les modificateurs magique, reroll1 et les options --bonusAttaque 3 --plus rd6. Au Mj et au joueur de v\xE9rifier que cette fl\xE8che n'est utilis\xE9e que contre la bonne cible...
    14. +
    15. Fl\xE8che intangible : ajouter une action avec le code #Attaque -1 --difficulteCarac DEX --ignoreObstacles. Attention, pour l'instant le script ne v\xE9rifie pas que l'arme utilis\xE9e est bien un arc.
    16. +
    17. Fl\xE8ches vivantes : ajoutez aux munitions du rang 1 et 2 l'option --if deAttaque 15 --plus 2d6 --message la fl\xE8che prend vie au contact du sang --endif.
    18. +
    19. Fl\xE8che chercheuse : faire une action avec le code #Attaque -1 --plus 2d6 --portee 1000 --limiteParJour 1 flecheChercheuse.

    Voie de l'expert

    - Reporter les bonus sur la fiche et créer les compétences adéquates. + Reporter les bonus sur la fiche et cr\xE9er les comp\xE9tences ad\xE9quates.

    Voie de l'expert du combat

      -
    1. Expertise du combat : créer un prédicat expertDuCombat avec comme valeur le rang dans la voie. La commande !cof-statut donne un état des lieux des dés dépensés pendant le combat/le tour. Les dés ne sont actifs qu'en combat et sont réinitialisés à l'utilisation de !cof-fin-combat. L'implémentation part du principe que l'augmentation de la DEF doit être décidée avant le jet de dommages, comme une esquive acrobatique par exemple.
    2. +
    3. Expertise du combat : cr\xE9er un pr\xE9dicat expertDuCombat avec comme valeur le rang dans la voie. La commande !cof-statut donne un \xE9tat des lieux des d\xE9s d\xE9pens\xE9s pendant le combat/le tour. Les d\xE9s ne sont actifs qu'en combat et sont r\xE9initialis\xE9s \xE0 l'utilisation de !cof-fin-combat. L'impl\xE9mentation part du principe que l'augmentation de la DEF doit \xEAtre d\xE9cid\xE9e avant le jet de dommages, comme une esquive acrobatique par exemple.
    4. Bousculer : !cof-expert-combat-bousculer @{selected|token_id} @{target|token_id}
    5. -
    6. Expertise supérieure : il suffit de mettre à jour la valeur du prédicat expertDuCombat ; le script automatise la mise à jour des limites et la possibilité d'augmenter les DM.
    7. -
    8. Déplacement tactique : pas de support spécifique pour le déplacement, mais on peut prévoir une action !cof-expert-combat pour le personnage, qui ne fera qu'une dépense simple de dé d'expertise.
    9. -
    10. Expertise majeure : les limites de dés par tour sont automatiques avec la bonne valeur du prédicat expertDuCombat. Pour l'instant le cumul de dés sur le même jet n'est pas supporté.
    11. +
    12. Expertise sup\xE9rieure : il suffit de mettre \xE0 jour la valeur du pr\xE9dicat expertDuCombat ; le script automatise la mise \xE0 jour des limites et la possibilit\xE9 d'augmenter les DM.
    13. +
    14. D\xE9placement tactique : pas de support sp\xE9cifique pour le d\xE9placement, mais on peut pr\xE9voir une action !cof-expert-combat pour le personnage, qui ne fera qu'une d\xE9pense simple de d\xE9 d'expertise.
    15. +
    16. Expertise majeure : les limites de d\xE9s par tour sont automatiques avec la bonne valeur du pr\xE9dicat expertDuCombat. Pour l'instant le cumul de d\xE9s sur le m\xEAme jet n'est pas support\xE9.

    Voie de l'homme du peuple

    - Reporter les bonus sur la fiche et créer les compétences adéquates. + Reporter les bonus sur la fiche et cr\xE9er les comp\xE9tences ad\xE9quates.

    Voie de la fusion lycanthropique

      -
    1. Lycanthropie : !cof-effet-temp lycanthropie [[5*@{selected|SAG}]]. Si vous souhaitez un changement d'image du token, utilisez un token à plusieurs faces. Dans la liste des faces, en partant de 0, on note n le numéro de la face qui contient l'image de loup-garou. Ajoutez alors --tokenSide n à la commande. Par exemple, si la première face est l'image normale du personnage, et la seconde face celle d'un loup-garou, on pourra utiliser !cof-effet-temp lycanthropie [[5*@{selected|SAG}]] --tokenSide 1.
    2. -
    3. Éventration : ajouter un prédicat lycanthropeEventre.
    4. +
    5. Lycanthropie : !cof-effet-temp lycanthropie [[5*@{selected|SAG}]]. Si vous souhaitez un changement d'image du token, utilisez un token \xE0 plusieurs faces. Dans la liste des faces, en partant de 0, on note n le num\xE9ro de la face qui contient l'image de loup-garou. Ajoutez alors --tokenSide n \xE0 la commande. Par exemple, si la premi\xE8re face est l'image normale du personnage, et la seconde face celle d'un loup-garou, on pourra utiliser !cof-effet-temp lycanthropie [[5*@{selected|SAG}]] --tokenSide 1.
    6. +
    7. \xC9ventration : ajouter un pr\xE9dicat lycanthropeEventre.

    Voie de Morn

      -
    1. Secrets de l'au-delà : !cof-effet-temp secretsDeLAuDela 1 --mana 0
    2. +
    3. Secrets de l'au-del\xE0 : !cof-effet-temp secretsDeLAuDela 1 --mana 0
    4. Souffle de vie : !cof-soin @{selected|token_id} @{target|token_id} souffleDeVie --mana 0
    5. -
    6. Souffle de mort : faire une attaque magique, de portée 20 m (la portée par défaut pour les sorts, mais rien n'est spécifié dans le texte), de dégâts 2d8+INT. Ajoutez auto dans les modificateurs. Pour les options, --disque 10 souffleDeMort --effet souffleDeMort 1 --save CON 10 --mana 1.
    7. +
    8. Souffle de mort : faire une attaque magique, de port\xE9e 20 m (la port\xE9e par d\xE9faut pour les sorts, mais rien n'est sp\xE9cifi\xE9 dans le texte), de d\xE9g\xE2ts 2d8+INT. Ajoutez auto dans les modificateurs. Pour les options, --disque 10 souffleDeMort --effet souffleDeMort 1 --save CON 10 --mana 1.
    -

    Voie de Prestige spécialisée

    +

    Voie de Prestige sp\xE9cialis\xE9e

      -
    1. Expertise : ajouter un prédicat expertiseSpecialisee, de valeur soit une caractéristique, soit une compétence, soit un mot-clé pour une capacité. Pour l'instant, ne sont implémentés que la rage du berserk (rageDuBerserk) et la furie du berserk (furieDuBerserk).
    2. +
    3. Expertise : ajouter un pr\xE9dicat expertiseSpecialisee, de valeur soit une caract\xE9ristique, soit une comp\xE9tence, soit un mot-cl\xE9 pour une capacit\xE9. Pour l'instant, ne sont impl\xE9ment\xE9s que la rage du berserk (rageDuBerserk) et la furie du berserk (furieDuBerserk).
    -

    Voie de Périndé

    +

    Voie de P\xE9rind\xE9

    1. Soutient
    2. -
    3. Présence réconfortante
    4. +
    5. Pr\xE9sence r\xE9confortante
    6. Prendre sur soit
    7. -
    8. Défendre les siens
    9. -
    10. Don de soi : !cof-soin @{selected|token_id} ?{Nombre de dés?|1|2|3|4|5}d6 --allies 10 --sacrifierPV --mana 3
    11. +
    12. D\xE9fendre les siens
    13. +
    14. Don de soi : !cof-soin @{selected|token_id} ?{Nombre de d\xE9s?|1|2|3|4|5}d6 --allies 10 --sacrifierPV --mana 3
    -

    Voie des armes à deux mains

    +

    Voie des armes \xE0 deux mains

      -
    1. Allonge : reporter le bonus d'attaque sur la fiche. Par facilité, j'ai considéré que le bonus d'Init était permanent et nous l'avons reporté sur la fiche.
    2. -
    3. Gros Monstre, grosse arme : ajouter un prédicat grosMonstreGrosseArme.
    4. -
    5. Tenir à distance (L) : !cof-effet-temp tenirADistance 1.
    6. -
    7. Attaque à outrance : !cof-attaque-a-outrance ?{Attaque à outrance ?|Non,0|-2 DEF / +1D6 DM,2}. Par facilité, cette "posture de combat" perdure jusqu'à la fin du combat ou jusqu'à ce que le guerrier en change. Au rang 5, on pourra utiliser !cof-attaque-a-outrance ?{Attaque à outrance ?|Non,0|-2 DEF/+1D6 DM,2|-5 DEF/+2D6 DM,5}
    8. -
    9. Critique destructeur : ajouter --plusCrit 2d6 aux attaques d'armes à 2 mains
    10. +
    11. Allonge : reporter le bonus d'attaque sur la fiche. Par facilit\xE9, j'ai consid\xE9r\xE9 que le bonus d'Init \xE9tait permanent et nous l'avons report\xE9 sur la fiche.
    12. +
    13. Gros Monstre, grosse arme : ajouter un pr\xE9dicat grosMonstreGrosseArme.
    14. +
    15. Tenir \xE0 distance (L) : !cof-effet-temp tenirADistance 1.
    16. +
    17. Attaque \xE0 outrance : !cof-attaque-a-outrance ?{Attaque \xE0 outrance ?|Non,0|-2 DEF / +1D6 DM,2}. Par facilit\xE9, cette "posture de combat" perdure jusqu'\xE0 la fin du combat ou jusqu'\xE0 ce que le guerrier en change. Au rang 5, on pourra utiliser !cof-attaque-a-outrance ?{Attaque \xE0 outrance ?|Non,0|-2 DEF/+1D6 DM,2|-5 DEF/+2D6 DM,5}
    18. +
    19. Critique destructeur : ajouter --plusCrit 2d6 aux attaques d'armes \xE0 2 mains

    Voie des vermines

      -
    1. Nuée de criquets : ajouter une attaque magique, de portée 20 m, type Sortilege, modificateur pasDeDmg et options --effet nueeDeCriquets [[5+@{selected|SAG}]]. Pas de support particulier pour les DM de zone qui détruisent la nuée (enlever l'attribut nueeDeCriquets sur la cible dans ce cas).
    2. +
    3. Nu\xE9e de criquets : ajouter une attaque magique, de port\xE9e 20 m, type Sortilege, modificateur pasDeDmg et options --effet nueeDeCriquets [[5+@{selected|SAG}]]. Pas de support particulier pour les DM de zone qui d\xE9truisent la nu\xE9e (enlever l'attribut nueeDeCriquets sur la cible dans ce cas).

    Voie du chasseur de corruption

    -

    Pour savoir si une cible est corrompue, le script va utiliser un prédicat corrompu qu'il appartient au MJ d'ajouter pour les créatures selon ses critères.

    +

    Pour savoir si une cible est corrompue, le script va utiliser un pr\xE9dicat corrompu qu'il appartient au MJ d'ajouter pour les cr\xE9atures selon ses crit\xE8res.

    1. Sentir la corruption : !cof-sentir-la-corruption @{selected|token_id} @{target|token_id}.
    2. -
    3. Combattre la corruption : ajouter un prédicat combattreLaCorruption. Y associer la valeur 2 au rang 4 dans la voie.
    4. -
    5. Chasseur de sorcière : ajouter un prédicat chasseurDeSorciere. Pour reconnaître les nécromanciens et autres prêtres maléfiques, il faut aussi leur ajouter un prédicat necromancien.
    6. -
    7. Frappe préventive : pas de support du script.
    8. +
    9. Combattre la corruption : ajouter un pr\xE9dicat combattreLaCorruption. Y associer la valeur 2 au rang 4 dans la voie.
    10. +
    11. Chasseur de sorci\xE8re : ajouter un pr\xE9dicat chasseurDeSorciere. Pour reconna\xEEtre les n\xE9cromanciens et autres pr\xEAtres mal\xE9fiques, il faut aussi leur ajouter un pr\xE9dicat necromancien.
    12. +
    13. Frappe pr\xE9ventive : pas de support du script.

    Voie du chevalier dragon

      -
    1. Ordre du chevalier dragon : créer les compétences Persuasion et Intimidation avec les bonus de base de +5. Ajouter un prédicat ordreDuChevalierDragon. Quand le personnage est monté, le script rajoutera automatiquement un bonus de +5 via !cof-jet
    2. -
    3. Épée de feu : !cof-effet-temp armeEnflammee [[5+@{selected|CHA}]] --lanceur @{selected|token_id} --target @{selected|token_id}. Ne se cumule pas avec l'Arme enflammée du Magicien.
    4. -
    5. Résistance au feu : rajouter feu:5 (ou 10 au rang 5) dans la partie RD de la fiche
    6. +
    7. Ordre du chevalier dragon : cr\xE9er les comp\xE9tences Persuasion et Intimidation avec les bonus de base de +5. Ajouter un pr\xE9dicat ordreDuChevalierDragon. Quand le personnage est mont\xE9, le script rajoutera automatiquement un bonus de +5 via !cof-jet
    8. +
    9. \xC9p\xE9e de feu : !cof-effet-temp armeEnflammee [[5+@{selected|CHA}]] --lanceur @{selected|token_id} --target @{selected|token_id}. Ne se cumule pas avec l'Arme enflamm\xE9e du Magicien.
    10. +
    11. R\xE9sistance au feu : rajouter feu:5 (ou 10 au rang 5) dans la partie RD de la fiche
    12. Monture puissante : modifier la fiche du Drake
    13. -
    14. Souffle enflammé : ajouter une attaque au dragon, même jet pour touche, dm 2d6, portée 40, arme naturelle qui inflige des dégâts de feu, avec comme options --disque 3 --dmSiRate 1d6 --dmCible 4d6
    15. +
    16. Souffle enflamm\xE9 : ajouter une attaque au dragon, m\xEAme jet pour touche, dm 2d6, port\xE9e 40, arme naturelle qui inflige des d\xE9g\xE2ts de feu, avec comme options --disque 3 --dmSiRate 1d6 --dmCible 4d6
    -

    Voie du combat à deux armes

    +

    Voie du combat \xE0 deux armes

      -
    1. Combat à deux armes amélioré : mettre une des attaques de type arme gauche, et y ajouter le modificateur avecd12crit. Pas encore de support pour la capacité avancée : dans ce cas, ajoutez le +1 dans la barre 3 du token ou sur les attaques.
    2. -
    3. Parade croisée : !cof-effet-temp paradeCroisee 1 --valeur rang --montreActionsrang est le rang dans la Voie.
    4. +
    5. Combat \xE0 deux armes am\xE9lior\xE9 : mettre une des attaques de type arme gauche, et y ajouter le modificateur avecd12crit. Pas encore de support pour la capacit\xE9 avanc\xE9e : dans ce cas, ajoutez le +1 dans la barre 3 du token ou sur les attaques.
    6. +
    7. Parade crois\xE9e : !cof-effet-temp paradeCroisee 1 --valeur rang --montreActions o\xF9 rang est le rang dans la Voie.

    Voie du danseur de guerre

      -
    1. Pirouettes : on peut rajouter les bonus sur la fiche, ou bien ajouter un prédicat pirouettes, de valeur le bonus en défense (qui ne s'applique que si le malus d'armure est inférieur à 4).
    2. -
    3. Vent des lames : pas de support du script, simplement ajouter les attaques adaptées sur la fiche
    4. +
    5. Pirouettes : on peut rajouter les bonus sur la fiche, ou bien ajouter un pr\xE9dicat pirouettes, de valeur le bonus en d\xE9fense (qui ne s'applique que si le malus d'armure est inf\xE9rieur \xE0 4).
    6. +
    7. Vent des lames : pas de support du script, simplement ajouter les attaques adapt\xE9es sur la fiche
    8. Attaque en mouvement : pas de support du script.
    9. -
    10. Danse des lames : !cof-effet-combat danseDesLames. Pour l'attaque gratuite supplémentaire, on peut faire #Attaque -1 --si etat danseDesLames --avecd12crit.
    11. +
    12. Danse des lames : !cof-effet-combat danseDesLames. Pour l'attaque gratuite suppl\xE9mentaire, on peut faire #Attaque -1 --si etat danseDesLames --avecd12crit.

    Voie du familier fantastique

      -
    1. Familier fantastique : créer un personnage (de type PNJ) pour le familier, controlé par le joueur et avec un token lié ayant la capacité de voir. +
    2. Familier fantastique : cr\xE9er un personnage (de type PNJ) pour le familier, control\xE9 par le joueur et avec un token li\xE9 ayant la capacit\xE9 de voir.
        -
      • Pour le bonus en initiative, ajouter au personnage un prédicat familier de valeur le nom du compagnon (doit être exactement le même que celui du token du compagnon). Cela automatise l'initiative quand le familier est présent.
      • -
      • Pour les points de vie partagés avec le familier, il faut mettre un prédicat PVPartagesAvec de valeur le nom du familier (celui de la fiche, pas forcément le même que le token) pour le personnage, et un prédicat similaire chez le familier, de valeur le nom du personnage. Le partage de PVs ne fonctionne pas avec des mooks, et il ne fait pas le partage de dégâts temporaires. En revanche, le script devrait gérer correctement les dégâts de zone.
      • -
      • Pour la défense du familier, ajouter lui un prédicat defDeriveeDe, de valeur le nom du personnage (nom complet sur la fiche, attention à bien utiliser la syntaxe avec :: si ce nom contient des espaces ou d'autres caractères spéciaux).
      • -
      • Pour l'initiative, ajoutez un prédicat initiativeDeriveeDe de valeur le nom du personnage.
      • +
      • Pour le bonus en initiative, ajouter au personnage un pr\xE9dicat familier de valeur le nom du compagnon (doit \xEAtre exactement le m\xEAme que celui du token du compagnon). Cela automatise l'initiative quand le familier est pr\xE9sent.
      • +
      • Pour les points de vie partag\xE9s avec le familier, il faut mettre un pr\xE9dicat PVPartagesAvec de valeur le nom du familier (celui de la fiche, pas forc\xE9ment le m\xEAme que le token) pour le personnage, et un pr\xE9dicat similaire chez le familier, de valeur le nom du personnage. Le partage de PVs ne fonctionne pas avec des mooks, et il ne fait pas le partage de d\xE9g\xE2ts temporaires. En revanche, le script devrait g\xE9rer correctement les d\xE9g\xE2ts de zone.
      • +
      • Pour la d\xE9fense du familier, ajouter lui un pr\xE9dicat defDeriveeDe, de valeur le nom du personnage (nom complet sur la fiche, attention \xE0 bien utiliser la syntaxe avec :: si ce nom contient des espaces ou d'autres caract\xE8res sp\xE9ciaux).
      • +
      • Pour l'initiative, ajoutez un pr\xE9dicat initiativeDeriveeDe de valeur le nom du personnage.
    3. Pouvoir mineur :
        -
      • Minimoi (Égocentrisme) : Téléportation, pas de support.
      • +
      • Minimoi (\xC9gocentrisme) : T\xE9l\xE9portation, pas de support.
    4. Canalisation : Lancer l'attaque avec l'option --canaliseParFamilier.
    5. -
    6. Pouvoir supérieur : +
    7. Pouvoir sup\xE9rieur :
        -
      • Minimoi (Clone) : à faire.
      • +
      • Minimoi (Clone) : \xE0 faire.
    @@ -2204,324 +2208,326 @@

    Voie du gel

    1. -
    2. Cône de froid : faire une attaque portee 20m, dégâts 2d6+INT de froid, avec comme modificateur auto et comme options --cone 30 --fx breath-frost --ifSaveFails CON 13 --effet ralenti 1 --else --diviseDmg 2 --endif. Pour un objet de sort : !cof-attack @{selected|token_id} @{target|token_id} Cône de froid --sortilege --auto --dm 2d6+[[@{selected|INT}]] --froid --portee 20 --cone 30 --fx breath-frost --ifSaveFails CON 13 --effet ralentiTemp 1 --else --diviseDmg 2 --endif
    3. -
    4. Présence glaciale : !cof-effet presenceGlaciale oui. Utiliser !cof-effet presenceGlaciale non pour mettre fin à l'effet. On peut préciser un bonus de DEF et des dégâts différents avec l'option --valeur. Ainsi, la version grimoire sera !cof-effet presenceGlaciale oui --valeur 3 1d4.
    5. +
    6. C\xF4ne de froid : faire une attaque portee 20m, d\xE9g\xE2ts 2d6+INT de froid, avec comme modificateur auto et comme options --cone 30 --fx breath-frost --ifSaveFails CON 13 --effet ralenti 1 --else --diviseDmg 2 --endif. Pour un objet de sort : !cof-attack @{selected|token_id} @{target|token_id} C\xF4ne de froid --sortilege --auto --dm 2d6+[[@{selected|INT}]] --froid --portee 20 --cone 30 --fx breath-frost --ifSaveFails CON 13 --effet ralentiTemp 1 --else --diviseDmg 2 --endif
    7. +
    8. Pr\xE9sence glaciale : !cof-effet presenceGlaciale oui. Utiliser !cof-effet presenceGlaciale non pour mettre fin \xE0 l'effet. On peut pr\xE9ciser un bonus de DEF et des d\xE9g\xE2ts diff\xE9rents avec l'option --valeur. Ainsi, la version grimoire sera !cof-effet presenceGlaciale oui --valeur 3 1d4.
    -

    Voie du guérisseur

    +

    Voie du gu\xE9risseur

      -
    1. Premiers soins : ajouter un prédicat voieDuGuerisseur de valeur le rang dans cette voie pour le bonus aux soins de la Voie des soins. Pour le sort, faire !cof-soin @{selected|token_id} @{target|token_id} premiersSoins --mana 0.
    2. -
    3. Immunité : utilisez !cof-immunite-guerisseur [[1d6+@{selected|SAG}]] --mana 0 --target @{target|token_id} dans les actions du tour. Si utilisé directement dans le chat, ajoutez --lanceur @{selected|token_id}.
    4. +
    5. Premiers soins : ajouter un pr\xE9dicat voieDuGuerisseur de valeur le rang dans cette voie pour le bonus aux soins de la Voie des soins. Pour le sort, faire !cof-soin @{selected|token_id} @{target|token_id} premiersSoins --mana 0.
    6. +
    7. Immunit\xE9 : utilisez !cof-immunite-guerisseur [[1d6+@{selected|SAG}]] --mana 0 --target @{target|token_id} dans les actions du tour. Si utilis\xE9 directement dans le chat, ajoutez --lanceur @{selected|token_id}.
    8. Soins rapides : pas de support au niveau du script.
    9. -
    10. Zone de vie : !cof-zone-de-vie [[1d6+@{selected|SAG}]] --mana 1 --limiteParJour 3 --lanceur @{selected|token_id}. Cela devrait respecter le sort, sauf pour le moment où le soin prend effet : c'est au début de chaque tour du prêtre.
    11. +
    12. Zone de vie : !cof-zone-de-vie [[1d6+@{selected|SAG}]] --mana 1 --limiteParJour 3 --lanceur @{selected|token_id}. Cela devrait respecter le sort, sauf pour le moment o\xF9 le soin prend effet : c'est au d\xE9but de chaque tour du pr\xEAtre.

    Voie du guerrier-mage

    -

    Penser à utiliser l'option --magieEnArmure pour le lancement des sorts affectés.

    +

    Penser \xE0 utiliser l'option --magieEnArmure pour le lancement des sorts affect\xE9s.

      -
    1. Magie en armure : Ajouter un prédicat magieEnArmure de valeur la DEF totale à partir de laquelle le personnage peut lancer des sorts. Comme la fiche ne contient pas l'information de la DEF normale (sans magie) de l'armure portée, le script utilise la moyenne de la DEF et du malus d'armure. En ajoutant un prédicat magieEnArmureFacilitee, le script diminue aussi la difficulté des jets d'INT pour les armures avec une DEF trop grande de la valeur du prédicat de magie en armure.
    2. -
    3. Rituel Assuré : !cof-effet-temp rituelAssure 2 --mana 0. Le script ne permet pas de préciser le sort, le premier qui sera lancé après le rituel assuré bénéficiera de l'effet.
    4. -
    5. MagieDeCombat : Ajouter un prédicat magieDeCombat.
    6. +
    7. Magie en armure : Ajouter un pr\xE9dicat magieEnArmure de valeur la DEF totale \xE0 partir de laquelle le personnage peut lancer des sorts. Comme la fiche ne contient pas l'information de la DEF normale (sans magie) de l'armure port\xE9e, le script utilise la moyenne de la DEF et du malus d'armure. En ajoutant un pr\xE9dicat magieEnArmureFacilitee, le script diminue aussi la difficult\xE9 des jets d'INT pour les armures avec une DEF trop grande de la valeur du pr\xE9dicat de magie en armure.
    8. +
    9. Rituel Assur\xE9 : !cof-effet-temp rituelAssure 2 --mana 0. Le script ne permet pas de pr\xE9ciser le sort, le premier qui sera lanc\xE9 apr\xE8s le rituel assur\xE9 b\xE9n\xE9ficiera de l'effet.
    10. +
    11. MagieDeCombat : Ajouter un pr\xE9dicat magieDeCombat.
    12. Frappe des arcanes : faire une attaque avec l'option --frappeDesArcanes, par exemple dans une action dont le code serait #Attaque -1 --frappeDesArcanes.
    13. +
    14. Expertise du combat : aucun support du script.
    -

    Voie du héro

    +

    Voie du h\xE9ro

      -
    1. Destin héroïque : ajouter le bonus au bonus de points de chances sur la fiche (utiliser la roue crantée à droite de la section CHANCE de la fiche).
    2. -
    3. Ténacité : ajouter un prédicat tenacite.
    4. +
    5. Destin h\xE9ro\xEFque : ajouter le bonus au bonus de points de chances sur la fiche (utiliser la roue crant\xE9e \xE0 droite de la section CHANCE de la fiche).
    6. +
    7. T\xE9nacit\xE9 : ajouter un pr\xE9dicat tenacite.
    8. Homme de la situation : pas de support.
    9. -
    10. Meneur d'hommes : Ajouter une action : !cof-set-attribute meneurDHommesCible @{selected|token_id} --target @{target|token_id}. Le personnage peut utiliser cette action pour désigner sa cible. Tous les alliés du personnage recevront automatiquement les bonus sur le reste du combat.
    11. +
    12. Meneur d'hommes : Ajouter une action : !cof-set-attribute meneurDHommesCible @{selected|token_id} --target @{target|token_id}. Le personnage peut utiliser cette action pour d\xE9signer sa cible. Tous les alli\xE9s du personnage recevront automatiquement les bonus sur le reste du combat.
    -

    Voie du maître des poisons

    +

    Voie du ma\xEEtre des poisons

    Rappel : pour appliquer un poison, utiliser !cof-enduire-poison -1 type force save.
      -
    1. Connaissance du poison : ajouter un prédicat connaissanceDuPoison pour éviter le test d'INT quand le voleur applique du poison.
    2. -
    3. Poison rapide : faire les applications à la main (!cof-enduire-poison L rapide 2d6 12).
    4. -
    5. Poison affaiblissant : faire les applications à la main (!cof-enduire-poison L affaiblissant 0 15).
    6. +
    7. Connaissance du poison : ajouter un pr\xE9dicat connaissanceDuPoison pour \xE9viter le test d'INT quand le voleur applique du poison.
    8. +
    9. Poison rapide : faire les applications \xE0 la main (!cof-enduire-poison L rapide 2d6 12).
    10. +
    11. Poison affaiblissant : faire les applications \xE0 la main (!cof-enduire-poison L affaiblissant 0 15).

    Voie du messager

    1. Muet comme une tombe : pas de support pour l'instant.
    2. -
    3. Jusqu'à bon port : ajouter les compétences correspondantes sur la fiche.
    4. -
    5. Conducteur de diligence : ajouter les compétences, et en cas de combat depuis une diligence, utiliser la barre 3 pour le bonus à l'attaque.
    6. +
    7. Jusqu'\xE0 bon port : ajouter les comp\xE9tences correspondantes sur la fiche.
    8. +
    9. Conducteur de diligence : ajouter les comp\xE9tences, et en cas de combat depuis une diligence, utiliser la barre 3 pour le bonus \xE0 l'attaque.
    10. Sens du devoir : Activer avec !cof-effet sensDuDevoir true. On peut enlever cet effet depuis le statut, au changement de jour, ou avec la commande !cof-effet sensDuDevoir false.
    11. Attaque en mouvement : pas de support pour l'instant.

    Voie du pacte vampirique

      -
    1. Blessure sanglante : ajuter un prédicat blessureSanglante.
    2. -
    3. Sang puissant : ajouter un prédicat immuniteSaignement et un prédicat immuniteAbsorptionVampire.
    4. -
    5. Drain de sang : ajouter un prédicat drainDeSang.
    6. -
    7. Flot de sang : associer la valeur 2 au prédicat blessureSanglante.
    8. -
    9. Énergie impie : ajouter un prédicat energieImpie.
    10. +
    11. Blessure sanglante : ajuter un pr\xE9dicat blessureSanglante.
    12. +
    13. Sang puissant : ajouter un pr\xE9dicat immuniteSaignement et un pr\xE9dicat immuniteAbsorptionVampire.
    14. +
    15. Drain de sang : ajouter un pr\xE9dicat drainDeSang.
    16. +
    17. Flot de sang : associer la valeur 2 au pr\xE9dicat blessureSanglante.
    18. +
    19. \xC9nergie impie : ajouter un pr\xE9dicat energieImpie.

    Voie du porteur de bouclier

      -
    1. Expertise du bouclier : reporter le bonus sur la fiche dans le bonus de DEF conféré par le bouclier.
    2. -
    3. Progresser à couvert : !cof-effet-temp progresserACouvert 1 --lanceur @{selected|token_id} --target @{target|token_id} --self --portee 1. A utiliser pour cibler un allié à portée si nécessaire. Au MJ de vérifier qu'elle reste bien près du chevalier pour profiter du bonus.
    4. -
    5. Attaque au bouclier : Ajouter une arme avec son Bouclier en "Arme gauche" sur la fiche du personnage. Dans les modificateurs de l'arme, ajoutez avecd12crit. Pour que cette attaque soit proposée dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un prédicat attaqueAuBouclier de valeur le label de l'attaque.
    6. -
    7. Dévier les coups : Ajouter un prédicat devierLesCoups (on peut y associer un nombre, si on souhaite plus d'une utlisation par tour). Le script ajoute automatiquement un bouton sur les attaques sur lesquelles cette capacité peut-être utilisée.
    8. -
    9. Parade au bouclier : Ajouter un prédicat paradeAuBouclier. Sur l'ability Coup de bouclier créé pour le rang 3, ajouter --attaqueBouclierRenverse --decrLimitePredicatParTour paradeAuBouclier. Le script ajoute automatiquement un bouton sur les attaques sur lesquelles cette capacité peut-être utilisée. Si le personnage possède un bouclier en arme gauche, le script utilisera le bonus éventuel de l'arme en question sur le jet opposé.
    10. +
    11. Expertise du bouclier : reporter le bonus sur la fiche dans le bonus de DEF conf\xE9r\xE9 par le bouclier.
    12. +
    13. Progresser \xE0 couvert : !cof-effet-temp progresserACouvert 1 --lanceur @{selected|token_id} --target @{target|token_id} --self --portee 1. A utiliser pour cibler un alli\xE9 \xE0 port\xE9e si n\xE9cessaire. Au MJ de v\xE9rifier qu'elle reste bien pr\xE8s du chevalier pour profiter du bonus.
    14. +
    15. Attaque au bouclier : Ajouter une arme avec son Bouclier en "Arme gauche" sur la fiche du personnage. Dans les modificateurs de l'arme, ajoutez avecd12crit. Pour que cette attaque soit propos\xE9e dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un pr\xE9dicat attaqueAuBouclier de valeur le label de l'attaque.
    16. +
    17. D\xE9vier les coups : Ajouter un pr\xE9dicat devierLesCoups (on peut y associer un nombre, si on souhaite plus d'une utlisation par tour). Le script ajoute automatiquement un bouton sur les attaques sur lesquelles cette capacit\xE9 peut-\xEAtre utilis\xE9e.
    18. +
    19. Parade au bouclier : Ajouter un pr\xE9dicat paradeAuBouclier. Sur l'ability Coup de bouclier cr\xE9\xE9 pour le rang 3, ajouter --attaqueBouclierRenverse --decrLimitePredicatParTour paradeAuBouclier. Le script ajoute automatiquement un bouton sur les attaques sur lesquelles cette capacit\xE9 peut-\xEAtre utilis\xE9e. Si le personnage poss\xE8de un bouclier en arme gauche, le script utilisera le bonus \xE9ventuel de l'arme en question sur le jet oppos\xE9.
    -

    Voie du tueur de géant

    +

    Voie du tueur de g\xE9ant

      -
    1. Réduire la distance : ajouter un prédicat reduireLaDistance.
    2. -
    3. Ventre mou : ajouter un prédicat ventreMou. Cela va diminuer la RD fixe de 3 maximum pour une créature grande, 6 maximum pour une créature énorme et 10 maximum pour une créature colossale.
    4. -
    5. Bûcheron : ajouter un prédicat bucheron.
    6. +
    7. R\xE9duire la distance : ajouter un pr\xE9dicat reduireLaDistance.
    8. +
    9. Ventre mou : ajouter un pr\xE9dicat ventreMou. Cela va diminuer la RD fixe de 3 maximum pour une cr\xE9ature grande, 6 maximum pour une cr\xE9ature \xE9norme et 10 maximum pour une cr\xE9ature colossale.
    10. +
    11. B\xFBcheron : ajouter un pr\xE9dicat bucheron.
    -

    Capacités épiques

    +

    Capacit\xE9s \xE9piques

      -
    • Libérateur de Dorn : ajouter un prédicat liberateurDeDorn.
    • -
    • Libérateur de Kerserac : ajouter un prédicat liberateurDeKerserac.
    • -
    • Libérateur d'Anathazerïn : ajouter un prédicat liberateurDAnathazerin. La capacité donne le bonus de +2 quel que soit le poison.
    • -
    • Lien épique: ajouter pour chaque personnage un prédicat lienEpique, qui contiennent la même chose dans le champ courant (pensez à un nom d'équipe, par exemple).
    • -
    • Vitalité épique : ajouter un prédicat vitaliteEpique. Pas de support pour le coup mortel ou la régénération horaire. Attention, si vous utlisez !cof-soin pour cette régénération, les soins seront aussi doublés.
    • +
    • Lib\xE9rateur de Dorn : ajouter un pr\xE9dicat liberateurDeDorn.
    • +
    • Lib\xE9rateur de Kerserac : ajouter un pr\xE9dicat liberateurDeKerserac.
    • +
    • Lib\xE9rateur d'Anathazer\xEFn : ajouter un pr\xE9dicat liberateurDAnathazerin. La capacit\xE9 donne le bonus de +2 quel que soit le poison.
    • +
    • Lien \xE9pique: ajouter pour chaque personnage un pr\xE9dicat lienEpique, qui contiennent la m\xEAme chose dans le champ courant (pensez \xE0 un nom d'\xE9quipe, par exemple).
    • +
    • Vitalit\xE9 \xE9pique : ajouter un pr\xE9dicat vitaliteEpique. Pas de support pour le coup mortel ou la r\xE9g\xE9n\xE9ration horaire. Attention, si vous utlisez !cof-soin pour cette r\xE9g\xE9n\xE9ration, les soins seront aussi doubl\xE9s.
    -

    4.3 Voies de créatures

    +

    4.3 Voies de cr\xE9atures

    Voie du champion

    1. Imparable:
        -
      • Utiliser l'option --m2d20 pour l'action limitée.
      • -
      • Pour l'effet permanent, utiliser un prédicat champion
      • +
      • Utiliser l'option --m2d20 pour l'action limit\xE9e.
      • +
      • Pour l'effet permanent, utiliser un pr\xE9dicat champion
    2. -
    3. Riposte : Ajouter un prédicat riposte. Les actions affichées en cas de riposte seront normalement une attaque avec l'arme en main si il y en a, plus les attaques naturelles cochées sur la liste d'attaque. Si ça ne convient pas, vous pouvez écrire une liste d'actions nomméeRipostes (voir les actions du tour).
    4. -
    5. Hausser le ton : ajouter un prédicat hausserLeTon.
    6. +
    7. Riposte : Ajouter un pr\xE9dicat riposte. Les actions affich\xE9es en cas de riposte seront normalement une attaque avec l'arme en main si il y en a, plus les attaques naturelles coch\xE9es sur la liste d'attaque. Si \xE7a ne convient pas, vous pouvez \xE9crire une liste d'actions nomm\xE9eRipostes (voir les actions du tour).
    8. +
    9. Hausser le ton : ajouter un pr\xE9dicat hausserLeTon.
    -

    Voie du chef d'armée

    +

    Voie du chef d'arm\xE9e

      -
    1. Sergent : ne pas oublier l'action de plus donnée à un allié par tour. Utiliser un prédicat sergent (pour l'attaque ignorée par combat)
    2. -
    3. Capitaine : pour désigner le capitaine d'un ensemble de tokens sélectionné (quelle que soit la méthode), on peut utiliser !cof-capitaine @{selected|token_id} 2, en ajoutant les options de sélection (comme --target @{target|token_id}). Au lieu de sélectionner une cible, on peut utiliser le nom d'un token. Si le capitaine fait parti de la sélection, il sera automatiquement exclu (on ne peut être son propre capitaine). Si à la place de 2, le deuxième argument est 0, cela enlève le capitaine. L'attribut généré est lié à un personnage, pas un token spécifique, il suffit donc de cibler un token représentant un personnage pour affecter tous les tokens qui représentent ce personnage. Pas de support particulier pour l'attaque supplémentaire en cas d'action limitée.
    4. -
    5. Commandant : il faut ajouter un prédicat commandant. La méthode pour désigner les personnages sous les ordres du commandant est la même que pour le capitaine : !cof-capitaine @{selected|token_id} 3 (notez que la valeur est 3 pour le commandant, et 2 pour le capitaine).
    6. +
    7. Sergent : ne pas oublier l'action de plus donn\xE9e \xE0 un alli\xE9 par tour. Utiliser un pr\xE9dicat sergent (pour l'attaque ignor\xE9e par combat)
    8. +
    9. Capitaine : pour d\xE9signer le capitaine d'un ensemble de tokens s\xE9lectionn\xE9 (quelle que soit la m\xE9thode), on peut utiliser !cof-capitaine @{selected|token_id} 2, en ajoutant les options de s\xE9lection (comme --target @{target|token_id}). Au lieu de s\xE9lectionner une cible, on peut utiliser le nom d'un token. Si le capitaine fait parti de la s\xE9lection, il sera automatiquement exclu (on ne peut \xEAtre son propre capitaine). Si \xE0 la place de 2, le deuxi\xE8me argument est 0, cela enl\xE8ve le capitaine. L'attribut g\xE9n\xE9r\xE9 est li\xE9 \xE0 un personnage, pas un token sp\xE9cifique, il suffit donc de cibler un token repr\xE9sentant un personnage pour affecter tous les tokens qui repr\xE9sentent ce personnage. Pas de support particulier pour l'attaque suppl\xE9mentaire en cas d'action limit\xE9e.
    10. +
    11. Commandant : il faut ajouter un pr\xE9dicat commandant. La m\xE9thode pour d\xE9signer les personnages sous les ordres du commandant est la m\xEAme que pour le capitaine : !cof-capitaine @{selected|token_id} 3 (notez que la valeur est 3 pour le commandant, et 2 pour le capitaine).

    Voie du cogneur

    1. Charge : Faire l'attaque avec les arguments --m2d20 --pietine.
    2. -
    3. Enrager : ajouter un prédicat peutEnrager.
    4. +
    5. Enrager : ajouter un pr\xE9dicat peutEnrager.
    6. Percuter : Remplacer --pietine par --percute dans l'attaque de Charge.

    Voie du colosse

      -
    1. Fauchage : ajouter la RD, et ajouter un prédicat fauchage, qui va faire automatiquement le renversement si le dé d'attaque est entre 15 et 20. Il est possible de changer ce seuil associant au prédicat la valeur à laquelle le dé d'attaque provoque le renversement (15 par défaut). Par défaut, le fauchage est impossible si la taille du défenseur est supérieure ou égale à celle de l'attaquant. Vous pouvez spécifier un seuil de taille maximale dans un prédicat tailleFauchage (5 = grand, 6 énorme et 7 colossal).
    2. +
    3. Fauchage : ajouter la RD, et ajouter un pr\xE9dicat fauchage, qui va faire automatiquement le renversement si le d\xE9 d'attaque est entre 15 et 20. Il est possible de changer ce seuil associant au pr\xE9dicat la valeur \xE0 laquelle le d\xE9 d'attaque provoque le renversement (15 par d\xE9faut). Par d\xE9faut, le fauchage est impossible si la taille du d\xE9fenseur est sup\xE9rieure ou \xE9gale \xE0 celle de l'attaquant. Vous pouvez sp\xE9cifier un seuil de taille maximale dans un pr\xE9dicat tailleFauchage (5 = grand, 6 \xE9norme et 7 colossal).
    4. Balayage : faire une version de l'attaque avec --target @{target|Cible 2|token_id}
    5. -
    6. Projection : ajouter un prédicat projection.
    7. +
    8. Projection : ajouter un pr\xE9dicat projection.
    -

    Voie des créatures élémentaires

    -

    Ajouter un prédicat immunite_type, où type est le type de la créature élémentaire (feu, acide, froid, ...)

    +

    Voie des cr\xE9atures \xE9l\xE9mentaires

    +

    Ajouter un pr\xE9dicat immunite_type, o\xF9 type est le type de la cr\xE9ature \xE9l\xE9mentaire (feu, acide, froid, ...)

      -
    1. Souffle : faire une attaque avec le bon nombre de d6 en DM, du type voulu, de portée la portée du souffle, à utiliser avec les modificateurs auto cone et les options --tempsRecharge rechargeSouffle [[1d4]] --psave DEX 13. Ne pas oublier la possibilité d'utiliser un token cible temporaire pour le cone.
    2. -
    3. Corps élémentaire : ajouter un prédicat corpsElementaire, de valeur l'élément (feu, froid,...). Cela va automatiquement ajouter les dégâts aux attaques de contact, et faire des dégâts à ceux qui l'attaquent au contact. Cela va aussi faire apparaître dans les actions du tour une action de régéneration, que le MJ peut utiliser chaque tour, à lui de voir si les conditions s'y prêtent (source élémentaire proche). Pas de support générique pour les victimes saisies ou agripper, à gérer au cas par cas.
    4. -
    5. Explosion finale : ajouter un prédicat explosionFinale de valeur le label de l'attaque d'explosion. Cette attaque ne doit contenir aucune demande de valeur (de type ?{Munitions}). Par exemple, pour une explosion finale qui fait 3d6 DM à tout le monde dans les 10 m et qui permettrait de diviser les dégâts par 2 par un test de DEX difficulte 13 (18 si au contact) : on crée une attaque Explosion, de dégâts 3d6 du type voulu, de portée 10, de modificateur auto et avec l'option --psave DEX 13 contact 18. Pour changer les dégâts du corps élémentaire, on peut utiliser un prédicat nbCorpsElementaire de valeur le nombre de d6 à utiliser (2 normalement pour cette capacité).
    6. +
    7. Souffle : faire une attaque avec le bon nombre de d6 en DM, du type voulu, de port\xE9e la port\xE9e du souffle, \xE0 utiliser avec les modificateurs auto cone et les options --tempsRecharge rechargeSouffle [[1d4]] --psave DEX 13. Ne pas oublier la possibilit\xE9 d'utiliser un token cible temporaire pour le cone.
    8. +
    9. Corps \xE9l\xE9mentaire : ajouter un pr\xE9dicat corpsElementaire, de valeur l'\xE9l\xE9ment (feu, froid,...). Cela va automatiquement ajouter les d\xE9g\xE2ts aux attaques de contact, et faire des d\xE9g\xE2ts \xE0 ceux qui l'attaquent au contact. Cela va aussi faire appara\xEEtre dans les actions du tour une action de r\xE9g\xE9neration, que le MJ peut utiliser chaque tour, \xE0 lui de voir si les conditions s'y pr\xEAtent (source \xE9l\xE9mentaire proche). Pas de support g\xE9n\xE9rique pour les victimes saisies ou agripp\xE9es, \xE0 g\xE9rer au cas par cas.
    10. +
    11. Explosion finale : ajouter un pr\xE9dicat explosionFinale de valeur le label de l'attaque d'explosion. Cette attaque ne doit contenir aucune demande de valeur (de type ?{Munitions}). Par exemple, pour une explosion finale qui fait 3d6 DM \xE0 tout le monde dans les 10 m et qui permettrait de diviser les d\xE9g\xE2ts par 2 par un test de DEX difficulte 13 (18 si au contact) : on cr\xE9e une attaque Explosion, de d\xE9g\xE2ts 3d6 du type voulu, de port\xE9e 10, de modificateur auto et avec l'option --psave DEX 13 contact 18. Pour changer les d\xE9g\xE2ts du corps \xE9l\xE9mentaire, on peut utiliser un pr\xE9dicat nbCorpsElementaire de valeur le nombre de d6 \xE0 utiliser (2 normalement pour cette capacit\xE9).
    -

    Voie des créatures magique

    +

    Voie des cr\xE9atures magique

      -
    1. Réduction des DM : Ajouter la RD sur la fiche 5/genre, où genre peut être magique ou un des types d'attaque (feu, acide, poison, etc...).
    2. -
    3. Vitalité surnaturelle : ajouter un prédicat vitaliteSurnaturelle, de valeur le nombre de PV régénéré par tour. Si la régénération doit continuer même à la mort du personnage, ajoutez un + à la fin de la valeur. Si un type de dégât empêche la régénération, faites suivre la valeur de régénération d'un / suivi du type (attention, ça ne peut pas être le type drain). Si plusieurs types de dégâts, les séparer par une virgule (et dans ce cas, penser à utiliser la syntaxe avec ::. Par exemple, un troll aura un prédicat vitaliteSurnaturelle:: 5+ / feu, acide, en faisant attention à ne rien mettre ensuite sur la même ligne. Si vous voulez réinitialiser les dégâts qui ne peuvent pas se régénérer sur un personnage, vous pouvez utiliser des soins normaux (!cof-soin), et si vous avez augmenté à la main les PVs, vous pouvez effacer les attributs DMSuivistype qui ont été créés par le script. Pour empêcher la régénération même mort, le mieux est d'enlever le token de la page (ou de le mettre en token générique).
    4. +
    5. R\xE9duction des DM : Ajouter la RD sur la fiche 5/genre, o\xF9 genre peut \xEAtre magique ou un des types d'attaque (feu, acide, poison, etc...).
    6. +
    7. Vitalit\xE9 surnaturelle : ajouter un pr\xE9dicat vitaliteSurnaturelle, de valeur le nombre de PV r\xE9g\xE9n\xE9r\xE9 par tour. Si la r\xE9g\xE9n\xE9ration doit continuer m\xEAme \xE0 la mort du personnage, ajoutez un + \xE0 la fin de la valeur. Si un type de d\xE9g\xE2t emp\xEAche la r\xE9g\xE9n\xE9ration, faites suivre la valeur de r\xE9g\xE9n\xE9ration d'un / suivi du type (attention, \xE7a ne peut pas \xEAtre le type drain). Si plusieurs types de d\xE9g\xE2ts, les s\xE9parer par une virgule (et dans ce cas, penser \xE0 utiliser la syntaxe avec ::. Par exemple, un troll aura un pr\xE9dicat vitaliteSurnaturelle:: 5+ / feu, acide, en faisant attention \xE0 ne rien mettre ensuite sur la m\xEAme ligne. Si vous voulez r\xE9initialiser les d\xE9g\xE2ts qui ne peuvent pas se r\xE9g\xE9n\xE9rer sur un personnage, vous pouvez utiliser des soins normaux (!cof-soin), et si vous avez augment\xE9 \xE0 la main les PVs, vous pouvez effacer les attributs DMSuivistype qui ont \xE9t\xE9 cr\xE9\xE9s par le script. Pour emp\xEAcher la r\xE9g\xE9n\xE9ration m\xEAme mort, le mieux est d'enlever le token de la page (ou de le mettre en token g\xE9n\xE9rique).
    -

    Voie des créatures volantes

    -

    On peut mettre un prédicat volant pour immuniser la créature à certains effets qui ne peuvent affecter que des créatures terrestres, comme l'armée des morts ou le croc-en-jambe.

    +

    Voie des cr\xE9atures volantes

    +

    On peut mettre un pr\xE9dicat volant pour immuniser la cr\xE9ature \xE0 certains effets qui ne peuvent affecter que des cr\xE9atures terrestres, comme l'arm\xE9e des morts ou le croc-en-jambe.

      -
    1. Vol rapide : simplement faire une variante de l'attaque avec les options --bonusAttaque 5 --plus 1d6 à utiliser le premier tour de combat si a créature est en vol et attaque une créature au sol. Ne pas oublier l'action de mouvement supplémentaire en vol.
    2. -
    3. Agripper : ajouter un prédicat agripper (ne fera agripper que sur les attaques de contact).
    4. +
    5. Vol rapide : simplement faire une variante de l'attaque avec les options --bonusAttaque 5 --plus 1d6 \xE0 utiliser le premier tour de combat si a cr\xE9ature est en vol et attaque une cr\xE9ature au sol. Ne pas oublier l'action de mouvement suppl\xE9mentaire en vol.
    6. +
    7. Agripper : ajouter un pr\xE9dicat agripper (ne fera agripper que sur les attaques de contact).

    Voie de la magie de combat

    1. Attaque magique : simplement une attaque, avec les options --sortilege --magique --fx beam-magic. Pour la version de zone, utiliser les options --disque 5 --auto --psave DEX 10.
    2. Armure magique : utiliser !cof-effet-combat armureMagique
    -

    Voie de la magie de guérison

    +

    Voie de la magie de gu\xE9rison

    1. Soigner : !cof-soin @{selected|token_id} @{target|target1|token_id} [[ceil(@{target|target1|PV|max}/2)]] --limiteCibleParJour 1
    2. -
    3. Guérir : !cof-guerir @{selected|token_id} @{target|token_id} --portee 0
    4. +
    5. Gu\xE9rir : !cof-guerir @{selected|token_id} @{target|token_id} --portee 0
    -

    Voie de la magie maléfique

    +

    Voie de la magie mal\xE9fique

    1. Vampirisation :
        -
      • Ajouter une attaque magique avec les DMs de vampirisation, faisant des dégâts de type drain. (En objet, on utilisera les options --sortilege et --drain).
      • -
      • Ajouter un prédicat siphonDesAmes, de valeur de NC de la créature (ou sans valeur, si le NC est 0). Si vous voulez que ce siphon empêche un autre siphon des âmes, rajoutez un prédicat siphonDesAmesPrioritaire de valeur un nombre positif et supérieur à ceux sur lequel il est prioritaire.
      • +
      • Ajouter une attaque magique avec les DMs de vampirisation, faisant des d\xE9g\xE2ts de type drain. (En objet, on utilisera les options --sortilege et --drain).
      • +
      • Ajouter un pr\xE9dicat siphonDesAmes, de valeur de NC de la cr\xE9ature (ou sans valeur, si le NC est 0). Si vous voulez que ce siphon emp\xEAche un autre siphon des \xE2mes, rajoutez un pr\xE9dicat siphonDesAmesPrioritaire de valeur un nombre positif et sup\xE9rieur \xE0 ceux sur lequel il est prioritaire.
    2. -
    3. Animer un cadavre : !cof-animer-cadavre @{selected|token_id} @{target|token_id}. Au cas où vous auriez besoin d'enlever l'état de cadavre, il suffit d'enlever l'attribut nommé cadavreAnime.
    4. +
    5. Animer un cadavre : !cof-animer-cadavre @{selected|token_id} @{target|token_id}. Au cas o\xF9 vous auriez besoin d'enlever l'\xE9tat de cadavre, il suffit d'enlever l'attribut nomm\xE9 cadavreAnime.
    6. Injonction Mortelle : !cof-injonction-mortelle @{selected|token_id} @{target|token_id}

    Voie de la meute

      -
    1. Intergeanchables : Utiliser un prédicat interchangeable, avec comme valeur le nombre d'opposants à partir duquel les cibles peuvent être interverties. Par défaut, cela va donner un bonus de +2 en DEF et +3 an attaque. Pour retrouver la valeur normale de +5 en DEF, utilisez !cof-options.
    2. -
    3. Attaque en traître : Au MJ de décider si une attaque est en traître ou pas. Pour une attaque en traître, rajouter les arguments --sournoise 2 --bonusAttaque 5.
    4. +
    5. Intergeanchables : Utiliser un pr\xE9dicat interchangeable, avec comme valeur le nombre d'opposants \xE0 partir duquel les cibles peuvent \xEAtre interverties. Par d\xE9faut, cela va donner un bonus de +2 en DEF et +3 an attaque. Pour retrouver la valeur normale de +5 en DEF, utilisez !cof-options.
    6. +
    7. Attaque en tra\xEEtre : Au MJ de d\xE9cider si une attaque est en tra\xEEtre ou pas. Pour une attaque en tra\xEEtre, rajouter les arguments --sournoise 2 --bonusAttaque 5.
    -

    Voie du PNJ récurrent

    +

    Voie du PNJ r\xE9current

      -
    1. Instinct de survie : ajouter un prédicat instinctDeSurvie avec comme valeur le nombre de PV en-dessous duquel le PNJ gagne un bonus de DEF. les autres effets sont à faire par le MJ.
    2. -
    3. Chair à canon : ajouter un prédicat chairACanon. Ajouter ensuite à tous ses sous-fifres un prédicat chairACanonDe de valeur le nom exact du token du PNJ. On peut y mettre plusieurs noms séparés par des virgules. Attention, dans ce cas (et aussi si le nom de token contient des espaces ou virgules, etc) pensez à utiliser :: au lieu de : pour le prédicat.
    4. +
    5. Instinct de survie : ajouter un pr\xE9dicat instinctDeSurvie avec comme valeur le nombre de PV en-dessous duquel le PNJ gagne un bonus de DEF. les autres effets sont \xE0 faire par le MJ.
    6. +
    7. Chair \xE0 canon : ajouter un pr\xE9dicat chairACanon. Ajouter ensuite \xE0 tous ses sous-fifres un pr\xE9dicat chairACanonDe de valeur le nom exact du token du PNJ. On peut y mettre plusieurs noms s\xE9par\xE9s par des virgules. Attention, dans ce cas (et aussi si le nom de token contient des espaces ou virgules, etc) pensez \xE0 utiliser :: au lieu de : pour le pr\xE9dicat.
    -

    Voie du prédateur

    +

    Voie du pr\xE9dateur

      -
    1. Embuscade : Sélectionner les ennemis du prédateurs, et utiliser !cof-surprise. Par exemple, contre une équipe de joueurs dans le handout Equipe joueurs (cf la méthode de sélection de groupes), on pourra utiliser l'ability !cof-surprise [[15 + @{selected|DEX}]] --equipe joueurs. Pour les bonus en discrétion et init, reporter sur la fiche (et à un prédicat discrétion), pour l'attaque en embuscade sur une cible surprise, rajouter à une attaque les options --sournoise 1 --if moins FOR --etat renverse --endif.
    2. -
    3. Dévorer : ajouter un prédicat devorer.
    4. -
    5. Gober : ajouter un prédicat gober. Le script ne vérifie pas que le personnage fait son jet de force avant d'attaquer (mais il propose un bouton pour le faire), ni que l'arme utilisée n'est pas plus grande qu'une dague.
    6. +
    7. Embuscade : S\xE9lectionner les ennemis du pr\xE9dateurs, et utiliser !cof-surprise. Par exemple, contre une \xE9quipe de joueurs dans le handout Equipe joueurs (cf la m\xE9thode de s\xE9lection de groupes), on pourra utiliser l'ability !cof-surprise [[15 + @{selected|DEX}]] --equipe joueurs. Pour les bonus en discr\xE9tion et init, reporter sur la fiche (et \xE0 un pr\xE9dicat discr\xE9tion), pour l'attaque en embuscade sur une cible surprise, rajouter \xE0 une attaque les options --sournoise 1 --if moins FOR --etat renverse --endif.
    8. +
    9. D\xE9vorer : ajouter un pr\xE9dicat devorer.
    10. +
    11. Gober : ajouter un pr\xE9dicat gober. Le script ne v\xE9rifie pas que le personnage fait son jet de force avant d'attaquer (mais il propose un bouton pour le faire), ni que l'arme utilis\xE9e n'est pas plus grande qu'une dague.

    Voie du tueur

      -
    1. Attaque mortelle : donner la possibilité de faire une attaque avec les options --bonusAttaque 5 --sournoise rang*2. Rajouter un prédicat discrétion avec comme valeur 5.
    2. -
    3. Disparition : donner la possibilité de faire une attaque avec les options --disparition rang*2.
    4. -
    5. Assassinat : rajouter --if etatCible surpris --etat mort --save CON 15 --endif à l'Attaque mortelle.
    6. +
    7. Attaque mortelle : donner la possibilit\xE9 de faire une attaque avec les options --bonusAttaque 5 --sournoise rang*2. Rajouter un pr\xE9dicat discr\xE9tion avec comme valeur 5.
    8. +
    9. Disparition : donner la possibilit\xE9 de faire une attaque avec les options --disparition rang*2.
    10. +
    11. Assassinat : rajouter --if etatCible surpris --etat mort --save CON 15 --endif \xE0 l'Attaque mortelle.

    4.4 Autres sorts

    Sorts qui ne sont pas dans des voies, mais peuvent venir du grimoire (dans le compagnon) ou d'effets de parchemins.
      -
    • Animation des objets : !cof-animation-des-objets @{selected|token_id} ?{Taille d'objet|tabouret ou coffret,1|chaise ou coffre,2|meuble bas ou table,4|grande table,7|grosse armoire,10} On peut ajouter un troisième argument, @{target|token_id} pour animer un token d'objet sur la carte.
    • -
    • Armure d'eau : !cof-effet-combat armureDEau. Le script automatise l'immunité aux étreintes (pas aux enveloppements) et à la capacité Agripper des créatures volantes.
    • -
    • Choc : Faire une attaque de portée 20 m, de type Sortilège, DM contondants, portée 20 m, et avec les options --etat renverse --save FOR 10.
    • +
    • Animation des objets : !cof-animation-des-objets @{selected|token_id} ?{Taille d'objet|tabouret ou coffret,1|chaise ou coffre,2|meuble bas ou table,4|grande table,7|grosse armoire,10} On peut ajouter un troisi\xE8me argument, @{target|token_id} pour animer un token d'objet sur la carte.
    • +
    • Armure d'eau : !cof-effet-combat armureDEau. Le script automatise l'immunit\xE9 aux \xE9treintes (pas aux enveloppements) et \xE0 la capacit\xE9 Agripper des cr\xE9atures volantes.
    • +
    • Choc : Faire une attaque de port\xE9e 20 m, de type Sortil\xE8ge, DM contondants, port\xE9e 20 m, et avec les options --etat renverse --save FOR 10.
    • Coup au but : !cof-effet-temp bonusAttaqueTemp 1 --valeur 10 --lanceur @{selected|token_id} --portee 10 --mana 0 --target @{target|token_id}.
    • -
    • Force de géant : !cof-effet-temp forceDeGeant 10. Le bonus est de 2 par défaut, mais peut être modifié en utilisant l'option --valeur.
    • -
    • Mur de vent : !cof-mur-de-force vent. Par défaut, la durée sera de 5+mod. d'INT, mais on peut donner une autre valeur en argument, après vent. On peut aussi changer le rayon du mur en utilisant --portee. Cela ne gère ni les immunités, ni le jet de force pour passer le mur.
    • -
    • Nuée de scorpions : ajouter une attaque magique, de portée 20 m, type Sortilège, modificateur --pasDeDmg et option --effet nueeDeScorpions 10. Pas de support particulier pour les DM de zone qui détruisent la nuée (enlever l'attribut nueeDeScorpions sur la cible dans ce cas).
    • -
    • Résistance à la magie : pour l'augmentation de la DEF contre la magie, utiliser un prédicat DEF_magie et pour le bonus aux tests, resistanceALaMagie
    • +
    • Force de g\xE9ant : !cof-effet-temp forceDeGeant 10. Le bonus est de 2 par d\xE9faut, mais peut \xEAtre modifi\xE9 en utilisant l'option --valeur.
    • +
    • Mur de vent : !cof-mur-de-force vent. Par d\xE9faut, la dur\xE9e sera de 5+mod. d'INT, mais on peut donner une autre valeur en argument, apr\xE8s vent. On peut aussi changer le rayon du mur en utilisant --portee. Cela ne g\xE8re ni les immunit\xE9s, ni le jet de force pour passer le mur.
    • +
    • Nu\xE9e de scorpions : ajouter une attaque magique, de port\xE9e 20 m, type Sortil\xE8ge, modificateur --pasDeDmg et option --effet nueeDeScorpions 10. Pas de support particulier pour les DM de zone qui d\xE9truisent la nu\xE9e (enlever l'attribut nueeDeScorpions sur la cible dans ce cas).
    • +
    • R\xE9sistance \xE0 la magie : pour l'augmentation de la DEF contre la magie, utiliser un pr\xE9dicat DEF_magie et pour le bonus aux tests, resistanceALaMagie
    • Simulacre de vie : !cof-set-attribute PVTemporaires [[1d10 + @{selected|niveau}]] --message simulacre de vie
    • -
    • Sixième sens : !cof-effet sixiemeSens true. Pour mettre fin à l'effet du sort (qui a une durée en heures), on peut effacer l'attribut sixiemeSens, ou mieux encore, sélectionner le token et faire !cof-effet sixiemeSens false.
    • +
    • Sixi\xE8me sens : !cof-effet sixiemeSens true. Pour mettre fin \xE0 l'effet du sort (qui a une dur\xE9e en heures), on peut effacer l'attribut sixiemeSens, ou mieux encore, s\xE9lectionner le token et faire !cof-effet sixiemeSens false.
    • Toiles : !cof-effet-temp toiles [[5+@{selected|SAG}]] --saveActifParTour FOR [[10+@{selected|SAG}]] --lanceur @{selected|token_id} --disque @{target|token_id} 5 20 --saufAllies --mana 0.
    -

    4.5 Capacités diverses

    +

    4.5 Capacit\xE9s diverses

      -
    • Absorption d'énergie (spectres et vampires) : ajouter un prédicat absorptionEnergie de valeur la valeur du soin accordé à l'attaquant à chaque fois qu'il endommage une cible (5 par défaut, si vous ne mettez aucune valeur). Pour l'absorption des vampires, ajouter un prédicat vampire.
    • -
    • Action libre : ajouter un prédicat actionLibre.
    • -
    • Agripper (démon dans Noirbois) : !cof-agripper-de-demon @{selected|token_id} @{target|token_id}
    • -
    • Apparition : un prédicat apparition immunise à tous les DMs, sauf ceux de canalisation (voir plus bas), ou les attaques avec l'option energiePositive.
    • -
    • Armes de l'été (Les seigneurs de l'hiver) : pour le bonus défensif contre le seigneur de l'hivers, ajoutez sur les arme un prédicat armeDeLEte et sur la créature qui attaque (a priori seulement le seigneur de l'hiver) le prédicat creatureDeLHiver. Pour la Flamme de l'été, on peut rajouter dans les options --if predicatCible CreatureDeLHiver --incrDmgCoef 3 --incrCritCoef 3 --else --plus 1d6 --feu --enflamme --endif, et pour la Lance de l'aubre, --if predicatCible CreatureDeLHiver --incrDmgCoef 1 --incrCritCoef 1 --else --plus 1d6 --feu --enflamme --endif
    • -
    • Attaque en meute : ajouter un prédicat attaqueEnMeute de valeur le bonus d'attaque (2 pour un gobelin). Cela confère le bonus pour toutes les attaques de personnages avec ce prédicat suivant une effectuée par un autre personnage avec ce prédicat, jusqu'au prochain tour de ce personnage. Ainsi, si 2 créatures continuent d'attaquer la même cible, elles bénéficieront du bonus tout le temps, sauf la toute première attaque.
    • -
    • Attaque violente (Invicible) : ajouter un prédicat attaqueViolente.
    • -
    • Auras : pour les capacités qui font un effet permanent à une certaine portée, comme l'aura glaciale des spectres, utiliser un attribut nommé aura, de valeur courante la portée en mètres de l'aura, et de valeur maximale l'effet à appliquer. Si cet effet contient la chaîne de caractère $TOKEN, cette chaîne sera remplacée par le nom du token à l'origine de l'aura. Pour un exemple d'utilisation, voyez la ligne Aura glaciale en dessous.
    • -
    • Aura glaciale : ajouter un attribut aura, de valeur courante 5, et de valeur maximale !cof-effet-temp ralenti [[1d6]] --save CON 12 --magique --seulementVivant --message une aura de froid intense émane de $TOKEN.
    • -
    • Baroud d'honneur : ajouter un prédicat baroudHonneur (Quand le personnage arrive à 0 PV, il ne meurt pas jusqu'à sa prochaine attaque, qui se fait avec un bonus de +5)
    • -
    • Bâton des runes mortes : ajoutez dans les prédicats de l'arme le prédicat batonDesRunesMortes. Dans la fiche de Swarathnak, ajoutez le prédicat ennemiDuBatonDesRunesMortes.
    • -
    • Bonus à l'attaque magique : utiliser un prédicat bonusAttaqueMagique de valeur le bonus permet d'ajouter ce bonus aux attaques magiques. Utile en particulier en prédicat d'arme.
    • -
    • Boutefeu (Invincible) : utilisez un prédicat boutefeu. -
    • Canalisation : !cof-canaliser typetype peut être positif ou négatif, selon le type d'énergie canalisée. Il faut au moins soit une option --soin expr ou --dm expr (il est possible d'avoir les deux), pour exprimer le montant des soins ou des dégâts. Si vous souhaitez avoir un certain nombre de dégâts par point de mana dépensé, vous pouvez utiliser un prédicat deCanalisation contenant l'expression des dégâts (ou soins) par point de mana, et utiliser la syntaxe --soin n pm.
    • -
    • Châtiment du mâle : utiliser un prédicat chatimentDuMale.
    • -
    • Cibles multiples (nuées) : ajouter un prédicat ciblesMultiples.
    • +
    • Absorption d'\xE9nergie (spectres et vampires) : ajouter un pr\xE9dicat absorptionEnergie de valeur la valeur du soin accord\xE9 \xE0 l'attaquant \xE0 chaque fois qu'il endommage une cible (5 par d\xE9faut, si vous ne mettez aucune valeur). Pour l'absorption des vampires, ajouter un pr\xE9dicat vampire.
    • +
    • Action libre : ajouter un pr\xE9dicat actionLibre.
    • +
    • Agripper (d\xE9mon dans Noirbois) : !cof-agripper-de-demon @{selected|token_id} @{target|token_id}
    • +
    • Apparition : un pr\xE9dicat apparition immunise \xE0 tous les DMs, sauf ceux de canalisation (voir plus bas), ou les attaques avec l'option energiePositive.
    • +
    • Armes de l'\xE9t\xE9 (Les seigneurs de l'hiver) : pour le bonus d\xE9fensif contre le seigneur de l'hivers, ajoutez sur les arme un pr\xE9dicat armeDeLEte et sur la cr\xE9ature qui attaque (a priori seulement le seigneur de l'hiver) le pr\xE9dicat creatureDeLHiver. Pour la Flamme de l'\xE9t\xE9, on peut rajouter dans les options --if predicatCible CreatureDeLHiver --incrDmgCoef 3 --incrCritCoef 3 --else --plus 1d6 --feu --enflamme --endif, et pour la Lance de l'aubre, --if predicatCible CreatureDeLHiver --incrDmgCoef 1 --incrCritCoef 1 --else --plus 1d6 --feu --enflamme --endif
    • +
    • Attaque en meute : ajouter un pr\xE9dicat attaqueEnMeute de valeur le bonus d'attaque (2 pour un gobelin). Cela conf\xE8re le bonus pour toutes les attaques de personnages avec ce pr\xE9dicat suivant une effectu\xE9e par un autre personnage avec ce pr\xE9dicat, jusqu'au prochain tour de ce personnage. Ainsi, si 2 cr\xE9atures continuent d'attaquer la m\xEAme cible, elles b\xE9n\xE9ficieront du bonus tout le temps, sauf la toute premi\xE8re attaque.
    • +
    • Attaque violente (Invicible) : ajouter un pr\xE9dicat attaqueViolente.
    • +
    • Auras : pour les capacit\xE9s qui font un effet permanent \xE0 une certaine port\xE9e, comme l'aura glaciale des spectres, utiliser un attribut nomm\xE9 aura, de valeur courante la port\xE9e en m\xE8tres de l'aura, et de valeur maximale l'effet \xE0 appliquer. Si cet effet contient la cha\xEEne de caract\xE8re $TOKEN, cette cha\xEEne sera remplac\xE9e par le nom du token \xE0 l'origine de l'aura. Pour un exemple d'utilisation, voyez la ligne Aura glaciale en dessous.
    • +
    • Aura glaciale : ajouter un attribut aura, de valeur courante 5, et de valeur maximale !cof-effet-temp ralenti [[1d6]] --save CON 12 --magique --seulementVivant --message une aura de froid intense \xE9mane de $TOKEN.
    • +
    • Aura de profanation : ajouter un pr\xE9dicat auraDeProfanation.
    • +
    • Baroud d'honneur : ajouter un pr\xE9dicat baroudHonneur (Quand le personnage arrive \xE0 0 PV, il ne meurt pas jusqu'\xE0 sa prochaine attaque, qui se fait avec un bonus de +5)
    • +
    • B\xE2ton des runes mortes (Invincible) : ajoutez dans les pr\xE9dicats de l'arme le pr\xE9dicat batonDesRunesMortes. Dans la fiche de Swarathnak, ajoutez le pr\xE9dicat ennemiDuBatonDesRunesMortes.
    • +
    • Bonus \xE0 l'attaque magique : utiliser un pr\xE9dicat bonusAttaqueMagique de valeur le bonus permet d'ajouter ce bonus aux attaques magiques. Utile en particulier en pr\xE9dicat d'arme.
    • +
    • Boutefeu (Invincible) : utilisez un pr\xE9dicat boutefeu. +
    • Canalisation : !cof-canaliser type o\xF9 type peut \xEAtre positif ou n\xE9gatif, selon le type d'\xE9nergie canalis\xE9e. Il faut au moins soit une option --soin expr ou --dm expr (il est possible d'avoir les deux), pour exprimer le montant des soins ou des d\xE9g\xE2ts. Si vous souhaitez avoir un certain nombre de d\xE9g\xE2ts par point de mana d\xE9pens\xE9, vous pouvez utiliser un pr\xE9dicat deCanalisation contenant l'expression des d\xE9g\xE2ts (ou soins) par point de mana, et utiliser la syntaxe --soin n pm.
    • +
    • Ch\xE2timent du m\xE2le : utiliser un pr\xE9dicat chatimentDuMale.
    • +
    • Cibles multiples (nu\xE9es) : ajouter un pr\xE9dicat ciblesMultiples.
    • Clignotement : !cof-effet-temp clignotement [[1d6+2]].
    • -
    • Créature non-vivante : ajouter un prédicat nonVivant.
    • -
    • Créature végétative : ajouter un prédicat vegetatif.
    • -
    • Cyclone (pour les élementaires) : !cof-effet-temp cyclone [[1d4+1]] --limiteParCombat 1. Cela va proposer une attaque Traverser dans les actions de l'élémentaire, qui ne peut fonctionner que si le personnage a au moins une attaque sur sa fiche. Par défaut, l'attaque utilisée en traversant est l'attaque de label 1, mais on peut préciser un autre label en utilisant l'option --valeur.
    • -
    • Dégâts si touché au contact (élémentaire de feu,...) : ajouter un prédicat nommé dmSiToucheContact, de valeur les dégâts, suivis de -- et du type si besoin. Par exemple, pour un élémentaire de feu, le prédicat dmSiToucheContact:: 1d6 --feu, en fin de ligne (rien ne doit suivre sur cette ligne).
    • -
    • Drain de force (pour la campagne Invincible) : ajouter un prédicat auraDrainDeForce
    • -
    • Écraser (pour la campagne Invincible) : ajouter un prédicat ecraser de valeur le label de l'attaque utilisée pour écraser.
    • -
    • Effroi (dragons) : !cof-peur [[10+@{selected|FOR}]] 1d4 --effroi --ralenti --disque @{selected|token_id} 50 à utiliser au premier tour de jeu.
    • -
    • Énergie de la mort (pour la campagne Vengeance) : ajouter un prédicat energieDeLaMort. Le MJ devra être attentif au message indiquant le retour à la vie, car c'est lui qui devra enlever l'état mort et ajuster les PVs.
    • -
    • Enveloppement (cube gélatineux) : ajouter l'option --enveloppe, puis quand le bouton apparaît si l'attaque réussit, cliquer dessus. En cas d'enveloppement, la cible ne peut plus bouger et se déplace avec le cube (déplacer le cube met la cible dans le cube), et au tour du cube, il faut presser les boutons de dégâts pour les infliger aux cibles enveloppées.
    • -
    • Étreinte (serpents) : ajouter l'option --etreinte difficulte, puis quand le bouton apparaît si l'attaque réussit, cliquer dessus. En cas d'étreinte réussie, la cible ne peut plus bouger et se déplace avec le serpent, et au tour du serpent, il faut presser les boutons de dégâts pour les infliger aux cibles étreintes.
    • -
    • Étreinte (scorpions) : ajouter l'option --etreinteScorpion. Le script prend le parti de ne pas étourdir la cible, mais le -5 en DEF, le jet de FOR et les dégâts sont automatisés. La cible est libérée automatiquement à la mort du scorpion.
    • -
    • Étreinte avec immolation (démon gardien) : pour l'attaque limitée qui immole, ajouter l'option --etreinteImmole. Cette attaque réussira automatiquement contre une cible qui est déjà étreinte.
    • -
    • Faucheuse de géants: ajouter le modifcateur tueurDeGrands aux attaques.
    • -
    • Fièvre du chêne : pour ajouter encore une RD de 5 contre le feu, ajouter un prédicat fievreChene.
    • -
    • Fiévreux : !cof-effet fievreux donne -2 en attaque, au dégâts et aux tests.
    • -
    • Foudres du temps : !cof-effet-chaque-d20 foudresDuTemps permet d'activer les foudres du temps. On peut donner un argument pour remplacer la valeur par défaut (13) par un autre jet de dés. Un deuxième argument permet de faire sortir la foudre pour tout jet entre les deux valeurs. Par exemple !cof-effet-chaque-d20 foudresDuTemps 13 14 fait venir la foudre pour tout jet de 13 ou 14. Si votre jeu contient un son (ou playlist) nommé Foudre (avec la majuscule), le son sera joué à chaque fois que la foudre frappera. Finalement, !cof-effet-chaque-d20 foudresDuTemps fin met fin aux foudres du temps.
    • -
    • Frénésie : Ajouter un prédicat frenesie avec comme valeur le nombre de PV en-dessous duquel la créature devient frénétique (+2 aus jets d'attaque).
    • -
    • Hors de portée : ajouter un prédicat horsDePortee
    • -
    • Huile de fort assaut : !cof-effet-temp dmgArme(L) 10 --valeur 1d6L est le label de l'arme qu'on veut enduire d'huile de fort assaut.
    • -
    • Hurlement : Pour les chiens infernaux, !cof-peur [[10+?{Nombre de chiens?}]] 2d4 --titre Hurlement --immuniseSiResiste hurlement --disque 50 --saufAllies, et pour les fantômes, !cof-peur 12 1d6 --titre Hurlement terrible --immuniseSiResiste hurlement --disque 10 --saufAllies.
    • -
    • Illusion : Pour les illusions qui disparaissent et réapparaissent un peu plus loin quand on essaie de les toucher, ajouter un prédicat estUneIllusion.
    • -
    • Immunité aux armes : ajouter un prédicat immuniteAuxArmes. À noter qu'il est possible de spécifier le niveau de magie d'une attaque en donnant un argument à l'option --magique. Ainsi une arme de niveau magique 3 aura en argument --magique 3.
    • -
    • Immunité aux attaques non magiques : ajouter un prédicat immunite_nonMagique
    • -
    • Immunité aux critiques : ajouter un prédicat immuniteAuxCritiques.
    • -
    • Indéracinable : ajouter un prédicat inderacinable.
    • -
    • Insensible : ajouter un prédicat insensibleAffaibli.
    • -
    • Intangible (à la Pathfinder 1) : ajouter un un prédicat creatureIntangible pour l'immunité aux armes non-magiques et la division des autres dégâts.
    • -
    • Invisible : passer le personnage invisible (!cof-set-state invisible true, ou mettre directment le statut sur le token). Si il peut rester invisible en combat, lui ajouter un prédicat invisibleEnCombat. Si il est attaqué autrement qu'avec tir en aveugle par quelqu'un qui ne voit pas l'invisble (à vous de montrer au moins temporairement le token), un malus de +5 en DEF au contact et +10 à distance sera appliqué, de même que le bonus de +5 en attaque contre ceux qui ne voient pas l'invisible. Le script suppose toujours qu'un personnage qui dispose de tir aveugle utilise sa capacité contre les cibles invisibles: à vous de vérifier qu'il ne cumule pas ça avec une capacité limitée.
    • -
    • Langage sombre : en plus de comprendre les elfes noirs, j'ai décidé d'octroyer un bonus de +1 en DEF et +1 aux DM contre les elfes noirs, bonus justifié par la meilleure compréhension de leur culture et de leurs tactiques. Pour cela, j'utiliser un prédicat langageSombreHetre.
    • -
    • Message en cas de coup critique reçu : on peut utiliser un prédicat messageSiCritique avec en valeur un message à afficher en cas d'echec critique subit. Pensez à bien utiliser la syntaxe avec ::.
    • +
    • Cr\xE9ature non-vivante : ajouter un pr\xE9dicat nonVivant.
    • +
    • Cr\xE9ature v\xE9g\xE9tative : ajouter un pr\xE9dicat vegetatif.
    • +
    • Cyclone (pour les \xE9lementaires) : !cof-effet-temp cyclone [[1d4+1]] --limiteParCombat 1. Cela va proposer une attaque Traverser dans les actions de l'\xE9l\xE9mentaire, qui ne peut fonctionner que si le personnage a au moins une attaque sur sa fiche. Par d\xE9faut, l'attaque utilis\xE9e en traversant est l'attaque de label 1, mais on peut pr\xE9ciser un autre label en utilisant l'option --valeur.
    • +
    • D\xE9g\xE2ts si touch\xE9 au contact (\xE9l\xE9mentaire de feu,...) : ajouter un pr\xE9dicat nomm\xE9 dmSiToucheContact, de valeur les d\xE9g\xE2ts, suivis de -- et du type si besoin. Par exemple, pour un \xE9l\xE9mentaire de feu, le pr\xE9dicat dmSiToucheContact:: 1d6 --feu, en fin de ligne (rien ne doit suivre sur cette ligne).
    • +
    • Drain de force (pour la campagne Invincible) : ajouter un pr\xE9dicat auraDrainDeForce
    • +
    • \xC9craser (pour la campagne Invincible) : ajouter un pr\xE9dicat ecraser de valeur le label de l'attaque utilis\xE9e pour \xE9craser.
    • +
    • Effroi (dragons) : !cof-peur [[10+@{selected|FOR}]] 1d4 --effroi --ralenti --disque @{selected|token_id} 50 \xE0 utiliser au premier tour de jeu.
    • +
    • \xC9nergie de la mort (pour la campagne Vengeance) : ajouter un pr\xE9dicat energieDeLaMort. Le MJ devra \xEAtre attentif au message indiquant le retour \xE0 la vie, car c'est lui qui devra enlever l'\xE9tat mort et ajuster les PVs.
    • +
    • Enveloppement (cube g\xE9latineux) : ajouter l'option --enveloppe, puis quand le bouton appara\xEEt si l'attaque r\xE9ussit, cliquer dessus. En cas d'enveloppement, la cible ne peut plus bouger et se d\xE9place avec le cube (d\xE9placer le cube met la cible dans le cube), et au tour du cube, il faut presser les boutons de d\xE9g\xE2ts pour les infliger aux cibles envelopp\xE9es.
    • +
    • \xC9treinte (serpents) : ajouter l'option --etreinte difficulte, puis quand le bouton appara\xEEt si l'attaque r\xE9ussit, cliquer dessus. En cas d'\xE9treinte r\xE9ussie, la cible ne peut plus bouger et se d\xE9place avec le serpent, et au tour du serpent, il faut presser les boutons de d\xE9g\xE2ts pour les infliger aux cibles \xE9treintes.
    • +
    • \xC9treinte (scorpions) : ajouter l'option --etreinteScorpion. Le script prend le parti de ne pas \xE9tourdir la cible, mais le -5 en DEF, le jet de FOR et les d\xE9g\xE2ts sont automatis\xE9s. La cible est lib\xE9r\xE9e automatiquement \xE0 la mort du scorpion.
    • +
    • \xC9treinte avec immolation (d\xE9mon gardien) : pour l'attaque limit\xE9e qui immole, ajouter l'option --etreinteImmole. Cette attaque r\xE9ussira automatiquement contre une cible qui est d\xE9j\xE0 \xE9treinte.
    • +
    • Faucheuse de g\xE9ants: ajouter le modifcateur tueurDeGrands aux attaques.
    • +
    • Fi\xE8vre du ch\xEAne : pour ajouter encore une RD de 5 contre le feu, ajouter un pr\xE9dicat fievreChene.
    • +
    • Fi\xE9vreux : !cof-effet fievreux donne -2 en attaque, au d\xE9g\xE2ts et aux tests.
    • +
    • Foudres du temps : !cof-effet-chaque-d20 foudresDuTemps permet d'activer les foudres du temps. On peut donner un argument pour remplacer la valeur par d\xE9faut (13) par un autre jet de d\xE9s. Un deuxi\xE8me argument permet de faire sortir la foudre pour tout jet entre les deux valeurs. Par exemple !cof-effet-chaque-d20 foudresDuTemps 13 14 fait venir la foudre pour tout jet de 13 ou 14. Si votre jeu contient un son (ou playlist) nomm\xE9 Foudre (avec la majuscule), le son sera jou\xE9 \xE0 chaque fois que la foudre frappera. Finalement, !cof-effet-chaque-d20 foudresDuTemps fin met fin aux foudres du temps.
    • +
    • Fr\xE9n\xE9sie : Ajouter un pr\xE9dicat frenesie avec comme valeur le nombre de PV en-dessous duquel la cr\xE9ature devient fr\xE9n\xE9tique (+2 aus jets d'attaque).
    • +
    • Hors de port\xE9e : ajouter un pr\xE9dicat horsDePortee
    • +
    • Huile de fort assaut : !cof-effet-temp dmgArme(L) 10 --valeur 1d6 o\xF9 L est le label de l'arme qu'on veut enduire d'huile de fort assaut.
    • +
    • Hurlement : Pour les chiens infernaux, !cof-peur [[10+?{Nombre de chiens?}]] 2d4 --titre Hurlement --immuniseSiResiste hurlement --disque 50 --saufAllies, et pour les fant\xF4mes, !cof-peur 12 1d6 --titre Hurlement terrible --immuniseSiResiste hurlement --disque 10 --saufAllies.
    • +
    • Illusion : Pour les illusions qui disparaissent et r\xE9apparaissent un peu plus loin quand on essaie de les toucher, ajouter un pr\xE9dicat estUneIllusion.
    • +
    • Immunit\xE9 aux armes : ajouter un pr\xE9dicat immuniteAuxArmes. \xC0 noter qu'il est possible de sp\xE9cifier le niveau de magie d'une attaque en donnant un argument \xE0 l'option --magique. Ainsi une arme de niveau magique 3 aura en argument --magique 3.
    • +
    • Immunit\xE9 aux attaques non magiques : ajouter un pr\xE9dicat immunite_nonMagique
    • +
    • Immunit\xE9 aux critiques : ajouter un pr\xE9dicat immuniteAuxCritiques.
    • +
    • Ind\xE9racinable : ajouter un pr\xE9dicat inderacinable.
    • +
    • Insensible : ajouter un pr\xE9dicat insensibleAffaibli.
    • +
    • Intangible (\xE0 la Pathfinder 1) : ajouter un un pr\xE9dicat creatureIntangible pour l'immunit\xE9 aux armes non-magiques et la division des autres d\xE9g\xE2ts.
    • +
    • Invisible : passer le personnage invisible (!cof-set-state invisible true, ou mettre directment le statut sur le token). Si il peut rester invisible en combat, lui ajouter un pr\xE9dicat invisibleEnCombat. Si il est attaqu\xE9 autrement qu'avec tir en aveugle par quelqu'un qui ne voit pas l'invisble (\xE0 vous de montrer au moins temporairement le token), un malus de +5 en DEF au contact et +10 \xE0 distance sera appliqu\xE9, de m\xEAme que le bonus de +5 en attaque contre ceux qui ne voient pas l'invisible. Le script suppose toujours qu'un personnage qui dispose de tir aveugle utilise sa capacit\xE9 contre les cibles invisibles: \xE0 vous de v\xE9rifier qu'il ne cumule pas \xE7a avec une capacit\xE9 limit\xE9e.
    • +
    • Langage sombre : en plus de comprendre les elfes noirs, j'ai d\xE9cid\xE9 d'octroyer un bonus de +1 en DEF et +1 aux DM contre les elfes noirs, bonus justifi\xE9 par la meilleure compr\xE9hension de leur culture et de leurs tactiques. Pour cela, j'utiliser un pr\xE9dicat langageSombreHetre.
    • +
    • Message en cas de coup critique re\xE7u : on peut utiliser un pr\xE9dicat messageSiCritique avec en valeur un message \xE0 afficher en cas d'echec critique subit. Pensez \xE0 bien utiliser la syntaxe avec ::.
    • Mot de pouvoir qui immobilise : !cof-mot-de-pouvoir-immobilise --lanceur @{selected|token_id} --enVue --saufAllies
    • -
    • N'abandonne jamais : ajouter un prédicat nAbandonnejamais.
    • -
    • Noirbois : À l'entrée dans des ténèbres magiques, utiliser la commande !cof-tenebres-magiques. À la sortie ou la fin de ces ténèbres, faire !cof-tenebres-magiques fin. Pour allumer la fiole de lumière, sélectionner un token est faire !cof-fiole-de-lumiere dd est la distance à laquelle la fiole éclaire. On peut ajouter un troisième argument, qui est la distance à laquelle la lumière devient moins brillante (pas d'effet sur la mécanique de jeu). Pour éteindre la lumière, il faut mettre utiliser !cof-fiole-de-lumiere fin.
    • -
    • Noyade (plante carnivore) : il existe un effet de combat nommé noyade (pas de durée, il dure par défaut tout le combat) qui fait perdre 1d6 PV par tour, sauf à réussir un test de CON difficulté 15, et qui impose un malus de -3 aux attaques et aux DMs.
    • -
    • Ondes corruptrices (Anathazerïn) : Pour simplement le premier effet, faire !cof-effet ondesCorruptrices 2, puis pour augmeter l'effet !cof-effet ondesCorruptrices +2. L'effet peut être annulé avec !cof-effet ondesCorruptrices 0. Pour le porteur du bouclier de Grabuge, on peut mettre un prédicat porteurDuBouclierDeGrabuge.
    • -
    • Paralysie des goules : ajouter à l'attaque de morsure --effet paralyseGoule [[1d6]] --save CON 10.
    • -
    • Perte de substance (Invincible) : Ajouter pour tous les personnages concernés un prédicat perteDeSubstance. Le changement de jour va augmenter un compteur, à condition que les tokens des joueurs soient sur la page, et soit on ne sélectionne aucun token quand on lance la commande de changement de jour, soit on sélectionne au moins tous les tokens des joueurs. Le test de CHA n'est pas automatisé, mais le script en rappelle la difficulté. Pour les ancres, ajouter un prédicat ancreInvincible (par exemple dans les prédicats de l'arme). Pour la réduction des dégâts, ajouter au dragon un prédicat dragonInvincible. Pour les DM indirects, il faudra gérer à la main la réduction de DM.
    • -
    • Phylactère de canalisation : ajouter un prédicat phylacterePositif pour un phylactère de canalisation positive, ou phylactereNegatif pour un phylactère de canalisation négative. Associez à ce prédicat la valeur ajoutée pour chaque PM dépensé (nécessite l'utilisation du prédicat deCanalisation). Une valeur de 1d4 semble adaptée pour le phylactère de canalisation de Pathfinder 1.
    • -
    • Piqûres d'insectes : Rajouter un prédicat piquresDInsectes avec comme valeur la résistance aux dégâts à distance appropriée
    • +
    • N'abandonne jamais : ajouter un pr\xE9dicat nAbandonnejamais.
    • +
    • Noirbois : \xC0 l'entr\xE9e dans des t\xE9n\xE8bres magiques, utiliser la commande !cof-tenebres-magiques. \xC0 la sortie ou la fin de ces t\xE9n\xE8bres, faire !cof-tenebres-magiques fin. Pour allumer la fiole de lumi\xE8re, s\xE9lectionner un token est faire !cof-fiole-de-lumiere d o\xF9 d est la distance \xE0 laquelle la fiole \xE9claire. On peut ajouter un troisi\xE8me argument, qui est la distance \xE0 laquelle la lumi\xE8re devient moins brillante (pas d'effet sur la m\xE9canique de jeu). Pour \xE9teindre la lumi\xE8re, il faut mettre utiliser !cof-fiole-de-lumiere fin.
    • +
    • Noyade (plante carnivore) : il existe un effet de combat nomm\xE9 noyade (pas de dur\xE9e, il dure par d\xE9faut tout le combat) qui fait perdre 1d6 PV par tour, sauf \xE0 r\xE9ussir un test de CON difficult\xE9 15, et qui impose un malus de -3 aux attaques et aux DMs.
    • +
    • Ondes corruptrices (Anathazer\xEFn) : Pour simplement le premier effet, faire !cof-effet ondesCorruptrices 2, puis pour augmeter l'effet !cof-effet ondesCorruptrices +2. L'effet peut \xEAtre annul\xE9 avec !cof-effet ondesCorruptrices 0. Pour le porteur du bouclier de Grabuge, on peut mettre un pr\xE9dicat porteurDuBouclierDeGrabuge.
    • +
    • Paralysie des goules : ajouter \xE0 l'attaque de morsure --effet paralyseGoule [[1d6]] --save CON 10.
    • +
    • Perte de substance (Invincible) : Ajouter pour tous les personnages concern\xE9s un pr\xE9dicat perteDeSubstance. Le changement de jour va augmenter un compteur, \xE0 condition que les tokens des joueurs soient sur la page, et soit on ne s\xE9lectionne aucun token quand on lance la commande de changement de jour, soit on s\xE9lectionne au moins tous les tokens des joueurs. Le test de CHA n'est pas automatis\xE9, mais le script en rappelle la difficult\xE9. Pour les ancres, ajouter un pr\xE9dicat ancreInvincible (par exemple dans les pr\xE9dicats de l'arme). Pour la r\xE9duction des d\xE9g\xE2ts, ajouter au dragon un pr\xE9dicat dragonInvincible. Pour les DM indirects, il faudra g\xE9rer \xE0 la main la r\xE9duction de DM.
    • +
    • Phylact\xE8re de canalisation : ajouter un pr\xE9dicat phylacterePositif pour un phylact\xE8re de canalisation positive, ou phylactereNegatif pour un phylact\xE8re de canalisation n\xE9gative. Associez \xE0 ce pr\xE9dicat la valeur ajout\xE9e pour chaque PM d\xE9pens\xE9 (n\xE9cessite l'utilisation du pr\xE9dicat deCanalisation). Une valeur de 1d4 semble adapt\xE9e pour le phylact\xE8re de canalisation de Pathfinder 1.
    • +
    • Piq\xFBres d'insectes : Rajouter un pr\xE9dicat piquresDInsectes avec comme valeur la r\xE9sistance aux d\xE9g\xE2ts \xE0 distance appropri\xE9e
    • - Poison : pour enduire une arme de label L de poison, utiliser !cof-enduire-poison L type force save. Pour l'instant, type ne peut être que rapide ou affaiblissant. Pour un poison rapide, force est une expression pour les dégâts (typiquement, 2d6), pour un poison affaiblissant c'est une expression indiquant au bout de combien de tours le poison fait effet (si c'est 0, alors l'affaiblissement ne dure que pendant un combat, sinon c'est une durée en heures, à gérer par le MJ). save est la difficulté du jet de CON pour résister au poison. On peut rajouter deux arguments optionnels : + Poison : pour enduire une arme de label L de poison, utiliser !cof-enduire-poison L type force save. Pour l'instant, type ne peut \xEAtre que rapide ou affaiblissant. Pour un poison rapide, force est une expression pour les d\xE9g\xE2ts (typiquement, 2d6), pour un poison affaiblissant c'est une expression indiquant au bout de combien de tours le poison fait effet (si c'est 0, alors l'affaiblissement ne dure que pendant un combat, sinon c'est une dur\xE9e en heures, \xE0 g\xE9rer par le MJ). save est la difficult\xE9 du jet de CON pour r\xE9sister au poison. On peut rajouter deux arguments optionnels :
        -
      • --testINT n: fixe la difficulté du jet d'INT pour réussir à poser le poison. La difficulté par défaut est 14.
      • -
      • --dose nom: indique une ressource dans laquelle on puise pour enduire de poison. Il faudra que le personnage ait un attribut de nom dose_nom avec comme valeur le nombre de doses possédées.
      • +
      • --testINT n: fixe la difficult\xE9 du jet d'INT pour r\xE9ussir \xE0 poser le poison. La difficult\xE9 par d\xE9faut est 14.
      • +
      • --dose nom: indique une ressource dans laquelle on puise pour enduire de poison. Il faudra que le personnage ait un attribut de nom dose_nom avec comme valeur le nombre de doses poss\xE9d\xE9es.
      - Il est aussi possible d'enduire de poison des munitions. Pour ce faire, remplacer le label de l'attaque par munition_LL est le label de la munition. Le script suppose que toute munition lancée perd son poison. + Il est aussi possible d'enduire de poison des munitions. Pour ce faire, remplacer le label de l'attaque par munition_L o\xF9 L est le label de la munition. Le script suppose que toute munition lanc\xE9e perd son poison.

      Il existe les effets suivants pour simuler directement des poisons affaiblissants :

      • poisonAffaiblissant est un effet qui rend affaibli pendant tout un combat.
      • -
      • poisonAffaiblissantLong, le même effet mais sans limite de durée (à gérer par le MJ).
      • -
      • poisonAffaiblissantLatent est un effet à durée en tours. Quand l'effet prend fin, le personnage devient empoisonné et affaibli.
      • +
      • poisonAffaiblissantLong, le m\xEAme effet mais sans limite de dur\xE9e (\xE0 g\xE9rer par le MJ).
      • +
      • poisonAffaiblissantLatent est un effet \xE0 dur\xE9e en tours. Quand l'effet prend fin, le personnage devient empoisonn\xE9 et affaibli.
    • -
    • Potion de sang de l'Arbre-Coeur : !cof-effet sangDeLArbreCoeur true, à enlever quand les 24h sont passées.
    • -
    • Protection contre les souffles et dégâts de zone : ajouter un prédicat protectionDMZone. Pour une protection contre un seul élément (feu, froid, etc), ajouter _ et le nom de l'élément. Par exemple, contre le feu, on aura un prédicat protectionDMZone_feu. On peut aussi avoir une protection contre les souffles de dragons uniquement, mais qui annule les DM en cas de succès au test de DEX, avec le prédicat protectionSouffleDeDragon. On peut aussi donner une RD contre les souffles de dragons avec un prédicat numérique rdSouffleDeDragon.
    • -
    • Putréfaction : ajouter à l'attaque --effet putrefaction 5 --save CON 14 (pour les données des momies)
    • +
    • Potion de sang de l'Arbre-Coeur : !cof-effet sangDeLArbreCoeur true, \xE0 enlever quand les 24h sont pass\xE9es.
    • +
    • Protection contre les souffles et d\xE9g\xE2ts de zone : ajouter un pr\xE9dicat protectionDMZone. Pour une protection contre un seul \xE9l\xE9ment (feu, froid, etc), ajouter _ et le nom de l'\xE9l\xE9ment. Par exemple, contre le feu, on aura un pr\xE9dicat protectionDMZone_feu. On peut aussi avoir une protection contre les souffles de dragons uniquement, mais qui annule les DM en cas de succ\xE8s au test de DEX, avec le pr\xE9dicat protectionSouffleDeDragon. On peut aussi donner une RD contre les souffles de dragons avec un pr\xE9dicat num\xE9rique rdSouffleDeDragon.
    • +
    • Putr\xE9faction : ajouter \xE0 l'attaque --effet putrefaction 5 --save CON 14 (pour les donn\xE9es des momies)
    • Rage (pour la campagne Invincible) : pour entrer en rage, faire !cof-effet-combat rage. On peut par exemple mettre cette commande dans une ability.
    • -
    • Réaction allergique : il existe un effet reactionAllergique qui fait le malus en DEX et CHA et disparaît en cas de soin magique. Pour une attaque, on peut par exemple mettre --effet reactionAllergique --save CON 11.
    • -
    • Résistant (insectes) : ajouter un prédicat durACuire.
    • -
    • Regard pétrifiant : ajouter un prédicat regardPetrifiant. Comme il est difficile de savoir qui est affecté et quand, le prédicat génère juste une action pour la créature et le MJ doit décider à qui l'appliquer et quand. À noter qu'on peut associer une valeur au prédicat pour changer la difficulté de 16 par défaut (-4 quand un adversaire est conscient du pouvoir et évite de croiser le regard). Pour détourner le regard d'une cible, utiliser !cof-effet-combat detournerLeRegard. Pour fermer les yeux, !cof-effet-combat detournerLeRegard --valeur 5. Pour arrêter de détourner le regard !cof-effet-combat detournerLeRegard fin. Si vous souhaitez enlever un effet de pétrification, vous pouvez utiliser la commande !cof-effet petrifie false.
    • -
    • Saisir et broyer : ajouter un prédicat saisirEtBroyer
    • -
    • Sang de fer : ajouter un prédicat sangDeFerIf.
    • -
    • Sans esprit : ajouter un prédicat sansEsprit permet la réussite automatique des jets de résistance basés sur INT, SAG ou CHA.
    • -
    • Sphère de feu : !cof-sphere-de-feu.
    • -
    • Tremblements de terre : !cof-effet-chaque-d20 tremblementsDeTerre permet d'activer les tremblements de terre. On peut donner un argument pour remplacer la valeur par défaut (13) par un autre jet de dés. Un deuxième argument permet de faire trembler la terre pour tout jet entre les deux valeurs. Si votre jeu contient un son (ou playlist) nommé TremblementTerre (avec la majuscule), le son sera joué à chaque fois que la terre tremblera. Finalement, !cof-effet-chaque-d20 tremblementsDeTerre fin met fin aux tremblements de terre.
    • +
    • R\xE9action allergique : il existe un effet reactionAllergique qui fait le malus en DEX et CHA et dispara\xEEt en cas de soin magique. Pour une attaque, on peut par exemple mettre --effet reactionAllergique --save CON 11.
    • +
    • R\xE9sistant (insectes) : ajouter un pr\xE9dicat durACuire.
    • +
    • Regard p\xE9trifiant : ajouter un pr\xE9dicat regardPetrifiant. Comme il est difficile de savoir qui est affect\xE9 et quand, le pr\xE9dicat g\xE9n\xE8re juste une action pour la cr\xE9ature et le MJ doit d\xE9cider \xE0 qui l'appliquer et quand. \xC0 noter qu'on peut associer une valeur au pr\xE9dicat pour changer la difficult\xE9 de 16 par d\xE9faut (-4 quand un adversaire est conscient du pouvoir et \xE9vite de croiser le regard). Pour d\xE9tourner le regard d'une cible, utiliser !cof-effet-combat detournerLeRegard. Pour fermer les yeux, !cof-effet-combat detournerLeRegard --valeur 5. Pour arr\xEAter de d\xE9tourner le regard !cof-effet-combat detournerLeRegard fin. Si vous souhaitez enlever un effet de p\xE9trification, vous pouvez utiliser la commande !cof-effet petrifie false.
    • +
    • Saisir et broyer : ajouter un pr\xE9dicat saisirEtBroyer
    • +
    • Sang de fer : ajouter un pr\xE9dicat sangDeFerIf.
    • +
    • Sans esprit : ajouter un pr\xE9dicat sansEsprit permet la r\xE9ussite automatique des jets de r\xE9sistance bas\xE9s sur INT, SAG ou CHA.
    • +
    • Sph\xE8re de feu : !cof-sphere-de-feu.
    • +
    • Tremblements de terre : !cof-effet-chaque-d20 tremblementsDeTerre permet d'activer les tremblements de terre. On peut donner un argument pour remplacer la valeur par d\xE9faut (13) par un autre jet de d\xE9s. Un deuxi\xE8me argument permet de faire trembler la terre pour tout jet entre les deux valeurs. Si votre jeu contient un son (ou playlist) nomm\xE9 TremblementTerre (avec la majuscule), le son sera jou\xE9 \xE0 chaque fois que la terre tremblera. Finalement, !cof-effet-chaque-d20 tremblementsDeTerre fin met fin aux tremblements de terre.
    • Vision nocturne : on peut utiliser !cof-vision-nocturne 18 pour un effet de potion de vision nocturne. Attention, pour remettre la vision habituelle, il faut encore effacer le token et remettre le token du personnage depuis la fiche.
    • -
    • Vulnérabilité aux coups critiques : si la créature possède un prédicat vulnerableCritique, le script interprète la valeur de ce prédicat comme les chances (sur 100) qu'un coup critique tue directment la créature. Par exemple, la valeur sera de 25 pour un esprit du givre.
    • -
    • Vulnérabilité à un type de dégâts : ajouter un prédicat vulnerableA_type, pour augmenter de 50% les dégâts reçus de ce type.
    • +
    • Vuln\xE9rabilit\xE9 aux coups critiques : si la cr\xE9ature poss\xE8de un pr\xE9dicat vulnerableCritique, le script interpr\xE8te la valeur de ce pr\xE9dicat comme les chances (sur 100) qu'un coup critique tue directment la cr\xE9ature. Par exemple, la valeur sera de 25 pour un esprit du givre.
    • +
    • Vuln\xE9rabilit\xE9 \xE0 un type de d\xE9g\xE2ts : ajouter un pr\xE9dicat vulnerableA_type, pour augmenter de 50% les d\xE9g\xE2ts re\xE7us de ce type.

    5. Terres d'Arran

    -

    Le script determine s'il doit utiliser les règles par défaut des Terres d'Arran ou celles de COF générique en fonction des fiches de personnages présentes sur la partie. Pour que toutes vox fiches soient bien adaptées au setting des Terres d'Arran, assurez-vous de bien sélectionner ce setting dans les réglages du jeu (accessibles avant de lancer la partie "Options de jeu" ou "Game Settings".

    +

    Le script determine s'il doit utiliser les r\xE8gles par d\xE9faut des Terres d'Arran ou celles de COF g\xE9n\xE9rique en fonction des fiches de personnages pr\xE9sentes sur la partie. Pour que toutes vox fiches soient bien adapt\xE9es au setting des Terres d'Arran, assurez-vous de bien s\xE9lectionner ce setting dans les r\xE9glages du jeu (accessibles avant de lancer la partie "Options de jeu" ou "Game Settings".

    -

    Le fait d'être dans ce mode de règles change le calcul de l'initiative et des mods d'attaque.

    +

    Le fait d'\xEAtre dans ce mode de r\xE8gles change le calcul de l'initiative et des mods d'attaque.

    5.1 Les peuples d'Arran

    5.1.1 Elfes

    Voie du peuple des Elfes
      -
    1. Grâce Elfique : Ajouter le bonus au jets de charisme sur la fiche, et une compétence discrétion pour les déplacements silencieux.
    2. -
    3. Essence magique : ajouter un prédicat DEF_magie de valeur 2, et un prédicat resistanceALaMagie de valeur 2 aussi. Passer ces valeurs à 4 au rang 4 dans la voie.
    4. -
    5. Maîtrise des armes elfiques : Pas de support pour l'instant
    6. +
    7. Gr\xE2ce Elfique : Ajouter le bonus au jets de charisme sur la fiche, et une comp\xE9tence discr\xE9tion pour les d\xE9placements silencieux.
    8. +
    9. Essence magique : ajouter un pr\xE9dicat DEF_magie de valeur 2, et un pr\xE9dicat resistanceALaMagie de valeur 2 aussi. Passer ces valeurs \xE0 4 au rang 4 dans la voie.
    10. +
    11. Ma\xEEtrise des armes elfiques : Pas de support pour l'instant
    12. Empathie elfique : Pas de support
    13. -
    14. Immortalité :TODO
    15. +
    16. Immortalit\xE9 :TODO
    Voie culturelle des elfes blancs
      -
    1. Mémoire du monde : En Attente
    2. -
    3. Prédispositions magiques : En Attente
    4. -
    5. Lancier d’élite : En Attente
    6. -
    7. Blancheur immaculée : En Attente
    8. +
    9. M\xE9moire du monde : En Attente
    10. +
    11. Pr\xE9dispositions magiques : En Attente
    12. +
    13. Lancier d\x2019\xE9lite : En Attente
    14. +
    15. Blancheur immacul\xE9e : En Attente
    16. Parangon elfe blanc : En Attente
    Voie culturelle des elfes bleus
      -
    1. Équilibre parfait : Ajouter une compétence équilibre avec le bonus.
    2. -
    3. Natif d’Elsémur : voir la capacité choisie.
    4. +
    5. \xC9quilibre parfait : Ajouter une comp\xE9tence \xE9quilibre avec le bonus.
    6. +
    7. Natif d\x2019Els\xE9mur : voir la capacit\xE9 choisie.
    8. Imperturbable : En Attente
    9. -
    10. Les enseignements de l’eau : En Attente
    11. +
    12. Les enseignements de l\x2019eau : En Attente
    13. Parangon elfe bleu : En Attente
    Voie culturelle des elfes noirs
      -
    1. Artiste de l’ombre : En Attente
    2. +
    3. Artiste de l\x2019ombre : En Attente
    4. Apprenti de Slurce : En Attente
    5. -
    6. Armes secrètes : En Attente
    7. +
    8. Armes secr\xE8tes : En Attente
    9. Noir comme le sang : En Attente
    10. Parangon elfe noir : En Attente
    Voie culturelle des elfes sylvains
    1. Le chant de la Terre : En Attente
    2. -
    3. Enfant de la forêt : voir la capacité choisie
    4. -
    5. Archer émérite : ajuster les chances de critique pour les attaques utilisant les arcs.
    6. -
    7. Compagnon animal supérieur : En Attente
    8. +
    9. Enfant de la for\xEAt : voir la capacit\xE9 choisie
    10. +
    11. Archer \xE9m\xE9rite : ajuster les chances de critique pour les attaques utilisant les arcs.
    12. +
    13. Compagnon animal sup\xE9rieur : En Attente
    14. Parangon elfe vert : En Attente
    @@ -2529,21 +2535,21 @@

    5.1.2 Nains

    Voie du peuple des Nains
      -
    1. Résistance : En Attente
    2. +
    3. R\xE9sistance : En Attente
    4. Solide comme un roc : En Attente
    5. -
    6. Maîtrise des armes runiques : En Attente
    7. -
    8. Résistance à la magie : En Attente
    9. -
    10. Ténacité naine : En Attente
    11. +
    12. Ma\xEEtrise des armes runiques : En Attente
    13. +
    14. R\xE9sistance \xE0 la magie : En Attente
    15. +
    16. T\xE9nacit\xE9 naine : En Attente
    -
    Voie culturelle de l’ordre de la Forge
    +
    Voie culturelle de l\x2019ordre de la Forge
    1. Artisan de la forge : En Attente
    2. Forgeron runique : En Attente
    3. -
    4. Marteler le métal : En Attente
    5. -
    6. Runes de défense : En Attente
    7. -
    8. Maître artisan : En Attente
    9. +
    10. Marteler le m\xE9tal : En Attente
    11. +
    12. Runes de d\xE9fense : En Attente
    13. +
    14. Ma\xEEtre artisan : En Attente
    -
    Voie culturelle de l’ordre du Talion
    +
    Voie culturelle de l\x2019ordre du Talion
    1. Plein aux as : En Attente
    2. Le sens des affaires : En Attente
    3. @@ -2551,15 +2557,15 @@
      Voie culturelle de l’ordre du Talion
    4. La Loge noire : En Attente
    5. Seigneur du Talion : En Attente
    -
    Voie culturelle de l’ordre du Temple
    +
    Voie culturelle de l\x2019ordre du Temple
      -
    1. Grosse tête : En Attente
    2. +
    3. Grosse t\xEAte : En Attente
    4. Enseigne du Temple : En Attente
    5. -
    6. Invention étrange : En Attente
    7. -
    8. Rites funéraires (L) : En Attente
    9. -
    10. Maître du temple : En Attente
    11. +
    12. Invention \xE9trange : En Attente
    13. +
    14. Rites fun\xE9raires (L) : En Attente
    15. +
    16. Ma\xEEtre du temple : En Attente
    -
    Voie culturelle de l’ordre du Bouclier
    +
    Voie culturelle de l\x2019ordre du Bouclier
    1. Combat en phalange : En Attente
    2. Formation militaire : En Attente
    3. @@ -2567,13 +2573,13 @@
      Voie culturelle de l’ordre du Bouclier
    4. Fuite interdite : En Attente
    5. Veilleur du roi : En Attente
    -
    Voie culturelle de l’ordre des Errants
    +
    Voie culturelle de l\x2019ordre des Errants
    1. Moins que rien : En Attente
    2. -
    3. Passé révolu : En Attente
    4. +
    5. Pass\xE9 r\xE9volu : En Attente
    6. Paysan aguerri : En Attente
    7. -
    8. Solidarité des Errants : En Attente
    9. -
    10. Volonté héroïque : En Attente
    11. +
    12. Solidarit\xE9 des Errants : En Attente
    13. +
    14. Volont\xE9 h\xE9ro\xEFque : En Attente
    @@ -2585,7 +2591,7 @@
    Voie du peuple des Humains
  • Loup parmi les loups : En Attente
  • Enseignement exotique : En Attente
  • Versatile : En Attente
  • -
  • Dépassement : En Attente
  • +
  • D\xE9passement : En Attente
  • Voie culturelle des ruines nordiques
      @@ -2593,28 +2599,28 @@
      Voie culturelle des ruines nordiques
    1. Barbare : En Attente
    2. Expertise des haches : En Attente
    3. Homme des clans : En Attente
    4. -
    5. Conquéran: En Attente
    6. +
    7. Conqu\xE9ran: En Attente
    Voie culturelle du Mitan
      -
    1. Homme des cités : En Attente
    2. -
    3. Entre tradition et progrès : En Attente
    4. +
    5. Homme des cit\xE9s : En Attente
    6. +
    7. Entre tradition et progr\xE8s : En Attente
    8. Modernisme : En Attente
    9. Conspirateur : En Attente
    10. -
    11. Maître marchand : En Attente
    12. +
    13. Ma\xEEtre marchand : En Attente
    Voie culturelle des empires austraux
      -
    1. Érudition : En Attente
    2. -
    3. Études arcaniques : En Attente
    4. -
    5. Autorité culturelle : En Attente
    6. -
    7. Prédispositions arcaniques : En Attente
    8. +
    9. \xC9rudition : En Attente
    10. +
    11. \xC9tudes arcaniques : En Attente
    12. +
    13. Autorit\xE9 culturelle : En Attente
    14. +
    15. Pr\xE9dispositions arcaniques : En Attente
    16. Mage : En Attente
    Voie culturelle des Terres orientales
    1. Connaissances cosmopolites : En Attente
    2. -
    3. Rejeton de la cité des Sang-mêlés : En Attente
    4. +
    5. Rejeton de la cit\xE9 des Sang-m\xEAl\xE9s : En Attente
    6. Sentir la magie : En Attente
    7. Chevaucheur de dragons : En Attente
    8. Expert en filouterie : En Attente
    9. @@ -2624,16 +2630,16 @@

      5.1.3 Peaux Vertes

      Voie du peuple des Peaux Vertes
        -
      1. Pour l’honneur : En Attente
      2. -
      3. Frappe déloyale : En Attente
      4. -
      5. Maîtrise des armes sauvages : En Attente
      6. -
      7. Croyances païennes : En Attente
      8. -
      9. Héros tribal : En Attente
      10. +
      11. Pour l\x2019honneur : En Attente
      12. +
      13. Frappe d\xE9loyale : En Attente
      14. +
      15. Ma\xEEtrise des armes sauvages : En Attente
      16. +
      17. Croyances pa\xEFennes : En Attente
      18. +
      19. H\xE9ros tribal : En Attente
      Voie culturelle des Ogres
        -
      1. Énorme : En Attente
      2. +
      3. \xC9norme : En Attente
      4. Brute : En Attente
      5. Attaque massive (L) : En Attente
      6. Intuable : En Attente
      7. @@ -2662,80 +2668,80 @@

        5.2 Voies de la f

        Voie du bastion

          -
        1. Protéger un allié : !cof-proteger-un-allie @{selected|token_id} @{target|token_id}. Fonctionne aussi si on remplace le target par un nom de token. Le script ne vérifie pas que le combattant ne change pas d'allié plus d'une fois par tour. Pour la capacité avancée, ajouter un prédicat protegerUnAllieAvance.
        2. +
        3. Prot\xE9ger un alli\xE9 : !cof-proteger-un-allie @{selected|token_id} @{target|token_id}. Fonctionne aussi si on remplace le target par un nom de token. Le script ne v\xE9rifie pas que le combattant ne change pas d'alli\xE9 plus d'une fois par tour. Pour la capacit\xE9 avanc\xE9e, ajouter un pr\xE9dicat protegerUnAllieAvance.
        4. Absorber un coup (L) :
            -
          • utiliser !cof-effet-temp absorberUnCoup 1 pour se mettre en position. Attention, ça ne vérifie pas si le combattant porte son bouclier.
          • -
          • le script propose un bouton à activer en cas d'attaque réussie alors que le combattant est en position.
          • +
          • utiliser !cof-effet-temp absorberUnCoup 1 pour se mettre en position. Attention, \xE7a ne v\xE9rifie pas si le combattant porte son bouclier.
          • +
          • le script propose un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le combattant est en position.
        5. -
        6. Coup de bouclier : faire une attaque de bouclier, de type Arme gauche, avec le modificateur avecd12crit. Pour que cette attaque soit proposée dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un prédicat attaqueAuBouclier de valeur le label de l'attaque.
        7. +
        8. Coup de bouclier : faire une attaque de bouclier, de type Arme gauche, avec le modificateur avecd12crit. Pour que cette attaque soit propos\xE9e dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un pr\xE9dicat attaqueAuBouclier de valeur le label de l'attaque.
        9. Absorber un sort (L) :
            -
          • utiliser !cof-effet-temp absorberUnSort 1 pour se mettre en position. Attention, ça ne vérifie pas si le combattant porte son bouclier.
          • -
          • le script propose un bouton à activer en cas d'attaque réussie alors que le combattant est en position.
          • +
          • utiliser !cof-effet-temp absorberUnSort 1 pour se mettre en position. Attention, \xE7a ne v\xE9rifie pas si le combattant porte son bouclier.
          • +
          • le script propose un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le combattant est en position.
        10. -
        11. Armure lourde : Noter l'armure sur la feuille du personnage, et ajouter un prédicat armureLourdeGuerrier au personnage. L'annulation du critique ne se produira que si l'armure est portée et que la valeur totale du bonus de défense supérieure ou égale à 7 (le bonus de DEF d'une armure de plaques complète).
        12. +
        13. Armure lourde : Noter l'armure sur la feuille du personnage, et ajouter un pr\xE9dicat armureLourdeGuerrier au personnage. L'annulation du critique ne se produira que si l'armure est port\xE9e et que la valeur totale du bonus de d\xE9fense sup\xE9rieure ou \xE9gale \xE0 7 (le bonus de DEF d'une armure de plaques compl\xE8te).

        Voie de la bravoure

        1. Robustesse : rajouter les PVs sur la fiche.
        2. Armure naturelle : rajouter la DEF sur la fiche
        3. -
        4. Prouesse : ajouter un prédicat prouesse (on peut y associer un nombre, si on souhaite plus d'une utilisation par tour). Le script générera automatiquement les boutons Prouesse sur les test appropriés.
        5. -
        6. Dernier rempart (L) : pas de support particulier, le MJ doit gérer les attaques supplémentaires.
        7. -
        8. Constitution héroïque : reporter les bonus sur la fiche.
        9. +
        10. Prouesse : ajouter un pr\xE9dicat prouesse (on peut y associer un nombre, si on souhaite plus d'une utilisation par tour). Le script g\xE9n\xE9rera automatiquement les boutons Prouesse sur les test appropri\xE9s.
        11. +
        12. Dernier rempart (L) : pas de support particulier, le MJ doit g\xE9rer les attaques suppl\xE9mentaires.
        13. +
        14. Constitution h\xE9ro\xEFque : reporter les bonus sur la fiche.
        -

        Voie du combat à deux armes

        +

        Voie du combat \xE0 deux armes

          -
        1. Combat à deux armes (L) : mettre une des attaques de type arme gauche, et y ajouter le modificateur avecd12crit. Pas encore de support pour la capacité avancée : dans ce cas, ajoutez le +1 dans la barre 3 du token ou sur les attaques.
        2. -
        3. Parade croisée (L) : !cof-effet-temp paradeCroisee 1 --valeur 2 --montreActions. Pour la capacité avancée, !cof-effet-temp paradeCroisee 1 --valeur 4 --montreActions.
        4. -
        5. Symétrie : En Attente
        6. +
        7. Combat \xE0 deux armes (L) : mettre une des attaques de type arme gauche, et y ajouter le modificateur avecd12crit. Pas encore de support pour la capacit\xE9 avanc\xE9e : dans ce cas, ajoutez le +1 dans la barre 3 du token ou sur les attaques.
        8. +
        9. Parade crois\xE9e (L) : !cof-effet-temp paradeCroisee 1 --valeur 2 --montreActions. Pour la capacit\xE9 avanc\xE9e, !cof-effet-temp paradeCroisee 1 --valeur 4 --montreActions.
        10. +
        11. Sym\xE9trie : En Attente
        12. Double peine : En Attente
        13. -
        14. Combat à deux armes parfait : En Attente
        15. +
        16. Combat \xE0 deux armes parfait : En Attente
        -

        Voie du combat monté

        +

        Voie du combat mont\xE9

          -
        1. Fidèle monture : Faire un personnage pour la monture, avec un prédicat monture. Pour monter sur la monture, on peut utiliser une ability de type token action, avec !cof-en-selle @{selected|token_id} nom_de_la_monture. Pour en descendre, il suffit de cliquer à nouveau sur le bouton de l'ability. Si vous souhaitez éviter que la monture apparaisse dans le turn tracker, vous pouvez ajouter un prédicat aucuneActionCombat à la monture.
        2. -
        3. Cavalier émérite : Ajouter au combattant un prédicat cavalierEmerite:2. Pour la défense de la monture, ajouter à cellle-ci un prédicat defDeriveeDe de valeur le nom du combattant (exactement tel qu'il apparaît sur la fiche, il est possible que cela demande d'utiliser la syntaxe avec ::). Attention, cela suppose que le combattant a une meilleure DEF que sa monture. Si ce n'est pas le cas, faire les ajustements sur la fiche du combattant.
        4. -
        5. Massacrer la piétaille : En Attente
        6. -
        7. Charge : pas de support pour le déplacement, mais +
        8. Fid\xE8le monture : Faire un personnage pour la monture, avec un pr\xE9dicat monture. Pour monter sur la monture, on peut utiliser une ability de type token action, avec !cof-en-selle @{selected|token_id} nom_de_la_monture. Pour en descendre, il suffit de cliquer \xE0 nouveau sur le bouton de l'ability. Si vous souhaitez \xE9viter que la monture apparaisse dans le turn tracker, vous pouvez ajouter un pr\xE9dicat aucuneActionCombat \xE0 la monture.
        9. +
        10. Cavalier \xE9m\xE9rite : Ajouter au combattant un pr\xE9dicat cavalierEmerite:2. Pour la d\xE9fense de la monture, ajouter \xE0 cellle-ci un pr\xE9dicat defDeriveeDe de valeur le nom du combattant (exactement tel qu'il appara\xEEt sur la fiche, il est possible que cela demande d'utiliser la syntaxe avec ::). Attention, cela suppose que le combattant a une meilleure DEF que sa monture. Si ce n'est pas le cas, faire les ajustements sur la fiche du combattant.
        11. +
        12. Massacrer la pi\xE9taille : En Attente
        13. +
        14. Charge : pas de support pour le d\xE9placement, mais
          • Pour l'attaque : utiliser --m2d20 --plus 1d6
          • -
          • Pour les créatures sur la trajectoire, utiliser !cof-jet FOR 18, et en cas de succès, infliger les DM (!cof-dmg 1d6)
          • +
          • Pour les cr\xE9atures sur la trajectoire, utiliser !cof-jet FOR 18, et en cas de succ\xE8s, infliger les DM (!cof-dmg 1d6)
        15. -
        16. Monture fantastique : faire un personnage pour la monture, avec un prédicat monture.
        17. +
        18. Monture fantastique : faire un personnage pour la monture, avec un pr\xE9dicat monture.

        Voie du commandement

          -
        1. Action concertée : utiliser !cof-echange-init @{selected|token_id} @{target|token_id} nn peut valoir 0, 1, 2 ou 3 selon le rang dans la voie et si la capacité est avancée.
        2. -
        3. À couvert (L) : !cof-a-couvert @{selected|token_id} @{target|token_id} le target est l'allié qui se déplace avec l'arquebusier. Se sélectionner soi-même si pas d'allié. Pas encore de support pour la capacité avancée.
        4. -
        5. Exemplaire : faire !cof-exemplaire, juste après l'attaque ratée.
        6. +
        7. Action concert\xE9e : utiliser !cof-echange-init @{selected|token_id} @{target|token_id} n o\xF9 n peut valoir 0, 1, 2 ou 3 selon le rang dans la voie et si la capacit\xE9 est avanc\xE9e.
        8. +
        9. \xC0 couvert (L) : !cof-a-couvert @{selected|token_id} @{target|token_id} le target est l'alli\xE9 qui se d\xE9place avec l'arquebusier. Se s\xE9lectionner soi-m\xEAme si pas d'alli\xE9. Pas encore de support pour la capacit\xE9 avanc\xE9e.
        10. +
        11. Exemplaire : faire !cof-exemplaire, juste apr\xE8s l'attaque rat\xE9e.
        12. Ordre de bataille : pas de support
        13. Charge fantastique (L) : !cof-charge-fantastique @{selected|token_id} --alliesEnVue --self --limiteParCombat 1
        -

        Voie de la férocité

        +

        Voie de la f\xE9rocit\xE9

        1. Cri de guerre : !cof-effet-combat criDeGuerre
        2. -
        3. Charge (L) : #Attaque -1 --bonusAttaque 2 --plus 1d6. Le déplacement n'est pas encore géré.
        4. -
        5. Rage du berserk (L) : utiliser !cof-rage-du-berserk, à la fois pour entrer en rage et pour tenter d'en sortir avant la fin du combat. Si le MJ souhaite mettre fin à la rage à cause d'un effet extérieur, il peut utiliser la commande !cof-effet-combat rageDuBerserk fin.
        6. -
        7. Même pas mal : ajouter un prédicat memePasMal. Le joueur doit lui-même activer la rage ou le furie si il souhaite en profiter.
        8. +
        9. Charge (L) : #Attaque -1 --bonusAttaque 2 --plus 1d6. Le d\xE9placement n'est pas encore g\xE9r\xE9.
        10. +
        11. Rage du berserk (L) : utiliser !cof-rage-du-berserk, \xE0 la fois pour entrer en rage et pour tenter d'en sortir avant la fin du combat. Si le MJ souhaite mettre fin \xE0 la rage \xE0 cause d'un effet ext\xE9rieur, il peut utiliser la commande !cof-effet-combat rageDuBerserk fin.
        12. +
        13. M\xEAme pas mal : ajouter un pr\xE9dicat memePasMal. Le joueur doit lui-m\xEAme activer la rage ou le furie si il souhaite en profiter.
        14. Attaque tourbillon (L) : !cof-explosion -1 --auto --disque 5 --saufAllies --limiteParCombat 1 tourbillon.

        Voie de la guerre

          -
        1. Posture de combat : !cof-posture-de-combat bonus attr1 attr2, où les deux attr peuvent être soit DEF soit ATT soit DM, et le bonus est retiré au premier attribut pour être ajouté au second. Le bonus peut être limité si le combattant a un prédicat voieDuSoldat qui indique son rang dans la voie. Exemple d'utilisation : !cof-posture-de-combat ?{Bonus|1|2|3|4|5} ?{Baisser|Défense,DEF|Attaque,ATT|Dégâts,DM} ?{Augmenter|Défense,DEF|Attaque,ATT|Dégâts,DM}. Normalement, la règle fait décider de sa posture au combattant à chaque tour, mais en pratique, il en change assez rarement. Une posture de combat reste donc active jusqu'à la fin du combat ou jusqu'à ce qu'on en change (elle est neutre si on a le même attribut à buffer et débuffer).
        2. -
        3. Désarmer (L) : !cof-desarmer @{selected|token_id} @{target|token_id}.
        4. -
        5. Double attaque (L) : faire deux attaques, avec l'option supplémentaire --bonusAttaque -2.
        6. -
        7. Attaque circulaire (L) : faire les attaques normalement, ce n'est pas considéré comme une aoe.
        8. +
        9. Posture de combat : !cof-posture-de-combat bonus attr1 attr2, o\xF9 les deux attr peuvent \xEAtre soit DEF soit ATT soit DM, et le bonus est retir\xE9 au premier attribut pour \xEAtre ajout\xE9 au second. Le bonus peut \xEAtre limit\xE9 si le combattant a un pr\xE9dicat voieDuSoldat qui indique son rang dans la voie. Exemple d'utilisation : !cof-posture-de-combat ?{Bonus|1|2|3|4|5} ?{Baisser|D\xE9fense,DEF|Attaque,ATT|D\xE9g\xE2ts,DM} ?{Augmenter|D\xE9fense,DEF|Attaque,ATT|D\xE9g\xE2ts,DM}. Normalement, la r\xE8gle fait d\xE9cider de sa posture au combattant \xE0 chaque tour, mais en pratique, il en change assez rarement. Une posture de combat reste donc active jusqu'\xE0 la fin du combat ou jusqu'\xE0 ce qu'on en change (elle est neutre si on a le m\xEAme attribut \xE0 buffer et d\xE9buffer).
        10. +
        11. D\xE9sarmer (L) : !cof-desarmer @{selected|token_id} @{target|token_id}.
        12. +
        13. Double attaque (L) : faire deux attaques, avec l'option suppl\xE9mentaire --bonusAttaque -2.
        14. +
        15. Attaque circulaire (L) : faire les attaques normalement, ce n'est pas consid\xE9r\xE9 comme une aoe.
        16. Attaque puissante : #Attaque -1 --avecd12crit --plus 2d6 --seulementContact.
        -

        Voie de la maîtrise des armes

        +

        Voie de la ma\xEEtrise des armes

          -
        1. Arme de prédilection : il est possible de préciser une famille d'armes de prédilection (un peu plus large que dans les règles), parmis arc, arbalete, fronde, hache, epee, marteau, masse, sabre, epieu, poudre, baton et rapiere. Si cela vous convient, ajoutez un prédicat armeDePredilection de valeur une de ces familles. Sinon, simplement ajouter le bonus sur les attaques dans la fiche.
        2. +
        3. Arme de pr\xE9dilection : il est possible de pr\xE9ciser une famille d'armes de pr\xE9dilection (un peu plus large que dans les r\xE8gles), parmis arc, arbalete, fronde, hache, epee, marteau, masse, sabre, epieu, poudre, baton et rapiere. Si cela vous convient, ajoutez un pr\xE9dicat armeDePredilection de valeur une de ces familles. Sinon, simplement ajouter le bonus sur les attaques dans la fiche.
        4. Science du critique : En Attente
        5. -
        6. Spécialisation : En Attente
        7. +
        8. Sp\xE9cialisation : En Attente
        9. Attaque parfaite (L) : En Attente
        10. Riposte : En Attente
        @@ -2743,61 +2749,61 @@

        Voie du pugilat

        1. Poings de fer : En Attente
        2. Peau de pierre : En Attente
        3. -
        4. Peau d’acier : En Attente
        5. -
        6. Déluge de coups (L) : En Attente
        7. -
        8. Force héroïque : En Attente
        9. +
        10. Peau d\x2019acier : En Attente
        11. +
        12. D\xE9luge de coups (L) : En Attente
        13. +
        14. Force h\xE9ro\xEFque : En Attente

        Voie de la puissance

        1. Argument de taille : En Attente
        2. Tour de force : En Attente
        3. Attaque brutale (L) : En Attente
        4. -
        5. Briseur d’os : En Attente
        6. -
        7. Vitalité débordante : En Attente
        8. +
        9. Briseur d\x2019os : En Attente
        10. +
        11. Vitalit\xE9 d\xE9bordante : En Attente

        5.3 Voies de la famille des aventuriers

        -

        Voie de l’acrobatie

        +

        Voie de l\x2019acrobatie

        1. Acrobate : En Attente
        2. -
        3. Grâce féline : En Attente
        4. +
        5. Gr\xE2ce f\xE9line : En Attente
        6. Lanceur de couteau : En Attente
        7. Esquive acrobatique : En Attente
        8. -
        9. Dextérité héroïque : En Attente
        10. +
        11. Dext\xE9rit\xE9 h\xE9ro\xEFque : En Attente
        -

        Voie de l’arbalètrie

        +

        Voie de l\x2019arbal\xE8trie

        1. Joli coup! : En Attente
        2. Cadence de tir : En Attente
        3. Tir double (L) : En Attente
        4. -
        5. As de la gâchette : En Attente
        6. +
        7. As de la g\xE2chette : En Attente
        8. Tir mortel : En Attente
        -

        Voie de l’archerie

        +

        Voie de l\x2019archerie

          -
        1. Sens affûtés : En Attente
        2. +
        3. Sens aff\xFBt\xE9s : En Attente
        4. Tir aveugle (L) : En Attente
        5. Tir rapide (L) : En Attente
        6. -
        7. Flèche de mort (L) : En Attente
        8. +
        9. Fl\xE8che de mort (L) : En Attente
        10. Dans le mille : En Attente
        -

        Voie de l’assassinat

        +

        Voie de l\x2019assassinat

          -
        1. Discrétion : En Attente
        2. +
        3. Discr\xE9tion : En Attente
        4. Attaque sournoise (L) : En Attente
        5. Frappe chirurgicale : En Attente
        6. Surprise : En Attente
        7. -
        8. Botte secrète : En Attente
        9. +
        10. Botte secr\xE8te : En Attente
        -

        Voie du bohème

        +

        Voie du boh\xE8me

          -
        1. Rumeurs et légendes : En Attente
        2. +
        3. Rumeurs et l\xE9gendes : En Attente
        4. Argumenter : En Attente
        5. -
        6. Débrouillard : En Attente
        7. -
        8. Déguisement : En Attente
        9. -
        10. Touche-à-tout : En Attente
        11. +
        12. D\xE9brouillard : En Attente
        13. +
        14. D\xE9guisement : En Attente
        15. +
        16. Touche-\xE0-tout : En Attente

        Voie du charme

          @@ -2805,15 +2811,15 @@

          Voie du charme

        1. Provocation (L) : En Attente
        2. Attaque flamboyante (L) : En Attente
        3. Suggestion (L) : En Attente
        4. -
        5. Charisme héroïque : En Attente
        6. +
        7. Charisme h\xE9ro\xEFque : En Attente

        Voie de la chasse

        1. Proche de la nature : En Attente
        2. -
        3. Nature nourricière : En Attente
        4. -
        5. Attaque éclair (L) : En Attente
        6. -
        7. Ennemis jurés : En Attente
        8. -
        9. Perception héroïque : En Attente
        10. +
        11. Nature nourrici\xE8re : En Attente
        12. +
        13. Attaque \xE9clair (L) : En Attente
        14. +
        15. Ennemis jur\xE9s : En Attente
        16. +
        17. Perception h\xE9ro\xEFque : En Attente

        Voie du compagnon animal

          @@ -2823,7 +2829,7 @@

          Voie du compagnon animal

        1. Empathie animale : En Attente
        2. Animal fabuleux : En Attente
        -

        Voie de l’escrime

        +

        Voie de l\x2019escrime

        1. Attaque en finesse : En Attente
        2. Intelligence du combat : En Attente
        3. @@ -2834,10 +2840,10 @@

          Voie de l’escrime

          Voie de la fourberie

          1. Doigts agiles : En Attente
          2. -
          3. Détecter les pièges : En Attente
          4. +
          5. D\xE9tecter les pi\xE8ges : En Attente
          6. Croc-en-jambe : En Attente
          7. Attaque paralysante (L) : En Attente
          8. -
          9. Attaque en traître : En Attente
          10. +
          11. Attaque en tra\xEEtre : En Attente
        @@ -2845,188 +2851,193 @@

        5.4 Voies de la fam

        Talents magiques

          -
        • Détection de la magie : pas de support.
        • +
        • D\xE9tection de la magie : pas de support.
        • Flamme : Faire une attaque magique de type feu pour l'attaque au contact. Pour l'illumination, !cof-lumiere @{selected|token_id} 5 1 --mana 0.
        • -
        • Inspiration : !cof-effet-temp inspiration [[2+@{selected|SAG}]] --target @{target|token_id} --lanceur @{selected|token_id} --portee 10. Pour l'instant le script ne vérifie pas que le sort n'est pas actif sur trop de cibles à la fois.
        • -
        • Lumières dansantes : !cof-lumiere @{selected|token_id} 20 15 --mana 0. Le script ne gère pas encore l'annulation de l'effet au moindre choc.
        • +
        • Inspiration : !cof-effet-temp inspiration [[2+@{selected|SAG}]] --target @{target|token_id} --lanceur @{selected|token_id} --portee 10. Pour l'instant le script ne v\xE9rifie pas que le sort n'est pas actif sur trop de cibles \xE0 la fois.
        • +
        • Lumi\xE8res dansantes : !cof-lumiere @{selected|token_id} 20 15 --mana 0. Le script ne g\xE8re pas encore l'annulation de l'effet au moindre choc.
        • Projectile de force : - Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4, portée 50, type Sortilège, modificateur auto dégâts contondants, option --mana 0. + Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4, port\xE9e 50, type Sortil\xE8ge, modificateur auto d\xE9g\xE2ts contondants, option --mana 0.
        -

        Voie de l’alchimie

        -

        Pour créer ou juste voir ses élixirs, utiliser la commande !cof-elixirs. Pour cela, il faut aussi un prédicat voieDeLAlchimie avec comme valeur le rang dans la voie. Noter que la commande !cof-elixirs affiche une liste d'élixirs, et que pour effectivement créer un élixir, il faut cliquer sur le bouton correspondant dans cette liste.

        +

        Voie de l\x2019alchimie

        +

        Pour cr\xE9er ou juste voir ses \xE9lixirs, utiliser la commande !cof-elixirs. Pour cela, il faut aussi un pr\xE9dicat voieDeLAlchimie avec comme valeur le rang dans la voie. Noter que la commande !cof-elixirs affiche une liste d'\xE9lixirs, et que pour effectivement cr\xE9er un \xE9lixir, il faut cliquer sur le bouton correspondant dans cette liste.

          -
        1. Fortifiant : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables. Pour la version avancée, ajouter un prédicat fortiviantAvance
        2. -
        3. Feu grégeois : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables. Pas de support pour la version avancée pour l'instant : utiliser !cof-dmg rang --feu pour les personnages qui auraient raté leur jet de DEX.
        4. -
        5. Huile instable : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
        6. -
        7. Élixir de guérison : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
        8. -
        9. Élixirs de Protection : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
        10. +
        11. Fortifiant : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables. Pour la version avanc\xE9e, ajouter un pr\xE9dicat fortiviantAvance
        12. +
        13. Feu gr\xE9geois : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables. Pas de support pour la version avanc\xE9e pour l'instant : utiliser !cof-dmg rang --feu pour les personnages qui auraient rat\xE9 leur jet de DEX.
        14. +
        15. Huile instable : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
        16. +
        17. \xC9lixir de gu\xE9rison : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
        18. +
        19. \xC9lixirs de Protection : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.

        Voie des arts druidiques

        1. Langage des animaux : En Attente
        2. -
        3. Nuée d’insectes* : En Attente
        4. +
        5. Nu\xE9e d\x2019insectes* : En Attente
        6. Le guetteur : En Attente
        7. -
        8. Masque du prédateur* : En Attente
        9. -
        10. Sagesse héroïque : En Attente
        11. +
        12. Masque du pr\xE9dateur* : En Attente
        13. +
        14. Sagesse h\xE9ro\xEFque : En Attente

        Voie de la divination

          -
        1. Sixième sens : ajouter le bonus en DEF divers et initiative divers, ajouter une compétence vigilance, de valeur 5 (le bonus aux jet de surprise).
        2. -
        3. Détection de l’invisible* : En Attente
        4. +
        5. Sixi\xE8me sens : ajouter le bonus en DEF divers et initiative divers, ajouter une comp\xE9tence vigilance, de valeur 5 (le bonus aux jet de surprise).
        6. +
        7. D\xE9tection de l\x2019invisible* : En Attente
        8. Clairvoyance* : En Attente
        9. Prescience* : En Attente
        10. Hyperconscience : En Attente
        -

        Voie de l’envoûtement

        +

        Voie de l\x2019envo\xFBtement

        1. Injonction* : En Attente
        2. Sommeil* : En Attente
        3. Confusion* : En Attente
        4. -
        5. Amitié* : En Attente
        6. +
        7. Amiti\xE9* : En Attente
        8. Domination* : En Attente
        -

        Voie des forêts

        +

        Voie des for\xEAts

          -
        1. Peau d’écorce* : - !cof-effet-temp peauDEcorce [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 1|Économe (L),--mana 0|Étendue (L),--puissant duree --mana 1}. Si le personnage a un prédicat voieDesForets de valeur 4 ou plus, le bonus sera de +4 en DEF. Ajouter un prédicat peauDEcorceAvancee pour la version en capacité avancée.
        2. -
        3. Prison végétale* : En Attente
        4. +
        5. Peau d\x2019\xE9corce* : + !cof-effet-temp peauDEcorce [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 1|\xC9conome (L),--mana 0|\xC9tendue (L),--puissant duree --mana 1}. Si le personnage a un pr\xE9dicat voieDesForets de valeur 4 ou plus, le bonus sera de +4 en DEF. Ajouter un pr\xE9dicat peauDEcorceAvancee pour la version en capacit\xE9 avanc\xE9e.
        6. +
        7. Prison v\xE9g\xE9tale* : En Attente
        8. Baies magiques* : En Attente
        9. -
        10. Animation d’un arbre* : En Attente
        11. -
        12. Régénération* : En Attente
        13. +
        14. Animation d\x2019un arbre* : En Attente
        15. +
        16. R\xE9g\xE9n\xE9ration* : En Attente

        Voie des illusions

          -
        1. Image décalée* : !cof-effet-temp imageDecalee [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 1|Économe (L),--mana 0|Étendue (L),--puissant duree --mana 1}. Pour la version avancée de la capacité, ajouter un prédicat imageDecaleeAvancee.
        2. +
        3. Image d\xE9cal\xE9e* : !cof-effet-temp imageDecalee [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 1|\xC9conome (L),--mana 0|\xC9tendue (L),--puissant duree --mana 1}. Pour la version avanc\xE9e de la capacit\xE9, ajouter un pr\xE9dicat imageDecaleeAvancee.
        4. Mirage* : En Attente
        5. Imitation* : En Attente
        6. -
        7. Dédoublement* : En Attente
        8. +
        9. D\xE9doublement* : En Attente
        10. Tueur fantasmagorique* : En Attente
        -

        Voie de la magie élémentaliste

        +

        Voie de la magie \xE9l\xE9mentaliste

        1. Brumes* : - !cof-tenebres @{selected|token_id} @{target|token_id} --brumes --mana 1. La commande pose un token de brouillard pour visualiser la zone. Tous les tokens présents dans la zone au lancement du sort sont automatiquement dans l'état pénombre. Au MJ ensuite d'enlever l'état pénombre quand les cibles sortent de la zone. A la fin de la durée du sort, ou à la fin du combat, la zone et les états pénombre restant disparaissent automatiquement. Il est aussi possible de changer les valeurs par défaut du sort (portée 20m, rayon 20m) avec les options --portee X et --rayon X. En règle custom, l'option puissant permet de doubler la superficie couverte (le script calcule le rayon approprié si custom).
        2. + !cof-tenebres @{selected|token_id} @{target|token_id} --brumes --mana 1. La commande pose un token de brouillard pour visualiser la zone. Tous les tokens pr\xE9sents dans la zone au lancement du sort sont automatiquement dans l'\xE9tat p\xE9nombre. Au MJ ensuite d'enlever l'\xE9tat p\xE9nombre quand les cibles sortent de la zone. A la fin de la dur\xE9e du sort, ou \xE0 la fin du combat, la zone et les \xE9tats p\xE9nombre restant disparaissent automatiquement. Il est aussi possible de changer les valeurs par d\xE9faut du sort (port\xE9e 20m, rayon 20m) avec les options --portee X et --rayon X. En r\xE8gle custom, l'option puissant permet de doubler la superficie couverte (le script calcule le rayon appropri\xE9 si custom).
        3. Sous tension* :
            -
          • !cof-effet-temp sousTension [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 2|Économe (L),--mana 0|Étendue (L),--puissant duree --mana 2|Puissante (L),--puissant --mana 2} pour lancer le sort et mettre le personnage sous tension
          • -
          • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, portée 10, type Sortilège, dégâts électriques, options --si etat sousTension --fx beam-holy.
          • -
          • Utiliser un prédicat voieDeLaMagieElementaliste de valeur le rang dans la voie pour le passage des dégâts à 2d6 quand le personnage est touché.
          • -
          • Pas de support particulier pour la version avancée.
          • +
          • !cof-effet-temp sousTension [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 2|\xC9conome (L),--mana 0|\xC9tendue (L),--puissant duree --mana 2|Puissante (L),--puissant --mana 2} pour lancer le sort et mettre le personnage sous tension
          • +
          • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, port\xE9e 10, type Sortil\xE8ge, d\xE9g\xE2ts \xE9lectriques, options --si etat sousTension --fx beam-holy.
          • +
          • Utiliser un pr\xE9dicat voieDeLaMagieElementaliste de valeur le rang dans la voie pour le passage des d\xE9g\xE2ts \xE0 2d6 quand le personnage est touch\xE9.
          • +
          • Pas de support particulier pour la version avanc\xE9e.
        4. Armure de terre* : - bien utiliser un prédicat voieDeLaMagieElementaliste avec comme valeur le rang dans la voie. Pour lancer le sort, faire !cof-effet-temp protectionContreLesElements [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 3|Économe (L),--mana 1|Étendue (L),--puissant duree --mana 3}.
        5. + bien utiliser un pr\xE9dicat voieDeLaMagieElementaliste avec comme valeur le rang dans la voie. Pour lancer le sort, faire !cof-effet-temp protectionContreLesElements [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 3|\xC9conome (L),--mana 1|\xC9tendue (L),--puissant duree --mana 3}.
        6. Boule de feu* : En Attente
        7. -
        8. Intelligence héroïque : En Attente
        9. +
        10. Intelligence h\xE9ro\xEFque : En Attente

        Voie de la magie runique

          -
        1. Forgeron* : Il faut un prédicat voieDuMetal pour connaître le rang (ou utiliser l'option --valeur). Lancer le sort avec !cof-effet-temp forgeron(L) [[5+@{selected|SAG}]]L est le label d'une attaque. Ensuite, chaque fois que cette attaque sera utilisée, les dégâts seront ajoutés. Limitations : si deux attaques utilisent la même arme, il faut faire deux fois l'action, une pour chaque attaque.
        2. -
        3. Rune d’énergie* : En Attente
        4. +
        5. Forgeron* : Il faut un pr\xE9dicat voieDuMetal pour conna\xEEtre le rang (ou utiliser l'option --valeur). Lancer le sort avec !cof-effet-temp forgeron(L) [[5+@{selected|SAG}]] o\xF9 L est le label d'une attaque. Ensuite, chaque fois que cette attaque sera utilis\xE9e, les d\xE9g\xE2ts seront ajout\xE9s. Limitations : si deux attaques utilisent la m\xEAme arme, il faut faire deux fois l'action, une pour chaque attaque.
        6. +
        7. Rune d\x2019\xE9nergie* : En Attente
        8. Rune de puissance* : En Attente
        9. Rune de garde* : En Attente
        10. Rune de tradition : En Attente

        Voie du mysticisme

          -
        1. Bénédiction* : En Attente
        2. +
        3. B\xE9n\xE9diction* : En Attente
        4. Protection contre le mal* : En Attente
        5. -
        6. Délivrance* : En Attente
        7. +
        8. D\xE9livrance* : En Attente
        9. Sanctuaire* : En Attente
        10. Rituel de puissance : En Attente

        Voie des sombres savoirs

        1. Saignements* : En Attente
        2. -
        3. Malédiction* : En Attente
        4. +
        5. Mal\xE9diction* : En Attente
        6. Pacte sanglant* : En Attente
        7. -
        8. Hémorragie* : En Attente
        9. -
        10. Invocation d’un démon* : En Attente
        11. +
        12. H\xE9morragie* : En Attente
        13. +
        14. Invocation d\x2019un d\xE9mon* : En Attente

        5.4 Voies de prestige

        -

        6. Markers Personnalisés

        -

        6.1 Présentation

        +

        6. Markers Personnalis\xE9s

        +

        6.1 Pr\xE9sentation

        -

        Roll20 peut être déroutant lors des premières utilisations pour des joueurs plus habitués au Jeu de Rôle sur table. Il introduit des notions peu courantes du fait que les combats vont se dérouler sur des "battlemaps" quadrillées ou non. Aussi on va prendre quelques minutes pour expliquer deux notions importantes : les tokens et les tokens markers (plus simplement appelés markers par la suite).

        -

        Le token : Un token est la représentation graphique d'un personnage (PJ ou PNJ) sur la battlemap. Grâce au token on sait à tout moment où se trouve le personnage, s'il subit un sort à effet de zone ou si sa ligne de tir est dégagée par exemple.

        -

        Le marker : Un marker est forcément attaché à un token. Il représente un "état" qui affecte le personnage (liste des états). Il se matérialise par une icône dans le coin en haut à doite du token. Un token peut afficher plusieurs markers au même moment. Ils représentent plusieurs états qui se cumulent pour ce personnage. +

        Roll20 peut \xEAtre d\xE9routant lors des premi\xE8res utilisations pour des joueurs plus habitu\xE9s au Jeu de R\xF4le sur table. Il introduit des notions peu courantes du fait que les combats vont se d\xE9rouler sur des "battlemaps" quadrill\xE9es ou non. Aussi on va prendre quelques minutes pour expliquer deux notions importantes : les tokens et les tokens markers (plus simplement appel\xE9s markers par la suite).

        +

        Le token : Un token est la repr\xE9sentation graphique d'un personnage (PJ ou PNJ) sur la battlemap. Gr\xE2ce au token on sait \xE0 tout moment o\xF9 se trouve le personnage, s'il subit un sort \xE0 effet de zone ou si sa ligne de tir est d\xE9gag\xE9e par exemple.

        +

        Le marker : Un marker est forc\xE9ment attach\xE9 \xE0 un token. Il repr\xE9sente un "\xE9tat" qui affecte le personnage (liste des \xE9tats). Il se mat\xE9rialise par une ic\xF4ne dans le coin en haut \xE0 doite du token. Un token peut afficher plusieurs markers au m\xEAme moment. Ils repr\xE9sentent plusieurs \xE9tats qui se cumulent pour ce personnage.

        -

        Dans l'image ci-dessus le token c'est le personnage à la cape bleue qui représente un PJ et le marker c'est le petit escargot qui signifie que ce même PJ est "ralenti". Le script gère les états des PJ et PNJ et il matérialisera leurs états grâce aux markers. Par exemple le MJ va demande un jet de surprise, le script effectue les jets de dés nécessaire et matérialise l'état "surpris" grâce à un marker pour les personnages qui ont raté leur jet de dé. Le script applique automatiquement le malus -5 à la DEF. Au bout d'un tour l'état "surpris" et le marker seront retirés automatiquement par le script. Le MJ peut aussi mettre directement un état à un personnage. Par exemple s'il considère que ses PJs voyagent trop chargés il peut ajouter le marker "encombré" qui lui rappelera que dorénavant les jets de DEX se font sur un d12 et plus sur un d20.

        -

        Il existe des markers qui ne représentent pas un état mais ils sont rares. On peut souligner les ronds de couleurs qui permmettent au joueur de retrouver son token plus facilement. De la même manière dans les markers cof il y existent deux marqueurs cof-init... qui permettent de repérer le prochain joueur pendant les combats. Ce n'est pas un état.

        +

        Dans l'image ci-dessus le token c'est le personnage \xE0 la cape bleue qui repr\xE9sente un PJ et le marker c'est le petit escargot qui signifie que ce m\xEAme PJ est "ralenti". Le script g\xE8re les \xE9tats des PJ et PNJ et il mat\xE9rialisera leurs \xE9tats gr\xE2ce aux markers. Par exemple le MJ va demande un jet de surprise, le script effectue les jets de d\xE9s n\xE9cessaire et mat\xE9rialise l'\xE9tat "surpris" gr\xE2ce \xE0 un marker pour les personnages qui ont rat\xE9 leur jet de d\xE9. Le script applique automatiquement le malus -5 \xE0 la DEF. Au bout d'un tour l'\xE9tat "surpris" et le marker seront retir\xE9s automatiquement par le script. Le MJ peut aussi mettre directement un \xE9tat \xE0 un personnage. Par exemple s'il consid\xE8re que ses PJs voyagent trop charg\xE9s il peut ajouter le marker "encombr\xE9" qui lui rappelera que dor\xE9navant les jets de DEX se font sur un d12 et plus sur un d20.

        +

        Il existe des markers qui ne repr\xE9sentent pas un \xE9tat mais ils sont rares. On peut souligner les ronds de couleurs qui permmettent au joueur de retrouver son token plus facilement. De la m\xEAme mani\xE8re dans les markers cof il y existent deux marqueurs cof-init... qui permettent de rep\xE9rer le prochain joueur pendant les combats. Ce n'est pas un \xE9tat.

        -

        6.2 Récupération des markers dédiés COF

        +

        6.2 R\xE9cup\xE9ration des markers d\xE9di\xE9s COF

        -

        Roll20 possède des markers par défaut mais ils ne sont pas toujours adaptés pour Chroniques Oubliées Fantasy. La communauté a voté pour choisir les tokens les plus pertinents dans le contexte COF. Voici le lien vers le post dans le forum BBE. N'hésitez pas à venir poser vos questions ou proposer vos talents de graphiste à la communauté.

        -

        Avant de pouvoir créer votre propre jeu de markers sur Roll20, vous devez préalablement télécharger ceux mis à disposition par la communauté depuis le repository GitHub du projet. Procédez comme suit :

        +

        Roll20 poss\xE8de des markers par d\xE9faut mais ils ne sont pas toujours adapt\xE9s pour Chroniques Oubli\xE9es Fantasy. La communaut\xE9 a vot\xE9 pour choisir les tokens les plus pertinents dans le contexte COF. Voici le lien vers le post dans le forum BBE. N'h\xE9sitez pas \xE0 venir poser vos questions ou proposer vos talents de graphiste \xE0 la communaut\xE9.

        +

        Avant de pouvoir cr\xE9er votre propre jeu de markers sur Roll20, vous devez pr\xE9alablement t\xE9l\xE9charger ceux mis \xE0 disposition par la communaut\xE9 depuis le repository GitHub du projet. Proc\xE9dez comme suit :

        -

        Une fois le fichier téléchargé sur votre PC dézippez le répertoire cof-marker-set et son sous-répertoire

        +

        Une fois le fichier t\xE9l\xE9charg\xE9 sur votre PC d\xE9zippez le r\xE9pertoire cof-marker-set et son sous-r\xE9pertoire

        6.3 Importation des markers dans Roll20

        -

        Dans le répertoire cof-marker-set vous trouverez tous les markers qui ont été choisis par la communauté. Dans le répertoire markers-alternatifs vous trouverez les glorieux seconds au vote que vous pouvez utiliser en lieu et place du marker choisi s'il vous plaît plus. Il vous suffit alors de glisser-déposer le fichier dans le répertoire principal et de confirmer l'écrasement de l'autre marker. Vous pouvez aussi choisir vos propres markers dans cette géniale bibliothéque d'icônes. Vous pouvez aussi déssiner vos propre marker. Les limites sont que la taille de l'image doit être exactement de 512x512 px. Un fichier PNG est préférable pour gérer la transparence. Enfin votre fichier doit porter exactement le même nom qu'indiqué dans cette documentation.

        +

        Dans le r\xE9pertoire cof-marker-set vous trouverez tous les markers qui ont \xE9t\xE9 choisis par la communaut\xE9. Dans le r\xE9pertoire markers-alternatifs vous trouverez les glorieux seconds au vote que vous pouvez utiliser en lieu et place du marker choisi s'il vous pla\xEEt plus. Il vous suffit alors de glisser-d\xE9poser le fichier dans le r\xE9pertoire principal et de confirmer l'\xE9crasement de l'autre marker. Vous pouvez aussi choisir vos propres markers dans cette g\xE9niale biblioth\xE9que d'ic\xF4nes. Vous pouvez aussi d\xE9ssiner vos propre marker. Les limites sont que la taille de l'image doit \xEAtre exactement de 512x512 px. Un fichier PNG est pr\xE9f\xE9rable pour g\xE9rer la transparence. Enfin votre fichier doit porter exactement le m\xEAme nom qu'indiqu\xE9 dans cette documentation.

        Dans Roll20 rendez-vous dans le menu "Outils" puis "Token Marker Library". Appuyez sur "Create Set". Puis renseignez le nom du marker set. "cof markers" par exemple. Appuyez sur "Create Set".

        -

        Vous arrivez alors sur la fenêtre suivante où il suffit de déposer les fichiers pour qu'ils soient uploadés sur Roll20

        +

        Vous arrivez alors sur la fen\xEAtre suivante o\xF9 il suffit de d\xE9poser les fichiers pour qu'ils soient upload\xE9s sur Roll20

        -

        A ce moment il y a deux écoles de vie : ceux qui lâchent tous leurs markers en même temps et qui laisse le soin aux serveurs de Roll20 de décider dans quel ordre ils verront apparaître les markers dans leur interface pour le restant de leur jour. Et ceux qui posent les fichiers un par un pour que l'ordre qu'ils souhaitent soit respecté par Roll20. Quand tout est prêt cliquez sur "Upload". Vous avez un message "Fichiers en cours de traitement" pendant 1 à 2 minutes. Ensuite Roll20 vous propose de renommer vos tokens. Ne changez rien et faîtes "Save". Ca y est, vos markers personnalisés sont enfin prêts !

        +

        A ce moment il y a deux \xE9coles de vie : ceux qui l\xE2chent tous leurs markers en m\xEAme temps et qui laisse le soin aux serveurs de Roll20 de d\xE9cider dans quel ordre ils verront appara\xEEtre les markers dans leur interface pour le restant de leur jour. Et ceux qui posent les fichiers un par un pour que l'ordre qu'ils souhaitent soit respect\xE9 par Roll20. Quand tout est pr\xEAt cliquez sur "Upload". Vous avez un message "Fichiers en cours de traitement" pendant 1 \xE0 2 minutes. Ensuite Roll20 vous propose de renommer vos tokens. Ne changez rien et fa\xEEtes "Save". Ca y est, vos markers personnalis\xE9s sont enfin pr\xEAts !

        -

        6.4 Activation et Vérification

        +

        6.4 Activation et V\xE9rification

        -

        Mais ce n'est pas fini il vous faut encore affecter vos markers à votre campagne. Cela se passe sur la page d'acceuil de votre campagne:

        +

        Mais ce n'est pas fini il vous faut encore affecter vos markers \xE0 votre campagne. Cela se passe sur la page d'acceuil de votre campagne:

        -

        Lancez votre campagne et vérifiez que les nouveaux markers apparaissent bien. Lancez ensuite la commande !cof-options pour cocher "Markers Personnalises". Enfin comme dernier contrôle allez dans la console des API, faîtes "restart API sandbox" et vérifiez que le message "Markers personnalisés activés" est bien présent. Si ce n'est pas le cas vous avez probablement oublié des markers "obligatoires" et le script n'a pas pu activer les markers cof pour cette raison. La liste des markers manquants devrait apparaître dans la console.

        +

        Lancez votre campagne et v\xE9rifiez que les nouveaux markers apparaissent bien. Lancez ensuite la commande !cof-options pour cocher "Markers Personnalises". Enfin comme dernier contr\xF4le allez dans la console des API, fa\xEEtes "restart API sandbox" et v\xE9rifiez que le message "Markers personnalis\xE9s activ\xE9s" est bien pr\xE9sent. Si ce n'est pas le cas vous avez probablement oubli\xE9 des markers "obligatoires" et le script n'a pas pu activer les markers cof pour cette raison. La liste des markers manquants devrait appara\xEEtre dans la console.

        7. Console API

        -

        7.1 Généralités sur la Console

        +

        7.1 G\xE9n\xE9ralit\xE9s sur la Console

        -

        Il est recommandé quand vous jouez de garder un onglet de votre navigateur ouvert sur la Console API de votre campagne (Paramètres -> Scripts API). En cas d'absence de réponse du jeu il vous permet de facilement prendre connaissance d'une éventuelle erreur et de prendre rapidement les actions correctives nécessaires.

        -

        Un message bloquant est écrit dans un bloc rouge en dehors de la fenêtre API Output Console et ressemble à l'image suivante :

        +

        Il est recommand\xE9 quand vous jouez de garder un onglet de votre navigateur ouvert sur la Console API de votre campagne (Param\xE8tres -> Scripts API). En cas d'absence de r\xE9ponse du jeu il vous permet de facilement prendre connaissance d'une \xE9ventuelle erreur et de prendre rapidement les actions correctives n\xE9cessaires.

        +

        Un message bloquant est \xE9crit dans un bloc rouge en dehors de la fen\xEAtre API Output Console et ressemble \xE0 l'image suivante :

        -

        Lorsqu'un message rouge comme celui-ci interrompt votre partie vérifiez s'il possède une solution identifiée dans le paragraphe ci-dessous. "Restart API sandbox" permet de relancer le script mais les mêmes causes provoqueront la même erreur. Si le message d'erreur n'est pas encore référencé ou ne propose pas de solution, essayez de comprendre quelle est votre dernière action ou quel bouton provoque cette erreur et terminez votre séance en évitant de l'utiliser. Retestez plus tard et si l'erreur se reproduit expliquez-nous votre problème sur ce post dans le forum BBE. Essayez d'être le plus exhaustif possible dans vos explications car malheureusement les messages de Roll20 ne sont pas précis du tout quant au contexte de l'erreur. Par exemple le numéro de la ligne de code incriminée ne nous est pas connue et l'on a donc besoin de toutes les précisions possibles pour comprendre le problème et être en capacité de le reproduire afin de le corriger.

        -

        Les messages qui sont à l'interieur de la fenêtre API Output Console sont des messages d'information ou d'alerte comme sur l'image suivante :

        +

        Lorsqu'un message rouge comme celui-ci interrompt votre partie v\xE9rifiez s'il poss\xE8de une solution identifi\xE9e dans le paragraphe ci-dessous. "Restart API sandbox" permet de relancer le script mais les m\xEAmes causes provoqueront la m\xEAme erreur. Si le message d'erreur n'est pas encore r\xE9f\xE9renc\xE9 ou ne propose pas de solution, essayez de comprendre quelle est votre derni\xE8re action ou quel bouton provoque cette erreur et terminez votre s\xE9ance en \xE9vitant de l'utiliser. Retestez plus tard et si l'erreur se reproduit expliquez-nous votre probl\xE8me sur ce post dans le forum BBE. Essayez d'\xEAtre le plus exhaustif possible dans vos explications car malheureusement les messages de Roll20 ne sont pas pr\xE9cis du tout quant au contexte de l'erreur. Par exemple le num\xE9ro de la ligne de code incrimin\xE9e ne nous est pas connue et l'on a donc besoin de toutes les pr\xE9cisions possibles pour comprendre le probl\xE8me et \xEAtre en capacit\xE9 de le reproduire afin de le corriger.

        +

        Les messages qui sont \xE0 l'interieur de la fen\xEAtre API Output Console sont des messages d'information ou d'alerte comme sur l'image suivante :

        -

        Malgré la gravité apparente de certains de ces messages (SyntaxError) ils n'empêchent jamais le bon fonctionnement du script. Seuls les messages bloquants apparaissants en rouge empêche le bon fonctionnement du script. Nous n'avons pas complétement la main sur l'apparition de ces messages d'alerte et nous travaillons activement avec Roll20 pour les éliminer. Des messages d'informations sont aussi présents comme par exemple le numéro de version du script que vous utilisez actuellement.

        +

        Malgr\xE9 la gravit\xE9 apparente de certains de ces messages (SyntaxError) ils n'emp\xEAchent jamais le bon fonctionnement du script. Seuls les messages bloquants apparaissants en rouge emp\xEAche le bon fonctionnement du script. Nous n'avons pas compl\xE9tement la main sur l'apparition de ces messages d'alerte et nous travaillons activement avec Roll20 pour les \xE9liminer. Des messages d'informations sont aussi pr\xE9sents comme par exemple le num\xE9ro de version du script que vous utilisez actuellement.

        7.2 Principaux messages bloquants

          -
        • There was an error communicating with the QuantumRoll server Erreur Roll20 courante. "Restart API Sandbox" règle normalement ce problème.
        • -
        • docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host? Erreur Roll20. "Restart API Sandbox" règle normalement ce problème.
        • -
        • SyntaxError: Invalid or unexpected token ... Erreur dans le code. Pas de solution évidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • -
        • SyntaxError: Unexpected token ... Erreur dans le code. Pas de solution évidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • -
        • TypeError: Cannot read property '...' of undefined Erreur dans le code. Pas de solution évidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • +
        • There was an error communicating with the QuantumRoll server Erreur Roll20 courante. "Restart API Sandbox" r\xE8gle normalement ce probl\xE8me.
        • +
        • docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host? Erreur Roll20. "Restart API Sandbox" r\xE8gle normalement ce probl\xE8me.
        • +
        • SyntaxError: Invalid or unexpected token ... Erreur dans le code. Pas de solution \xE9vidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • +
        • SyntaxError: Unexpected token ... Erreur dans le code. Pas de solution \xE9vidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • +
        • TypeError: Cannot read property '...' of undefined Erreur dans le code. Pas de solution \xE9vidente. Le signaler uniquement si c'est un message bloquant (rouge).

        7.3 Principaux messages d'information et d'alerte

          -
        • COFantasy X.XX loaded Information : Le script a correctement démarré. Vous indique le numéro de version utilisé.
        • -
        • Markers personnalisés activés Information : Succès de l'activation des Markers Personnalisés.
        • +
        • COFantasy X.XX loaded Information : Le script a correctement d\xE9marr\xE9. Vous indique le num\xE9ro de version utilis\xE9.
        • +
        • Markers personnalis\xE9s activ\xE9s Information : Succ\xE8s de l'activation des Markers Personnalis\xE9s.
        • API sandbox shutdown due to campaign inactivity Information : "Restart API Sandbox" ou l'utilisation de la campagne remet en route la sandbox.
        • -
        • XXX dans l'équipe XXX est inconnu Alerte : Erreur dans le handout servant de sélection d'équipe. Vérifiez l'orthographe de vos personnages.
        • -
        • Markers personnalisés manquants -> Retour aux markers standards Roll20. Voir erreur(s) ci-dessus. Alerte : Impossibilité d'activer les Markers Personnalisés pour cause d'un marker obligatoire absent.
        • -
        • Marker cof-XXX introuvable Alerte : Erreur dans le nom d'un marker. Voir Markers Personnalisés ou liste des états.
        • -
        • Compétences sans caractéristique associéeAlerte : Erreur de déclaration dans le handout de jets de caractéristique.
        • +
        • XXX dans l'\xE9quipe XXX est inconnu Alerte : Erreur dans le handout servant de s\xE9lection d'\xE9quipe. V\xE9rifiez l'orthographe de vos personnages.
        • +
        • Markers personnalis\xE9s manquants -> Retour aux markers standards Roll20. Voir erreur(s) ci-dessus. Alerte : Impossibilit\xE9 d'activer les Markers Personnalis\xE9s pour cause d'un marker obligatoire absent.
        • +
        • Marker cof-XXX introuvable Alerte : Erreur dans le nom d'un marker. Voir Markers Personnalis\xE9s ou liste des \xE9tats.
        • +
        • Comp\xE9tences sans caract\xE9ristique associ\xE9eAlerte : Erreur de d\xE9claration dans le handout de jets de caract\xE9ristique.
        +

        7.4 Purger les variables d'\xE9tat du jeu

        +
        +

        Pour son bon fonctionnement, le script stoque des donn\xE9es, parfois complexes, et il peut arriver que ces donn\xE9es soient corrompues. Dans ce cas, le script peut planter de mani\xE8re syst\xE9matique, m\xEAme sur des actions simples. Si vous soup\xE7onnez une corruption des donn\xE9es, vous pouvez tenter de lancer la commande !cof-clean-global-state. +

        +

        8. Utiliser des personnages Pathfinder

        -

        Il existe un support basique des fiches Roll20 venant du système Pathfinder 1. La fonction !cof-pathfinder1 se lance en sélectionnant un ou plusieurs tokens liés à des fiches Pathfinder (par exemple obtenues en achetant des aventures Pathfinder sur le marketplace de Roll20). L'effet est d'une part de transformer une partie des attributs de la fiche en attributs compris par la fiche COF et le script COFantasy, de changer un peu le token associé à la fiche, mais surtout d'effacer les attributs inutiles pour COF. En effet, le script est relativement sensible au nombre total d'attributs en jeu, et les fiches Pathfinder ont tendence à en avoir vraiment beaucoup. Tout ce qui n'est pas compris par le script se retrouve dans un attribut Attributs Pathfinder. Mais le mieux est de compléter la fiche COF en se basant sur la fiche Pathfinder ouverte dans une autre partie.

        +

        Il existe un support basique des fiches Roll20 venant du syst\xE8me Pathfinder 1. La fonction !cof-pathfinder1 se lance en s\xE9lectionnant un ou plusieurs tokens li\xE9s \xE0 des fiches Pathfinder (par exemple obtenues en achetant des aventures Pathfinder sur le marketplace de Roll20). L'effet est d'une part de transformer une partie des attributs de la fiche en attributs compris par la fiche COF et le script COFantasy, de changer un peu le token associ\xE9 \xE0 la fiche, mais surtout d'effacer les attributs inutiles pour COF. En effet, le script est relativement sensible au nombre total d'attributs en jeu, et les fiches Pathfinder ont tendence \xE0 en avoir vraiment beaucoup. Tout ce qui n'est pas compris par le script se retrouve dans un attribut Attributs Pathfinder. Mais le mieux est de compl\xE9ter la fiche COF en se basant sur la fiche Pathfinder ouverte dans une autre partie.

        9. Statistiques

        Il est possible d'activer la collecte de statistiques en utilisant la commande !cof-demarrer-statistiques.

        -

        On peut arrêter la collecte avec !cof-arreter-statistiques, et la mettre en pause avec !cof-pause-statistiques.
        - Si on redémarre après une mise en pause, on reprend les statistiques comme elles étaient au moment de la pause. Si on redémarre des statistiques en court, cela remet les statistiques à zéro. +

        On peut arr\xEAter la collecte avec !cof-arreter-statistiques, et la mettre en pause avec !cof-pause-statistiques.
        + Si on red\xE9marre apr\xE8s une mise en pause, on reprend les statistiques comme elles \xE9taient au moment de la pause. Si on red\xE9marre des statistiques en court, cela remet les statistiques \xE0 z\xE9ro.

    -

    Ce site utilise des marques déposées et des droits d’auteurs qui sont la propriété de Black Book Editions comme l’y autorisent les conditions d’utilisation de Black Book Editions. Ce site n’est pas publié par Black Book Editions et n’a pas reçu son aval ni une quelconque approbation de sa part. Pour de plus amples informations sur Black Book Editions, consultez www.black-book-editions.fr.

    +

    Ce site utilise des marques d\xE9pos\xE9es et des droits d\x2019auteurs qui sont la propri\xE9t\xE9 de Black Book Editions comme l\x2019y autorisent les conditions d\x2019utilisation de Black Book Editions. Ce site n\x2019est pas publi\xE9 par Black Book Editions et n\x2019a pas re\xE7u son aval ni une quelconque approbation de sa part. Pour de plus amples informations sur Black Book Editions, consultez www.black-book-editions.fr.

    diff --git a/COFantasy/COFantasy.js b/COFantasy/COFantasy.js index e429abcd18..686a347288 100644 --- a/COFantasy/COFantasy.js +++ b/COFantasy/COFantasy.js @@ -37,48 +37,50 @@ const generateUUID = (function() { }; //--------------- end generateRowID ---------------------------------------- -const COF_BETA = false; +const COF_BETA = true; let COF_loaded = false; -// Le script utilise la partie COFantasy de la variable d'\xE9tat state -// Pour plus de facilit\xE9, on utilise stateCOF = state.COFantasy -// Champs utilis\xE9s: +// Le script utilise la partie COFantasy de la variable d'état state +// Pour plus de facilité, on utilise stateCOF = state.COFantasy +// Champs utilisés: // - options : les options de jeu -// - setting_arran : toutes les fiches utilisent les r\xE8gles Terres d'Arran +// - setting_arran : toutes les fiches utilisent les règles Terres d'Arran // - setting_mixte : on a un mixte de fiches classiques et Terres d'Arran -// - roundMarkerId : l'id du token utilis\xE9 pour l'aura d'initiative -// - combat : d\xE9fini si le jeu est en mode tour par tour, contient : +// - roundMarkerId : l'id du token utilisé pour l'aura d'initiative +// - combat : défini si le jeu est en mode tour par tour, contient : // - pageId : la pageid du combat // - activeTokenId : id du token dont c'est le tour -// - activeTokenName : nom du token dont c'est le tour, au cas o\xF9 l'id change -// - tour : num\xE9ro de tour dans le combat +// - activeTokenName : nom du token dont c'est le tour, au cas où l'id change +// - tour : numéro de tour dans le combat // - init : niveau d'initiative courant // - armeesDesMorts : map de token id vers perso // - auras : liste des auras actives // - aurasCounts : computeur pour id des auras // - usureOff : on ne compte plus l'usure du combat -// - personnageCibleCree : pour savoir si on a cr\xE9\xE9 un personnage cible (avec 0 PV pour centrer les aoe) -// - tablesCrees : pour savoir si on a cr\xE9\xE9 les tables par d\xE9faut -// - gameMacros : la liste des macros cr\xE9\xE9es par le script +// - personnageCibleCree : pour savoir si on a créé un personnage cible (avec 0 PV pour centrer les aoe) +// - tablesCrees : pour savoir si on a créé les tables par défaut +// - gameMacros : la liste des macros créées par le script // - chargeFantastique : tout ce dont on a besoin pour une charge fantastique en cours (TODO: passer sous combat) // - eventId : compteur d'events pour avoir une id unique -// - tokensTemps : liste de tokens \xE0 dur\xE9e de vie limit\xE9e, effac\xE9s \xE0 la fin du combat -// - effetAuD20 : les effets qui se produisent \xE0 chaque jet de d\xE9. -// chaque effet est d\xE9termin\xE9 par un champ, puis pour chaque champ, -// - min: valeur minimale du d\xE9 pour d\xE9clencher -// - max: valeur maximale du d\xE9 pour d\xE9clencher -// - fct: nom de la fonction \xE0 appeler -// - nomFin: nom \xE0 afficher pour le statut et mettre fin aux \xE9v\xE9nements +// - tokensTemps : liste de tokens à durée de vie limitée, effacés à la fin du combat +// - effetAuD20 : les effets qui se produisent à chaque jet de dé. +// chaque effet est déterminé par un champ, puis pour chaque champ, +// - min: valeur minimale du dé pour déclencher +// - max: valeur maximale du dé pour déclencher +// - fct: nom de la fonction à appeler +// - nomFin: nom à afficher pour le statut et mettre fin aux événements // par exemple, foudreDuTemps pour les foudres du temps -// - tenebresMagiques : \xE9tat g\xE9n\xE9ral de t\xE9n\xE8bres magiques -// - jetsEnCours : pour laisser le MJ montrer ou non un jet qui lui a \xE9t\xE9 montr\xE9 \xE0 lui seul +// - tenebresMagiques : état général de ténèbres magiques +// - jetsEnCours : pour laisser le MJ montrer ou non un jet qui lui a été montré à lui seul // - currentAttackDisplay : pour pouvoir remontrer des display aux joueurs // - pause : le jeu est en pause -// - prescience : un personnage sur la carte de combat a la capacit\xE9 prescience (TODO: passer sous combat) +// - prescience : un personnage sur la carte de combat a la capacité prescience (TODO: passer sous combat) // - nextPrescience : pour le changement de tour car prescience ne revient que d'un tour -// - afterDisplay : donn\xE9es \xE0 afficher apr\xE8s un display -// - version : la version du script en cours, pour d\xE9tecter qu'on change de version +// - afterDisplay : données à afficher après un display +// - version : la version du script en cours, pour détecter qu'on change de version +// statistiques : des statistiques pour les jets de dés +// statistiquesEnPause var COFantasy = COFantasy || function() { @@ -118,7 +120,7 @@ var COFantasy = COFantasy || function() { const defaultOptions = { regles: { - explications: "Options qui influent sur les r\xE8gles du jeu", + explications: "Options qui influent sur les règles du jeu", type: 'options', val: { divers: { @@ -126,105 +128,105 @@ var COFantasy = COFantasy || function() { type: 'options', val: { forme_d_arbre_amelioree: { - explications: "+50% \xE0 l'effet de la peau d'\xE9corce en forme d'arbre.", + explications: "+50% à l'effet de la peau d'écorce en forme d'arbre.", val: true, type: 'bool' }, poudre_explosif: { - explications: "Les armes \xE0 poudre font des d\xE9g\xE2ts explosifs", + explications: "Les armes à poudre font des dégâts explosifs", val: true, type: 'bool' }, interchangeable_attaque: { - explications: "La capacit\xE9 interchangeable donne moins de DEF mais plus d'attaque", + explications: "La capacité interchangeable donne moins de DEF mais plus d'attaque", val: true, type: 'bool' }, coups_critiques_etendus: { - explications: "Coup critique \xE0 une attaque d\xE8s qu'elle d\xE9passe DEF + 10", + explications: "Coup critique à une attaque dès qu'elle dépasse DEF + 10", val: false, type: 'bool' }, echec_critique_boule_de_feu: { - explications: "Nombre de m\xE8tre dont le centre d'une boule de feu peut \xEAtre d\xE9plac\xE9 de mani\xE8re al\xE9atoire en cas d'\xE9chec critique. La probabilit\xE9 est inversement proportionelle \xE0 la distance.", + explications: "Nombre de mètre dont le centre d'une boule de feu peut être déplacé de manière aléatoire en cas d'échec critique. La probabilité est inversement proportionelle à la distance.", val: 12, type: 'int' } } }, dommages: { - explications: "R\xE8gles optionnelles sur les dommages", + explications: "Règles optionnelles sur les dommages", type: 'options', val: { blessures_graves: { - explications: "Si on arrive \xE0 0 PV, on perd 1PR, et si on a plus de PR, on a une blessure grave.", + explications: "Si on arrive à 0 PV, on perd 1PR, et si on a plus de PR, on a une blessure grave.", val: true, type: 'bool' }, degats_importants: { - explications: "Si les DMs d\xE9passent CON+niveau en une attaque, on applique aussi la r\xE8gle de blessure grave. Si la valeur de cette option est 0, la r\xE8gles n'est pas appliqu\xE9e. Sinon, la r\xE8gle n'est appliqu\xE9e que si, de plus, les DMs d\xE9passent maxPV / valeur.", + explications: "Si les DMs dépassent CON+niveau en une attaque, on applique aussi la règle de blessure grave. Si la valeur de cette option est 0, la règles n'est pas appliquée. Sinon, la règle n'est appliquée que si, de plus, les DMs dépassent maxPV / valeur.", val: 3, type: 'int' }, dm_minimum: { - explications: "D\xE9g\xE2ts minimum d'une attaque ou autre source de DM.", + explications: "Dégâts minimum d'une attaque ou autre source de DM.", val: 0, type: 'int' }, crit_elementaire: { - explications: "Les DMs constants d'un autre type que celui de l'arme sont aussi multipli\xE9s en cas de critique", + explications: "Les DMs constants d'un autre type que celui de l'arme sont aussi multipliés en cas de critique", val: false, type: 'bool' }, max_rune_protection: { - explications: "Les DMs qu'une rune de protection est capable d'absorber sont limit\xE9s \xE0 10x le rang du forgesort dans la voie des runes", + explications: "Les DMs qu'une rune de protection est capable d'absorber sont limités à 10x le rang du forgesort dans la voie des runes", val: true, type: 'bool' }, dm_explosifs: { - explications: "Tous les d\xE9s de DM sont explosifs", + explications: "Tous les dés de DM sont explosifs", val: false, type: 'bool' } } }, haute_DEF: { - explications: "Options de jeu pour g\xE9rer la haute DEF", + explications: "Options de jeu pour gérer la haute DEF", type: 'options', val: { usure_DEF: { - explications: "Malus de -2 en DEF tous les n tours. Mettre \xE0 0 pour ne pas avoir de malus d'usure", + explications: "Malus de -2 en DEF tous les n tours. Mettre à 0 pour ne pas avoir de malus d'usure", val: 6, type: 'int' }, bonus_attaque_groupe: { - explications: "Lors d'une attaque de groupe, bonus \xE0 la touche par cr\xE9ature suppl\xE9mentaire", + explications: "Lors d'une attaque de groupe, bonus à la touche par créature supplémentaire", val: 2, type: 'int' }, crit_attaque_groupe: { - explications: "Lors d'une attaque de groupe, si le jet de touche d\xE9passe DEF + cette valeur, les dommages sont doubl\xE9s (0 = jamais)", + explications: "Lors d'une attaque de groupe, si le jet de touche dépasse DEF + cette valeur, les dommages sont doublés (0 = jamais)", val: 5, type: 'int' } } }, initiative: { - explications: "Options qui influent sur les r\xE8gles du jeu", + explications: "Options qui influent sur les règles du jeu", type: 'options', val: { initiative_variable: { - explications: "Ajoute 1d6 \xE0 l'initiative, lanc\xE9 une fois par combat par type de cr\xE9ature", + explications: "Ajoute 1d6 à l'initiative, lancé une fois par combat par type de créature", val: false, type: 'bool' }, initiative_variable_individuelle: { - explications: "Lancer l'initiative variable pour chaque cr\xE9ature (n\xE9cessite d'activer l'Initiative variable)", + explications: "Lancer l'initiative variable pour chaque créature (nécessite d'activer l'Initiative variable)", val: false, type: 'bool' }, joueurs_lancent_init: { - explications: "Fait appara\xEEtre un bouton pour que les joueurs lancent leur initiative (n\xE9cessite d'activer l'Initiative variable)", + explications: "Fait apparaître un bouton pour que les joueurs lancent leur initiative (nécessite d'activer l'Initiative variable)", val: false, type: 'bool' } @@ -235,12 +237,12 @@ var COFantasy = COFantasy || function() { type: 'options', val: { mana_totale: { - explications: "Tous les sorts ont un co\xFBt, celui des temp\xEAtes de mana est multipli\xE9 par 3", + explications: "Tous les sorts ont un coût, celui des tempêtes de mana est multiplié par 3", val: false, type: 'bool' }, contrecoup: { - explications: "Avec la Mana Totale, permet au lanceur de sort de payer un d\xE9ficit de PM en PV (COF p. 181)", + explications: "Avec la Mana Totale, permet au lanceur de sort de payer un déficit de PM en PV (COF p. 181)", val: false, type: 'bool' }, @@ -250,7 +252,7 @@ var COFantasy = COFantasy || function() { type: 'bool' }, elixirs_sorts: { - explications: "Toutes fabrications d'\xE9lixir sont consid\xE9r\xE9es comme des sorts (qui peuvent co\xFBter de la mana)", + explications: "Toutes fabrications d'élixir sont considérées comme des sorts (qui peuvent coûter de la mana)", val: true, type: 'bool' }, @@ -263,17 +265,17 @@ var COFantasy = COFantasy || function() { type: 'options', val: { MJ_voit_actions: { - explications: "\xC0 chaque nouveau personnage en combat, montre le choix d'actions au MJ, m\xEAme pour les PJs.", + explications: "À chaque nouveau personnage en combat, montre le choix d'actions au MJ, même pour les PJs.", val: false, type: 'bool' }, MJ_valide_affichage_attaques: { - explications: "Les r\xE9sultats des attaques sont d'abord montr\xE9es au MJ seul, qui peut ensuite les montrer aux joueurs", + explications: "Les résultats des attaques sont d'abord montrées au MJ seul, qui peut ensuite les montrer aux joueurs", val: false, type: 'bool' }, MJ_valide_affichage_jets: { - explications: "Les r\xE9sultats des jets de caract\xE9ristiques sont d'abord montr\xE9es au MJ seul, qui peut ensuite les montrer aux joueurs", + explications: "Les résultats des jets de caractéristiques sont d'abord montrées au MJ seul, qui peut ensuite les montrer aux joueurs", val: false, type: 'bool' }, @@ -298,96 +300,96 @@ var COFantasy = COFantasy || function() { type: 'bool' }, duree_effets: { - explications: "Le script indique la dur\xE9e des effets associ\xE9s aux tokens", + explications: "Le script indique la durée des effets associés aux tokens", val: false, type: 'bool' }, init_dynamique: { - explications: "Fait appara\xEEtre une aura dynamique sur le token qui a l'initiative", + explications: "Fait apparaître une aura dynamique sur le token qui a l'initiative", val: true, type: 'bool' }, markers_personnalises: { - explications: "Utilisation des markers personnalis\xE9s commen\xE7ant par cof", + explications: "Utilisation des markers personnalisés commençant par cof", val: true, type: 'bool' }, table_crit: { - explications: "Utilisation d'une table de critiques nomm\xE9e Echec-Critique-Contact", + explications: "Utilisation d'une table de critiques nommée Echec-Critique-Contact", val: false, type: 'bool' }, depense_mana: { - explications: "Le script pr\xE9cise la quantit\xE9 de mana utilis\xE9e dans le chat \xE0 chaque fois", + explications: "Le script précise la quantité de mana utilisée dans le chat à chaque fois", val: false, type: 'bool' } } }, images: { - explications: "Images par d\xE9faut", + explications: "Images par défaut", type: 'options', val: { image_init: { - explications: "Image utilis\xE9e pour indiquer le personnage dont c'est le tour", + explications: "Image utilisée pour indiquer le personnage dont c'est le tour", type: 'image', val: DEFAULT_DYNAMIC_INIT_IMG }, image_double: { - explications: 'Image utilis\xE9e pour la capacit\xE9 d\xE9doublement', + explications: 'Image utilisée pour la capacité dédoublement', type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/33854984/q10B3KtWsCxcMczLo4BSUw/thumb.png?1496303265" }, image_ombre: { - explications: "Image utilis\xE9e pour l'ombre mortelle", + explications: "Image utilisée pour l'ombre mortelle", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/2781735/LcllgIHvqvu0HAbWdXZbJQ/thumb.png?13900368485" }, image_arbre: { - explications: "Image utilis\xE9e pour la forme d'arbre", + explications: "Image utilisée pour la forme d'arbre", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/52767134/KEGYUXeKnxZr5dbDwQEO4Q/thumb.png?15248300835" }, image_mur_de_force: { - explication: "Image utilis\xE9e pour un mur de force sph\xE9rique", + explication: "Image utilisée pour un mur de force sphérique", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/33213510/5r3NGSso1QBJMJewTEKv0A/thumb.png?1495195634" }, image_mur_de_vent: { - explication: "Image utilis\xE9e pour un mur de vent sph\xE9rique", + explication: "Image utilisée pour un mur de vent sphérique", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/308931095/X5zH4itb9QI9La8O7KfMBQ/thumb.png?1665585092" }, prison_vegetale: { - explication: "Image utilis\xE9e pour la prison v\xE9g\xE9tale", + explication: "Image utilisée pour la prison végétale", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/254738719/c97DFw6JlEePDVXBf-MPsA/thumb.png?1636471250" }, zone_de_vie: { - explication: "Image utilis\xE9e pour les zones de vie", + explication: "Image utilisée pour les zones de vie", type: 'image', val: "https://s3.amazonaws.com/files.d20.io/images/349749304/q3q75jWu9Izlci5YB688WA/thumb.png?1689005544" } } }, sons: { - explications: "Sons par d\xE9faut", + explications: "Sons par défaut", type: 'options', val: { attaque_echec_critique: { - explication: "Son utilis\xE9 pour les \xE9checs critiques d'attaques", + explication: "Son utilisé pour les échecs critiques d'attaques", type: 'son', val: '' }, attaque_reussite_critique: { - explication: "Son utilis\xE9 pour les r\xE9ussites critiques d'attaques", + explication: "Son utilisé pour les réussites critiques d'attaques", type: 'son', val: '' } } }, macros_a_jour: { - explications: "Met automatiquement les macros \xE0 jour", + explications: "Met automatiquement les macros à jour", type: 'bool', val: true } @@ -414,43 +416,43 @@ var COFantasy = COFantasy || function() { } } - //Liste de tables par d\xE9faut + //Liste de tables par défaut const gameTables = [{ name: "Echec-Critique-Contact", showplayers: false, items: [{ - name: "FOR - Bouscul\xE9 : le personnage est renvers\xE9 par son adversaire. Il subit un d\xE9 malus au test de FOR si l\x2019adversaire " + - "est d\x2019une cat\xE9gorie de taille sup\xE9rieure et b\xE9n\xE9ficie d\x2019un d\xE9 bonus dans le cas inverse. " + - "Il subit une attaque gratuite de la part d\x2019un adversaire pendant qu\x2019il est \xE9tal\xE9 au sol (-5 en DEF).", + name: "FOR - Bousculé : le personnage est renversé par son adversaire. Il subit un dé malus au test de FOR si l’adversaire " + + "est d’une catégorie de taille supérieure et bénéficie d’un dé bonus dans le cas inverse. " + + "Il subit une attaque gratuite de la part d’un adversaire pendant qu’il est étalé au sol (-5 en DEF).", weight: 1, }, { - name: "DEX - Maladresse : le personnage laisse tomber au sol l'objet avec lequel il attaque. S\x2019il essaye de le ramasser, " + + name: "DEX - Maladresse : le personnage laisse tomber au sol l'objet avec lequel il attaque. S’il essaye de le ramasser, " + "il subit une attaque gratuite.", weight: 1, }, { - name: "CON - Coup de mou: le personnage subit l\x2019\xE9tat affaibli pendant 3 rounds. Ou il peut annuler cet \xE9tat en reprenant" + - "son souffle par une action limit\xE9e.", + name: "CON - Coup de mou: le personnage subit l’état affaibli pendant 3 rounds. Ou il peut annuler cet état en reprenant" + + "son souffle par une action limitée.", weight: 1, }, { - name: "INT - Erreur tactique : le personnage subit une attaque (gratuite) d\x2019un adversaire \xE0 son contact.", + name: "INT - Erreur tactique : le personnage subit une attaque (gratuite) d’un adversaire à son contact.", weight: 1, }, { name: "SAG - Distrait : le personnage se laisse distraire et ne voit pas venir la prochaine attaque, " + - "l\x2019adversaire b\xE9n\xE9ficiera d\x2019un bonus de +10.", + "l’adversaire bénéficiera d’un bonus de +10.", weight: 1, }, { - name: "CHA - Ridicule : le personnage fait un faux mouvement \xE0 la fois douloureux et ridicule, il subit " + - "l\x2019\xE9tat \xE9tourdi pendant un round pour reprendre contenance.", + name: "CHA - Ridicule : le personnage fait un faux mouvement à la fois douloureux et ridicule, il subit " + + "l’état étourdi pendant un round pour reprendre contenance.", weight: 1, }, { - name: "Votre arme se brise. S\x2019il s\x2019agit d\x2019une arme magique, le d\xE9 DM est simplement r\xE9duit d'une cat\xE9gorie " + - "(2d6/d12=>d10=>d8=>d6=>d4=>d3) jusqu\x2019\xE0 la fin du combat.", + name: "Votre arme se brise. S’il s’agit d’une arme magique, le dé DM est simplement réduit d'une catégorie " + + "(2d6/d12=>d10=>d8=>d6=>d4=>d3) jusqu’à la fin du combat.", weight: 1, }, { - name: "Une pi\xE8ce d\x2019armure bouge et elle devient plus g\xEAnante que protectrice : malus en DEF et en attaque pour le reste du combat. Cuir : -1, Maille : -2, Plaque -3.", + name: "Une pièce d’armure bouge et elle devient plus gênante que protectrice : malus en DEF et en attaque pour le reste du combat. Cuir : -1, Maille : -2, Plaque -3.", weight: 1, }, { - name: "Simple \xE9chec de l'attaque", + name: "Simple échec de l'attaque", weight: 12, }, ], }, ]; @@ -534,7 +536,7 @@ var COFantasy = COFantasy || function() { return false; } - // Attention, def, la valeur par d\xE9faut, doit \xEAtre la m\xEAme que sur la fiche + // Attention, def, la valeur par défaut, doit être la même que sur la fiche // personnage peut ne pas avoir de token function ficheAttribute(personnage, name, def) { let attr = charAttribute(personnage.charId, name, { @@ -553,7 +555,7 @@ var COFantasy = COFantasy || function() { return attrAsInt(attr, def, defPresent); } - //Il faut une valeur par d\xE9faut, qui correspond \xE0 celle de la fiche + //Il faut une valeur par défaut, qui correspond à celle de la fiche function ficheAttributeAsBool(personnage, name, def) { let attr = charAttribute(personnage.charId, name, { caseInsensitive: true @@ -562,7 +564,7 @@ var COFantasy = COFantasy || function() { return attrAsBool(attr); } - //Attention \xE0 ne pas utiliser si l'attribut ne d\xE9pend pas du token + //Attention à ne pas utiliser si l'attribut ne dépend pas du token //defPresent est optionnel //personnage peut ne pas avoir de token function attributeAsInt(personnage, name, def, defPresent) { @@ -703,8 +705,8 @@ var COFantasy = COFantasy || function() { } - //Probl\xE8me : \xE7a ne peut pas marcher pour les boucliers en main gauche - //car \xE7a utilise lui-m\xEAme un bouclier... + //Problème : ça ne peut pas marcher pour les boucliers en main gauche + //car ça utilise lui-même un bouclier... function getPredicates(perso) { if (perso.predicates === undefined) { const estMook = perso.token && perso.token.get('bar1_link') === ''; @@ -718,12 +720,12 @@ var COFantasy = COFantasy || function() { raw += '\n' + perso.arme.predicats; if (perso.armeGauche && perso.armeGauche.predicats) raw += '\n' + perso.armeGauche.predicats; - } else if (perso.arme) { //possible si appel\xE9 depuis armesEnMain + } else if (perso.arme) { //possible si appelé depuis armesEnMain if (perso.arme.predicats) raw += '\n' + perso.arme.predicats; - } else { //il faut chercher les pr\xE9dicats des armes en main - //On n'appelle pas armesEnMain pour \xE9viter la r\xE9cursion - //et pour \xE9viter trop de calcul + } else { //il faut chercher les prédicats des armes en main + //On n'appelle pas armesEnMain pour éviter la récursion + //et pour éviter trop de calcul let attrArmes = tokenAttribute(perso, 'armeEnMain'); if (attrArmes.length > 0) { let att; @@ -811,7 +813,7 @@ var COFantasy = COFantasy || function() { caseInsensitive: true }); if (typePerso.length > 0 && typePerso[0].get('current') == 'PNJ') - return; //Les fiches de PNJ sont les m\xEAmes + return; //Les fiches de PNJ sont les mêmes let setting = charAttribute(c.id, 'option_setting', { caseInsensitive: true }); @@ -823,7 +825,7 @@ var COFantasy = COFantasy || function() { else charsGenerique.push(c); }); if (charsArran.length <= charsGenerique.length) { - log("Utilisation des r\xE8gles COF g\xE9n\xE9riques"); + log("Utilisation des règles COF génériques"); if (charsArran.length > 0) { error("Attention, des personnages suivent les options de jeu des Terres d'Arran (voir le log pour la liste)", charsArran); charsArran.forEach(function(c) { @@ -835,7 +837,7 @@ var COFantasy = COFantasy || function() { } return; } - log("Utilisation des r\xE8gles des Terres d'Arran"); + log("Utilisation des règles des Terres d'Arran"); if (charsGenerique.length > 0) { error("Attention, des personnages ne suivent pas les options de jeu des Terres d'Arran (voir le log pour la liste)", charsGenerique); charsGenerique.forEach(function(c) { @@ -869,7 +871,7 @@ var COFantasy = COFantasy || function() { effet_de_marker[m.tag] = effet; } else if (ms) { if (effet_de_marker[ms] && effet_de_marker[ms] != effet) { - sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le m\xEAme icone"); + sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le même icone"); } effet_de_marker[ms] = effet; } else { @@ -880,7 +882,7 @@ var COFantasy = COFantasy || function() { function splitIdName(idn) { let pos = idn.indexOf(' '); if (pos < 1 || pos >= idn.length) { - error("idName mal form\xE9", idn); + error("idName mal formé", idn); return; } let name = idn.substring(pos + 1); @@ -890,8 +892,8 @@ var COFantasy = COFantasy || function() { }; } - //Renvoie le token et le charId. Si l'id ne correspond \xE0 rien, cherche si - //on trouve un nom de token, sur la page pass\xE9e en argument (ou sinon + //Renvoie le token et le charId. Si l'id ne correspond à rien, cherche si + //on trouve un nom de token, sur la page passée en argument (ou sinon //sur la page active de la campagne) function persoOfId(id, name, pageId, allPages) { let token = getObj('graphic', id); @@ -926,14 +928,14 @@ var COFantasy = COFantasy || function() { } else return undefined; } if (tokens.length > 1) { - error("Ambig\xFCit\xE9 sur le choix d'un token : il y a " + - tokens.length + " tokens nomm\xE9s " + name, tokens); + error("Ambigüité sur le choix d'un token : il y a " + + tokens.length + " tokens nommés " + name, tokens); } token = tokens[0]; } let charId = token.get('represents'); if (charId === '') { - error("le token s\xE9lectionn\xE9 ne repr\xE9sente pas de personnage", token); + error("le token sélectionné ne représente pas de personnage", token); return undefined; } return { @@ -942,7 +944,7 @@ var COFantasy = COFantasy || function() { }; } - //Retourne le perso correspondant \xE0 un token id suivi du nom de token + //Retourne le perso correspondant à un token id suivi du nom de token //Permet d'avoir une information robuste en cas d'interruption du script //peuple tokName function persoOfIdName(idn, pageId, allPages) { @@ -950,7 +952,7 @@ var COFantasy = COFantasy || function() { if (sp === undefined) return; let perso = persoOfId(sp.id, sp.name, pageId, allPages); if (perso === undefined) { - log("Impossible de trouver le personnage correspondant \xE0 " + sp.name); + log("Impossible de trouver le personnage correspondant à " + sp.name); return; } perso.tokName = perso.token.get('name'); @@ -1008,7 +1010,7 @@ var COFantasy = COFantasy || function() { } if (sync != threadSync) return; if (token) { - // Cas sp\xE9ciaux du cavaliers + // Cas spéciaux du cavaliers let pageId = token.get('pageid'); let personnage = persoOfId(token.id); let monteSur = tokenAttribute(personnage, 'monteSur'); @@ -1047,7 +1049,7 @@ var COFantasy = COFantasy || function() { return false; }); } catch (uriError) { - log("Erreur de d\xE9codage URI dans la note GM de " + token.get('name') + " : " + gmNotes); + log("Erreur de décodage URI dans la note GM de " + token.get('name') + " : " + gmNotes); } roundMarker = createObj('graphic', roundMarkerSpec); if (roundMarker === undefined && localImage) { @@ -1061,12 +1063,12 @@ var COFantasy = COFantasy || function() { roundMarker = createObj('graphic', roundMarkerSpec); } if (roundMarker === undefined) { - error("Impossible de cr\xE9er le token pour l'aura dynamique", roundMarkerSpec); + error("Impossible de créer le token pour l'aura dynamique", roundMarkerSpec); return false; } stateCOF.roundMarkerId = roundMarker.id; if (roundMarkerSpec.layer === 'map') toFront(roundMarker); - // Ne pas amener une monture mont\xE9e en avant pour \xE9viter de cacher le cavalier + // Ne pas amener une monture montée en avant pour éviter de cacher le cavalier if (cavalier && monture) { toFront(monture.token); toFront(cavalier.token); @@ -1094,7 +1096,7 @@ var COFantasy = COFantasy || function() { token.set('aura2_radius', ''); token.set('showplayers_aura2', false); } else { - // Cas des tokens personnalis\xE9s + // Cas des tokens personnalisés if (statusForInitEnemy && statusForInitAlly) { token.set(statusForInitAlly, false); token.set(statusForInitEnemy, false); @@ -1102,14 +1104,14 @@ var COFantasy = COFantasy || function() { } } - //Appel\xE9 au lancement du script, mise \xE0 jour de certaines variables globales + //Appelé au lancement du script, mise à jour de certaines variables globales function setStateCOF() { stateCOF = state.COFantasy; - stateCOF.predicats = {}; //pr\xE9dicats par charId. + stateCOF.predicats = {}; //prédicats par charId. if (stateCOF.roundMarkerId) { roundMarker = getObj('graphic', stateCOF.roundMarkerId); if (roundMarker === undefined) { - log("Le marqueur d'init a chang\xE9 d'id"); + log("Le marqueur d'init a changé d'id"); let roundMarkers = findObjs({ _type: 'graphic', represents: '', @@ -1139,7 +1141,7 @@ var COFantasy = COFantasy || function() { } } if (!stateCOF.personnageCibleCree) { - //On cherche si un personnage cible existe d\xE9j\xE0 + //On cherche si un personnage cible existe déjà let persos = findObjs({ _type: 'character', name: 'Cible', @@ -1200,7 +1202,7 @@ var COFantasy = COFantasy || function() { } stateCOF.personnageCibleCree = true; } - //Cr\xE9ation des tables par d\xE9faut + //Création des tables par défaut if (!stateCOF.tablesCrees) { let allTables = findObjs({ _type: 'rollabletable', @@ -1257,7 +1259,7 @@ var COFantasy = COFantasy || function() { m.set('visibleto', ngm.visibleto); if (ngm.istokenaction != gm.istokenaction && m.get('istokenaction') == gm.istokenaction) m.set('istokenaction', ngm.istokenaction); - sendChat('COF', '/w GM Macro ' + ngm.name + ' mise \xE0 jour.'); + sendChat('COF', '/w GM Macro ' + ngm.name + ' mise à jour.'); }); } else { ngm = gameMacros.find(function(ngm) { @@ -1276,14 +1278,14 @@ var COFantasy = COFantasy || function() { m.set('visibleto', ngm.visibleto); if (ngm.istokenaction != gm.istokenaction && m.get('istokenaction') == gm.istokenaction) m.set('istokenaction', ngm.istokenaction); - sendChat('COF', '/w GM Macro ' + ngm.name + ' mise \xE0 jour.'); + sendChat('COF', '/w GM Macro ' + ngm.name + ' mise à jour.'); }); } else { macros.forEach(function(m) { if (m.get('name') != gm.name) return; if (m.get('action') != gm.action) return; m.remove(); - sendChat('COF', '/w GM Macro ' + gm.name + ' effac\xE9e.'); + sendChat('COF', '/w GM Macro ' + gm.name + ' effacée.'); }); } } @@ -1299,7 +1301,7 @@ var COFantasy = COFantasy || function() { return macro.get('name') == ngm.name; }); if (prev === undefined) { - sendChat('COF', '/w GM Macro ' + ngm.name + ' cr\xE9\xE9e.'); + sendChat('COF', '/w GM Macro ' + ngm.name + ' créée.'); if (ngm.inBar) inBar.push(ngm.name); mjs.forEach(function(playerId, i) { if (i === 0 || ngm.visibleto === '') { @@ -1311,10 +1313,10 @@ var COFantasy = COFantasy || function() { } }); } else { - //Peut-\xEAtre la premi\xE8re fois, v\xE9rifier les macros + //Peut-être la première fois, vérifier les macros if (stateCOF.macros) { - //ancienne version, et on avait copi\xE9 les macros - //on enl\xE8ve juste Escalier, et on remplace par Monter et Descendre + //ancienne version, et on avait copié les macros + //on enlève juste Escalier, et on remplace par Monter et Descendre let mesc = macros.find(function(m) { return m.get('name') == 'Escalier'; }); @@ -1344,7 +1346,7 @@ var COFantasy = COFantasy || function() { return macro.get('name') == m.name; }); if (prev === undefined) { - sendChat('COF', '/w GM Macro ' + m.name + ' cr\xE9\xE9e.'); + sendChat('COF', '/w GM Macro ' + m.name + ' créée.'); if (m.inBar) inBar.push(m.name); mjs.forEach(function(playerId, i) { if (i === 0 || m.visibleto === '') { @@ -1357,16 +1359,16 @@ var COFantasy = COFantasy || function() { } } if (inBar.length > 0) { - sendChat('COF', "/w GM Macros \xE0 mettre dans la barre d'action du MJ : " + inBar.join(', ')); + sendChat('COF', "/w GM Macros à mettre dans la barre d'action du MJ : " + inBar.join(', ')); } stateCOF.gameMacros = gameMacros; } - // R\xE9cup\xE9ration des token Markers attach\xE9s \xE0 la campagne image, nom, tag, Id + // Récupération des token Markers attachés à la campagne image, nom, tag, Id const markers = JSON.parse(Campaign().get('token_markers')); markers.forEach(function(m) { markerCatalog[m.name] = m; }); - // Option Markers personnalis\xE9s activ\xE9 + // Option Markers personnalisés activé if (stateCOF.options.affichage.val.markers_personnalises.val) { const cof_states_perso = { assomme: 'status_cof-assomme', @@ -1384,10 +1386,10 @@ var COFantasy = COFantasy || function() { blesse: 'status_cof-blesse', encombre: 'status_cof-encombre', penombre: 'status_cof-penombre', - //enseveli: 'status_edge-crack' -> \xC0 dessiner + //enseveli: 'status_edge-crack' -> À dessiner chef: 'status_cof-chef', }; - // On boucle sur la liste des \xE9tats pour v\xE9rifier que les markers sont bien pr\xE9sents ! + // On boucle sur la liste des états pour vérifier que les markers sont bien présents ! let markersAbsents = []; let ancientSet = true; for (let etat in cof_states_perso) { @@ -1429,7 +1431,7 @@ var COFantasy = COFantasy || function() { default: if (ms) { if (effet_de_marker[ms] && effet_de_marker[ms] != effet) { - sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le m\xEAme icone"); + sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le même icone"); } effet_de_marker[ms] = effet; } @@ -1445,7 +1447,7 @@ var COFantasy = COFantasy || function() { default: if (ms) { if (effet_de_marker[ms] && effet_de_marker[ms] != effet) { - sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le m\xEAme icone"); + sendChat('COF', effet_de_marker[ms] + " et " + effet + " ont le même icone"); } effet_de_marker[ms] = effet; } @@ -1455,9 +1457,9 @@ var COFantasy = COFantasy || function() { markersAbsents.forEach(function(m) { log("Marker " + m + " introuvable"); }); - log("Markers personnalis\xE9s activ\xE9s."); + log("Markers personnalisés activés."); } else { - log("Utilisation des markers par d\xE9faut"); + log("Utilisation des markers par défaut"); } } //Construction de la table markers => etat @@ -1476,7 +1478,7 @@ var COFantasy = COFantasy || function() { return res; } - // retourne un tableau contenant la liste des ID de joueurs connect\xE9s controllant le personnage li\xE9 au Token + // retourne un tableau contenant la liste des ID de joueurs connectés controllant le personnage lié au Token function getPlayerIds(perso) { let character = getObj('character', perso.charId); if (character === undefined) return; @@ -1525,7 +1527,7 @@ var COFantasy = COFantasy || function() { return res; } - //PNJ au sens de la fiche utilis\xE9e, pas forc\xE9ment en jeu + //PNJ au sens de la fiche utilisée, pas forcément en jeu //perso peut ne pas avoir de token function persoEstPNJ(perso) { if (perso.pnj) return true; @@ -1586,7 +1588,7 @@ var COFantasy = COFantasy || function() { return true; } - //Met le champ field \xE0 value du token dans evt, pour permettre le undo + //Met le champ field à value du token dans evt, pour permettre le undo //Retourne evt.affectes[token.id] function affectToken(token, field, value, evt) { evt.affectes = evt.affectes || {}; @@ -1656,7 +1658,7 @@ var COFantasy = COFantasy || function() { sendChat(dest, msg); } - //Chuchote le message \xE0 tous les joueurs pr\xE9sents qui controllent le + //Chuchote le message à tous les joueurs présents qui controllent le //personnage, plus le MJ function whisperChar(charId, msg) { let character = getObj('character', charId); @@ -1783,7 +1785,7 @@ var COFantasy = COFantasy || function() { // resultatDesSeuls (rempli par la fonction si true) //Renvoie 1dk + bonus, avec le texte //champs val et roll - //de peut \xEAtre un nombre > 0 ou bien le r\xE9sultat de parseDice + //de peut être un nombre > 0 ou bien le résultat de parseDice function rollDePlus(de, options) { options = options || {}; options.nbDes = options.nbDes || 1; @@ -1844,7 +1846,7 @@ var COFantasy = COFantasy || function() { return res; } - //Si evt est d\xE9fini, alors on consid\xE8re qu'il faut y mettre la valeur actuelle + //Si evt est défini, alors on considère qu'il faut y mettre la valeur actuelle function updateCurrentBar(perso, barNumber, val, evt, maxVal) { let token = perso.token; let prevToken; @@ -1891,7 +1893,7 @@ var COFantasy = COFantasy || function() { if (maxVal) aset.max = maxVal; attr.setWithWorker(aset); if (HTdeclared) HealthColors.Update(token, prevToken); - //Gestion du lien des PVs entre familier et son ma\xEEtre + //Gestion du lien des PVs entre familier et son maître if (barNumber == 1) { let nomPersoLie = predicateAsBool(perso, 'PVPartagesAvec'); if (nomPersoLie) { @@ -2052,7 +2054,7 @@ var COFantasy = COFantasy || function() { case 'FOR': return 'force'; case 'DEX': - if (accent) return 'dext\xE9rit\xE9'; + if (accent) return 'dextérité'; return 'dexterite'; case 'CON': return 'constitution'; @@ -2071,9 +2073,9 @@ var COFantasy = COFantasy || function() { return 'pnj_' + m.toLowerCase(); } - //Retourne le mod de la caract\xE9ristque enti\xE8re. + //Retourne le mod de la caractéristque entière. //si carac n'est pas une carac, retourne 0 - //perso peut ne pas avoir de token ou \xEAtre juste un charId + //perso peut ne pas avoir de token ou être juste un charId function modCarac(perso, carac) { if (perso.charId === undefined) perso = { charId: perso @@ -2131,11 +2133,11 @@ var COFantasy = COFantasy || function() { } //options peut contenir - // msg: un message \xE0 afficher + // msg: un message à afficher // maxVal: la valeur max de l'attribut - // secret: le message n'est pas affich\xE9 pour tout le monde. - // charAttr: si pr\xE9sent, on utilise un attribut de personnage - // renvoie l'attribut cr\xE9\xE9 ou mis \xE0 jour + // secret: le message n'est pas affiché pour tout le monde. + // charAttr: si présent, on utilise un attribut de personnage + // renvoie l'attribut créé ou mis à jour function setTokenAttr(personnage, attribute, value, evt, options) { let charId = personnage.charId; let token = personnage.token; @@ -2155,7 +2157,7 @@ var COFantasy = COFantasy || function() { }; let name = 'inconnu'; if (token) name = token.get('name'); - error("Cr\xE9ation d'un attribut undefined pour " + name, args); + error("Création d'un attribut undefined pour " + name, args); return; } let attr = findObjs({ @@ -2183,7 +2185,7 @@ var COFantasy = COFantasy || function() { let taille = taillePersonnage(personnage, 4); if (taille == 5) { arme.deuxMains = false; - sendPerso(personnage, "peut maintenant tenir " + arme.name + " \xE0 une main"); + sendPerso(personnage, "peut maintenant tenir " + arme.name + " à une main"); degainerArme(personnage, arme.label, evt); } } @@ -2197,11 +2199,11 @@ var COFantasy = COFantasy || function() { token.set('height', height); break; case 'formeDArbre': - //On copie les PVs pour pouvoir les restaurer \xE0 la fin de l'effet + //On copie les PVs pour pouvoir les restaurer à la fin de l'effet setTokenAttr(personnage, 'anciensPV', token.get('bar1_value'), evt, { maxVal: token.get('bar1_max') }); - //On va cr\xE9er une copie de token, mais avec une image d'arbre + //On va créer une copie de token, mais avec une image d'arbre let tokenFields = getTokenFields(token, pageId, personnage.charId); let tokenArbre; let imageArbre = predicateAsBool(personnage, 'tokenFormeDArbre'); @@ -2216,7 +2218,7 @@ var COFantasy = COFantasy || function() { if (tokenArbre) { evt.tokens = evt.tokens || []; evt.tokens.push(tokenArbre); - //On met l'ancien token dans le gmlayer, car si l'image vient du marketplace, il est impossible de le recr\xE9er depuis l'API + //On met l'ancien token dans le gmlayer, car si l'image vient du marketplace, il est impossible de le recréer depuis l'API setToken(token, 'layer', 'gmlayer', evt); setTokenAttr(personnage, 'changementDeToken', true, evt); replaceInTurnTracker(token.id, tokenArbre.id, evt); @@ -2314,7 +2316,7 @@ var COFantasy = COFantasy || function() { return attr; } - // evt peut \xEAtre undefined + // evt peut être undefined // options peut avoir les champs msg et secret function removeTokenAttr(personnage, attribute, evt, options) { attribute = fullAttributeName(personnage, attribute, options); @@ -2351,8 +2353,8 @@ var COFantasy = COFantasy || function() { }); } - //cherche l'attribut attribute de valeur par d\xE9faut def - //et lui ajoute la valeur val. Cr\xE9e l'attribut si besoin + //cherche l'attribut attribute de valeur par défaut def + //et lui ajoute la valeur val. Crée l'attribut si besoin //retourne la nouvelle valeur de l'attribut function addToAttributeAsInt(perso, attribute, def, val, evt) { evt.attributes = evt.attributes || []; @@ -2398,11 +2400,11 @@ var COFantasy = COFantasy || function() { //options: //fromTemp si on est en train de supprimer un effet temporaire - //affectToken si on a d\xE9j\xE0 chang\xE9 le statusmarkers (on vient donc d'un changement \xE0 la main d'un marker + //affectToken si on a déjà changé le statusmarkers (on vient donc d'un changement à la main d'un marker function setState(personnage, etat, value, evt, options) { let token = personnage.token; if (value && predicateAsBool(personnage, 'immunite_' + etat)) { - sendPerso(personnage, 'ne peut pas \xEAtre ' + stringOfEtat(etat, personnage)); + sendPerso(personnage, 'ne peut pas être ' + stringOfEtat(etat, personnage)); return false; } options = options || {}; @@ -2456,7 +2458,7 @@ var COFantasy = COFantasy || function() { } } } - if (!value) { //On enl\xE8ve le save si il y en a un + if (!value) { //On enlève le save si il y en a un removeTokenAttr(personnage, etat + 'Save', evt); removeTokenAttr(personnage, etat + 'SaveParTour', evt); } @@ -2482,7 +2484,7 @@ var COFantasy = COFantasy || function() { token.set('light_losangle', 0); } //Normalement, ne peut plus suivre personne ? - //Si il peut parce qu'il touche ou tient une corde, r\xE9utiliser la macro + //Si il peut parce qu'il touche ou tient une corde, réutiliser la macro //pour suivre nePlusSuivre(personnage, pageId, evt); } else { @@ -2499,7 +2501,7 @@ var COFantasy = COFantasy || function() { let attrInvisible = tokenAttribute(personnage, 'tokenInvisible'); if (value) { if (attrInvisible.length === 0) { - //On va cr\xE9er une copie de token, mais avec une image invisible et aura visible seulement de ceux qui contr\xF4lent le token + //On va créer une copie de token, mais avec une image invisible et aura visible seulement de ceux qui contrôlent le token let tokenFields = getTokenFields(token, pageId, personnage.charId); tokenFields.layer = 'objects'; tokenFields.aura1_radius = 0; @@ -2520,7 +2522,7 @@ var COFantasy = COFantasy || function() { } evt.tokens = evt.tokens || []; evt.tokens.push(tokenInvisible); - //On met l'ancien token dans le gmlayer, car si l'image vient du marketplace, il est impossible de le recr\xE9er depuis l'API + //On met l'ancien token dans le gmlayer, car si l'image vient du marketplace, il est impossible de le recréer depuis l'API setToken(token, 'layer', 'gmlayer', evt); setTokenAttr(personnage, 'tokenInvisible', token.id, evt, { maxVal: tokenInvisible.id @@ -2534,7 +2536,7 @@ var COFantasy = COFantasy || function() { } } } - } else { //On enl\xE8ve l'\xE9tat invisible + } else { //On enlève l'état invisible if (attrInvisible.length > 0) { let tokenOriginel = getObj('graphic', attrInvisible[0].get('current')); if (!tokenOriginel) { @@ -2551,7 +2553,7 @@ var COFantasy = COFantasy || function() { }); if (tokenOriginel.length > 0) tokenOriginel = tokenOriginel[0]; else { - error("Impossible de retrouver le token de d\xE9part de " + token.get('name') + " quand on enl\xE8ve l'\xE9tat invisible", attrInvisible); + error("Impossible de retrouver le token de départ de " + token.get('name') + " quand on enlève l'état invisible", attrInvisible); tokenOriginel = false; } } @@ -2571,7 +2573,7 @@ var COFantasy = COFantasy || function() { }); if (tokenCourant.length > 0) tokenCourant = tokenCourant[0]; else { - error("Impossible de retrouver le token visible de " + token.get('name') + " quand on enl\xE8ve l'\xE9tat invisible", attrInvisible); + error("Impossible de retrouver le token visible de " + token.get('name') + " quand on enlève l'état invisible", attrInvisible); tokenCourant = false; } } @@ -2611,7 +2613,7 @@ var COFantasy = COFantasy || function() { switch (etat) { case 'mort': { - //On s'assure de mettre les PV de la cible \xE0 0 (pour les insta kills sans dommages) + //On s'assure de mettre les PV de la cible à 0 (pour les insta kills sans dommages) if (token.get('bar1_value') > 0) updateCurrentBar(personnage, 1, 0, evt); nePlusSuivre(personnage, pageId, evt); lockToken(personnage, evt); @@ -2630,14 +2632,14 @@ var COFantasy = COFantasy || function() { removeTokenAttr(personnage, 'estMontePar', evt); removeTokenAttr(personnage, 'positionSurMonture', evt); } - //On lib\xE8re les personnages envelopp\xE9s, si il y en a. + //On libère les personnages enveloppés, si il y en a. let attrEnveloppe = tokenAttribute(personnage, 'enveloppe'); attrEnveloppe.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); if (cible) { let envDM = a.get('max'); if (envDM.startsWith('etreinte')) { - //On a une \xE9treinte, on enl\xE8ve donc l'\xE9tat immobilis\xE9 + //On a une étreinte, on enlève donc l'état immobilisé setState(cible, 'immobilise', false, evt); } evt.deletedAttributes = evt.deletedAttributes || []; @@ -2648,7 +2650,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); } else if (cube.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + cube.tokName); + sendPerso(cible, 'se libère de ' + cube.tokName); toFront(cible.token); evt.deletedAttributes.push(a); a.remove(); @@ -2659,14 +2661,14 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //Si le mort est envelopp\xE9, il est relach\xE9 + //Si le mort est enveloppé, il est relaché attrEnveloppe = tokenAttribute(personnage, 'enveloppePar'); attrEnveloppe.forEach(function(a) { let cube = persoOfIdName(a.get('current'), pageId); if (cube) { let envDiff = a.get('max'); if (envDiff.startsWith('etreinte')) { - //On a une \xE9treinte, on enl\xE8ve donc l'\xE9tat immobilis\xE9 + //On a une étreinte, on enlève donc l'état immobilisé setState(personnage, 'immobilise', false, evt); } evt.deletedAttributes = evt.deletedAttributes || []; @@ -2686,7 +2688,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages agripp\xE9s, si il y en a. + //On libère les personnages agrippés, si il y en a. let attrAgrippe = tokenAttribute(personnage, 'agrippe'); attrAgrippe.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2696,7 +2698,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); if (a.get('max')) setState(cible, 'immobilise', false, evt); evt.deletedAttributes.push(a); @@ -2708,7 +2710,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages d\xE9vor\xE9s, si il y en a. + //On libère les personnages dévorés, si il y en a. let attrDevore = tokenAttribute(personnage, 'devore'); attrDevore.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2718,7 +2720,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); setState(cible, 'immobilise', false, evt); evt.deletedAttributes.push(a); @@ -2729,7 +2731,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages \xE9cras\xE9s, si il y en a. + //On libère les personnages écrasés, si il y en a. let attrEcrase = tokenAttribute(personnage, 'ecrase'); attrEcrase.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2739,7 +2741,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); evt.deletedAttributes.push(a); a.remove(); @@ -2749,7 +2751,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages aval\xE9s, si il y en a. + //On libère les personnages avalés, si il y en a. let attrGobe = tokenAttribute(personnage, 'aGobe'); attrGobe.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2770,7 +2772,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages sous \xE9treinte et immolation + //On libère les personnages sous étreinte et immolation let attrEtreinteImmole = tokenAttribute(personnage, 'etreinteImmole'); attrEtreinteImmole.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2780,7 +2782,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); setState(cible, 'immobilise', false, evt); evt.deletedAttributes.push(a); @@ -2791,7 +2793,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(a); a.remove(); }); - //On lib\xE8re les personnages sous \xE9treinte de scorpion + //On libère les personnages sous étreinte de scorpion let attrEtreinteScorpion = tokenAttribute(personnage, 'etreinteScorpionSur'); attrEtreinteScorpion.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); @@ -2802,7 +2804,7 @@ var COFantasy = COFantasy || function() { attrCible.forEach(function(a) { let agrippant = persoOfIdName(a.get('current', pageId)); if (agrippant.token.id == personnage.token.id) { - sendPerso(cible, 'se lib\xE8re de ' + agrippant.tokName); + sendPerso(cible, 'se libère de ' + agrippant.tokName); toFront(cible.token); evt.deletedAttributes.push(a); a.remove(); @@ -2850,7 +2852,7 @@ var COFantasy = COFantasy || function() { attaqueExplosion(msg); } } - //On termine les effets temporaires li\xE9s au personnage + //On termine les effets temporaires liés au personnage let etlAttr = tokenAttribute(personnage, 'effetsTemporairesLies'); if (etlAttr.length > 0) { etlAttr = etlAttr[0]; @@ -2873,7 +2875,7 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes.push(etlAttr); etlAttr.remove(); } - //On enl\xE8ve les auras + //On enlève les auras if (stateCOF.combat && (predicateAsBool(personnage, 'auraDrainDeForce') || attributeAsBool(personnage, 'aura')) ) { @@ -2893,7 +2895,7 @@ var COFantasy = COFantasy || function() { } else if (charAttributeAsBool(personnage, 'armeeConjuree')) { removeFromTurnTracker(personnage, evt); deleteTokenWithUndo(personnage.token, evt); - sendPerso(personnage, 'dispara\xEEt'); + sendPerso(personnage, 'disparaît'); let armeeChar = getObj('character', personnage.charId); if (armeeChar) { evt.deletedCharacters = evt.deletedCharacters || []; @@ -2913,7 +2915,7 @@ var COFantasy = COFantasy || function() { armeeChar.remove(); } } else if (!estNonVivant(personnage)) { - //Cherche si certains peuvent siphoner l'\xE2me + //Cherche si certains peuvent siphoner l'âme let allToks = findObjs({ _type: 'graphic', @@ -2921,7 +2923,7 @@ var COFantasy = COFantasy || function() { _subtype: 'token', layer: 'objects' }); - //On cherche d'abord si un siphon des \xE2mes est prioritaire + //On cherche d'abord si un siphon des âmes est prioritaire let prioriteSiphon = []; allToks = allToks.filter(function(tok) { if (tok.id == token.id) return false; @@ -2946,7 +2948,7 @@ var COFantasy = COFantasy || function() { let jetSiphon = "(1d6"; if (bonus > 0) jetSiphon += '+' + bonus; jetSiphon += ")"; - sendChat('COF', "/w GM " + personnage.token.get('name') + " est un personnage joueur, possible qu'il ne soit pas vraiment mort mais juste inconscient. S'il est vraiment mort, faire le siphon des \xE2mes par " + siphoneur.token.get('name') + " \xE0 la main " + jetSiphon); + sendChat('COF', "/w GM " + personnage.token.get('name') + " est un personnage joueur, possible qu'il ne soit pas vraiment mort mais juste inconscient. S'il est vraiment mort, faire le siphon des âmes par " + siphoneur.token.get('name') + " à la main " + jetSiphon); } else { prioriteSiphon.sort(function(a, b) { return b.priorite - a.priorite; @@ -2961,7 +2963,7 @@ var COFantasy = COFantasy || function() { } let p = x.perso; if (fractionPriorite < 1) { - whisperChar(p.charId, "ne r\xE9ussit pas \xE0 siphoner l'\xE2me de " + token.get('name') + " un autre pouvoir l'a siphon\xE9e avant lui"); + whisperChar(p.charId, "ne réussit pas à siphoner l'âme de " + token.get('name') + " un autre pouvoir l'a siphonée avant lui"); return true; } let bonus = predicateAsInt(p, 'siphonDesAmes', 0); @@ -2971,7 +2973,7 @@ var COFantasy = COFantasy || function() { nbDes }); let soinTotal = soin.val; - //Le montant total des soins ne peut exc\xE9der les pv max du personnage qui vient de mourrir. + //Le montant total des soins ne peut excéder les pv max du personnage qui vient de mourrir. let display = true; if (soinTotal > pvMax) { soinTotal = pvMax; @@ -2980,12 +2982,12 @@ var COFantasy = COFantasy || function() { if (soinTotal < 1) soinTotal = 1; soin.val = soinTotal; soin.val = Math.ceil(soin.val * fractionPriorite / 100); - //Cherche si il y a un perso li\xE9 + //Cherche si il y a un perso lié let lie = personnageAmeLiee(p, pageId, allToks); soigneToken(p, soin.val, evt, function(s) { - let siphMsg = "siphone l'\xE2me de " + token.get('name') + - ". " + onGenre(p, 'Il', 'Elle') + " r\xE9cup\xE8re "; + let siphMsg = "siphone l'âme de " + token.get('name') + + ". " + onGenre(p, 'Il', 'Elle') + " récupère "; if (s == soinTotal) { if (display) siphMsg += soin.roll + " pv."; else siphMsg += s + " pv (jet " + soin.roll + ")."; @@ -3000,8 +3002,8 @@ var COFantasy = COFantasy || function() { let soin2 = soinTotal - s + Math.floor(s / 5); soigneToken(lie, soin2, evt, function(s) { let siphMsg = - "r\xE9cup\xE8re une partie de l'\xE2me de " + token.get('name') + - " siphon\xE9e par " + nomPerso(p) + ". " + onGenre(lie, 'Il', 'Elle') + " r\xE9cup\xE8re " + s + " pv."; + "récupère une partie de l'âme de " + token.get('name') + + " siphonée par " + nomPerso(p) + ". " + onGenre(lie, 'Il', 'Elle') + " récupère " + s + " pv."; if (s == soin2) { fraction = 0; } else { @@ -3010,15 +3012,15 @@ var COFantasy = COFantasy || function() { pvMax -= s; whisperChar(lie.charId, siphMsg); }, function() { - whisperChar(lie.charId, "sent qu'" + onGenre(lie, 'il', 'elle') + " aurait pu b\xE9n\xE9ficier d'une \xE2me"); + whisperChar(lie.charId, "sent qu'" + onGenre(lie, 'il', 'elle') + " aurait pu bénéficier d'une âme"); }); } }, function() { if (lie) { soigneToken(lie, soin.val, evt, function(s) { - let siphMsg = "siphone l'\xE2me de " + token.get('name') + - " gr\xE2ce \xE0 " + nomPerso(p) + ". " + onGenre(lie, 'Il', 'Elle') + " r\xE9cup\xE8re "; + let siphMsg = "siphone l'âme de " + token.get('name') + + " grâce à " + nomPerso(p) + ". " + onGenre(lie, 'Il', 'Elle') + " récupère "; if (s == soinTotal) { siphMsg += soin.roll + " pv."; fraction = 0; @@ -3030,11 +3032,11 @@ var COFantasy = COFantasy || function() { whisperChar(lie.charId, siphMsg); }, function() { whisperChar(p.charId, - "est d\xE9j\xE0 au maximum de point de vie. " + onGenre(p, 'Il', 'Elle') + " laisse \xE9chapper l'\xE2me de " + token.get('name')); + "est déjà au maximum de point de vie. " + onGenre(p, 'Il', 'Elle') + " laisse échapper l'âme de " + token.get('name')); }); } else { whisperChar(p.charId, - "est d\xE9j\xE0 au maximum de point de vie. " + onGenre(p, 'Il', 'Elle') + " laisse \xE9chapper l'\xE2me de " + token.get('name')); + "est déjà au maximum de point de vie. " + onGenre(p, 'Il', 'Elle') + " laisse échapper l'âme de " + token.get('name')); } }); }); @@ -3074,7 +3076,7 @@ var COFantasy = COFantasy || function() { } //fonction avec callback, mais synchrone - // n'ajoute pas evt \xE0 l'historique + // n'ajoute pas evt à l'historique function soigneToken(perso, soins, evt, callTrue, callMax, options) { options = options || {}; let token = perso.token; @@ -3111,7 +3113,7 @@ var COFantasy = COFantasy || function() { let ds = parseInt(a.get('current')); if (ds > 0) { if (an[0].length < 2) { - error("Match non trouv\xE9 pour les soins", an); + error("Match non trouvé pour les soins", an); return; } if (soinsImpossible.has(an[1])) { @@ -3179,7 +3181,7 @@ var COFantasy = COFantasy || function() { } } } - // On cherche si il y a des DM temporaires \xE0 soigner + // On cherche si il y a des DM temporaires à soigner if (bar1 > pvmax) { let hasMana = (ficheAttributeAsInt(perso, 'PM', 0) > 0); let dmgTemp; @@ -3224,7 +3226,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(perso, 'reactionAllergique')) { removeTokenAttr(perso, 'reactionAllergique', evt, { - msg: ": les soins mettent fin \xE0 la r\xE9action allergique" + msg: ": les soins mettent fin à la réaction allergique" }); } } @@ -3261,7 +3263,7 @@ var COFantasy = COFantasy || function() { return scale; } - // si le token est plus grand que thresh, r\xE9duit la distance + // si le token est plus grand que thresh, réduit la distance function tokenSize(tok, thresh) { let size = (tok.get('width') + tok.get('height')) / 2; if (size > thresh) return ((size - thresh) / 2); @@ -3307,7 +3309,7 @@ var COFantasy = COFantasy || function() { } //Distance en pixels entre un token et un segment - //le segment est donn\xE9 par ses extr\xE9mit\xE9s, sous forme de {x, y} + //le segment est donné par ses extrémités, sous forme de {x, y} function distancePixTokenSegment(token, pt1, pt2) { let pt = pointOfToken(token); let seg = { @@ -3317,26 +3319,26 @@ var COFantasy = COFantasy || function() { let vec = { x: pt.x - pt1.x, y: pt.y - pt1.y - }; //vecteur de pt1 \xE0 pt - //On regarde d'abord si le projet\xE9 de token sur (pt1, pt2) est dans le segment + }; //vecteur de pt1 à pt + //On regarde d'abord si le projeté de token sur (pt1, pt2) est dans le segment let ps = seg.x * vec.x + seg.y * vec.y; if (ps <= 0) { //On est avant pt1 return Math.sqrt(vec.x * vec.x + vec.y * vec.y); } let dseg = seg.x * seg.x + seg.y * seg.y; - if (ps >= dseg) { //On est apr\xE8s pt2, on retourne donc la distance pt pt2 + if (ps >= dseg) { //On est après pt2, on retourne donc la distance pt pt2 let x = pt.x - pt2.x; let y = pt.y - pt2.y; return Math.sqrt(x * x + y * y); } - //On calcule le d\xE9terminant de vec et seg + //On calcule le déterminant de vec et seg let det = vec.x * seg.y - vec.y * seg.x; //Et on divise par la longueur du segment return Math.abs(det) / Math.sqrt(dseg); } //options peut avoir les champs: - // - strict1 = true si on consid\xE8re que tok1 doit avoir une taille nulle + // - strict1 = true si on considère que tok1 doit avoir une taille nulle // - strict2 // - allonge function distanceCombat(tok1, tok2, pageId, options) { @@ -3344,7 +3346,7 @@ var COFantasy = COFantasy || function() { pageId = tok1.get('pageid'); } options = options || {}; - //perso mont\xE9s + //perso montés let pseudoTok1 = tok1; if (!options.strict1) { let perso1 = persoOfToken(tok1); @@ -3377,7 +3379,7 @@ var COFantasy = COFantasy || function() { } //Attention, seulement faire pour les tokens avec une image dans la librairie - //C'est toujours le cas pour un token cr\xE9\xE9 par le script + //C'est toujours le cas pour un token créé par le script function deleteTokenWithUndo(token, evt) { let tokenFields = getTokenFields(token); evt.deletedTokens = evt.deletedTokens || []; @@ -3385,8 +3387,8 @@ var COFantasy = COFantasy || function() { token.remove(); } - //L'argument effetC doit \xEAtre le nom complet, pas la base - //evt.deletedAttributes doit \xEAtre d\xE9fini + //L'argument effetC doit être le nom complet, pas la base + //evt.deletedAttributes doit être défini function enleverEffetAttribut(charId, effetC, attrName, extension, evt) { let attrSave = attributeExtending(charId, attrName, effetC, extension); attrSave. @@ -3396,14 +3398,14 @@ var COFantasy = COFantasy || function() { }); } - function finDEffet(attr, effet, attrName, charId, evt, options) { //L'effet arrive en fin de vie, doit \xEAtre supprim\xE9 + function finDEffet(attr, effet, attrName, charId, evt, options) { //L'effet arrive en fin de vie, doit être supprimé options = options || {}; evt.deletedAttributes = evt.deletedAttributes || []; let res; let newInit = []; let efComplet = effetComplet(effet, attrName); - //Si on a un attrSave, alors on a d\xE9j\xE0 imprim\xE9 le message de fin d'effet - if (options.attrSave) { //on a un attribut associ\xE9 \xE0 supprimer) + //Si on a un attrSave, alors on a déjà imprimé le message de fin d'effet + if (options.attrSave) { //on a un attribut associé à supprimer) evt.deletedAttributes.push(options.attrSave); options.attrSave.remove(); } else if (options.gardeAutresAttributs === undefined) { //On cherche si il y en a un @@ -3424,7 +3426,7 @@ var COFantasy = COFantasy || function() { let character; let combat = stateCOF.combat; switch (effet) { - case 'affecteParAura': //voir si l'aura est toujours l\xE0 + case 'affecteParAura': //voir si l'aura est toujours là if (combat && combat.auras && efComplet.length > 15) { let id = efComplet.substring(15, efComplet.length - 1); let aura = combat.auras.find(function(a) { @@ -3474,7 +3476,7 @@ var COFantasy = COFantasy || function() { if (arme && arme.armeDeGrand) { let taille = taillePersonnage(perso, 4); if (taille == 4 && arme.label != perso.attrArmeEnMain.get('max')) { - sendPerso(perso, "ne peut plus tenir " + arme.name + " \xE0 une main"); + sendPerso(perso, "ne peut plus tenir " + arme.name + " à une main"); degainerArme(perso, arme.label, evt, { deuxMains: true }); @@ -3673,22 +3675,22 @@ var COFantasy = COFantasy || function() { function(s) { options.print = function(m) {}; //Pour ne pas afficher le message final. let tempsEffectif = Math.ceil(s / regen); - sendPerso(perso, "r\xE9cup\xE8re encore " + s + " PV en " + tempsEffectif + " tours."); + sendPerso(perso, "récupère encore " + s + " PV en " + tempsEffectif + " tours."); }); } - //R\xE9g\xE9n\xE9ration d'une carac physique affaiblie de 1d4, si il y en a. + //Régénération d'une carac physique affaiblie de 1d4, si il y en a. if (attributeAsInt(perso, 'affaiblissementdeconstitution', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(perso, 'constitution', d4.val, evt); - sendPerso(perso, "r\xE9cup\xE8re " + d4.roll + " points de constitution"); + sendPerso(perso, "récupère " + d4.roll + " points de constitution"); } else if (attributeAsInt(perso, 'affaiblissementdeforce', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(perso, 'force', d4.val, evt); - sendPerso(perso, "r\xE9cup\xE8re " + d4.roll + " points de force"); + sendPerso(perso, "récupère " + d4.roll + " points de force"); } else if (attributeAsInt(perso, 'affaiblissementdedexterite', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(perso, 'dexterite', d4.val, evt); - sendPerso(perso, "r\xE9cup\xE8re " + d4.roll + " points de dext\xE9rit\xE9"); + sendPerso(perso, "récupère " + d4.roll + " points de dextérité"); } }); break; @@ -3697,7 +3699,7 @@ var COFantasy = COFantasy || function() { case 'arbreAnime': case 'objetAnime': case 'degradationZombie': //effacer le personnage - //Dans le cas d'un Zombie, diminuer la limite du n\xE9cromant si n\xE9cessaire + //Dans le cas d'un Zombie, diminuer la limite du nécromant si nécessaire if (effet == 'degradationZombie') { let attrNecromant = charAttribute(charId, 'necromant'); if (attrNecromant.length > 0) { @@ -3809,7 +3811,7 @@ var COFantasy = COFantasy || function() { abilities: charAbilities, allies: [] }; - // Retrait du perso de toutes les listes d'alli\xE9s + // Retrait du perso de toutes les listes d'alliés for (const [perso, alliesPerso] of Object.entries(alliesParPerso)) { if (alliesPerso.has(charId)) { deletedChar.allies.push(perso); @@ -3901,7 +3903,7 @@ var COFantasy = COFantasy || function() { if (pv == 0) { //jshint ignore:line mort(perso, undefined, evt); } else { - //On note qu'il l'a d\xE9j\xE0 fait pour qu'il ne puisse le refaire dans le combat + //On note qu'il l'a déjà fait pour qu'il ne puisse le refaire dans le combat setTokenAttr(perso, 'aAgiAZeroPV', true, evt); } }); @@ -3945,7 +3947,7 @@ var COFantasy = COFantasy || function() { }; if (getState(perso, 'mort')) return; if (!combat) { - sendChat('', "Il restait un effet retard\xE9 " + effetRetarde + " qui devait se d\xE9clencher pour " + token.get('name')); + sendChat('', "Il restait un effet retardé " + effetRetarde + " qui devait se déclencher pour " + token.get('name')); return; } let duree = getIntValeurOfEffet(perso, efComplet, 1); @@ -3977,7 +3979,7 @@ var COFantasy = COFantasy || function() { charId: charId }; if (getState(perso, 'mort')) return; - whisperChar(charId, "Le poison commence \xE0 faire effet !"); + whisperChar(charId, "Le poison commence à faire effet !"); setTokenAttr(perso, 'poisonAffaiblissantLong', true, evt, {}); }); break; @@ -3986,7 +3988,7 @@ var COFantasy = COFantasy || function() { let messageRetarde = efComplet.substring(15, efComplet.length - 1); iterTokensOfAttribute(charId, options.pageId, efComplet, attrName, function(token) { whisperChar(charId, messageRetarde); - //Puis on regarde si il y a une valeur \xE0 afficher + //Puis on regarde si il y a une valeur à afficher let perso = { token: token, charId: charId @@ -3999,7 +4001,7 @@ var COFantasy = COFantasy || function() { break; case 'tenebres': iterTokensOfAttribute(charId, options.pageId, efComplet, attrName, function(token) { - //Puis on regarde si il y a une valeur \xE0 afficher + //Puis on regarde si il y a une valeur à afficher let perso = { token: token, charId: charId @@ -4011,7 +4013,7 @@ var COFantasy = COFantasy || function() { break; case 'brumes': iterTokensOfAttribute(charId, options.pageId, efComplet, attrName, function(token) { - //Puis on regarde si il y a une valeur \xE0 afficher + //Puis on regarde si il y a une valeur à afficher let perso = { token: token, charId: charId @@ -4104,7 +4106,7 @@ var COFantasy = COFantasy || function() { } evt.deletedAttributes.push(attr); attr.remove(); - //D\xE9bloque les tokens si l'effet les immobilisait + //Débloque les tokens si l'effet les immobilisait switch (effet) { case 'bloqueManoeuvre': case 'prisonVegetale': @@ -4131,7 +4133,7 @@ var COFantasy = COFantasy || function() { } } - //retourne le personnage du compagnon s'il est pr\xE9sent et actif + //retourne le personnage du compagnon s'il est présent et actif function compagnonPresent(personnage, nomCompagnon) { let compagnon = predicateAsBool(personnage, nomCompagnon); if (compagnon) { @@ -4199,7 +4201,7 @@ var COFantasy = COFantasy || function() { } //Pour savoir si un personnage est un personnage joueur - // -> fiche de PJ + d\xE9 de vie + token li\xE9 + controll\xE9 par au moins un joueur. + // -> fiche de PJ + dé de vie + token lié + controllé par au moins un joueur. function estPJ(perso) { if (persoEstPNJ(perso)) return false; let dv = ficheAttributeAsInt(perso, 'DV', 0); @@ -4219,50 +4221,50 @@ var COFantasy = COFantasy || function() { }); }*/ - /* \xC9v\xE9nements, utilis\xE9s pour les undo, en particulier undo pour refaire - * une action quand une r\xE8gle le permet (utilisation de points de chance, etc..) - * Champ d'un \xE9v\xE9nement (variables evt en g\xE9n\xE9ral dans le code): + /* Événements, utilisés pour les undo, en particulier undo pour refaire + * une action quand une règle le permet (utilisation de points de chance, etc..) + * Champ d'un événement (variables evt en général dans le code): * id : identificateur unique (int) - * type : description de l'\xE9v\xE9nement (string) - * affectes : liste de tokens affect\xE9s par l'\xE9v\xE9nement - * tokens : liste des tokens cr\xE9\xE9s - * deletedTokens : liste de tokens effac\xE9s - * !!!!! -> ne garde pas les tokens effac\xE9s si on n'est pas s\xFBr que son image est au bon endroit. Typiquement, on ne va le faire que pour les tokens cr\xE9es dans le script - * attributes : liste de attributs cr\xE9\xE9s ou modifi\xE9s - * deletesAttributes: lites des attributs effac\xE9s - * characters : liste des personnages cr\xE9\xE9s + * type : description de l'événement (string) + * affectes : liste de tokens affectés par l'événement + * tokens : liste des tokens créés + * deletedTokens : liste de tokens effacés + * !!!!! -> ne garde pas les tokens effacés si on n'est pas sûr que son image est au bon endroit. Typiquement, on ne va le faire que pour les tokens crées dans le script + * attributes : liste de attributs créés ou modifiés + * deletesAttributes: lites des attributs effacés + * characters : liste des personnages créés * characterNames : liste de character * name - * defaultTokens : liste de tokens par d\xE9faut (objet) + * defaultTokens : liste de tokens par défaut (objet) * (character, defaultToken) - * deletedCharacters: liste des personnages effac\xE9s - * combat : valeur de la variable d'\xE9tat combat + * deletedCharacters: liste des personnages effacés + * combat : valeur de la variable d'état combat * updateNextInitSet: valeur de l'ensemble des tokens dont il faut recalculer l'init - * turnorder : le turnorder (si il a chang\xE9) + * turnorder : le turnorder (si il a changé) * initiativepage : true si le turnorder est actif - * personnage : le perso qui 'fait' l'\xE9v\xE9nement - * succes : stoque si l'attaque \xE9tait un succ\xE8s (bool) - * action : sauvegarde des param\xE8tres de l'evt, pour la rejouer - * - caracteristique : carac test\xE9e (pour un jet) + * personnage : le perso qui 'fait' l'événement + * succes : stoque si l'attaque était un succès (bool) + * action : sauvegarde des paramètres de l'evt, pour la rejouer + * - caracteristique : carac testée (pour un jet) * - titre : titre du jet - * - playerId : id du joueur qui a lanc\xE9 l'action - * - selected : cibles s\xE9lectionn\xE9s des l'action + * - playerId : id du joueur qui a lancé l'action + * - selected : cibles sélectionnés des l'action * - attaquant: personnage attaquant (TODO: voir si doublon avec personnage) * - cibles: liste des cibles d'attaque, avec leurs tags - * - weaponStats: stats de l'arme (ou attaque) utilis\xE9e - * - rolls: les jets de l'action, pour les avoir \xE0 l'identique - * les d\xE9g\xE2ts sont stoqu\xE9s dans chaque cible, dans cible.rollsDmg + * - weaponStats: stats de l'arme (ou attaque) utilisée + * - rolls: les jets de l'action, pour les avoir à l'identique + * les dégâts sont stoqués dans chaque cible, dans cible.rollsDmg * - attack: les jets de l'attaque - * - etat_e_index_targetid: save pour entrer dans l'\xE9tat e + * - etat_e_index_targetid: save pour entrer dans l'état e * - effet_e_index_targetid: save pour l'effet e - * - attaquant_pietinement_targetid: jet de l'attaquant pour le pi\xE9tinement - * - defenseur_pietinement_targetid: jet de du d\xE9fenseur pour le pi\xE9tinement + * - attaquant_pietinement_targetid: jet de l'attaquant pour le piétinement + * - defenseur_pietinement_targetid: jet de du défenseur pour le piétinement * - options : options de l'action - * attenteResultat : permet de savoir que le jet est en attente de d\xE9cision pour savoir si c'est un succ\xE8s ou non (quand il n'y a pas de difficult\xE9 donn\xE9e et que le personnage est sous l'emprise d'une mal\xE9diction) + * attenteResultat : permet de savoir que le jet est en attente de décision pour savoir si c'est un succès ou non (quand il n'y a pas de difficulté donnée et que le personnage est sous l'emprise d'une malédiction) */ function addEvent(evt) { if (evt.id) { - error("Tentative d'ajouter un \xE9v\xE9nement d\xE9j\xE0 dans l'historique", evt); + error("Tentative d'ajouter un événement déjà dans l'historique", evt); return; } evt.id = stateCOF.eventId++; @@ -4302,11 +4304,11 @@ var COFantasy = COFantasy || function() { } } - //Si evt n'est pas d\xE9fini, annule le dernier evt + //Si evt n'est pas défini, annule le dernier evt function undoEvent(evt) { if (evt === undefined) { if (eventHistory.length === 0) { - sendChat('COF', "/w GM Historique d'\xE9v\xE8nements vide"); + sendChat('COF', "/w GM Historique d'évènements vide"); return; } evt = eventHistory.pop(); @@ -4344,7 +4346,7 @@ var COFantasy = COFantasy || function() { } if (evt.defaultTokens) { evt.defaultTokens.forEach(function(dt) { - //On cherche d'abord un token qui repr\xE9sente dt.character + //On cherche d'abord un token qui représente dt.character let tokens = findObjs({ _type: 'graphic', represents: dt.character.id @@ -4429,7 +4431,7 @@ var COFantasy = COFantasy || function() { }); }); } - // On le remet chez ses alli\xE9s + // On le remet chez ses alliés if (character.allies.length > 0) { Object.values(character.allies).forEach(function(allie) { let alliesPerso = alliesParPerso[allie] || new Set(); @@ -4497,7 +4499,7 @@ var COFantasy = COFantasy || function() { } if (_.has(evt, 'combat')) { let combat = stateCOF.combat; - //regarde si le token actif a chang\xE9 + //regarde si le token actif a changé if (evt.combat && (!combat || evt.combat.activeTokenId != combat.activeTokenId) && stateCOF.options.affichage.val.init_dynamique.val) { @@ -4527,14 +4529,14 @@ var COFantasy = COFantasy || function() { stateCOF.tokensTemps.push(tt); }); } - if (evt.tokensTemps) { //ceux pour lesquels on a diminu\xE9 la dur\xE9e + if (evt.tokensTemps) { //ceux pour lesquels on a diminué la durée evt.tokensTemps.forEach(function(tt) { if (tt.tt) tt.tt.duree = tt.ancienneDuree; }); } } - //origin peut \xEAtre un message ou un nom de joueur + //origin peut être un message ou un nom de joueur function sendPlayer(origin, msg, playerId) { let dest = origin; if (origin.who) { @@ -4544,7 +4546,7 @@ var COFantasy = COFantasy || function() { } if (dest.includes('"')) { sendChat('COF', msg); - log("Impossible d'envoyer des messages priv\xE9s \xE0 " + dest + " car le nom contient des guillemets"); + log("Impossible d'envoyer des messages privés à " + dest + " car le nom contient des guillemets"); } sendChat('COF', '/w "' + dest + '" ' + msg); } @@ -4574,7 +4576,7 @@ var COFantasy = COFantasy || function() { case 'FOR': return "de force"; case 'DEX': - return "de dext\xE9rit\xE9"; + return "de dextérité"; case 'CON': return "de constitution"; case 'SAG': @@ -4588,7 +4590,7 @@ var COFantasy = COFantasy || function() { } } - //msg peut \xEAtre un message ou un playerId + //msg peut être un message ou un playerId function peutController(msg, perso) { if (msg === undefined) return true; let playerId = getPlayerIdFromMsg(msg); @@ -4621,12 +4623,12 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let action = evt.action; if (action === undefined) { - error("Erreur interne du bouton de confirmation: l'\xE9v\xE8nement n'a pas d'action", cmd); + error("Erreur interne du bouton de confirmation: l'évènement n'a pas d'action", cmd); return; } let options = action.currentOptions || {}; @@ -4667,7 +4669,7 @@ var COFantasy = COFantasy || function() { let prev = aff.prev; let tok = aff.affecte; if (prev === undefined || tok === undefined) { - error("Pas d'\xE9tat pr\xE9c\xE9dant", aff); + error("Pas d'état précédant", aff); return; } let prevTok; @@ -4676,7 +4678,7 @@ var COFantasy = COFantasy || function() { tok.set(key, val); }); if (HTdeclared) HealthColors.Update(tok, prevTok); - sendChat("COF", "\xC9tat de " + tok.get("name") + " restaur\xE9."); + sendChat("COF", "État de " + tok.get("name") + " restauré."); }); } @@ -4693,7 +4695,7 @@ var COFantasy = COFantasy || function() { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string } - //Remplace une macro ou ability par sa d\xE9finition (r\xE9cursivement) + //Remplace une macro ou ability par sa définition (récursivement) function replaceAction(action, perso, macros, abilities) { let remplacement = false; if (action.indexOf('#') >= 0) { @@ -4710,7 +4712,7 @@ var COFantasy = COFantasy || function() { if (!remplacement) macros = macros.filter(function(m, k) { return (k != i); - }); //Pour \xE9viter la r\xE9cursion + }); //Pour éviter la récursion remplacement = true; } }); @@ -4726,7 +4728,7 @@ var COFantasy = COFantasy || function() { let daName = '%' + aName; if (action.indexOf(daName) >= 0) { action = action.replace(daName, a.get('action')); - if (!remplacement) abilities = abilities.splice(i); //Pour \xE9viter la r\xE9cursion + if (!remplacement) abilities = abilities.splice(i); //Pour éviter la récursion remplacement = true; } daName = '%{selected|' + aName + '}'; @@ -4735,7 +4737,7 @@ var COFantasy = COFantasy || function() { if (!remplacement) abilities = abilities.filter(function(m, k) { return (k != i); - }); //Pour \xE9viter la r\xE9cursion + }); //Pour éviter la récursion remplacement = true; } }); @@ -4847,7 +4849,7 @@ var COFantasy = COFantasy || function() { armeDeCreatureFeerique(perso, weaponStats, 3); break; default: - //On cherche si c'est une arme \xE0 2 mains + //On cherche si c'est une arme à 2 mains //Ne devrait pas servir, on a toujours un type, maintenant let t = weaponStats.name.toLowerCase(); if (t.includes('2 mains') || t.includes('deux mains')) { @@ -4862,19 +4864,19 @@ var COFantasy = COFantasy || function() { } } } - //Informations dans le champ sp\xE9cial + //Informations dans le champ spécial let champDivers = weaponStats.divers; if (champDivers === '') champDivers = weaponStats.predicats; else if (weaponStats.predicats !== '') champDivers += '\n' + weaponStats.predicats; let pred = predicateOfRaw(champDivers); - //On transfert les pr\xE9dicats connus dans weaponStats + //On transfert les prédicats connus dans weaponStats if (pred.charge) weaponStats.charge = toInt(pred.charge, 1); weaponStats.eclaire = toInt(pred.eclaire); weaponStats.eclaireFaible = toInt(pred.eclaireFaible); weaponStats.batarde = pred.batarde; if (weaponStats.batarde && weaponStats.deuxMains) { - error("L'arme " + weaponStats.name + " est d\xE9clar\xE9e comme bat\xE2rde, il faudrait en faire une arme \xE0 une main par d\xE9faut", weaponStats); + error("L'arme " + weaponStats.name + " est déclarée comme batârde, il faudrait en faire une arme à une main par défaut", weaponStats); weaponStats.deuxMains = undefined; } if (pred.armeDeGrand) { @@ -4883,17 +4885,17 @@ var COFantasy = COFantasy || function() { if (taille < 5) weaponStats.deuxMains = true; else weaponStats.deuxMains = false; } - //Identification des cat\xE9gories d'armes utilis\xE9es en jeu + //Identification des catégories d'armes utilisées en jeu identifierArme(weaponStats, pred, 'arc', /\barc\b/i); - identifierArme(weaponStats, pred, 'arbalete', /\barbal[e\xE8]te\b/i); - identifierArme(weaponStats, pred, 'baton', /\bb[a\xE2]ton\b/i); + identifierArme(weaponStats, pred, 'arbalete', /\barbal[eè]te\b/i); + identifierArme(weaponStats, pred, 'baton', /\bb[aâ]ton\b/i); identifierArme(weaponStats, pred, 'hache', /\bhache\b/i); - identifierArme(weaponStats, pred, 'epee', /\b[e\xE9]p[e\xE9]e\b/i); - identifierArme(weaponStats, pred, 'epieu', /\b[e\xE9]pieu\b/i); + identifierArme(weaponStats, pred, 'epee', /\b[eé]p[eé]e\b/i); + identifierArme(weaponStats, pred, 'epieu', /\b[eé]pieu\b/i); identifierArme(weaponStats, pred, 'fronde', /\bfronde\b/i); identifierArme(weaponStats, pred, 'marteau', /\bmarteau\b/i); identifierArme(weaponStats, pred, 'masse', /\bmasse\b/i); - identifierArme(weaponStats, pred, 'rapiere', /\brapi[e\xE8]re\b/i); + identifierArme(weaponStats, pred, 'rapiere', /\brapi[eè]re\b/i); identifierArme(weaponStats, pred, 'poudre', /\bpoudre\b/i); identifierArme(weaponStats, pred, 'sabre', /\b(katana|wakizachi|boken|demi-lame|vivelame|sabre)\b/i); if (weaponStats.arc && predicateAsBool(perso, 'arcDeMaitre')) { @@ -4926,8 +4928,8 @@ var COFantasy = COFantasy || function() { bar2 = parseInt(token.get('bar2_value')); if (isNaN(bar2)) { if (token.get('bar1_link') === '') bar2 = 0; - else { //devrait \xEAtre li\xE9 \xE0 la mana courante - sendPerso(personnage, "*** Attention, la barre de mana du token n'est pas li\xE9e \xE0 la mana de la fiche ***"); + else { //devrait être lié à la mana courante + sendPerso(personnage, "*** Attention, la barre de mana du token n'est pas liée à la mana de la fiche ***"); bar2 = parseInt(manaAttr[0].get('current')); } } @@ -4970,7 +4972,7 @@ var COFantasy = COFantasy || function() { } //depasse est un string qui commence par --depasseLimite - //args doit \xEAtre d\xE9fini et contient des valeur \xE0 modifier : + //args doit être défini et contient des valeur à modifier : // - mana // - text function peutDepasserLimite(depasse, perso, attrName, args) { @@ -5034,7 +5036,7 @@ var COFantasy = COFantasy || function() { if (attributeAsInt(perso, ressourceParJour, limiteParJour) > 0) { return false; } - //Reste le cas o\xF9 on peut d\xE9passer cette limite par jour + //Reste le cas où on peut dépasser cette limite par jour let depasse = options.find(function(o) { return o.startsWith('depasseLimite '); }); @@ -5078,7 +5080,7 @@ var COFantasy = COFantasy || function() { return ai; } - //Enl\xE8ve les cha\xEEnes de type ?{..} pour \xEAtre s\xFBr que l'action est impossible + //Enlève les chaînes de type ?{..} pour être sûr que l'action est impossible function removeUserInputs(act) { let m = act.match(/\?\{[^\}]*\}/g); if (!m) return act; @@ -5100,7 +5102,7 @@ var COFantasy = COFantasy || function() { if (labelArmePrincipale) perso.arme = getWeaponStats(perso, labelArmePrincipale); let labelArmeGauche = attr[0].get('max'); if (labelArmeGauche) { - if (labelArmeGauche == labelArmePrincipale) { //arme tenue \xE0 2 mains + if (labelArmeGauche == labelArmePrincipale) { //arme tenue à 2 mains perso.arme.deuxMains = true; } else { perso.armeGauche = getWeaponStats(perso, labelArmeGauche); @@ -5118,7 +5120,7 @@ var COFantasy = COFantasy || function() { function listAllMunitions(perso) { if (perso.munitions) return perso.munitions; let rawList = extractRepeating(perso, 'munitions'); - let liste = {}; //liste tri\xE9e par label de munition + let liste = {}; //liste triée par label de munition for (let pref in rawList) { let ra = rawList[pref]; if (ra.labelmunition === undefined) ra.labelmunition = 0; @@ -5133,11 +5135,11 @@ var COFantasy = COFantasy || function() { return liste; } - //Les options de l'arme doivent d\xE9j\xE0 \xEAtre dans act + //Les options de l'arme doivent déjà être dans act function demandeMunition(perso, weaponStats, options, act) { if (act.includes('--munition')) return act; let typeMunition; - if (weaponStats.arc) typeMunition = 'Fl\xE8che'; + if (weaponStats.arc) typeMunition = 'Flèche'; else if (weaponStats.arbalete) typeMunition = 'Carreau'; else if (weaponStats.poudre) typeMunition = 'Balle'; else if (weaponStats.fronde) typeMunition = 'Autre'; //TODO: ajouter le type bille sur la fiche @@ -5146,7 +5148,7 @@ var COFantasy = COFantasy || function() { let munitionsDeType = []; for (let label in munitions) { let munition = munitions[label]; - let tm = fieldAsString(munition, 'typemunition', 'Fl\xE8che'); + let tm = fieldAsString(munition, 'typemunition', 'Flèche'); if (tm != typeMunition) return; let nb = fieldAsInt(munition, 'qtemunition', 1); if (nb > 0) munitionsDeType.push(munition); @@ -5166,7 +5168,7 @@ var COFantasy = COFantasy || function() { // - overlay // - buttonStyle // - attackStats - // et la fonction peut \xE9crire actionImpossible = true dans options. + // et la fonction peut écrire actionImpossible = true dans options. function bouton(action, text, perso, options) { if (action === undefined || action.trim() === '') return text; else action = action.trim(); @@ -5179,12 +5181,12 @@ var COFantasy = COFantasy || function() { if (character) perso.name = character.get('name'); else perso.name = nomPerso(perso); } - //Cas de plusieurs actions apr\xE8s expansion + //Cas de plusieurs actions après expansion let actions = action.split('\n'); //Cherche le picto et le style let style = ''; let picto = ''; - let groupe; //Pour g\xE9n\xE9rer un bouton d'attaque de groupe. \xC0 revoir + let groupe; //Pour générer un bouton d'attaque de groupe. À revoir actions = actions.map(function(act) { act = act.trim(); if (act.startsWith("/as ")) { @@ -5195,7 +5197,7 @@ var COFantasy = COFantasy || function() { let actSansChoix = removeUserInputs(act); const args = actSansChoix.split(' --'); let defRessource = ''; - if (act.startsWith('!cof-guerison ')) defRessource = 'gu\xE9rison'; + if (act.startsWith('!cof-guerison ')) defRessource = 'guérison'; let dai = { text }; @@ -5203,13 +5205,13 @@ var COFantasy = COFantasy || function() { options.actionImpossible = true; else text = dai.text; if (!options.actionImpossible) { - if (act.startsWith('!cof-soin ') && !actSansChoix.includes('--limitePar') && !actSansChoix.includes('--dose')) { //Limitations sp\xE9ficiques + if (act.startsWith('!cof-soin ') && !actSansChoix.includes('--limitePar') && !actSansChoix.includes('--dose')) { //Limitations spéficiques let rangSoin = predicateAsInt(perso, 'voieDesSoins', 0); let cmd = args[0].split(' '); if (cmd.includes('leger')) { let soinsLegers = attributeAsInt(perso, 'soinsLegers', 0); if (soinsLegers >= rangSoin) { - //Peut-\xEAtre qu'on peut encore d\xE9passer la limite + //Peut-être qu'on peut encore dépasser la limite let depasse = actSansChoix.indexOf('--depasseLimite '); if (depasse > 0) { let dp = { @@ -5224,7 +5226,7 @@ var COFantasy = COFantasy || function() { } else if (cmd.includes('modere')) { let soinsModeres = attributeAsInt(perso, 'soinsModeres', 0); if (soinsModeres >= rangSoin) { - //Peut-\xEAtre qu'on peut encore d\xE9passer la limite + //Peut-être qu'on peut encore dépasser la limite let depasse = actSansChoix.indexOf('--depasseLimite '); if (depasse > 0) { let dp = { @@ -5251,7 +5253,7 @@ var COFantasy = COFantasy || function() { } else if (act.startsWith('!cof-attack ')) { let cmd = act.split(' '); if (cmd.length > 3 && cmd[3] == '-1') { - //Selon l'arme en main, une action peut \xEAtre possible ou non + //Selon l'arme en main, une action peut être possible ou non let weaponStats = armesEnMain(perso); if (weaponStats) { options.attackStats = options.attackStats || weaponStats; @@ -5303,7 +5305,7 @@ var COFantasy = COFantasy || function() { } act = demandeMunition(perso, attackStats, options, act); } - //On cherche la port\xE9e dans les options (\xE7a a la priorit\xE9) + //On cherche la portée dans les options (ça a la priorité) args.forEach(function(o) { if (o.startsWith('portee ')) { let p = parseInt(o.substring(7)); @@ -5424,13 +5426,13 @@ var COFantasy = COFantasy || function() { } } if (act.indexOf('@{selected') !== -1) { - // cas sp\xE9cial pour @{selected|token_id} o\xF9 l'on remplace toutes les occurences par token.id + // cas spécial pour @{selected|token_id} où l'on remplace toutes les occurences par token.id act = act.replace(new RegExp(escapeRegExp('@{selected|token_id}'), 'g'), tid); act = act.replace(new RegExp(escapeRegExp('@{selected|token_name}'), 'g'), nomPerso(perso)); let tmp = act.split('@{selected'); tmp.forEach(function(elem) { if (elem.startsWith('|')) { - // attribut demand\xE9 + // attribut demandé let attribute_name = elem.substring(0, elem.indexOf("}")).substr(1); let carac = caracOfMod(attribute_name); let replacement; @@ -5468,12 +5470,12 @@ var COFantasy = COFantasy || function() { act.indexOf('--enVue') == -1 && act.indexOf('--disque') == -1 && act.indexOf('--target ' + tid) == -1) { - //Si on n'a pas de cible, on fait comme si le token \xE9tait s\xE9lectionn\xE9. + //Si on n'a pas de cible, on fait comme si le token était sélectionné. let add_token = " --target " + tid; if (act.indexOf(' --allie') >= 0) { if (act.indexOf('--lanceur') == -1) add_token = " --lanceur " + tid; - else add_token = ""; //La cible sont les alli\xE9s de --lanceur. + else add_token = ""; //La cible sont les alliés de --lanceur. } if (act.indexOf(' --message ') != -1) act = act.replace(' --message ', add_token + ' --message '); else act += add_token; @@ -5509,8 +5511,8 @@ var COFantasy = COFantasy || function() { } } - //Fonction s\xE9par\xE9e pour pouvoir envoyer un frame \xE0 plusieurs joueurs - // playerId peut \xEAtre undefined (en particulier pour envoyer au mj) + //Fonction séparée pour pouvoir envoyer un frame à plusieurs joueurs + // playerId peut être undefined (en particulier pour envoyer au mj) function addFramedHeader(display, playerId, chuchote) { let perso1 = display.perso1; let perso2 = display.perso2; @@ -5648,9 +5650,9 @@ var COFantasy = COFantasy || function() { display.header = res; } - //Si options.chuchote est vrai, la frame est chuchot\xE9e au joueur qui fait l'action - //Si options.chuchote est un nom, on chuchote la frame \xE0 ce nom - //Pour retarder la d\xE9cision sur la cible de chuchotement, utiliser options.retarder + //Si options.chuchote est vrai, la frame est chuchotée au joueur qui fait l'action + //Si options.chuchote est un nom, on chuchote la frame à ce nom + //Pour retarder la décision sur la cible de chuchotement, utiliser options.retarder function startFramedDisplay(playerId, action, perso, options) { options = options || {}; if (options.secret) { @@ -5721,7 +5723,7 @@ var COFantasy = COFantasy || function() { display.output += ""; } - //newLine indique qu'on commence une nouvelle rang\xE9e + //newLine indique qu'on commence une nouvelle rangée function addCellInFramedDisplay(display, cell, size, newLine, fond) { size = size || 100; if (display.endColumn) { @@ -5733,7 +5735,8 @@ var COFantasy = COFantasy || function() { display.output += '' + cell + ''; } - function endFramedDisplay(display) { + //Termine le carde et l'envoie dans le chat + function sendFramedDisplay(display) { if (display.header === undefined) { error("Pas de titre pour le cadre", display); return; @@ -5741,7 +5744,7 @@ var COFantasy = COFantasy || function() { let res = display.header + display.output; res += '
    '; // line_content res += ''; // all_content - return res; + sendChat('', res); } function nomLimiteCapa(capa, unite) { @@ -5760,7 +5763,7 @@ var COFantasy = COFantasy || function() { nomLimite += 'Jour'; break; default: - error("Unit\xE9 d'utilisation de capacit\xE9 " + capa + " non reconnue", unite); + error("Unité d'utilisation de capacité " + capa + " non reconnue", unite); return; } return nomLimite + '__' + capa; @@ -5793,14 +5796,14 @@ var COFantasy = COFantasy || function() { expliquer("Perte de substance : -10 aux interactions sociales"); bonus -= 10; if (perteDeSubstance >= 15) { - expliquer("Perte de substance : faire un test de CHA 15 pour se faire remarquer \xE0 chaque tour"); + expliquer("Perte de substance : faire un test de CHA 15 pour se faire remarquer à chaque tour"); } } } return bonus; } - //expliquer est optionnel, et si pr\xE9sent, il faut msg + //expliquer est optionnel, et si présent, il faut msg function malusArmure(personnage, expliquer, msg) { let malusArmure = 0; if (personnage.malusArmure === undefined) { @@ -5825,7 +5828,7 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'graceFelineVoleur')) { let bonusGraceFeline = modCarac(personnage, 'charisme'); if (bonusGraceFeline > 0) { - expliquer("Gr\xE2ce f\xE9line : +" + bonusGraceFeline + " en acrobaties"); + expliquer("Grâce féline : +" + bonusGraceFeline + " en acrobaties"); bonus += bonusGraceFeline; } } @@ -5835,7 +5838,7 @@ var COFantasy = COFantasy || function() { } let a = predicateAsInt(personnage, 'ameFeline', 0); if (a > 0) { - expliquer("\xC2me f\xE9line : +" + a + " en acrobaties"); + expliquer("Âme féline : +" + a + " en acrobaties"); bonus += a; } break; @@ -5850,18 +5853,18 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'graceFelineVoleur')) { let bonusGraceFeline = modCarac(personnage, 'charisme'); if (bonusGraceFeline > 0) { - expliquer("Gr\xE2ce f\xE9line : +" + bonusGraceFeline + " en course"); + expliquer("Grâce féline : +" + bonusGraceFeline + " en course"); bonus += bonusGraceFeline; } } let a = predicateAsInt(personnage, 'ameFeline', 0); if (a > 0) { - expliquer("\xC2me f\xE9line : +" + a + " en course"); + expliquer("Âme féline : +" + a + " en course"); bonus += a; } a = predicateAsInt(personnage, 'vitesseDuFelin', 0); if (a > 0) { - expliquer("Vitesse du f\xE9lin : +" + a + " en course"); + expliquer("Vitesse du félin : +" + a + " en course"); bonus += a; } break; @@ -5872,10 +5875,10 @@ var COFantasy = COFantasy || function() { bonus += 5; } break; - case 'discr\xE9tion': + case 'discrétion': case 'discretion': if (attributeAsBool(personnage, 'foretVivanteEnnemie')) { - expliquer("For\xEAt hostile : -5 en discr\xE9tion"); + expliquer("Forêt hostile : -5 en discrétion"); bonus -= 5; } let perteDeSubstance = 0; @@ -5883,31 +5886,31 @@ var COFantasy = COFantasy || function() { perteDeSubstance = attributeAsInt(personnage, 'perteDeSubstance', 0); if (perteDeSubstance >= 5) { if (perteDeSubstance < 7) { - expliquer("Perte de substance : +2 en discr\xE9tion"); + expliquer("Perte de substance : +2 en discrétion"); bonus += 2; } else if (perteDeSubstance < 10) { - expliquer("Perte de substance : +5 en discr\xE9tion"); + expliquer("Perte de substance : +5 en discrétion"); bonus += 5; } else { - expliquer("Perte de substance : +10 en discr\xE9tion"); + expliquer("Perte de substance : +10 en discrétion"); bonus += 10; } } if (predicateAsBool(personnage, 'toutPetit') && !attributeAsBool(personnage, 'grandeTaille')) { - expliquer("Tout petit : +5 en discr\xE9tion"); + expliquer("Tout petit : +5 en discrétion"); bonus += 5; } break; case 'intimidation': bonus += bonusArgumentDeTaille(personnage, expliquer); if (predicateAsBool(personnage, 'ordreDuChevalierDragon') && attributeAsBool(personnage, 'monteSur')) { - expliquer("Chevalier Dragon mont\xE9 : +5 en intimidation"); + expliquer("Chevalier Dragon monté : +5 en intimidation"); bonus += 5; } bonus += bonusInteractionsSociales(personnage, expliquer); if (predicateAsBool(personnage, 'batonDesRunesMortes') && (attributeAsBool(personnage, 'runeLizura') || attributeAsBool(personnage, 'runeMitrah'))) { - expliquer("Recouvert" + eForFemale(personnage) + " de la boue noire du b\xE2ton : +5 aux tests d'intimidation"); + expliquer("Recouvert" + eForFemale(personnage) + " de la boue noire du bâton : +5 aux tests d'intimidation"); bonus += 5; } break; @@ -5916,18 +5919,18 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'graceFelineVoleur')) { let bonusGraceFeline = modCarac(personnage, 'charisme'); if (bonusGraceFeline > 0) { - expliquer("Gr\xE2ce f\xE9line : +" + bonusGraceFeline + " en escalade"); + expliquer("Grâce féline : +" + bonusGraceFeline + " en escalade"); bonus += bonusGraceFeline; } } let a = predicateAsInt(personnage, 'ameFeline', 0); if (a > 0) { - expliquer("\xC2me f\xE9line : +" + a + " en escalade"); + expliquer("Âme féline : +" + a + " en escalade"); bonus += a; } a = predicateAsInt(personnage, 'vitesseDuFelin', 0); if (a > 0) { - expliquer("Vitesse du f\xE9lin : +" + a + " en escalade"); + expliquer("Vitesse du félin : +" + a + " en escalade"); bonus += a; } break; @@ -5935,20 +5938,20 @@ var COFantasy = COFantasy || function() { case 'mentir': bonus += bonusInteractionsSociales(personnage, expliquer); break; - case 'n\xE9gociation': + case 'négociation': case 'negociation': bonus += bonusArgumentDeTaille(personnage, expliquer); bonus += bonusInteractionsSociales(personnage, expliquer); break; case 'orientation': if (attributeAsBool(personnage, 'foretVivanteEnnemie')) { - expliquer("For\xEAt hostile : -5 en orientation"); + expliquer("Forêt hostile : -5 en orientation"); bonus -= 5; } break; case 'perception': if (attributeAsBool(personnage, 'foretVivanteEnnemie')) { - expliquer("For\xEAt hostile : -5 en perception"); + expliquer("Forêt hostile : -5 en perception"); bonus -= 5; } if (compagnonPresent(personnage, 'guetteur')) { @@ -5964,7 +5967,7 @@ var COFantasy = COFantasy || function() { case 'persuasion': bonus += bonusArgumentDeTaille(personnage, expliquer); if (predicateAsBool(personnage, 'ordreDuChevalierDragon') && attributeAsBool(personnage, 'monteSur')) { - expliquer("Chevalier Dragon mont\xE9 : +5 en persuasion"); + expliquer("Chevalier Dragon monté : +5 en persuasion"); bonus += 5; } bonus += bonusInteractionsSociales(personnage, expliquer); @@ -5975,25 +5978,25 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'graceFelineVoleur')) { let bonusGraceFeline = modCarac(personnage, 'charisme'); if (bonusGraceFeline > 0) { - expliquer("Gr\xE2ce f\xE9line : +" + bonusGraceFeline + " en saut"); + expliquer("Grâce féline : +" + bonusGraceFeline + " en saut"); bonus += bonusGraceFeline; } } let a = predicateAsInt(personnage, 'ameFeline', 0); if (a > 0) { - expliquer("\xC2me f\xE9line : +" + a + " en saut"); + expliquer("Âme féline : +" + a + " en saut"); bonus += a; } a = predicateAsInt(personnage, 'vitesseDuFelin', 0); if (a > 0) { - expliquer("Vitesse du f\xE9lin : +" + a + " en saut"); + expliquer("Vitesse du félin : +" + a + " en saut"); bonus += a; } break; } case 'survie': if (attributeAsBool(personnage, 'foretVivanteEnnemie')) { - expliquer("For\xEAt hostile : -5 en survie"); + expliquer("Forêt hostile : -5 en survie"); bonus -= 5; } break; @@ -6021,7 +6024,7 @@ var COFantasy = COFantasy || function() { let bonusChantDesHeros = getIntValeurOfEffet(personnage, 'chantDesHeros', 1); let chantDesHerosIntense = attributeAsInt(personnage, 'chantDesHerosTempeteDeManaIntense', 0); bonusChantDesHeros += chantDesHerosIntense; - expliquer("Chant des h\xE9ros : +" + bonusChantDesHeros + " au jet"); + expliquer("Chant des héros : +" + bonusChantDesHeros + " au jet"); bonus += bonusChantDesHeros; if (chantDesHerosIntense && evt) removeTokenAttr(personnage, 'chantDesHerosTempeteDeManaIntense', evt); @@ -6030,7 +6033,7 @@ var COFantasy = COFantasy || function() { let bonusBenediction = getIntValeurOfEffet(personnage, 'benediction', 1); let benedictionIntense = attributeAsInt(personnage, 'benedictionTempeteDeManaIntense', 0); bonusBenediction += benedictionIntense; - expliquer("B\xE9n\xE9diction : +" + bonusBenediction + " au jet"); + expliquer("Bénédiction : +" + bonusBenediction + " au jet"); bonus += bonusBenediction; if (benedictionIntense && evt) removeTokenAttr(personnage, 'benedictionTempeteDeManaIntense', evt); @@ -6045,7 +6048,7 @@ var COFantasy = COFantasy || function() { removeTokenAttr(personnage, 'inspirationTempeteDeManaIntense', evt); } if (attributeAsBool(personnage, 'lameDeLigneePerdue')) { - expliquer("Lame de lign\xE9e perdue : -1 au jet"); + expliquer("Lame de lignée perdue : -1 au jet"); bonus -= 1; } if (attributeAsBool(personnage, 'strangulation')) { @@ -6056,7 +6059,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'nueeDInsectes')) { let malusNuee = 2 + attributeAsInt(personnage, 'nueeDInsectesTempeteDeManaIntense', 0); - expliquer("Nu\xE9e d\'insectes : -" + malusNuee + " au jet"); + expliquer("Nuée d\'insectes : -" + malusNuee + " au jet"); bonus -= malusNuee; if (malusNuee > 2 && evt) removeTokenAttr(personnage, 'nueeDInsectesTempeteDeManaIntense', evt); @@ -6064,13 +6067,13 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(personnage, 'nueeDeCriquets')) { let malusNueeCriquets = 3 + attributeAsInt(personnage, 'nueeDeCriquetsTempeteDeManaIntense', 0); - expliquer("Nu\xE9e de criquets : -" + malusNueeCriquets + " au jet"); + expliquer("Nuée de criquets : -" + malusNueeCriquets + " au jet"); bonus -= malusNueeCriquets; if (malusNueeCriquets > 3 && evt) removeTokenAttr(personnage, 'nueeDeCriquetsTempeteDeManaIntense', evt); } if (attributeAsBool(personnage, 'nueeDeScorpions')) { - expliquer("Nu\xE9e de scorpions : -3 au jet"); + expliquer("Nuée de scorpions : -3 au jet"); bonus -= 3; } if (attributeAsBool(personnage, 'etatExsangue')) { @@ -6078,12 +6081,12 @@ var COFantasy = COFantasy || function() { bonus -= 2; } if (attributeAsBool(personnage, 'putrefactionOutrTombe')) { - expliquer("Putr\xE9fi\xE9 : -2 au jet"); + expliquer("Putréfié : -2 au jet"); bonus -= 2; } let fortifie = attributeAsInt(personnage, 'fortifie', 0); if (fortifie > 0) { - expliquer("Fortifi\xE9 : +3 au jet"); + expliquer("Fortifié : +3 au jet"); bonus += 3; if (evt) { fortifie--; @@ -6098,18 +6101,18 @@ var COFantasy = COFantasy || function() { !predicateAsBool(personnage, 'porteurDuBouclierDeGrabuge') && !attributeAsBool(personnage, 'sangDeLArbreCoeur')) { let malusOndesCorruptrices = attributeAsInt(personnage, 'ondesCorruptrices', 2); - let msgOndesCorruptrices = "Naus\xE9eu" + onGenre(personnage, "x", "se"); + let msgOndesCorruptrices = "Nauséeu" + onGenre(personnage, "x", "se"); msgOndesCorruptrices += " : -" + malusOndesCorruptrices; expliquer(msgOndesCorruptrices + " aux tests"); bonus -= malusOndesCorruptrices; } if (attributeAsBool(personnage, 'fievreux')) { bonus -= 2; - expliquer("Fi\xE9vreu" + onGenre(personnage, 'x', 'se') + " : -2 aux tests"); + expliquer("Fiévreu" + onGenre(personnage, 'x', 'se') + " : -2 aux tests"); } if (attributeAsBool(personnage, 'secoue')) { bonus -= 2; - expliquer("Secou\xE9" + eForFemale(personnage) + " : -2 aux tests"); + expliquer("Secoué" + eForFemale(personnage) + " : -2 aux tests"); } let bonusCondition = attributeAsInt(personnage, 'modificateurTests', 0); if (bonusCondition != 0) { @@ -6117,7 +6120,7 @@ var COFantasy = COFantasy || function() { if (bonusCondition > 0) { expliquer("Bonus de condition : +" + bonusCondition); } else { - expliquer("P\xE9nalit\xE9 de condition : " + bonusCondition); + expliquer("Pénalité de condition : " + bonusCondition); } } if (attributeAsBool(personnage, 'sensDuDevoir')) { @@ -6149,7 +6152,7 @@ var COFantasy = COFantasy || function() { options.bonusPreds.forEach(function(pred) { let bonusPred = predicateAsInt(personnage, pred, 0); if (bonusPred !== 0) { - expliquer("Pr\xE9dicat " + pred + " : " + ((bonusPred < 0) ? "-" : "+") + bonusPred); + expliquer("Prédicat " + pred + " : " + ((bonusPred < 0) ? "-" : "+") + bonusPred); bonus += bonusPred; } }); @@ -6206,12 +6209,12 @@ var COFantasy = COFantasy || function() { } //retourne un entier - // evt n'est d\xE9fini que si la caract\xE9ristique est effectivement utilis\xE9e + // evt n'est défini que si la caractéristique est effectivement utilisée function bonusTestCarac(carac, personnage, options, testId, evt, explications) { const expliquer = function(msg) { if (explications) explications.push(msg); }; - // D'abord la partie qui d\xE9pend de la caract\xE9ristique + // D'abord la partie qui dépend de la caractéristique let bonus = modCarac(personnage, caracOfMod(carac)); if (!persoEstPNJ(personnage)) { bonus += ficheAttributeAsInt(personnage, carac + "_BONUS", 0); @@ -6235,11 +6238,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'aspectDuDemon')) { bonusAspectDuDemon = getIntValeurOfEffet(personnage, 'aspectDuDemon', 2); - expliquer("Aspect du d\xE9mon : +" + bonusAspectDuDemon + " au jet de DEX"); + expliquer("Aspect du démon : +" + bonusAspectDuDemon + " au jet de DEX"); bonus += bonusAspectDuDemon; } if (attributeAsBool(personnage, 'osBrises')) { - expliquer("Des os sont bris\xE9s : -2 au jet de DEX"); + expliquer("Des os sont brisés : -2 au jet de DEX"); bonus -= 2; } if (attributeAsBool(personnage, 'espaceExigu')) { @@ -6252,19 +6255,19 @@ var COFantasy = COFantasy || function() { bonus -= 1; } if (attributeAsBool(personnage, 'reactionAllergique')) { - expliquer("D\xE9mangeaisons : -2 au jet de DEX"); + expliquer("Démangeaisons : -2 au jet de DEX"); bonus -= 2; } let conditions = attributeAsInt(personnage, 'conditionsHostiles', 0, 2); if (conditions > 0 && (!predicateAsBool(personnage, 'marcheSylvestre') || conditions > 4)) { let msgConditions = "Conditions "; if (conditions < 5) msgConditions += "hostiles"; - else msgConditions += "extr\xEAmes"; + else msgConditions += "extrêmes"; msgConditions += " : -" + conditions + " au jet de DEX"; expliquer(msgConditions); bonus -= conditions; } - if (expertiseSpecialisee == 'dex' || expertiseSpecialisee == 'dexterite' || expertiseSpecialisee == 'dext\xE9rit\xE9') { + if (expertiseSpecialisee == 'dex' || expertiseSpecialisee == 'dexterite' || expertiseSpecialisee == 'dextérité') { expliquer("Expertise : +5 aux jets de DEX"); bonus += 5; } @@ -6283,11 +6286,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'aspectDuDemon')) { bonusAspectDuDemon = getIntValeurOfEffet(personnage, 'aspectDuDemon', 2); - expliquer("Aspect du d\xE9mon : +" + bonusAspectDuDemon + " au jet de FOR"); + expliquer("Aspect du démon : +" + bonusAspectDuDemon + " au jet de FOR"); bonus += bonusAspectDuDemon; } if (attributeAsBool(personnage, 'osBrises')) { - expliquer("Des os sont bris\xE9s : -2 au jet de FOR"); + expliquer("Des os sont brisés : -2 au jet de FOR"); bonus -= 2; } if (attributeAsBool(personnage, 'espaceExigu')) { @@ -6308,7 +6311,7 @@ var COFantasy = COFantasy || function() { bonusInt += ficheAttributeAsInt(personnage, "INT_BONUS", 0); } if (bonusInt > bonusCarac) { - let msgGrosseTete = "Grosse t\xEAte : "; + let msgGrosseTete = "Grosse tête : "; if (bonusInt > 0) msgGrosseTete += '+'; msgGrosseTete += bonusInt + " au lieu de "; if (bonusCarac > 0) msgGrosseTete += '+'; @@ -6321,7 +6324,7 @@ var COFantasy = COFantasy || function() { if (conditions > 0 && (!predicateAsBool(personnage, 'marcheSylvestre') || conditions > 4)) { let msgConditions = "Conditions "; if (conditions < 5) msgConditions += "hostiles"; - else msgConditions += "extr\xEAmes"; + else msgConditions += "extrêmes"; msgConditions += " : -" + conditions + " au jet de FOR"; expliquer(msgConditions); bonus -= conditions; @@ -6336,7 +6339,7 @@ var COFantasy = COFantasy || function() { { if (attributeAsBool(personnage, 'secretsDeLAuDela')) { bonus += 5; - expliquer("Secrets de l'au-del\xE0 : +5"); + expliquer("Secrets de l'au-delà : +5"); } if (expertiseSpecialisee == 'int' || expertiseSpecialisee == 'intelligence') { expliquer("Expertise : +5 aux jets d'INT"); @@ -6358,7 +6361,7 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'batonDesRunesMortes') && (attributeAsBool(personnage, 'runeLizura') || attributeAsBool(personnage, 'runeMitrah'))) { if (!options.competence || options.competence.trim().toLowerCase() != 'intimidation') { - expliquer("Recouvert" + eForFemale(personnage) + " de la boue noire du b\xE2ton : -10 aux tests de CHA"); + expliquer("Recouvert" + eForFemale(personnage) + " de la boue noire du bâton : -10 aux tests de CHA"); bonus -= 10; } } @@ -6377,13 +6380,13 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(personnage, 'controleDuMetabolisme')) { let mod = modCarac(personnage, 'charisme'); if (mod > 0) { - expliquer("Controle du m\xE9tabolisme : +" + mod + " au jet de CON"); + expliquer("Controle du métabolisme : +" + mod + " au jet de CON"); bonus += mod; } } if (attributeAsBool(personnage, 'aspectDuDemon')) { bonusAspectDuDemon = getIntValeurOfEffet(personnage, 'aspectDuDemon', 2); - expliquer("Aspect du d\xE9mon : +" + bonusAspectDuDemon + " au jet de CON"); + expliquer("Aspect du démon : +" + bonusAspectDuDemon + " au jet de CON"); bonus += bonusAspectDuDemon; } if (expertiseSpecialisee == 'con' || expertiseSpecialisee == 'constitution') { @@ -6432,7 +6435,7 @@ var COFantasy = COFantasy || function() { } } } else { - let msgComp = "Comp\xE9tence " + options.competence + " : "; + let msgComp = "Compétence " + options.competence + " : "; if (bonusCompetence === 0) { msgComp += 0; } else { @@ -6462,7 +6465,7 @@ var COFantasy = COFantasy || function() { // Puis la partie commune options = options || {}; bonus += bonusTestToutesCaracs(personnage, options, testId, evt, expliquer); - //Pas besoin de mettre la valeur de caract\xE9ristique si c'est le seul bonus + //Pas besoin de mettre la valeur de caractéristique si c'est le seul bonus if (explications && explications.length == 1) explications.pop(); return bonus; } @@ -6524,7 +6527,7 @@ var COFantasy = COFantasy || function() { fct = tremblementDeTerre; break; default: - error("Impossible de trouver la fonction li\xE9e \xE0 l'effet " + e, ev); + error("Impossible de trouver la fonction liée à l'effet " + e, ev); return; } } @@ -6540,38 +6543,38 @@ var COFantasy = COFantasy || function() { let pl = getPlayerIds(perso); if (pl === undefined) return; let playerId; - if (pl.length > 0) playerId = pl[0]; //Utilis\xE9 juste pour la couleur + if (pl.length > 0) playerId = pl[0]; //Utilisé juste pour la couleur let display = startFramedDisplay(playerId, titre, perso, { chuchote: 'GM' }); switch (d6.val) { case 1: { - let commande = '!cof-dmg 4d6 --psave DEX 15 --titre \xC9boulement majeur'; - addLineToFramedDisplay(display, "\xC9boulement majeur : s\xE9lectionnez les tokens dans la zone et " + boutonSimple(commande, 'cliquez ici')); + let commande = '!cof-dmg 4d6 --psave DEX 15 --titre Éboulement majeur'; + addLineToFramedDisplay(display, "Éboulement majeur : sélectionnez les tokens dans la zone et " + boutonSimple(commande, 'cliquez ici')); break; } case 2: case 3: { - let commande = '!cof-dmg 2d6 --psave DEX 15 --titre \xC9boulement mineur'; - addLineToFramedDisplay(display, "\xC9boulement mineur : choisissez un personnage au hasard et " + boutonSimple(commande, 'cliquez ici')); + let commande = '!cof-dmg 2d6 --psave DEX 15 --titre Éboulement mineur'; + addLineToFramedDisplay(display, "Éboulement mineur : choisissez un personnage au hasard et " + boutonSimple(commande, 'cliquez ici')); break; } case 6: { let commande = '!cof-set-state renverse true --save DEX 12'; - addLineToFramedDisplay(display, "Le sol tremble et se fissure : s\xE9lectionnez les personnages dans une zone d'environ 10 m\xE8tres et " + boutonSimple(commande, 'cliquez ici')); + addLineToFramedDisplay(display, "Le sol tremble et se fissure : sélectionnez les personnages dans une zone d'environ 10 mètres et " + boutonSimple(commande, 'cliquez ici')); break; } default: // 4 ou 5 { let commande = '!cof-effet-temp tremblementMineur 1'; - addLineToFramedDisplay(display, "Tremblement mineur : s\xE9lectionnez les personnages dans la zone et " + boutonSimple(commande, 'cliquez ici')); + addLineToFramedDisplay(display, "Tremblement mineur : sélectionnez les personnages dans la zone et " + boutonSimple(commande, 'cliquez ici')); break; } } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } function foudreDuTemps(perso, d20roll) { @@ -6582,14 +6585,14 @@ var COFantasy = COFantasy || function() { let pl = getPlayerIds(perso); if (pl === undefined) return; let playerId; - if (pl.length > 0) playerId = pl[0]; //Utilis\xE9 juste pour la couleur + if (pl.length > 0) playerId = pl[0]; //Utilisé juste pour la couleur let display = startFramedDisplay(playerId, titre, perso); let explications = []; let np = nomPerso(perso); switch (d6.val) { case 1: { - addLineToFramedDisplay(display, np + " est frapp\xE9" + eForFemale(perso) + " de plein fouet !"); + addLineToFramedDisplay(display, np + " est frappé" + eForFemale(perso) + " de plein fouet !"); let options = { partialSave: { carac: 'DEX', @@ -6621,11 +6624,11 @@ var COFantasy = COFantasy || function() { dmg.display = buildinline(dmg.roll.inlinerolls[dmgRollNumber], dmg.type); dealDamage(perso, dmg, [], evt, false, options, explications, function(dmgDisplay, dmgFinal) { addLineToFramedDisplay(display, - np + " re\xE7oit " + dmgDisplay + " DM"); + np + " reçoit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); return; @@ -6639,7 +6642,7 @@ var COFantasy = COFantasy || function() { save: { carac: 'FOR', seuil: 10, - msgPour: "pour ne pas \xEAtre tomber" + msgPour: "pour ne pas être tomber" } }; let evt = { @@ -6655,7 +6658,7 @@ var COFantasy = COFantasy || function() { addEvent(evt); let saveOpts = { msgPour: options.msgPour, - msgRate: ", rat\xE9.", + msgRate: ", raté.", }; let expliquer = function(s) { explications.push(s); @@ -6668,7 +6671,7 @@ var COFantasy = COFantasy || function() { textDist = distance.val / 2; seuil = 2; } - textDist += distance.val > seuil ? ' m\xE8tres' : ' m\xE8tre'; + textDist += distance.val > seuil ? ' mètres' : ' mètre'; sendChat('', '[[2d6]]', function(resDmg) { let afterEvaluateDmg = resDmg[0].content.split(' '); let dmgRollNumber = rollNumber(afterEvaluateDmg[0]); @@ -6678,16 +6681,16 @@ var COFantasy = COFantasy || function() { type: 'electrique' }; dealDamage(perso, dmg, [], evt, false, options, explications, function(dmgDisplay, dmgFinal) { - addLineToFramedDisplay(display, np + " est projet\xE9" + eForFemale(perso) + " de " + textDist + " par la foudre, et subit " + dmgDisplay + " DM"); + addLineToFramedDisplay(display, np + " est projeté" + eForFemale(perso) + " de " + textDist + " par la foudre, et subit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); if (reussite) { - addLineToFramedDisplay(display, np + " r\xE9siste, la distance de projection passe de " + distance.roll + " \xE0 " + (distance.val / 2)); + addLineToFramedDisplay(display, np + " résiste, la distance de projection passe de " + distance.roll + " à " + (distance.val / 2)); } else { setState(perso, 'renverse', true, evt); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); }); @@ -6697,14 +6700,14 @@ var COFantasy = COFantasy || function() { { addLineToFramedDisplay(display, np + " est dans la zone d'impact !"); if (getState(perso, 'affaibli')) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } let options = { save: { carac: 'CON', seuil: 10, - msgPour: ' pour ne pas \xEAtre affaibli' + eForFemale(perso) + msgPour: ' pour ne pas être affaibli' + eForFemale(perso) } }; const evt = { @@ -6732,17 +6735,17 @@ var COFantasy = COFantasy || function() { return ficheAttributeAsInt(perso, 'pc', 3); } - // Test de caract\xE9ristique + // Test de caractéristique // options : bonusAttrs, bonusPreds, bonus, roll - // Apr\xE8s le test, lance callback(testRes, explications - // testRes.texte est l'affichage du jet de d\xE9 - // testRes.reussite indique si le jet est r\xE9ussi + // Après le test, lance callback(testRes, explications + // testRes.texte est l'affichage du jet de dé + // testRes.reussite indique si le jet est réussi // testRes.echecCritique, testRes.critique pour le type // testRes.valeur pour la valeur totale du jet - // testRes.rerolls pour le texte avec les boutons de rerolls adapt\xE9s. - // testRes.modifiers pour les boutons qui peuvent \xEAtre activ\xE9s sur le roll, qu'il soit r\xE9ussi ou non. - // Pour que les boutons de rerolls fonctionnent, le type d'\xE9v\xE8nement doit \xEAtre support\xE9 par redoEvent() - // ne rajoute pas evt \xE0 l'historique + // testRes.rerolls pour le texte avec les boutons de rerolls adaptés. + // testRes.modifiers pour les boutons qui peuvent être activés sur le roll, qu'il soit réussi ou non. + // Pour que les boutons de rerolls fonctionnent, le type d'évènement doit être supporté par redoEvent() + // ne rajoute pas evt à l'historique function testCaracteristique(personnage, carac, seuil, testId, options, evt, callback) { //asynchrone options = options || {}; let testRes = {}; @@ -6846,10 +6849,10 @@ var COFantasy = COFantasy || function() { boutonSimple("!cof-bouton-chance " + evt.id + " " + testId, "Chance") + " (reste " + pc + " PC)"; } - if (stateCOF.combat && attributeAsBool(personnage, 'runeForgesort_\xE9nergie') && - attributeAsInt(personnage, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0 && + if (stateCOF.combat && attributeAsBool(personnage, 'runeForgesort_énergie') && + attributeAsInt(personnage, 'limiteParCombat_runeForgesort_énergie', 1) > 0 && (carac == 'FOR' || carac == 'CON' || carac == 'DEX')) { - testRes.rerolls += '
    ' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'\xE9nergie"); + testRes.rerolls += '
    ' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'énergie"); } if (stateCOF.combat && capaciteDisponible(personnage, 'petitVeinard', 'combat')) { testRes.rerolls += '
    ' + boutonSimple("!cof-bouton-petit-veinard " + evt.id + " " + testId, "Petit veinard"); @@ -6870,18 +6873,18 @@ var COFantasy = COFantasy || function() { testRes.modifiers += "
    " + boutonSimple("!cof-pacte-sanglant " + evt.id + " 5 " + testId, "Pacte sanglant (+5)"); } } - if (jetCache) sendChat('COF', "/w GM Jet cach\xE9 : " + buildinline(roll) + bonusText); + if (jetCache) sendChat('COF', "/w GM Jet caché : " + buildinline(roll) + bonusText); callback(testRes, explications); }); } catch (e) { - error("Erreur pendant l'\xE9valuation de " + rollExpr + " dans un test de caract\xE9ristiques"); + error("Erreur pendant l'évaluation de " + rollExpr + " dans un test de caractéristiques"); log(e.name + ": " + e.message); } } //callback peut prendre en argument une structure avec les champs: // - texte: Le texte du jet - // - total : Le r\xE9sultat total du jet + // - total : Le résultat total du jet // - echecCritique, critique pour indiquer si 1 ou 20 // - roll: le inlineroll function jetCaracteristique(personnage, carac, options, testId, evt, callback) { @@ -6922,15 +6925,15 @@ var COFantasy = COFantasy || function() { total: d20roll + bonusCarac, }; if (d20roll <= plageEC) { - rtext += " -> \xE9chec critique"; + rtext += " -> échec critique"; rt.echecCritique = true; } else if (d20roll == 20) { - rtext += " -> r\xE9ussite critique"; + rtext += " -> réussite critique"; rt.critique = true; } else if (bonusCarac !== 0 && !jetCache) rtext += " = " + rt.total; rt.texte = rtext; rt.roll = roll; - if (jetCache) sendChat('COF', "/w GM Jet cach\xE9 de caract\xE9ristique : " + buildinline(roll) + bonusText); + if (jetCache) sendChat('COF', "/w GM Jet caché de caractéristique : " + buildinline(roll) + bonusText); callback(rt, explications); }); } @@ -6952,9 +6955,9 @@ var COFantasy = COFantasy || function() { } if (display.retarde) { addFramedHeader(display, cmd[1], false); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } @@ -6978,12 +6981,12 @@ var COFantasy = COFantasy || function() { }; addLineToFramedDisplay(display, boutonSimple('!cof-montrer-resultats-jet ' + playerId, "Montrer aux joueurs")); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); if (!playerIsGM(playerId)) { let dest = joueurJ.get('displayname'); if (dest.includes('"')) { sendChat('COF', display.action); - log("Impossible d'envoyer des messages priv\xE9s \xE0 " + dest + " car le nom contient des guillemets"); + log("Impossible d'envoyer des messages privés à " + dest + " car le nom contient des guillemets"); } sendChat('COF', '/w "' + dest + '" ' + display.action); } @@ -6992,10 +6995,10 @@ var COFantasy = COFantasy || function() { } if (display.retarde) { addFramedHeader(display, playerId, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); - } else sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); + } else sendFramedDisplay(display); } function jetPerso(perso, caracteristique, difficulte, titre, playerId, options) { @@ -7021,12 +7024,12 @@ var COFantasy = COFantasy || function() { if (difficulte === undefined) { jetCaracteristique(perso, caracteristique, options, testId, evt, function(rt, explications) { - addLineToFramedDisplay(display, "R\xE9sultat : " + rt.texte); + addLineToFramedDisplay(display, "Résultat : " + rt.texte); explications.forEach(function(m) { addLineToFramedDisplay(display, m, 80); }); addStatistics(playerId, ["Jet de carac", caracteristique], rt.roll); - // Maintenant, on diminue la mal\xE9diction si le test est un \xE9chec + // Maintenant, on diminue la malédiction si le test est un échec let attrMalediction = tokenAttribute(perso, 'malediction'); if (attrMalediction.length > 0) { if (rt.echecCritique) @@ -7034,8 +7037,8 @@ var COFantasy = COFantasy || function() { else if (!rt.critique) { let action = "!cof-resultat-jet " + evt.id; let ligne = "L'action est-elle "; - ligne += bouton(action + " reussi", "r\xE9ussie", perso); - ligne += " ou " + bouton(action + " rate", "rat\xE9e", perso); + ligne += bouton(action + " reussi", "réussie", perso); + ligne += " ou " + bouton(action + " rate", "ratée", perso); ligne += " ?"; addLineToFramedDisplay(display, ligne); evt.attenteResultat = true; @@ -7048,10 +7051,10 @@ var COFantasy = COFantasy || function() { '
    ' + boutonSimple("!cof-bouton-chance " + evt.id + " " + testId, "Chance") + " (reste " + pc + " PC)"; } - if (stateCOF.combat && attributeAsBool(perso, 'runeForgesort_\xE9nergie') && - attributeAsInt(perso, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0 && + if (stateCOF.combat && attributeAsBool(perso, 'runeForgesort_énergie') && + attributeAsInt(perso, 'limiteParCombat_runeForgesort_énergie', 1) > 0 && (caracteristique == 'FOR' || caracteristique == 'CON' || caracteristique == 'DEX')) { - boutonsReroll += '
    ' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'\xE9nergie"); + boutonsReroll += '
    ' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'énergie"); } if (stateCOF.combat && capaciteDisponible(perso, 'petitVeinard', 'combat')) { boutonsReroll += '
    ' + boutonSimple("!cof-bouton-petit-veinard " + evt.id + " " + testId, "Petit veinard"); @@ -7077,14 +7080,15 @@ var COFantasy = COFantasy || function() { } else { testCaracteristique(perso, caracteristique, difficulte, testId, options, evt, function(tr, explications) { - addLineToFramedDisplay(display, "R\xE9sultat : " + tr.texte); + addLineToFramedDisplay(display, "Résultat : " + tr.texte); explications.forEach(function(m) { addLineToFramedDisplay(display, m, 80); }); if (tr.reussite) { - addLineToFramedDisplay(display, "C'est r\xE9ussi." + tr.modifiers); + let msgReussite = options.messageSiSucces || "C'est réussi."; + addLineToFramedDisplay(display, msgReussite + tr.modifiers); } else { - let msgRate = "C'est rat\xE9." + tr.rerolls + tr.modifiers; + let msgRate = "C'est raté." + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, msgRate); } sendDisplayJetPerso(display, playerId, options); @@ -7097,8 +7101,8 @@ var COFantasy = COFantasy || function() { function boutonsCompetences(display, perso, carac, msg, fond) { let action = msg.content; action = action.replace(/ --competences /, ''); - action = action.replace(/ --competences/, ''); //au cas o\xF9 ce serait le dernier argument - let args = action.substring(9); //on enl\xE8ve !cof-jet + action = action.replace(/ --competences/, ''); //au cas où ce serait le dernier argument + let args = action.substring(9); //on enlève !cof-jet if (!args.startsWith(carac)) action = "!cof-jet " + carac + " " + args; let overlay; switch (carac) { @@ -7106,7 +7110,7 @@ var COFantasy = COFantasy || function() { overlay = 'Force'; break; case 'DEX': - overlay = 'Dext\xE9rit\xE9'; + overlay = 'Dextérité'; break; case 'CON': overlay = 'Constitution'; @@ -7153,8 +7157,8 @@ var COFantasy = COFantasy || function() { addCellInFramedDisplay(display, cell, 80, false, fond); } - // prend une distance en m\xE8tre et retourne une distance dans l'unit\xE9 - // utilis\xE9e sur la page du personnage + // prend une distance en mètre et retourne une distance dans l'unité + // utilisée sur la page du personnage function scaleDistance(perso, distance) { if (perso.scale) return distance * perso.scale; let pageId = perso.pageId; @@ -7188,7 +7192,7 @@ var COFantasy = COFantasy || function() { perso.scale = 39.3701; break; default: - sendChat('COF', "Attention, unit\xE9 de mesure de la page (" + unit + ") non reconnue"); + sendChat('COF', "Attention, unité de mesure de la page (" + unit + ") non reconnue"); perso.scale = 1; } return distance * perso.scale; @@ -7210,9 +7214,9 @@ var COFantasy = COFantasy || function() { return pageId; } - // si d\xE9fini, callback est appel\xE9 \xE0 chaque \xE9l\xE9ment de selected + // si défini, callback est appelé à chaque élément de selected // qui n'est pas un personnage - // iter seulement sur les \xE9l\xE9ment qui correspondent \xE0 des personnages + // iter seulement sur les élément qui correspondent à des personnages function iterSelected(selected, iter, callback) { selected.forEach(function(sel) { let token = getObj('graphic', sel._id); @@ -7249,9 +7253,9 @@ var COFantasy = COFantasy || function() { return true; } - //traduction des coordon\xE9es de path en coordon\xE9es r\xE9elles sur la carte + //traduction des coordonées de path en coordonées réelles sur la carte function translatePathCoordinates(x, y, p) { - //D'abord on calcule les coordonn\xE9es relatives au centre + //D'abord on calcule les coordonnées relatives au centre x -= p.width / 2; y -= p.height / 2; //Puis on applique le scale @@ -7262,7 +7266,7 @@ var COFantasy = COFantasy || function() { let s = Math.sin(p.angle); x = c * x + s * y; y = c * y - s * x; - //Et finalement on ajoute les coordonn\xE9es du centre + //Et finalement on ajoute les coordonnées du centre x += p.left; y += p.top; return { @@ -7297,7 +7301,7 @@ var COFantasy = COFantasy || function() { }); return chemin; }); - //On rajoute les portes ferm\xE9es. + //On rajoute les portes fermées. let doors = findObjs({ _type: 'door', _pageid: pageId, @@ -7319,7 +7323,7 @@ var COFantasy = COFantasy || function() { return murs; } - //v\xE9rifie si de la nouvelle position on peut voir le suivi + //vérifie si de la nouvelle position on peut voir le suivi function obstaclePresent(nsx, nsy, pt, murs) { if (nsx == pt.x && nsy == pt.y) return false; let ps = { @@ -7438,7 +7442,7 @@ var COFantasy = COFantasy || function() { if (saufAllies) allies = (new Set(allies)).add(actif.charId); } else { if (msg.selected === undefined || msg.selected.length === 0) { - error("Pas d'alli\xE9 car pas de token s\xE9lectionn\xE9", msg); + error("Pas d'allié car pas de token sélectionné", msg); return; } iterSelected(msg.selected, function(personnage) { @@ -7467,7 +7471,7 @@ var COFantasy = COFantasy || function() { let ci = tok.get('represents'); if (ci === '') return; if (!allies.has(ci)) return; - //On enl\xE8ve le token actif, mais seulement pour allies + //On enlève le token actif, mais seulement pour allies if (cmdSplit[0] == 'allies') { if (actives.indexOf(function(perso) { return perso.charId == ci; @@ -7498,7 +7502,7 @@ var COFantasy = COFantasy || function() { return; case 'target': if (cmdSplit.length < 2) { - error("Il manque l'id de la cible (apr\xE8s --target)", cmd); + error("Il manque l'id de la cible (après --target)", cmd); return; } selected.push({ @@ -7515,7 +7519,7 @@ var COFantasy = COFantasy || function() { centre = actif; rayon = parseInt(cmdSplit[1]); } else { - error("Pas assez d'arguments pour d\xE9finir un disque", cmdSplit); + error("Pas assez d'arguments pour définir un disque", cmdSplit); return; } } else { @@ -7527,7 +7531,7 @@ var COFantasy = COFantasy || function() { rayon = parseInt(cmdSplit[2]); } if (isNaN(rayon) || rayon < 0) { - error("Rayon du disque mal d\xE9fini", cmdSplit); + error("Rayon du disque mal défini", cmdSplit); return; } let tokenCentre = centre.token; @@ -7535,17 +7539,17 @@ var COFantasy = COFantasy || function() { if (cmdSplit.length > 3) { portee = parseInt(cmdSplit[3]); if (isNaN(portee) || portee < 0) { - error("La port\xE9e du disque est mal form\xE9e", cmdSplit); + error("La portée du disque est mal formée", cmdSplit); return; } if (actif === undefined) { - error("Pas de token s\xE9lectionn\xE9 pour calculer la distance du disque", msg); + error("Pas de token sélectionné pour calculer la distance du disque", msg); return; } if (distanceCombat(tokenCentre, actif.token, pageId, { strict1: true }) > portee) { - sendPerso(actif, "Le centre de l'effet est plac\xE9 trop loin (port\xE9e " + portee + " m)"); + sendPerso(actif, "Le centre de l'effet est placé trop loin (portée " + portee + " m)"); return; } } @@ -7571,7 +7575,7 @@ var COFantasy = COFantasy || function() { layer: 'objects' }); allToksDisque.forEach(function(obj) { - if (actif && portee === 0 && obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-m\xEAme + if (actif && portee === 0 && obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-même let objCharId = obj.get('represents'); if (objCharId === '') return; if (getState({ @@ -7596,8 +7600,8 @@ var COFantasy = COFantasy || function() { spawnFx(tokenCentre.get('left'), tokenCentre.get('top'), options.targetFx, pageId); } if (tokenCentre.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir le disque - tokenCentre.remove(); //On l'enl\xE8ve, normalement plus besoin + //C'est juste un token utilisé pour définir le disque + tokenCentre.remove(); //On l'enlève, normalement plus besoin delete options.targetFx; } return; @@ -7607,7 +7611,7 @@ var COFantasy = COFantasy || function() { observateur = persoOfId(cmdSplit[1], cmdSplit[1], pageId); } if (observateur === undefined) { - error("Impossible de trouver la personne \xE0 partir de laquelle on s\xE9lectionne les tokens en vue", msg); + error("Impossible de trouver la personne à partir de laquelle on sélectionne les tokens en vue", msg); return; } page = page || getObj("page", pageId); @@ -7625,7 +7629,7 @@ var COFantasy = COFantasy || function() { layer: 'objects' }); tokensEnVue.forEach(function(obj) { - if (actif && obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-m\xEAme + if (actif && obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-même let objCharId = obj.get('represents'); if (objCharId === '') return; if (obj.get('bar1_max') == 0) return; // jshint ignore:line @@ -7641,12 +7645,12 @@ var COFantasy = COFantasy || function() { return; case 'alliesEnVue': if (actif === undefined) { - error("Impossible de trouver la personne dont on s\xE9lectionne les lli\xE9s en vue", msg); + error("Impossible de trouver la personne dont on sélectionne les lliés en vue", msg); return; } let alliesEnVue = alliesParPerso[actif.charId]; if (alliesEnVue === undefined) { - log("Personnage sans alli\xE9", actif); + log("Personnage sans allié", actif); return; } page = page || getObj("page", pageId); @@ -7664,7 +7668,7 @@ var COFantasy = COFantasy || function() { layer: 'objects' }); tokensAlliesEnVue.forEach(function(obj) { - if (obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-m\xEAme + if (obj.id == actif.token.id) return; //on ne se cible pas si le centre de l'aoe est soi-même let objCharId = obj.get('represents'); if (objCharId === '') return; if (!alliesEnVue.has(objCharId)) return; @@ -7704,7 +7708,7 @@ var COFantasy = COFantasy || function() { } } - //msg peut \xEAtre directement le playerId ou un message + //msg peut être directement le playerId ou un message function getPlayerIdFromMsg(msg) { if (msg.playerid === undefined) return msg; let playerId = msg.playerid; @@ -7741,7 +7745,7 @@ var COFantasy = COFantasy || function() { //!cof-jet [carac] [difficulte] // - carac : FOR, DEX, CON, INT, SAG, CHA - // Les tokens s\xE9lectionn\xE9s sont ceux qui doivent faire le jet + // Les tokens sélectionnés sont ceux qui doivent faire le jet function jet(msg) { let opts = msg.content.split(' --'); let cmd = opts.shift().split(' '); @@ -7754,13 +7758,13 @@ var COFantasy = COFantasy || function() { switch (args[0]) { case 'nom': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } args.shift(); let nom = args.join(' '); if (options.nom && options.nom != nom) { - error("Nom du jet d\xE9fini deux fois !", options.nom); + error("Nom du jet défini deux fois !", options.nom); } options.nom = nom; if (options.competence) { @@ -7770,26 +7774,26 @@ var COFantasy = COFantasy || function() { return; case 'attribut': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } options.bonusAttrs.push(args[1]); return; case 'predicat': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } options.bonusPreds.push(args[1]); return; case 'bonus': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } let bonus = parseInt(args[1]); if (isNaN(bonus)) { - error("Le bonus doit \xEAtre un nombre", opts); + error("Le bonus doit être un nombre", opts); return; } options.bonus = (options.bonus || 0) + bonus; @@ -7800,30 +7804,34 @@ var COFantasy = COFantasy || function() { return; case 'plageEchecCritique': if (args.length < 2) { - error("Il manque un argument \xE0 l'option " + args[0], opts); + error("Il manque un argument à l'option " + args[0], opts); return; } let plageEC = parseInt(args[1]); if (isNaN(plageEC) || plageEC < 0 || plageEC > 19) { - error("La plage d'\xE9checs critqiques doit \xEAtre un nombre positif inf\xE9rieur \xE0 19", opts); + error("La plage d'échecs critqiques doit être un nombre positif inférieur à 19", opts); return; } options.plageEchecCritique = plageEC; + return; + case 'succes': + options.messageSiSucces = args.slice(1).join(' '); + return; } }); getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Utilisation de !cof-jet sans s\xE9lection de token", playerId); + sendPlayer(msg, "Utilisation de !cof-jet sans sélection de token", playerId); return; } - if (cmd.length < 2) { //On demande la carac et la comp\xE9tence, si d\xE9finies dans un handout Comp\xE9tence + if (cmd.length < 2) { //On demande la carac et la compétence, si définies dans un handout Compétence if (options.nom) { - error("Il manque la caract\xE9ristique \xE0 utiliser pour la comp\xE9tence " + options.nom, msg.content); + error("Il manque la caractéristique à utiliser pour la compétence " + options.nom, msg.content); return; } let fond = listeCompetences.nombre > 25; iterSelected(selected, function(perso) { - let display = startFramedDisplay(playerId, "Jet de caract\xE9ristique", perso, { + let display = startFramedDisplay(playerId, "Jet de caractéristique", perso, { chuchote: true }); startTableInFramedDisplay(display); @@ -7834,7 +7842,7 @@ var COFantasy = COFantasy || function() { boutonsCompetences(display, perso, 'INT', msg); boutonsCompetences(display, perso, 'CHA', msg, fond); endTableInFramedDisplay(display); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); //fin de iterSelected return; } @@ -7848,11 +7856,11 @@ var COFantasy = COFantasy || function() { let display = startFramedDisplay(playerId, "Jet " + deCarac(caracteristique), perso, { chuchote: true }); - addLineToFramedDisplay(display, "Choisissez la comp\xE9tence"); + addLineToFramedDisplay(display, "Choisissez la compétence"); startTableInFramedDisplay(display); boutonsCompetences(display, perso, caracteristique, msg); endTableInFramedDisplay(display); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); //fin de iterSelected return; } @@ -7887,7 +7895,7 @@ var COFantasy = COFantasy || function() { } if (options.bonus) titre += " (" + ((options.bonus > 0) ? '+' : '') + options.bonus + ")"; - if (difficulte !== undefined) titre += " difficult\xE9 " + difficulte; + if (difficulte !== undefined) titre += " difficulté " + difficulte; iterSelected(selected, function(perso) { jetPerso(perso, caracteristique, difficulte, titre, playerId, options); }); //fin de iterSelected @@ -7902,7 +7910,7 @@ var COFantasy = COFantasy || function() { } const evt = findEvent(args[1]); if (evt === undefined) { - error("Le jet est trop ancien ou \xE9te annul\xE9", args); + error("Le jet est trop ancien ou éte annulé", args); return; } if (evt.personnage === undefined) { @@ -7913,12 +7921,12 @@ var COFantasy = COFantasy || function() { let message = evt.type + " "; if (args[2] == 'rate') { diminueMalediction(evt.personnage, evt); - message += "rat\xE9."; - } else message += "r\xE9ussi."; + message += "raté."; + } else message += "réussi."; sendPerso(evt.personnage, message); delete evt.attenteResultat; } else { - sendPlayer(msg, "R\xE9sultat d\xE9j\xE0 d\xE9cid\xE9"); + sendPlayer(msg, "Résultat déjà décidé"); } } @@ -7938,7 +7946,7 @@ var COFantasy = COFantasy || function() { function optionsDeTempeteDeMana(msg) { if (tempeteDeManaCourante.vide) { - error("Pas de temp\xEAte de mana en cours", tempeteDeManaCourante); + error("Pas de tempête de mana en cours", tempeteDeManaCourante); return; } let perso = tempeteDeManaCourante.perso; @@ -7988,7 +7996,7 @@ var COFantasy = COFantasy || function() { tempeteDeManaCourante.intense = it; } } - let title = "Temp\xEAte de mana"; + let title = "Tempête de mana"; if (tempeteDeManaCourante.cout) { title += " de puissance " + tempeteDeManaCourante.cout; } @@ -8003,14 +8011,14 @@ var COFantasy = COFantasy || function() { if (tempeteDeManaCourante.dureeDeBase && tempeteDeManaCourante.dm === undefined && tempeteDeManaCourante.soins === undefined) - ajouterOptionTempete(display, "duree", "Dur\xE9e", restant); + ajouterOptionTempete(display, "duree", "Durée", restant); if (tempeteDeManaCourante.porteeDeBase) - ajouterOptionTempete(display, "portee", "Port\xE9e", restant); + ajouterOptionTempete(display, "portee", "Portée", restant); ajouterOptionTempete(display, "rapide", "Rapide", restant); if (tempeteDeManaCourante.altruistePossible) { let la = 'Magie altruiste : '; if (restant || tempeteDeManaCourante.altruiste) { - let tla = "S\xE9lectionner"; + let tla = "Sélectionner"; if (tempeteDeManaCourante.altruiste) { tla = nomPerso(tempeteDeManaCourante.altruiste); } @@ -8043,7 +8051,7 @@ var COFantasy = COFantasy || function() { } v = v.replace(/--tempeteDeMana/, vopt); addLineToFramedDisplay(display, boutonSimple(v, "Valider")); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } function setTempeteDeMana(playerId, perso, cmd, options) { @@ -8069,7 +8077,7 @@ var COFantasy = COFantasy || function() { if (max === undefined || max > niveau - (mana / cout_par_effet)) max = Math.floor(niveau - (mana / cout_par_effet)); if (max < 1) { - sendPerso(perso, "ne peut pas d\xE9penser plus de mana en temp\xEAte de mana (niveau " + niveau + ", mana d\xE9j\xE0 d\xE9pens\xE9e " + mana + ")"); + sendPerso(perso, "ne peut pas dépenser plus de mana en tempête de mana (niveau " + niveau + ", mana déjà dépensée " + mana + ")"); return; } tempeteDeManaCourante.max = max; @@ -8118,7 +8126,7 @@ var COFantasy = COFantasy || function() { } else { let intensite = parseInt(ta); if (isNaN(ta) || ta <= 0) { - error("Option de temp\xEAte de mana " + ta + " non reconnue", cmd); + error("Option de tempête de mana " + ta + " non reconnue", cmd); break; } options.tempeteDeManaIntense = options.tempeteDeManaIntense || 0; @@ -8225,7 +8233,7 @@ var COFantasy = COFantasy || function() { } case 'predicatCible': if (args.length < 2) { - error("Il manque le pr\xE9dicat de la cible", args); + error("Il manque le prédicat de la cible", args); return; } let valeur; @@ -8253,8 +8261,8 @@ var COFantasy = COFantasy || function() { } let valeurDeAttaque = parseInt(args[1]); if (isNaN(valeurDeAttaque)) { - error("La condition de d\xE9 d'attaque doit \xEAtre un nombre", args); - // on continue expr\xE8s pour tomber dans le cas par d\xE9faut + error("La condition de dé d'attaque doit être un nombre", args); + // on continue exprès pour tomber dans le cas par défaut } else { return { type: 'deAttaque', @@ -8282,7 +8290,7 @@ var COFantasy = COFantasy || function() { function getFx(cmd, argName, obj, funName) { if (cmd.length < 2) { - let errMsg = "Il manque un argument \xE0 l'option --" + argName; + let errMsg = "Il manque un argument à l'option --" + argName; if (funName) errMsg += " de " + funName; sendChat("COF", errMsg); return; @@ -8306,7 +8314,8 @@ var COFantasy = COFantasy || function() { let dm = { nbDe: 0, dice: 4, - bonus: 0 + bonus: 0, + id: generateUUID() }; let exprDM = expr.trim().toLowerCase(); let indexD = exprDM.indexOf('d'); @@ -8314,7 +8323,7 @@ var COFantasy = COFantasy || function() { dm.nbDe = parseInt(exprDM.substring(0, indexD)); if (isNaN(dm.nbDe) || dm.nbDe < 0) { if (msg) - error("Expression de " + msg + ' ' + exprDM + " mal form\xE9e", expr); + error("Expression de " + msg + ' ' + exprDM + " mal formée", expr); return; } exprDM = exprDM.substring(indexD + 1); @@ -8363,12 +8372,12 @@ var COFantasy = COFantasy || function() { } const res = parseCarac(cmd[1]); if (res === undefined) { - error("Le premier argument de save n'est pas une caract\xE9ristique", cmd); + error("Le premier argument de save n'est pas une caractéristique", cmd); return; } res.seuil = parseInt(cmd[2]); if (isNaN(res.seuil)) { - error("Le deuxi\xE8me argument de --psave n'est pas un nombre", cmd); + error("Le deuxième argument de --psave n'est pas un nombre", cmd); return; } if (cmd.length > 3) { @@ -8380,7 +8389,7 @@ var COFantasy = COFantasy || function() { case 'carac': case 'carac2': case 'seuil': - error("Argument suppl\xE9mentaire de save inconnu", cmd); + error("Argument supplémentaire de save inconnu", cmd); return; case 'tempete': let ti = 1; @@ -8392,12 +8401,12 @@ var COFantasy = COFantasy || function() { return; case 'contact': if (oa.length < 2) { - error("Il manque la difficult\xE9 pour les cibles au contact"); + error("Il manque la difficulté pour les cibles au contact"); return; } let diff = parseInt(oa[1]); if (isNaN(diff)) { - error("La difficult\xE9 pour les cibles au contact n'est pas un nombre"); + error("La difficulté pour les cibles au contact n'est pas un nombre"); return; } res.contact = diff; @@ -8411,8 +8420,8 @@ var COFantasy = COFantasy || function() { } //juste le traitement d'une liste d'options - // lastEtat : dernier de etats et effets - // lastType : dernier type de d\xE9g\xE2ts inflig\xE9s + // lastEtat : dernier de etats et effets, pour savoir à quoi appliquer --save + // lastType : dernier type de dégâts infligés // scope : pour les conditionnelles function parseAttackOptions(attaquant, optArgs, lastEtat, lastType, scope, playerId, msg, targetToken, attackLabel, weaponStats, options) { optArgs.forEach(function(arg) { @@ -8483,7 +8492,7 @@ var COFantasy = COFantasy || function() { case 'tirDeBarrage': case 'test': case 'traquenard': - case 'tueurDeGeants': //obsol\xE8te + case 'tueurDeGeants': //obsolète case 'tueurDeGrands': case 'grenaille': case 'attaqueArmeeConjuree': @@ -8501,7 +8510,7 @@ var COFantasy = COFantasy || function() { return; case 'aussiArmeDeJet': if (cmd.length < 2) { - error("Il faut pr\xE9ciser l'arme associ\xE9e \xE0 celle-ci pour --aussiArmeDeJet", cmd); + error("Il faut préciser l'arme associée à celle-ci pour --aussiArmeDeJet", cmd); return; } options.aussiArmeDeJet = cmd[1]; @@ -8511,7 +8520,7 @@ var COFantasy = COFantasy || function() { options.avantage = options.avantage || 1; options.avantage++; return; - case 'd\xE9savantage': + case 'désavantage': case 'desavantage': options.avantage = options.avantage || 1; options.avantage--; @@ -8532,7 +8541,7 @@ var COFantasy = COFantasy || function() { case 'nom': case 'special': if (cmd.length < 1) { - error("Il manque le nom apr\xE8s l'option --" + cmd[0], cmd); + error("Il manque le nom après l'option --" + cmd[0], cmd); return; } options[cmd[0]] = cmd.slice(1).join(' ').trim(); @@ -8540,7 +8549,7 @@ var COFantasy = COFantasy || function() { case 'toucher': case 'modifiePortee': if (cmd.length < 1) { - error("Il manque la valeur apr\xE8s l'option --" + cmd[0], cmd); + error("Il manque la valeur après l'option --" + cmd[0], cmd); return; } let intArg = parseInt(cmd[1]); @@ -8552,7 +8561,7 @@ var COFantasy = COFantasy || function() { return; case 'crit': if (cmd.length < 1) { - error("Il manque la valeur apr\xE8s l'option --crit", cmd); + error("Il manque la valeur après l'option --crit", cmd); return; } let crit = parseInt(cmd[1]); @@ -8566,15 +8575,15 @@ var COFantasy = COFantasy || function() { return; case 'dm': if (cmd.length < 1) { - error("Il manque la valeur apr\xE8s l'option --dm", cmd); + error("Il manque la valeur après l'option --dm", cmd); return; } - let dm = parseDice(cmd.slice(1).join(''), 'd\xE9g\xE2ts'); + let dm = parseDice(cmd.slice(1).join(''), 'dégâts'); if (dm) options.dm = dm; return; case 'portee': if (cmd.length < 1) { - error("Il manque la valeur apr\xE8s l'option --portee", cmd); + error("Il manque la valeur après l'option --portee", cmd); return; } let portee = parseInt(cmd[1]); @@ -8594,7 +8603,7 @@ var COFantasy = COFantasy || function() { return; case 'attaqueMagiqueDe': if (cmd.length < 1) { - error("Il manque le nom du personnage apr\xE8s l'option --attaqueMagiqueDe", cmd); + error("Il manque le nom du personnage après l'option --attaqueMagiqueDe", cmd); return; } let attaqueMagiqueDe = cmd.slice(1).join(' '); @@ -8603,22 +8612,22 @@ var COFantasy = COFantasy || function() { name: attaqueMagiqueDe }); if (ficheAttaqueMagique.length === 0) { - error("Il n'existe pas de personnage nomm\xE9 " + attaqueMagiqueDe, cmd); + error("Il n'existe pas de personnage nommé " + attaqueMagiqueDe, cmd); return; } if (ficheAttaqueMagique.length > 1) { - error("Attention, il existe plus d'un pesonnage nomm\xE9 " + attaqueMagiqueDe, cmd); + error("Attention, il existe plus d'un pesonnage nommé " + attaqueMagiqueDe, cmd); } let amCid = { charId: ficheAttaqueMagique[0].id }; let toucher = computeArmeAtk(amCid, '@{ATKMAG}'); if (isNaN(toucher)) { - error("Impossible de d\xE9terminer l'attaque de " + attaqueMagiqueDe, toucher); + error("Impossible de déterminer l'attaque de " + attaqueMagiqueDe, toucher); return; } if (options.toucher !== undefined) { - error("Attention, on a \xE0 la fois une option toucher et une option attaqueMagiqueDe. On ignore l'option --toucher", optArgs); + error("Attention, on a à la fois une option toucher et une option attaqueMagiqueDe. On ignore l'option --toucher", optArgs); } options.toucher = toucher; return; @@ -8639,14 +8648,14 @@ var COFantasy = COFantasy || function() { } scope.ignoreRD = parseInt(cmd[1]); if (isNaN(scope.ignoreRD) || scope.ignoreRD < 1) { - log("Pas un nombre positif apr\xE8s --ignoreRD, interpr\xE9t\xE9 comme ignore toute la RD"); + log("Pas un nombre positif après --ignoreRD, interprété comme ignore toute la RD"); scope.ignoreRD = undefined; scope.ignoreTouteRD = true; } return; case 'tueurDe': if (cmd.length < 2) { - log("Il faut pr\xE9ciser --tueurDe quoi"); + log("Il faut préciser --tueurDe quoi"); return; } options.tueurDe = options.tueurDe || []; @@ -8657,7 +8666,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { niveauMagie = parseInt(cmd[1]); if (isNaN(niveauMagie) || niveauMagie < 1) { - error("Le niveau de magie doit \xEAtre au moins 1", cmd); + error("Le niveau de magie doit être au moins 1", cmd); niveauMagie = 1; } } @@ -8668,16 +8677,16 @@ var COFantasy = COFantasy || function() { return; case 'tempsRecharge': if (cmd.length < 3) { - error("Il manque un argument \xE0 l'option --tempsRecharge de !cof-attack", cmd); + error("Il manque un argument à l'option --tempsRecharge de !cof-attack", cmd); return; } if (!estEffetTemp(cmd[1])) { - error("Le premier argument de l'option --tempsRecharge doit \xEAtre un effet temporaire r\xE9pertori\xE9", cmd); + error("Le premier argument de l'option --tempsRecharge doit être un effet temporaire répertorié", cmd); return; } let tr = parseInt(cmd[2]); if (isNaN(tr)) { - error("Le deuxi\xE8me argument de l'option --tempsRecharge doit \xEAtre un nombre", cmd); + error("Le deuxième argument de l'option --tempsRecharge doit être un nombre", cmd); return; } options.tempsRecharge = { @@ -8687,7 +8696,7 @@ var COFantasy = COFantasy || function() { return; case 'plus': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --plus de !cof-attack", cmd); + error("Il manque un argument à l'option --plus de !cof-attack", cmd); return; } let val = arg.substring(arg.indexOf(' ') + 1); @@ -8699,7 +8708,7 @@ var COFantasy = COFantasy || function() { break; case 'plusCrit': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --plusCrit de !cof-attack", cmd); + error("Il manque un argument à l'option --plusCrit de !cof-attack", cmd); return; } let valCrit = arg.substring(arg.indexOf(' ') + 1); @@ -8712,7 +8721,7 @@ var COFantasy = COFantasy || function() { case 'dmSiRate': case 'dmCible': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --" + cmd[0] + " de !cof-attack", cmd); + error("Il manque un argument à l'option --" + cmd[0] + " de !cof-attack", cmd); return; } let valDm = arg.substring(arg.indexOf(' ') + 1); @@ -8723,7 +8732,7 @@ var COFantasy = COFantasy || function() { break; case 'effet': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --effet de !cof-attack", cmd); + error("Il manque un argument à l'option --effet de !cof-attack", cmd); return; } let effet = cmd[1]; @@ -8736,7 +8745,7 @@ var COFantasy = COFantasy || function() { duree = parseInt(cmd[2]); if (isNaN(duree) || duree < 1) { error( - "Le deuxi\xE8me argument de --effet doit \xEAtre un nombre positif", + "Le deuxième argument de --effet doit être un nombre positif", cmd); return; } @@ -8762,7 +8771,7 @@ var COFantasy = COFantasy || function() { typeDmg: lastType }; } else { - error(cmd[1] + " n'est pas un effet temporaire r\xE9pertori\xE9", cmd); + error(cmd[1] + " n'est pas un effet temporaire répertorié", cmd); return; } scope.effets = scope.effets || []; @@ -8770,7 +8779,7 @@ var COFantasy = COFantasy || function() { return; case 'valeur': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --valeur de !cof-attack", cmd); + error("Il manque un argument à l'option --valeur de !cof-attack", cmd); return; } if (scope.effets === undefined || scope.effets.length === 0) { @@ -8816,10 +8825,10 @@ var COFantasy = COFantasy || function() { case 'etatSi': case 'etat': if (cmd.length < 3 && cmd[0] == 'etatSi') { - error("Il manque un argument \xE0 l'option --etatSi de !cof-attack", cmd); + error("Il manque un argument à l'option --etatSi de !cof-attack", cmd); return; } else if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --etat de !cof-attack", cmd); + error("Il manque un argument à l'option --etat de !cof-attack", cmd); return; } let etat = cmd[1]; @@ -8841,7 +8850,7 @@ var COFantasy = COFantasy || function() { if (cmd[0] == 'etat' && cmd.length > 3) { if (!isCarac(cmd[2]) && (cmd[2].length != 6 || !isCarac(cmd[2].substring(0, 3)) || !isCarac(cmd[2].substring(3, 6)))) { - error("Caract\xE9ristique du jet de sauvegarde incorrecte", cmd); + error("Caractéristique du jet de sauvegarde incorrecte", cmd); return; } lastEtat.saveCarac = cmd[2]; @@ -8851,7 +8860,7 @@ var COFantasy = COFantasy || function() { } else { lastEtat.saveDifficulte = parseInt(cmd[3]); if (isNaN(lastEtat.saveDifficulte)) { - error("Difficult\xE9 du jet de sauvegarde incorrecte", cmd); + error("Difficulté du jet de sauvegarde incorrecte", cmd); delete lastEtat.saveCarac; delete lastEtat.saveDifficulte; } @@ -8861,7 +8870,7 @@ var COFantasy = COFantasy || function() { return; case 'peur': if (cmd.length < 3) { - error("Il manque un argument \xE0 l'option --peur de !cof-attack", cmd); + error("Il manque un argument à l'option --peur de !cof-attack", cmd); return; } scope.peur = { @@ -8869,10 +8878,10 @@ var COFantasy = COFantasy || function() { duree: parseInt(cmd[2]) }; if (isNaN(scope.peur.seuil)) { - error("Le premier argument de --peur doit \xEAtre un nombre (le seuil)", cmd); + error("Le premier argument de --peur doit être un nombre (le seuil)", cmd); } if (isNaN(scope.peur.duree) || scope.peur.duree <= 0) { - error("Le deuxi\xE8me argument de --peur doit \xEAtre un nombre positif (la dur\xE9e)", cmd); + error("Le deuxième argument de --peur doit être un nombre positif (la durée)", cmd); } return; case 'feu': @@ -8903,7 +8912,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { vampirise = parseInt(cmd[1]); if (isNaN(vampirise)) { - error("Il faut un pourcentage entier comme argument \xE0 --vampirise", cmd); + error("Il faut un pourcentage entier comme argument à --vampirise", cmd); vampirise = 100; } } @@ -8934,7 +8943,7 @@ var COFantasy = COFantasy || function() { break; case 'disparition': if (cmd.length < 2) { - error("Il manque un argument \xE0 l'option --disparition de !cof-attack", cmd); + error("Il manque un argument à l'option --disparition de !cof-attack", cmd); return; } let disparition = parseInt(cmd[1]); @@ -8986,7 +8995,7 @@ var COFantasy = COFantasy || function() { case 'save': if (lastEtat) { if (lastEtat.save) { - error("Red\xE9finition de la condition de save pour un effet", optArgs); + error("Redéfinition de la condition de save pour un effet", optArgs); } let saveParams = parseSave(cmd); if (saveParams) { @@ -9004,7 +9013,7 @@ var COFantasy = COFantasy || function() { case 'saveParJour': if (lastEtat) { if (lastEtat[cmd[0]]) { - error("Red\xE9finition de la condition de save pour un effet", optArgs); + error("Redéfinition de la condition de save pour un effet", optArgs); } let saveParTourParams = parseSave(cmd); if (saveParTourParams) { @@ -9025,12 +9034,12 @@ var COFantasy = COFantasy || function() { case 'mana': { if (cmd.length < 2) { - error("Usage : --mana co\xFBt", cmd); + error("Usage : --mana coût", cmd); return; } let mana = parseInt(cmd[1]); if (isNaN(mana) || mana < 0) { - error("Le co\xFBt en mana doit \xEAtre un nombre positif"); + error("Le coût en mana doit être un nombre positif"); return; } if (scope.mana === undefined) scope.mana = 0; @@ -9044,7 +9053,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { cout = parseInt(cmd[1]); if (isNaN(cout) || cout < 0) { - error("Le co\xFBt de la magie rapide n'est pas un entier positif", cmd); + error("Le coût de la magie rapide n'est pas un entier positif", cmd); cout = 1; } } @@ -9062,7 +9071,7 @@ var COFantasy = COFantasy || function() { } else { let base = parseInt(cmd[1]); if (isNaN(base)) { - error("L'argument de --magieEnArmure doit \xEAtre un nombre ou mana", cmd); + error("L'argument de --magieEnArmure doit être un nombre ou mana", cmd); return; } options.magieEnArmure = { @@ -9080,7 +9089,7 @@ var COFantasy = COFantasy || function() { } let rang = parseInt(cmd[1]); if (isNaN(rang) || rang < 1) { - error("Le rang doit \xEAtre un nombre positif"); + error("Le rang doit être un nombre positif"); return; } scope.rang = rang; @@ -9094,7 +9103,7 @@ var COFantasy = COFantasy || function() { } let bAtt = parseInt(cmd[1]); if (isNaN(bAtt)) { - error("Le bonus (" + cmd[0] + ") doit \xEAtre un nombre"); + error("Le bonus (" + cmd[0] + ") doit être un nombre"); return; } if (scope[cmd[0]] === undefined) scope[cmd[0]] = 0; @@ -9108,7 +9117,7 @@ var COFantasy = COFantasy || function() { } let b2Att = parseInt(cmd[1]); if (isNaN(b2Att)) { - error("Le bonus (" + cmd[0] + ") doit \xEAtre un nombre"); + error("Le bonus (" + cmd[0] + ") doit être un nombre"); return; } if (options[cmd[0]] === undefined) options[cmd[0]] = 0; @@ -9154,12 +9163,12 @@ var COFantasy = COFantasy || function() { } return; case 'munition': - if (options.munition) { //on \xE9vite la r\xE9cursion - error("Plusieurs options --munition. Seule la premi\xE8re est prise en compte", cmd); + if (options.munition) { //on évite la récursion + error("Plusieurs options --munition. Seule la première est prise en compte", cmd); return; } if (cmd.length < 2) { - error("Pour les munitions, il faut pr\xE9ciser le label de la munition", cmd); + error("Pour les munitions, il faut préciser le label de la munition", cmd); return; } let labelMunition = cmd[1]; @@ -9189,13 +9198,13 @@ var COFantasy = COFantasy || function() { } return; } - sendPlayer(msg, "Utilisez plut\xF4t les munitions d\xE9finies sur la fiche", playerId); - //Compatibilit\xE9 avec ancienne version: - let tauxPertes = 100; //Par d\xE9faut, les munitions sont perdues + sendPlayer(msg, "Utilisez plutôt les munitions définies sur la fiche", playerId); + //Compatibilité avec ancienne version: + let tauxPertes = 100; //Par défaut, les munitions sont perdues if (cmd.length > 2) tauxPertes = parseInt(cmd[2]); if (isNaN(tauxPertes) || tauxPertes < 0 || tauxPertes > 100) { - error("Le taux de pertes des munitions doit \xEAtre un nombre entre 0 et 100"); + error("Le taux de pertes des munitions doit être un nombre entre 0 et 100"); tauxPertes = 100; } options.munition = { @@ -9205,7 +9214,7 @@ var COFantasy = COFantasy || function() { return; case "ligne": if (options.aoe) { - error("Deux options pour d\xE9finir une aoe", optArgs); + error("Deux options pour définir une aoe", optArgs); return; } options.aoe = { @@ -9214,7 +9223,7 @@ var COFantasy = COFantasy || function() { return; case 'disque': if (options.aoe) { - error("Deux options pour d\xE9finir une aoe", optArgs); + error("Deux options pour définir une aoe", optArgs); return; } if (cmd.length < 2) { @@ -9235,14 +9244,14 @@ var COFantasy = COFantasy || function() { return; case 'cone': if (options.aoe) { - error("Deux options pour d\xE9finir une aoe", optArgs); + error("Deux options pour définir une aoe", optArgs); return; } let angle = 90; if (cmd.length > 1) { angle = parseInt(cmd[1]); if (isNaN(angle) || angle < 0 || angle > 360) { - error("Param\xE8tre d'angle du cone incorrect", cmd); + error("Paramètre d'angle du cone incorrect", cmd); angle = 90; } } @@ -9258,7 +9267,7 @@ var COFantasy = COFantasy || function() { } let targetS = persoOfId(cmd[1]); if (targetS === undefined) { - error("Cible suppl\xE9mentaire invalide", cmd); + error("Cible supplémentaire invalide", cmd); return; } if (targetToken.id == targetS.token.id) return; @@ -9314,12 +9323,12 @@ var COFantasy = COFantasy || function() { return; case 'limiteParJour': if (cmd.length < 2) { - error("Il manque la limite journali\xE8re", cmd); + error("Il manque la limite journalière", cmd); return; } let limiteParJour = parseInt(cmd[1]); if (isNaN(limiteParJour) || limiteParJour < 1) { - error("La limite journali\xE8re doit \xEAtre un nombre positif", cmd); + error("La limite journalière doit être un nombre positif", cmd); return; } scope.limiteParJour = limiteParJour; @@ -9335,7 +9344,7 @@ var COFantasy = COFantasy || function() { } let limiteParCombat = parseInt(cmd[1]); if (isNaN(limiteParCombat) || limiteParCombat < 1) { - error("La limite par combat doit \xEAtre un nombre positif", cmd); + error("La limite par combat doit être un nombre positif", cmd); return; } scope.limiteParCombat = limiteParCombat; @@ -9351,7 +9360,7 @@ var COFantasy = COFantasy || function() { } let limiteParTour = parseInt(cmd[1]); if (isNaN(limiteParTour) || limiteParTour < 1) { - error("La limite par tour doit \xEAtre un nombre positif", cmd); + error("La limite par tour doit être un nombre positif", cmd); return; } scope.limiteParTour = limiteParTour; @@ -9362,14 +9371,14 @@ var COFantasy = COFantasy || function() { return; case 'decrAttribute': if (cmd.length < 2) { - error("Erreur interne d'une commande g\xE9n\xE9r\xE9e par bouton", cmd); + error("Erreur interne d'une commande générée par bouton", cmd); return; } let attr = getObj('attribute', cmd[1]); if (attr === undefined) { attr = tokenAttribute(attaquant, cmd[1]); if (attr.length === 0) { - log("Attribut \xE0 changer perdu"); + log("Attribut à changer perdu"); log(cmd); return; } @@ -9379,7 +9388,7 @@ var COFantasy = COFantasy || function() { return; case 'decrLimitePredicatParTour': if (cmd.length < 2) { - error("Erreur interne d'une commande g\xE9n\xE9r\xE9e par bouton", cmd); + error("Erreur interne d'une commande générée par bouton", cmd); return; } scope.decrLimitePredicatParTour = cmd[1]; @@ -9391,7 +9400,7 @@ var COFantasy = COFantasy || function() { } let forceMin = parseInt(cmd[1]); if (isNaN(forceMin)) { - error("La force minimum doit \xEAtre un nombre", cmd); + error("La force minimum doit être un nombre", cmd); return; } scope.forceMinimum = forceMin; @@ -9403,7 +9412,7 @@ var COFantasy = COFantasy || function() { } let arcComposite = parseInt(cmd[1]); if (isNaN(arcComposite)) { - error("Le bonus d'arc composite doit \xEAtre un nombre", cmd); + error("Le bonus d'arc composite doit être un nombre", cmd); return; } scope.arcComposite = arcComposite; @@ -9419,7 +9428,7 @@ var COFantasy = COFantasy || function() { scope.dmgCoef += incrDmgCoef; return; } - scope.dmgCoef++; //Par d\xE9faut, incr\xE9mente de 1 + scope.dmgCoef++; //Par défaut, incrémente de 1 return; case 'toucheDoubleDmg': options.toucheDoubleDmg = true; @@ -9437,7 +9446,7 @@ var COFantasy = COFantasy || function() { scope.diviseDmg *= divise; return; } - scope.diviseDmg *= 2; //Par d\xE9faut, divise par 2 + scope.diviseDmg *= 2; //Par défaut, divise par 2 return; case 'divisePortee': scope.divisePortee = (scope.divisePortee || 1); @@ -9450,7 +9459,7 @@ var COFantasy = COFantasy || function() { scope.divisePortee *= divise; return; } - scope.divisePortee *= 2; //Par d\xE9faut, divise par 2 + scope.divisePortee *= 2; //Par défaut, divise par 2 return; case 'incrCritCoef': scope.critCoef = (scope.critCoef || 1); @@ -9463,7 +9472,7 @@ var COFantasy = COFantasy || function() { scope.critCoef += incrCritCoef; return; } - scope.critCoef++; //Par d\xE9faut, incr\xE9mente de 1 + scope.critCoef++; //Par défaut, incrémente de 1 return; case 'if': let ifCond = parseCondition(cmd.slice(1)); @@ -9514,7 +9523,7 @@ var COFantasy = COFantasy || function() { } let iteL = psElse.ite[psElse.ite.length - 1]; if (iteL.else) { - error("Il y a d\xE9j\xE0 un --else pour ce --if", cmd); + error("Il y a déjà un --else pour ce --if", cmd); return; } delete scope.parentScope; @@ -9527,7 +9536,7 @@ var COFantasy = COFantasy || function() { } case 'message': if (cmd.length < 2) { - error("Il manque le message apr\xE8s --message", cmd); + error("Il manque le message après --message", cmd); return; } scope.messages = scope.messages || []; @@ -9535,11 +9544,11 @@ var COFantasy = COFantasy || function() { return; case 'allonge': if (cmd.length < 2) { - error("Il manque le message apr\xE8s --allonge", cmd); + error("Il manque le message après --allonge", cmd); return; } if (options.allonge !== undefined) { - log("Red\xE9finition de l'allong"); + log("Redéfinition de l'allong"); } options.allonge = parseFloat(cmd[1]); if (isNaN(options.allonge)) { @@ -9562,7 +9571,7 @@ var COFantasy = COFantasy || function() { scope.enveloppe.expression = cmd[3]; } if (scope.enveloppe.expression === undefined) { - error("Il n'est pas encore possible d'utiliser l'option --enveloppe sans expression si le label de l'attaque n'est pas d\xE9fini", cmd); + error("Il n'est pas encore possible d'utiliser l'option --enveloppe sans expression si le label de l'attaque n'est pas défini", cmd); scope.enveloppe = undefined; } return; @@ -9589,7 +9598,7 @@ var COFantasy = COFantasy || function() { case 'imgAttackSuccesChampion': case 'imgAttackSuccesCritique': if (cmd.length < 1) { - error("Il manque une image apr\xE8s --" + cmd[0], cmd); + error("Il manque une image après --" + cmd[0], cmd); return; } options[cmd[0]] = cmd[1]; @@ -9602,12 +9611,12 @@ var COFantasy = COFantasy || function() { case 'soundAttackSuccesChampion': case 'soundAttackSuccesCritique': if (cmd.length < 1) { - error("Il manque le son apr\xE8s --" + cmd[0], cmd); + error("Il manque le son après --" + cmd[0], cmd); return; } options[cmd[0]] = cmd.slice(1).join(' '); return; - //Anciennes variantes, gard\xE9es pour la compatibilit\xE9 + //Anciennes variantes, gardées pour la compatibilité case 'img-attack-echec-critique': case 'img-attack-echec': case 'img-attack-echec-clignotement': @@ -9617,7 +9626,7 @@ var COFantasy = COFantasy || function() { case 'img-attack-succes-champion': case 'img-attack-succes-critique': if (cmd.length < 1) { - error("Il manque une image apr\xE8s --" + cmd[0], cmd); + error("Il manque une image après --" + cmd[0], cmd); return; } let imgCmd = @@ -9635,7 +9644,7 @@ var COFantasy = COFantasy || function() { case 'sound-attack-succes-champion': case 'sound-attack-succes-critique': if (cmd.length < 2) { - error("Il manque le son apr\xE8s --" + cmd[0], cmd); + error("Il manque le son après --" + cmd[0], cmd); return; } let soundCmd = cmd[0].replace('-a', 'A').replace('-e', 'E').replace('-c', 'C').replace('-n', 'N').replace('-s', 'S').replace('-t', 'T'); @@ -9661,7 +9670,7 @@ var COFantasy = COFantasy || function() { case 'FOR': carac = 'force'; break; - case 'dext\xE9rit\xE9': + case 'dextérité': case 'DEX': carac = 'dexterite'; break; @@ -9682,29 +9691,30 @@ var COFantasy = COFantasy || function() { carac = 'random'; break; default: - error("Le premier argument de affaiblirCarac n'est pas une caract\xE9ristique", cmd); + error("Le premier argument de affaiblirCarac n'est pas une caractéristique", cmd); return; } - let valAff = parseInt(cmd[2]); - if (isNaN(valAff)) { - error("Le deuxi\xE8me argument de --affaiblirCarac doit \xEAtre un nombre", cmd); + let valAff = parseDice(cmd[2]); + if (!valAff || !dePositif(valAff)) { + error("Le deuxième argument de --affaiblirCarac doit être un nombre", cmd); return; } if (valAff === 0) return; - scope.affaiblissementsCarac = scope.affaiblissementsCarac || []; - scope.affaiblissementsCarac.push({ + lastEtat = { carac, val: valAff - }); + }; + scope.affaiblissementsCarac = scope.affaiblissementsCarac || []; + scope.affaiblissementsCarac.push(lastEtat); return; case 'difficulteCarac': if (cmd.length < 2) { - error("Il manque la caract\xE9ristique \xE0 laquelle mesurer le jet d'attaque", cmd); + error("Il manque la caractéristique à laquelle mesurer le jet d'attaque", cmd); return; } options.difficulteCarac = parseCarac(cmd[1]); if (options.difficulteCarac === undefined) { - error("L'argument de --difficulteCarac n'est pas une caract\xE9ristique", cmd); + error("L'argument de --difficulteCarac n'est pas une caractéristique", cmd); } return; case 'attackId': @@ -9737,7 +9747,7 @@ var COFantasy = COFantasy || function() { } } }); - closeIte(scope); //pour fermer les endif mal form\xE9s et \xE9viter les boucles + closeIte(scope); //pour fermer les endif mal formés et éviter les boucles return { lastEtat, lastType, @@ -9769,7 +9779,7 @@ var COFantasy = COFantasy || function() { } let pageId = attaquant.token.get('pageid'); let targetToken = getObj('graphic', args[2]); - if (targetToken === undefined) { //reste la possibilit\xE9 de trouver un token de ce nom + if (targetToken === undefined) { //reste la possibilité de trouver un token de ce nom let tokens = findObjs({ _type: 'graphic', _subtype: 'token', @@ -9777,12 +9787,12 @@ var COFantasy = COFantasy || function() { name: args[2] }); if (tokens.length == 0) { - error("le second argument de !cof-attack doit \xEAtre un token", args[2]); + error("le second argument de !cof-attack doit être un token", args[2]); return; } if (tokens.length > 1) { - error("Ambig\xFCit\xE9 sur le choix d'un token : il y a " + - tokens.length + " tokens nomm\xE9s " + args[2], tokens); + error("Ambigüité sur le choix d'un token : il y a " + + tokens.length + " tokens nommés " + args[2], tokens); } targetToken = tokens[0]; } @@ -9793,7 +9803,7 @@ var COFantasy = COFantasy || function() { let weaponStats; let attaqueArray; try { - attaqueArray = JSON.parse(attackLabel); //plus document\xE9 depuis 2020 + attaqueArray = JSON.parse(attackLabel); //plus documenté depuis 2020 } catch (e) {} if (Array.isArray(attaqueArray) && attaqueArray.length > 4 && attaqueArray[1].length > 1 && attaqueArray[3].length > 3) { @@ -9840,10 +9850,10 @@ var COFantasy = COFantasy || function() { return; } if (weaponStats.deuxMains && attributeAsBool(attaquant, 'espaceExigu')) { - sendPerso(attaquant, "ne peut pas utiliser d'arme \xE0 deux mains dans un espace aussi exigu."); + sendPerso(attaquant, "ne peut pas utiliser d'arme à deux mains dans un espace aussi exigu."); return; } - //Si c'est aussi une arme de jet, et que le personnage attaque \xE0 distance, on va utiliser la version arme de jet de l'attaque. + //Si c'est aussi une arme de jet, et que le personnage attaque à distance, on va utiliser la version arme de jet de l'attaque. let msgIndex = msg.content; let indexAussiJet = msgIndex.indexOf('--aussiArmeDeJet '); if (indexAussiJet == -1 && weaponStats.options) { @@ -9854,19 +9864,22 @@ var COFantasy = COFantasy || function() { let labelAussiJet = parseInt(msgIndex.substring(indexAussiJet + 17)); if (isNaN(labelAussiJet)) { error("Label --aussiArmeDeJet n'est pas un entier", msgIndex.substring(indexAussiJet + 17)); + indexAussiJet = 0; } else { let armeAssociee = getWeaponStats(attaquant, labelAussiJet); if (armeAssociee === undefined) { error("Label --aussiArmeDeJet pas une attaque", labelAussiJet); + indexAussiJet = 0; } else { if (distanceCombat(attaquant.token, targetToken) > 0) weaponStats = armeAssociee; + else indexAussiJet = 0; } } } //Ajout des options de l'arme let wo = weaponStats.options.trim(); - //Pour la partie options, il est possible qu'elle soit d\xE9j\xE0 pass\xE9e en ligne de commande + //Pour la partie options, il est possible qu'elle soit déjà passée en ligne de commande if (wo !== '' && ((optArgs.length < 1 || !optArgs[0].startsWith('attaqueOptions'))) || indexAussiJet > 0) { wo = ' ' + wo; wo.split(' --').reverse().forEach(function(o) { @@ -9910,7 +9923,7 @@ var COFantasy = COFantasy || function() { break; case 'magique': options.magique = true; - options.type = 'energie'; //Les d\xE9g\xE2ts magiques sans type associ\xE9 sont suppos\xE9s de type \xE9nergie, l'\xE9quivalent de force dans PF1 + options.type = 'energie'; //Les dégâts magiques sans type associé sont supposés de type énergie, l'équivalent de force dans PF1 break; case 'tranchant': case 'percant': @@ -9919,7 +9932,7 @@ var COFantasy = COFantasy || function() { break; } let lastEtat; //dernier de etats et effets - let lastType = options.type; //dernier type de d\xE9g\xE2ts inflig\xE9s + let lastType = options.type; //dernier type de dégâts infligés let scope = options; //Pour les conditionnelles parseAttackOptions(attaquant, optArgs, lastEtat, lastType, scope, playerId, msg, targetToken, attackLabel, weaponStats, options); let bene = predicateAsInt(attaquant, 'benedictionSuperieure', 0); @@ -9933,7 +9946,7 @@ var COFantasy = COFantasy || function() { options.additionalDmg = options.additionalDmg || []; if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, rang: options.rang, @@ -9959,7 +9972,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -9976,7 +9989,7 @@ var COFantasy = COFantasy || function() { } } else { if (options.tempeteDeManaDuree) { - sendPlayerAndGM(msg, playerId, "Attention, l'option temp\xEAte de mana pour la dur\xE9e n'est pas prise en compte. Utiliser l'option --pasDeDmg si le sort ne fait pas de DM"); + sendPlayerAndGM(msg, playerId, "Attention, l'option tempête de mana pour la durée n'est pas prise en compte. Utiliser l'option --pasDeDmg si le sort ne fait pas de DM"); options.tempeteDeManaDuree = false; if (options.tempeteDeMana && options.tempeteDeMana.cout) options.tempeteDeMana.cout--; @@ -10006,30 +10019,30 @@ var COFantasy = COFantasy || function() { if (f) f(evt); } - // Fait d\xE9penser de la mana, dep doit contenir une d\xE9pense possible + // Fait dépenser de la mana, dep doit contenir une dépense possible function depenseMana(perso, dep, msg, evt) { if (!dep || dep.cout_null) return; updateCurrentBar(perso, 2, dep.pm, evt); msg = msg || ''; if (dep.depense_pv) { - let source = reglesOptionelles.mana.val.brulure_de_magie.val ? "de la Br\xFBlure de Magie" : "du Contrecoup"; + let source = reglesOptionelles.mana.val.brulure_de_magie.val ? "de la Brûlure de Magie" : "du Contrecoup"; updateCurrentBar(perso, 1, dep.pv, evt); let pre = 'p'; if (stateCOF.options.affichage.val.depense_mana.val && dep.depense_pm > 0) - pre = "d\xE9pense " + dep.depense_pm + " PM et p"; - sendPerso(perso, pre + "erd " + dep.depense_pv + " PV \xE0 cause " + source + " pour " + msg); + pre = "dépense " + dep.depense_pm + " PM et p"; + sendPerso(perso, pre + "erd " + dep.depense_pv + " PV à cause " + source + " pour " + msg); } else { if (stateCOF.options.affichage.val.depense_mana.val) - sendPerso(perso, "d\xE9pense " + dep.depense_pm + " PM pour " + msg); + sendPerso(perso, "dépense " + dep.depense_pm + " PM pour " + msg); } let niveau = ficheAttributeAsInt(perso, 'niveau', 1); if (reglesOptionelles.mana.val.mana_totale.val) { if (dep.depense_pm > niveau * 3) { - sendPerso(perso, "Attention, la d\xE9pense totale de mana est sup\xE9rieure au niveau * 3"); + sendPerso(perso, "Attention, la dépense totale de mana est supérieure au niveau * 3"); } } else { if (dep.depense_pm > niveau) { - sendPerso(perso, "Attention, la d\xE9pense totale de mana est sup\xE9rieure au niveau"); + sendPerso(perso, "Attention, la dépense totale de mana est supérieure au niveau"); } } return; @@ -10058,7 +10071,7 @@ var COFantasy = COFantasy || function() { case 'animal': return estAnimal(perso); case 'demon': - case 'd\xE9mon': + case 'démon': return estDemon(perso); case 'dragon': return estDraconique(perso); @@ -10066,9 +10079,9 @@ var COFantasy = COFantasy || function() { case 'elfe-noir': return estElfeNoir(perso); case 'fee': - case 'f\xE9e': + case 'fée': return estFee(perso); - case 'g\xE9ant': + case 'géant': case 'geant': return estGeant(perso); case 'gobelin': @@ -10084,7 +10097,7 @@ var COFantasy = COFantasy || function() { } } - //Si l'attribut est un mod. de caract\xE9ristique, va chercher le + //Si l'attribut est un mod. de caractéristique, va chercher le //bon attribut, selon que perso est un PNJ ou nom function valAttribute(perso, originalAttr, caracAttr) { if (caracAttr) { @@ -10096,10 +10109,10 @@ var COFantasy = COFantasy || function() { return charAttributeAsInt(perso, originalAttr, 0); } - //test si l'attribut est pr\xE9sent et si sa valeur est bonne + //test si l'attribut est présent et si sa valeur est bonne // options peut contenir - // fiche : si on cherche un attribut de fiche, et dans ce cas, le champ def donne la valeur par d\xE9faut - // local : si c'est un attribut diff\xE9rent selon le mook + // fiche : si on cherche un attribut de fiche, et dans ce cas, le champ def donne la valeur par défaut + // local : si c'est un attribut différent selon le mook function testAttribut(perso, attrName, valeur, options) { let attr; if (options.fiche) { @@ -10117,7 +10130,7 @@ var COFantasy = COFantasy || function() { if (cond == 'toujoursVrai') return true; switch (cond.type) { case 'moins': - // Au cas o\xF9 on utilise les MOD au lieu de l'attribut de base: + // Au cas où on utilise les MOD au lieu de l'attribut de base: let caracAttr = caracOfMod(cond.attribute); let attackerAttr = valAttribute(attaquant, cond.attribute, caracAttr); let resMoins = true; @@ -10175,13 +10188,13 @@ var COFantasy = COFantasy || function() { case 'deAttaque': if (options && options.auto) return false; if (deAttaque === undefined) { - error("Condition de d\xE9 d'attaque non support\xE9e ici", cond); + error("Condition de dé d'attaque non supportée ici", cond); return true; } return deAttaque >= cond.seuil; case 'echecCritique': if (deAttaque === undefined) { - error("Condition de d\xE9 d'attaque non support\xE9e ici", cond); + error("Condition de dé d'attaque non supportée ici", cond); return true; } return deAttaque == 1; @@ -10225,7 +10238,7 @@ var COFantasy = COFantasy || function() { case 'mana': case 'bonusAttaque': case 'bonusContreArmure': - case 'bonusContreBouclier': //num\xE9riques additives + case 'bonusContreBouclier': //numériques additives opt[field] = opt[field] || 0; opt[field] += branch[field]; break; @@ -10272,11 +10285,11 @@ var COFantasy = COFantasy || function() { attr.set('current', oldval - 1); break; case 'decrLimitePredicatParTour': - //Ne fait que diminuer l'attribut, n'emp\xEAche pas l'attaque + //Ne fait que diminuer l'attribut, n'empêche pas l'attaque let pred = branch.decrLimitePredicatParTour; let test = testLimiteUtilisationsCapa(attaquant, pred, 'tour', "ne peut plus utiliser " + pred + " ce tour", - "Attaque impossible, pas de pr\xE9dicat " + pred); + "Attaque impossible, pas de prédicat " + pred); if (test === undefined) break; utiliseCapacite(attaquant, test, evt); break; @@ -10295,7 +10308,7 @@ var COFantasy = COFantasy || function() { if (etat.aTraiter === 0) callback(); } - //Evaluation r\xE9cursive des if-then-else + //Evaluation récursive des if-then-else function evalITE(attaquant, target, deAttaque, options, phase, evt, explications, scope, callback, inTarget, etatParent) { etatParent = etatParent || {}; if (scope.ite === undefined || scope.ite.length < 1) { @@ -10364,7 +10377,7 @@ var COFantasy = COFantasy || function() { callIfAllDone(etatParent, callback); return true; } - let msgPour = " pour r\xE9sister \xE0 un effet"; + let msgPour = " pour résister à un effet"; let msgRate = ", " + nomPerso(target) + " rate son jet de sauvegarde"; let saveOpts = { msgPour: msgPour, @@ -10378,7 +10391,7 @@ var COFantasy = COFantasy || function() { }; const saveId = condInTarget ? 'ifSave_' + etatParent.aTraiter + '_' + target.token.id : 'ifSave_' + etatParent.aTraiter + '_' + attaquant.token.id; - if (phase > 0) { //le save a d\xE9j\xE0 \xE9t\xE9 r\xE9solu + if (phase > 0) { //le save a déjà été résolu condInTarget = true; resCondition = target.saveResults && target.saveResults[saveId]; break; @@ -10394,7 +10407,7 @@ var COFantasy = COFantasy || function() { branch = ite.else; target.saveResults[saveId] = true; } else { - branch = ite.then; //on teste si le save est rat\xE9 + branch = ite.then; //on teste si le save est raté target.saveResults[saveId] = false; } if (branch === undefined) { @@ -10417,7 +10430,7 @@ var COFantasy = COFantasy || function() { else branch = ite.else; if (branch === undefined) { callIfAllDone(etatParent, callback); - return condInTarget; //On garde l'ite si on d\xE9pend de la cible + return condInTarget; //On garde l'ite si on dépend de la cible } //On copie les champs de scope dans options ou dans target if (phase === 0) @@ -10430,7 +10443,7 @@ var COFantasy = COFantasy || function() { }); } - // Retourne tous les attributs dans attrs, de nom name ou commen\xE7ant par name_ + // Retourne tous les attributs dans attrs, de nom name ou commençant par name_ function allAttributesNamed(attrs, name) { let reg = new RegExp("^" + name + "($|_|\\()"); return attrs.filter(function(obj) { @@ -10546,7 +10559,7 @@ var COFantasy = COFantasy || function() { already = already || new Set(); let pid = [perso.charId, perso.token.id]; if (already.has(pid)) { - error("Il y a un cycle d'initiatives d\xE9riv\xE9es les unes des autres impliquant " + nomPerso(perso), already); + error("Il y a un cycle d'initiatives dérivées les unes des autres impliquant " + nomPerso(perso), already); return perso; } let persoD = initDerivee(perso, already); @@ -10577,7 +10590,7 @@ var COFantasy = COFantasy || function() { // retourne undefined sinon } - //ne rajoute pas evt \xE0 l'historique + //ne rajoute pas evt à l'historique function persoInit(perso, evt, already) { let persoD = initDerivee(perso); if (persoD) perso = persoD; @@ -10591,13 +10604,13 @@ var COFantasy = COFantasy || function() { init += ficheAttributeAsInt(perso, 'mod_initiative', 0); } if (attributeAsBool(perso, 'formeDArbre')) init = 7; - //R\xE8gle optionelle : +1d6, \xE0 lancer en entrant en combat + //Règle optionelle : +1d6, à lancer en entrant en combat if (reglesOptionelles.initiative.val.initiative_variable.val) { let bonusVariable; let jetPartage; if (reglesOptionelles.initiative.val.initiative_variable_individuelle.val) { // Un jet par perso mook bonusVariable = attributeAsInt(perso, 'bonusInitVariable', 0); - } else { //Un seul pour tous les mook du m\xEAme personnage + } else { //Un seul pour tous les mook du même personnage bonusVariable = charAttributeAsInt(perso, 'bonusInitVariable', 0); jetPartage = true; } @@ -10611,7 +10624,7 @@ var COFantasy = COFantasy || function() { let msgSecret = perso.token.get('layer') == 'gmlayer'; if (!jetCache) { msg += onGenre(perso, 'Il', 'Elle') + " fait " + rollD6.roll; - msg += " \xE0 son jet d'initiative"; + msg += " à son jet d'initiative"; } setTokenAttr(perso, 'bonusInitVariable', bonusVariable, evt, { msg: msg, @@ -10626,9 +10639,9 @@ var COFantasy = COFantasy || function() { init += attributeAsInt(perso, 'bonusInitEmbuscade', 0); // Familier if (compagnonPresent(perso, 'familier')) init += 2; - // Sixi\xE8me sens en sort + // Sixième sens en sort if (attributeAsBool(perso, 'sixiemeSens')) init += 2; - // Voie du chef d'arm\xE9e rangs 2 et 3 (Capitaine) + // Voie du chef d'armée rangs 2 et 3 (Capitaine) let bonusCapitaine = aUnCapitaine(perso, evt); if (bonusCapitaine) init += parseInt(bonusCapitaine); if (predicateAsBool(perso, 'graceFeline')) { @@ -10655,16 +10668,16 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(perso, 'intelligenceDuCombat')) { init += modCarac(perso, 'intelligence'); } - // R\xE9flexes felins de la Voie du pourfendeur + // Réflexes felins de la Voie du pourfendeur init += predicateAsInt(perso, 'reflexesFelins', 0); - // \xC2me f\xE9line (f\xE9lis) + // Âme féline (félis) init += predicateAsInt(perso, 'ameFeline', 0); init += predicateAsInt(perso, 'vitesseDuFelin', 0); init += predicateAsInt(perso, 'espritVide', 0, 3); init += predicateAsInt(perso, 'pasDuVent', 0, 1); //Prescience de l'ensorceleur if (attributeAsBool(perso, 'prescienceUtilisee')) init += 10; - //For\xEAt vivante + //Forêt vivante if (attributeAsBool(perso, 'foretVivanteEnnemie')) { init -= 5; } @@ -10688,12 +10701,12 @@ var COFantasy = COFantasy || function() { }); } - //ne rajoute pas evt \xE0 l'historique - //options: recompute : si pas encore agi, on remet \xE0 sa place dans le turn order - //already est l\xE0 pour \xE9viter les r\xE9cursions infinies + //ne rajoute pas evt à l'historique + //options: recompute : si pas encore agi, on remet à sa place dans le turn order + //already est là pour éviter les récursions infinies //boutonRoll: vient de l'utilisation d'un bouton de roll function initiative(selected, evt, recompute, already, boutonRoll) { //set initiative for selected tokens - // Toujours appel\xE9 quand on entre en combat + // Toujours appelé quand on entre en combat // Initialise le compteur de tour, si besoin // Assumption: all tokens that have not acted yet are those before the turn // counter. @@ -10703,7 +10716,7 @@ var COFantasy = COFantasy || function() { // Tokens appearing before the turn are sorted if (!Campaign().get('initiativepage')) evt.initiativepage = false; let debutCombat = false; - if (!stateCOF.combat) { //actions de d\xE9but de combat + if (!stateCOF.combat) { //actions de début de combat evt.combat = false; stateCOF.combat = { tour: 1, @@ -10718,7 +10731,7 @@ var COFantasy = COFantasy || function() { }]), initiativepage: true }); - removeAllAttributes('transeDeGu\xE9rison', evt); + removeAllAttributes('transeDeGuérison', evt); debutCombat = true; } const combat = stateCOF.combat; @@ -10726,7 +10739,7 @@ var COFantasy = COFantasy || function() { Campaign().set('initiativepage', true); } let to = getTurnOrder(combat, evt); - if (to.pasAgi.length === 0) { // Fin de tour, on met le tour \xE0 la fin et on retrie + if (to.pasAgi.length === 0) { // Fin de tour, on met le tour à la fin et on retrie to.pasAgi = to.dejaAgi; to.dejaAgi = []; } @@ -10736,7 +10749,7 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(perso) { let pageId = perso.token.get('pageid'); combat.pageId = pageId; - //Si besoin, on stoque les PVs de d\xE9but de combat + //Si besoin, on stoque les PVs de début de combat if (!attributeAsBool(perso, 'PVsDebutCombat')) { setTokenAttr(perso, 'PVsDebutCombat', perso.token.get('bar1_value'), evt); } @@ -10761,7 +10774,7 @@ var COFantasy = COFantasy || function() { } } let init = persoInit(perso, evt); - // On place le token \xE0 sa place dans la liste du tour + // On place le token à sa place dans la liste du tour let dejaIndex = to.dejaAgi.findIndex(function(elt) { return (elt.id == perso.token.id); @@ -10778,7 +10791,7 @@ var COFantasy = COFantasy || function() { updateNextInit(perso); return true; } else { - return false; //On enl\xE8ve le perso des pasAgi + return false; //On enlève le perso des pasAgi } } push = false; //Sinon, comme on ne recalcule pas, on le laisse @@ -10826,7 +10839,7 @@ var COFantasy = COFantasy || function() { }; addAura(perso, aura, aurasCreees, combat, evt); }); - //Les autres persos qui entrent en combat en m\xEAme temps + //Les autres persos qui entrent en combat en même temps let ajouterEnCombat = predicatesNamed(perso, 'entrerEnCombatAvec'); if (ajouterEnCombat.length > 0) { let aec = new Set(ajouterEnCombat); @@ -10858,7 +10871,7 @@ var COFantasy = COFantasy || function() { to.dejaAgi[dejaIndex].pr = init; } }); - if (debutCombat) { //On cherche si un des personnages de la carte a la capacit\xE9 Prescience + if (debutCombat) { //On cherche si un des personnages de la carte a la capacité Prescience let allToks = findObjs({ _type: 'graphic', @@ -10874,7 +10887,7 @@ var COFantasy = COFantasy || function() { }; return capaciteDisponible(perso, 'prescience', 'combat'); }); - if (prescience) { //Il faut stoquer les positions de tous les token pour le retour en arri\xE8re. + if (prescience) { //Il faut stoquer les positions de tous les token pour le retour en arrière. stateCOF.prescience = { evt: evt, dernieresPositions: [] @@ -10921,7 +10934,7 @@ var COFantasy = COFantasy || function() { function initiativeInterface(msg) { getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - error("Dans !cof-init : rien \xE0 faire, pas de token selectionn\xE9", msg); + error("Dans !cof-init : rien à faire, pas de token selectionné", msg); return; } aura_token_on_turn = msg.content.indexOf('--aura') !== -1; @@ -11047,7 +11060,7 @@ var COFantasy = COFantasy || function() { }); return r !== undefined; } catch (uriError) { - log("Erreur de d\xE9codage URI dans la note GM de " + token.get('name') + " : " + gmNotes); + log("Erreur de décodage URI dans la note GM de " + token.get('name') + " : " + gmNotes); } } return false; @@ -11057,9 +11070,9 @@ var COFantasy = COFantasy || function() { return false; } - // bonus d'attaque d'un token, ind\xE9pendament des options + // bonus d'attaque d'un token, indépendament des options // Mise en commun pour attack et attaque-magique - // options pour modifier \xE9ventuellement l'affichage si pas de DM et pour mettre \xE0 jour options.bonusDM si pr\xE9sent + // options pour modifier éventuellement l'affichage si pas de DM et pour mettre à jour options.bonusDM si présent function bonusDAttaque(personnage, explications, evt, options) { explications = explications || []; let tempAttkMod; // Utilise la barre 3 de l'attaquant @@ -11086,7 +11099,7 @@ var COFantasy = COFantasy || function() { attributeAsInt(personnage, 'chantDesHerosTempeteDeManaIntense', 0); bonusChantDesHeros += chantDesHerosIntense; attBonus += bonusChantDesHeros; - explications.push("Chant des h\xE9ros => +" + bonusChantDesHeros + " en Attaque"); + explications.push("Chant des héros => +" + bonusChantDesHeros + " en Attaque"); if (chantDesHerosIntense) removeTokenAttr(personnage, 'chantDesHerosTempeteDeManaIntense', evt); } @@ -11095,7 +11108,7 @@ var COFantasy = COFantasy || function() { let benedictionIntense = attributeAsInt(personnage, 'benedictionTempeteDeManaIntense', 0); bonusBenediction += benedictionIntense; attBonus += bonusBenediction; - explications.push("B\xE9n\xE9diction => +" + bonusBenediction + " en Attaque"); + explications.push("Bénédiction => +" + bonusBenediction + " en Attaque"); if (benedictionIntense) removeTokenAttr(personnage, 'benedictionTempeteDeManaIntense', evt); } @@ -11110,17 +11123,17 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'lameDeLigneePerdue')) { attBonus -= 1; - explications.push("Lame de lign\xE9e perdue => -1 en Attaque"); + explications.push("Lame de lignée perdue => -1 en Attaque"); } if (attributeAsBool(personnage, 'strangulation')) { let malusStrangulation = 1 + attributeAsInt(personnage, 'dureeStrangulation', 0); attBonus -= malusStrangulation; - explications.push("L'attaquant est \xE9trangl\xE9 => -" + malusStrangulation + " en Attaque"); + explications.push("L'attaquant est étranglé => -" + malusStrangulation + " en Attaque"); } if (getState(personnage, 'renverse')) { attBonus -= 5; - explications.push("Attaquant \xE0 terre => -5 en Attaque"); + explications.push("Attaquant à terre => -5 en Attaque"); } let attrPosture = tokenAttribute(personnage, 'postureDeCombat'); if (attrPosture.length > 0) { @@ -11143,7 +11156,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'cadavreAnime')) { attBonus -= 4; - explications.push("Cadavre anim\xE9 => -2 en Attaque"); + explications.push("Cadavre animé => -2 en Attaque"); } let bonusCapitaine = aUnCapitaine(personnage, evt); if (bonusCapitaine) { @@ -11158,13 +11171,13 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(personnage, 'forceDeGeant')) { let bonusForceDeGeant = getIntValeurOfEffet(personnage, 'forceDeGeant', 2); attBonus += bonusForceDeGeant; - explications.push("Force de g\xE9ant => +" + bonusForceDeGeant + " en Attaque"); + explications.push("Force de géant => +" + bonusForceDeGeant + " en Attaque"); } if (attributeAsBool(personnage, 'nueeDInsectes')) { let malusNuee = 2 + attributeAsInt(personnage, 'nueeDInsectesTempeteDeManaIntense', 0); attBonus -= malusNuee; - explications.push("Nu\xE9e d\'insectes => -" + malusNuee + " en Attaque"); + explications.push("Nuée d\'insectes => -" + malusNuee + " en Attaque"); if (malusNuee > 2) removeTokenAttr(personnage, 'nueeDInsectesTempeteDeManaIntense', evt); } @@ -11172,13 +11185,13 @@ var COFantasy = COFantasy || function() { let malusNueeCriquets = 3 + attributeAsInt(personnage, 'nueeDeCriquetsTempeteDeManaIntense', 0); attBonus -= malusNueeCriquets; - explications.push("Nu\xE9e de criquets => -" + malusNueeCriquets + " en Attaque"); + explications.push("Nuée de criquets => -" + malusNueeCriquets + " en Attaque"); if (malusNueeCriquets > 3) removeTokenAttr(personnage, 'nueeDeCriquetsTempeteDeManaIntense', evt); } if (attributeAsBool(personnage, 'nueeDeScorpions')) { attBonus -= 3; - explications.push("Nu\xE9e de scorpions => -3 en Attaque"); + explications.push("Nuée de scorpions => -3 en Attaque"); } if (attributeAsBool(personnage, 'etatExsangue')) { attBonus -= 2; @@ -11186,7 +11199,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'armeBrulante')) { attBonus -= 2; - explications.push("Arme br\xFBlante => -2 en Attaque"); + explications.push("Arme brûlante => -2 en Attaque"); } if (marcheSylvestreActive(personnage)) { attBonus += 2; @@ -11194,11 +11207,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(personnage, 'prisonVegetale')) { attBonus -= getIntValeurOfEffet(personnage, 'prisonVegetale', 2); - explications.push("Prison v\xE9g\xE9tale : -2 en Attaque"); + explications.push("Prison végétale : -2 en Attaque"); } if (attributeAsBool(personnage, 'toiles')) { attBonus -= getIntValeurOfEffet(personnage, 'toiles', 2); - explications.push("Entrav\xE9 : -2 en Attaque"); + explications.push("Entravé : -2 en Attaque"); } if (attributeAsBool(personnage, 'masqueDuPredateur')) { let bonusMasque = getIntValeurOfEffet(personnage, 'masqueDuPredateur', modCarac(personnage, 'sagesse')); @@ -11206,10 +11219,10 @@ var COFantasy = COFantasy || function() { bonusMasque += masqueIntense; attBonus += bonusMasque; if (options && options.bonusDM !== undefined) { - explications.push("Masque du pr\xE9dateur : +" + bonusMasque + " en Attaque et DM"); + explications.push("Masque du prédateur : +" + bonusMasque + " en Attaque et DM"); options.bonusDM += bonusMasque; } else { - explications.push("Masque du pr\xE9dateur : +" + bonusMasque + " en Attaque"); + explications.push("Masque du prédateur : +" + bonusMasque + " en Attaque"); } if (masqueIntense) removeTokenAttr(personnage, 'masqueDuPredateurTempeteDeManaIntense', evt); @@ -11218,15 +11231,15 @@ var COFantasy = COFantasy || function() { getIntValeurOfEffet(personnage, 'masqueDuPredateurAmeLiee', 1); attBonus += bonusMasque; if (options && options.bonusDM !== undefined) { - explications.push("Masque du pr\xE9dateur li\xE9 : +" + bonusMasque + " en Attaque et DM"); + explications.push("Masque du prédateur lié : +" + bonusMasque + " en Attaque et DM"); options.bonusDM += bonusMasque; } else { - explications.push("Masque du pr\xE9dateur li\xE9 : +" + bonusMasque + " en Attaque"); + explications.push("Masque du prédateur lié : +" + bonusMasque + " en Attaque"); } } if (attributeAsBool(personnage, 'armeSecreteBarde')) { attBonus -= 10; - explications.push("D\xE9stabilis\xE9 par une action de charme => -10 en Attaque"); + explications.push("Déstabilisé par une action de charme => -10 en Attaque"); } if (attributeAsBool(personnage, 'espaceExigu')) { let bonusForce = modCarac(personnage, 'force'); @@ -11238,28 +11251,28 @@ var COFantasy = COFantasy || function() { attBonus -= 1; } if (attributeAsBool(personnage, 'agrippeParUnDemon')) { - explications.push("agripp\xE9 : -3 en Attaque"); + explications.push("agrippé : -3 en Attaque"); attBonus -= 3; } if (attributeAsBool(personnage, 'ondesCorruptrices') && !attributeAsBool(personnage, 'sangDeLArbreCoeur') && !predicateAsBool(personnage, 'porteurDuBouclierDeGrabuge')) { let malus = attributeAsInt(personnage, 'ondesCorruptrices', 2); - explications.push("naus\xE9eux : -" + malus + " aux tests"); + explications.push("nauséeux : -" + malus + " aux tests"); attBonus -= malus; } if (attributeAsBool(personnage, 'inconfort')) { let inconfortValeur = attributeAsInt(personnage, 'inconfortValeur', 0); attBonus -= inconfortValeur; - explications.push("G\xEAne due \xE0 l'armure : -" + inconfortValeur); + explications.push("Gêne due à l'armure : -" + inconfortValeur); } if (attributeAsBool(personnage, 'putrefactionOutreTombe')) { attBonus -= 2; - explications.push("Putr\xE9faction => -2 en Attaque"); + explications.push("Putréfaction => -2 en Attaque"); } if (attributeAsBool(personnage, 'secoue')) { attBonus -= 2; - let msg = "Secou\xE9" + eForFemale(personnage) + " => -2 en Attaque"; + let msg = "Secoué" + eForFemale(personnage) + " => -2 en Attaque"; explications.push(msg); } if (attributeAsBool(personnage, 'bonusAttaqueTemp')) { @@ -11280,7 +11293,7 @@ var COFantasy = COFantasy || function() { let bonus = getIntValeurOfEffet(personnage, 'detournerLeRegard', 2); let msg; if (bonus < 5) { - msg = "D\xE9tourne le regard"; + msg = "Détourne le regard"; } else { msg = "Ferme les yeux"; } @@ -11311,8 +11324,8 @@ var COFantasy = COFantasy || function() { switch (ficheAttribute(perso, 'taille', '').trim().toLowerCase()) { case "minuscule": return 1; - case "tr\xE8s petit": - case "tr\xE8s petite": + case "très petit": + case "très petite": case "tres petit": return 2; case "petit": @@ -11326,13 +11339,13 @@ var COFantasy = COFantasy || function() { case "grand": case "grande": return 5; - case "\xE9norme": + case "énorme": case "enorme": return 6; case "colossal": case "colossale": return 7; - default: //On passe \xE0 la m\xE9thode suivante + default: //On passe à la méthode suivante } if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); @@ -11353,7 +11366,7 @@ var COFantasy = COFantasy || function() { case 'demi-orque': case 'orque': case 'gnome': - case '\xE2me-forg\xE9e': + case 'âme-forgée': return 4; case 'centaure': case 'demi-ogre': @@ -11366,11 +11379,11 @@ var COFantasy = COFantasy || function() { //Retourne un encodage des tailes : // 1 : minuscule - // 2 : tr\xE8s petit + // 2 : très petit // 3 : petit // 4 : moyen // 5 : grand - // 6 : \xE9norme + // 6 : énorme // 7 : colossal function taillePersonnage(perso, def) { if (perso.taille) return perso.taille; @@ -11380,19 +11393,27 @@ var COFantasy = COFantasy || function() { return taille; } - //tm doit \xEAtre stateCOF.tenebresMagiques, et bien d\xE9fini. + //tm doit être stateCOF.tenebresMagiques, et bien défini. function eclaireParFioleDeLumiere(perso, tm) { let fio = tm.fioleDeLumiere; if (fio === undefined || fio.porteur === undefined) return false; return distanceCombat(fio.porteur.token, perso.token) < fio.distance; } + function defenseBouclier(perso) { + let defense = 0; + if (ficheAttributeAsInt(perso, 'defbouclieron', 0) > 0) { + defense += ficheAttributeAsInt(perso, 'defbouclier', 0); + defense += predicateAsInt(perso, 'bouclierDeLaFoi', 0, 1); + } + return defense; + } + function defenseArmure(perso) { let defense = 0; if (ficheAttributeAsInt(perso, 'defarmureon', 0) > 0) defense = ficheAttributeAsInt(perso, 'defarmure', 0); - if (ficheAttributeAsInt(perso, 'defbouclieron', 0) > 0) - defense += ficheAttributeAsInt(perso, 'defbouclier', 0); + defense += defenseBouclier(perso); return defense; } @@ -11402,7 +11423,7 @@ var COFantasy = COFantasy || function() { if (options.difficultePVmax) { let pvmax = parseInt(target.token.get('bar1_max')); if (isNaN(pvmax)) { - error("Points de vie de " + nomPerso(target) + " mal form\xE9s", + error("Points de vie de " + nomPerso(target) + " mal formés", target.token.get('bar1_max')); return 0; } @@ -11410,7 +11431,7 @@ var COFantasy = COFantasy || function() { } else if (options.difficultePV) { let pv = parseInt(target.token.get('bar1_value')); if (isNaN(pv)) { - error("Points de vie de " + nomPerso(target) + " mal form\xE9s", + error("Points de vie de " + nomPerso(target) + " mal formés", target.token.get('bar1_value')); return 0; } @@ -11472,7 +11493,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'armureDuMage')) { let bonusArmureDuMage = getIntValeurOfEffet(target, 'armureDuMage', 4); - if (defense > 12) defense += bonusArmureDuMage / 2; // On a d\xE9j\xE0 une armure physique, \xE7a ne se cumule pas. + if (defense > 12) defense += bonusArmureDuMage / 2; // On a déjà une armure physique, ça ne se cumule pas. else defense += bonusArmureDuMage; } defense += ficheAttributeAsInt(target, 'DEFDIV', 0); @@ -11482,7 +11503,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(target, 'inconfort')) { let inconfortValeur = attributeAsInt(target, "inconfortValeur", 0); defense -= inconfortValeur; - explications.push("L'adversaire est g\xEAn\xE9 par son armure : -" + inconfortValeur + " en DEF"); + explications.push("L'adversaire est gêné par son armure : -" + inconfortValeur + " en DEF"); } let formeDarbre; if (attributeAsBool(target, 'formeDArbre')) { @@ -11491,12 +11512,12 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'statueDeBois')) defense = 10; else if (attributeAsBool(target, 'petrifie')) defense = 5; - // Malus de d\xE9fense global pour les longs combats + // Malus de défense global pour les longs combats let combat = stateCOF.combat; if (combat && reglesOptionelles.haute_DEF.val.usure_DEF.val && !combat.usureOff && combat.tour > 1) defense -= (Math.floor((combat.tour - 1) / reglesOptionelles.haute_DEF.val.usure_DEF.val) * 2); - // Autres modificateurs de d\xE9fense + // Autres modificateurs de défense defense += attributeAsInt(target, 'defenseTotale', 0); let pacifisme = predicateAsInt(target, 'pacifisme', 0, 5); if (pacifisme > 0 && !attributeAsBool(target, 'attributDeCombat_pacifismeAnnule')) @@ -11517,14 +11538,14 @@ var COFantasy = COFantasy || function() { bonusPeau = Math.ceil(bonusPeau * 1.5); } defense += bonusPeau; - explications.push("Peau d'\xE9corce : +" + bonusPeau + " en DEF"); + explications.push("Peau d'écorce : +" + bonusPeau + " en DEF"); if (peauIntense && evt && !options.test) removeTokenAttr(target, 'peauDEcorceTempeteDeManaIntense', evt); } if (attributeAsBool(target, 'peauDEcorceAmeLiee')) { let bonus = getIntValeurOfEffet(target, 'peauDEcorceAmeLiee', 1); defense += bonus; - explications.push("Peau d'\xE9corce li\xE9e : +" + bonus + " en DEF"); + explications.push("Peau d'écorce liée : +" + bonus + " en DEF"); } if (attributeAsBool(target, 'champDeProtection')) { let bonusChamp = @@ -11544,13 +11565,13 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'sixiemeSens')) { defense += 2; - explications.push("Sixi\xE8me sens : +2 DEF"); + explications.push("Sixième sens : +2 DEF"); } if (getState(target, 'surpris')) defense -= 5; if (getState(target, 'renverse')) defense -= 5; if (getState(target, 'aveugle') || attributeAsBool(target, 'aveugleManoeuvre')) { if (options.contact && predicateAsBool(target, 'radarMental') && attaquant && !estNonVivant(attaquant)) { - explications.push(tokenName + " est aveugle, mais b\xE9n\xE9ficie de son radar mental"); + explications.push(tokenName + " est aveugle, mais bénéficie de son radar mental"); } else { defense -= 5; } @@ -11560,7 +11581,7 @@ var COFantasy = COFantasy || function() { if (getState(target, 'invisible') && attaquant && !attributeAsBool(attaquant, 'detectionDeLInvisible')) { if (options.distance) { if (options.tirAveugle) { - explications.push("Cible invisible, mais " + nomPerso(attaquant) + " sait tirer \xE0 l'aveugle"); + explications.push("Cible invisible, mais " + nomPerso(attaquant) + " sait tirer à l'aveugle"); } else { defense += 10; explications.push("Invisible : +10 en DEF"); @@ -11596,13 +11617,13 @@ var COFantasy = COFantasy || function() { defense += modCarac(target, 'intelligence'); } if (attributeAsBool(target, 'armeSecreteBarde')) { - explications.push(tokenName + " est d\xE9stabilis\xE9 par une action de charme => -10 en DEF"); + explications.push(tokenName + " est déstabilisé par une action de charme => -10 en DEF"); defense -= 10; } if (options.metal && attributeAsBool(target, 'magnetisme')) { let magnetisme = getIntValeurOfEffet(target, 'magnetisme', 5); defense += magnetisme; - explications.push(tokenName + " contr\xF4le le magn\xE9tisme (+" + magnetisme + " DEF)"); + explications.push(tokenName + " contrôle le magnétisme (+" + magnetisme + " DEF)"); } if (attributeAsBool(target, 'diversionManoeuvre')) { let diversion = getIntValeurOfEffet(target, 'diversionManoeuvre', -5); @@ -11611,7 +11632,7 @@ var COFantasy = COFantasy || function() { } if (options.attaqueMentale && predicateAsBool(target, 'bouclierPsi')) { defense += 5; - explications.push(tokenName + " b\xE9n\xE9ficie d'un bouclier psi => +5 DEF"); + explications.push(tokenName + " bénéficie d'un bouclier psi => +5 DEF"); } if (attributeAsBool(target, 'monteSur')) { if (predicateAsBool(target, 'montureLoyale')) { @@ -11620,7 +11641,7 @@ var COFantasy = COFantasy || function() { } if (options.contact && predicateAsBool(target, "horsDePortee")) { defense += 5; - explications.push(tokenName + " est hors de port\xE9e sur sa monture => +5 DEF"); + explications.push(tokenName + " est hors de portée sur sa monture => +5 DEF"); } } let attrsProtegePar = findObjs({ @@ -11636,20 +11657,20 @@ var COFantasy = COFantasy || function() { evt.deletedAttributes = evt.deletedAttributes || []; evt.deletedAttributes.push(attr); attr.remove(); - sendPerso(target, "n'est plus prot\xE9g\xE9 : son protecteur n'est pas sur la page"); + sendPerso(target, "n'est plus protégé : son protecteur n'est pas sur la page"); } return; } let nameProtecteur = nomPerso(protecteur); if (!isActive(protecteur)) { - explications.push(nameProtecteur + " n'est pas en \xE9tat de prot\xE9ger " + + explications.push(nameProtecteur + " n'est pas en état de protéger " + tokenName); return; } let distTargetProtecteur = distanceCombat(target.token, protecteur.token, pageId); if (distTargetProtecteur > 0) { explications.push(nameProtecteur + " est trop loin de " + - tokenName + " pour le prot\xE9ger"); + tokenName + " pour le protéger"); return; } if (ficheAttributeAsInt(protecteur, 'defbouclieron', 0) === 0) { @@ -11661,9 +11682,9 @@ var COFantasy = COFantasy || function() { } let defBouclierProtecteur; if (persoEstPNJ(protecteur)) defBouclierProtecteur = 2; - else defBouclierProtecteur = ficheAttributeAsInt(protecteur, 'defbouclier', 0); + else defBouclierProtecteur = ficheAttributeAsInt(protecteur, 'defbouclier', 0) + predicateAsInt(protecteur, 'bouclierDeLaFoi', 0, 1); defense += defBouclierProtecteur; - explications.push(nameProtecteur + " prot\xE8ge " + + explications.push(nameProtecteur + " protège " + tokenName + " de son bouclier (+" + defBouclierProtecteur + " DEF)"); } }); @@ -11685,7 +11706,7 @@ var COFantasy = COFantasy || function() { let attaqueAOutrance = attributeAsInt(target, 'attaqueAOutrance', 0); if (attaqueAOutrance) { defense -= attaqueAOutrance; - explications.push("Attaque \xE0 outrance => -" + attaqueAOutrance + " DEF"); + explications.push("Attaque à outrance => -" + attaqueAOutrance + " DEF"); } let niveau = ficheAttributeAsInt(target, 'niveau', 1); let instinctSurvie = predicateAsInt(target, 'instinctDeSurvie', 0, niveau * 5); @@ -11699,7 +11720,7 @@ var COFantasy = COFantasy || function() { defense += predicateAsInt(target, 'DEF_magie', 0); if (predicateAsBool(target, 'chasseurDeSorciere')) { defense += 2; - explications.push("Chasseur de sorci\xE8re => +2 DEF"); + explications.push("Chasseur de sorcière => +2 DEF"); } } if (marcheSylvestreActive(target)) { @@ -11708,11 +11729,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'prisonVegetale')) { defense -= getIntValeurOfEffet(target, 'prisonVegetale', 2); - explications.push("Prison v\xE9g\xE9tale => -2 DEF"); + explications.push("Prison végétale => -2 DEF"); } if (attributeAsBool(target, 'toiles')) { defense -= getIntValeurOfEffet(target, 'toiles', 2); - explications.push("Entrav\xE9 => -2 DEF"); + explications.push("Entravé => -2 DEF"); } if (attributeAsBool(target, 'protectionContreLeMal') && (attaquant && estMauvais(attaquant))) { @@ -11738,7 +11759,7 @@ var COFantasy = COFantasy || function() { explications.push(msgRage + " du berserk => " + modRage + " DEF"); defense += modRage; } else if (attributeAsBool(target, 'frenesieMinotaure')) { - explications.push("Fren\xE9sie => -2 en DEF"); + explications.push("Frenésie => -2 en DEF"); defense -= 2; } let combatEnPhalange = predicateAsBool(target, 'combatEnPhalange'); @@ -11795,36 +11816,36 @@ var COFantasy = COFantasy || function() { defense += predicateAsInt(target, 'voieDesRunes', 0, 1); if (attributeAsBool(target, 'attaqueRisquee')) { defense -= 4; - explications.push("Suite \xE0 une attaque risqu\xE9e, -4 en DEF"); + explications.push("Suite à une attaque risquée, -4 en DEF"); } let armeTarget = armesEnMain(target); //peuple target.arme et armeGauche - //gestion de l'\xE9pieu + //gestion de l'épieu if (attaquant) { if (armeTarget && armeTarget.epieu && !armesEnMain(attaquant)) { defense += 2; - explications.push("\xC9pieu contre une attaque sans arme => +2 DEF"); + explications.push("Épieu contre une attaque sans arme => +2 DEF"); } } if (options.distance) { let bonusCouvert = attributeAsInt(target, 'bonusCouvert'); if (bonusCouvert) { if (attaquant && predicateAsBool(attaquant, 'joliCoup')) { - explications.push("Cible \xE0 couvert, mais " + nomPerso(attaquant) + " sait bien viser"); + explications.push("Cible à couvert, mais " + nomPerso(attaquant) + " sait bien viser"); } else { defense += bonusCouvert; - explications.push("Cible \xE0 couvert => +" + bonusCouvert + " DEF"); + explications.push("Cible à couvert => +" + bonusCouvert + " DEF"); } } if (attributeAsBool(target, 'progresserACouvert')) { if (attaquant && predicateAsBool(attaquant, 'joliCoup')) { - explications.push("Cible \xE0 couvert de bouclier, mais " + nomPerso(attaquant) + " sait bien viser"); + explications.push("Cible à couvert de bouclier, mais " + nomPerso(attaquant) + " sait bien viser"); } else { defense += 5; - explications.push("Cible \xE0 couvert de bouclier => +5 DEF"); + explications.push("Cible à couvert de bouclier => +5 DEF"); } } } - //Chair \xE0 canon + //Chair à canon if (capaciteDisponible(target, 'chairACanon', 'tour')) { let tokensChairACanon = findObjs({ _type: 'graphic', @@ -11866,15 +11887,15 @@ var COFantasy = COFantasy || function() { switch (taillePersonnage(attaquant, 4)) { case 5: defense += 2; - explications.push(nomPerso(target) + " r\xE9duit la distance => +2 en DEF"); + explications.push(nomPerso(target) + " réduit la distance => +2 en DEF"); break; case 6: defense += 3; - explications.push(nomPerso(target) + " r\xE9duit la distance => +3 en DEF"); + explications.push(nomPerso(target) + " réduit la distance => +3 en DEF"); break; case 7: defense += 4; - explications.push(nomPerso(target) + " r\xE9duit la distance => +4 en DEF"); + explications.push(nomPerso(target) + " réduit la distance => +4 en DEF"); } } if (attaquant && predicateAsBool(target, 'insignifiant')) { @@ -11891,11 +11912,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'etreinteImmole')) { defense -= 5; - explications.push(nomPerso(target) + " \xE9treint quelqu'un => -5 en DEF"); + explications.push(nomPerso(target) + " étreint quelqu'un => -5 en DEF"); } if (attributeAsBool(target, 'etreinteScorpionRatee')) { defense -= 5; - explications.push(nomPerso(target) + " est \xE9treint par un scorpion => -5 DEF"); + explications.push(nomPerso(target) + " est étreint par un scorpion => -5 DEF"); } if (attaquant && predicateAsBool(target, 'langageSombreHetre') && estElfeNoir(attaquant)) { defense += 1; @@ -11903,7 +11924,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'presenceGlaciale')) { let defenseGlaciale = getIntValeurOfEffet(target, 'presenceGlaciale', 4); - explications.push("Pr\xE9sence glaciale => +" + defenseGlaciale + " en DEF"); + explications.push("Présence glaciale => +" + defenseGlaciale + " en DEF"); defense += defenseGlaciale; } if (attributeAsBool(target, 'cyclone')) { @@ -11935,24 +11956,24 @@ var COFantasy = COFantasy || function() { defense += 10; } if (options.contact && attributeAsBool(target, 'tenirADistance')) { - explications.push("Tient l'ennemi \xE0 distance => +5 en DEF"); + explications.push("Tient l'ennemi à distance => +5 en DEF"); defense += 5; } let tm = stateCOF.tenebresMagiques; if (tm) { if (estDemon(target)) { if (eclaireParFioleDeLumiere(target, tm)) { - explications.push("Aveugl\xE9 par la fiole de lumi\xE8re => -2 en DEF"); + explications.push("Aveuglé par la fiole de lumière => -2 en DEF"); defense -= 2; } } else if (attaquant && !eclaireParFioleDeLumiere(attaquant, tm)) { - explications.push("T\xE9n\xE8bres magiques => -5 en DEF"); + explications.push("Ténèbres magiques => -5 en DEF"); defense -= 5; } } if (attributeAsBool(target, 'agrippeParUnDemon')) { - explications.push("agripp\xE9 => -3 en DEF"); + explications.push("agrippé => -3 en DEF"); defense -= 3; } if (estNecromancie(options) && attributeAsBool(target, 'sangDeLArbreCoeur')) { @@ -11960,7 +11981,7 @@ var COFantasy = COFantasy || function() { defense += 5; } if (predicateAsBool(target, 'liberateurDeDorn') && estGeant(attaquant)) { - explications.push('Lib\xE9rateur de Dorn => +2 en DEF'); + explications.push('Libérateur de Dorn => +2 en DEF'); defense += 2; } let pirouettes = predicateAsInt(target, 'pirouettes', 0); @@ -11978,14 +11999,14 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(target, 'paradeCroisee')) { let bonus = getIntValeurOfEffet(target, 'paradeCroisee', 2); - explications.push("Parade crois\xE9e => +" + bonus + " en DEF"); + explications.push("Parade croisée => +" + bonus + " en DEF"); defense += bonus; } let conditions = attributeAsInt(target, 'conditionsHostiles', 0, 2); if (conditions > 0 && (!predicateAsBool(target, 'marcheSylvestre') || conditions > 4)) { let msgConditions = "Conditions "; if (conditions < 5) msgConditions += "hostiles"; - else msgConditions += "extr\xEAmes"; + else msgConditions += "extrêmes"; msgConditions += " : -" + conditions + " en DEF"; explications.push(msgConditions); defense -= conditions; @@ -12005,7 +12026,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(target, 'detournerLeRegard')) { let bonus = getIntValeurOfEffet(target, 'detournerLeRegard', 2); if (bonus < 5) { - explications.push("D\xE9tourne le regard => -" + bonus + " en DEF"); + explications.push("Détourne le regard => -" + bonus + " en DEF"); } else { explications.push("Ferme les yeux => -" + bonus + " en DEF"); } @@ -12013,13 +12034,13 @@ var COFantasy = COFantasy || function() { } defense += predicateAsInt(target, 'DEF', 0); if (attaquant && predicateAsBool(target, 'armeDeLEte') && predicateAsBool(attaquant, 'creatureDeLHiver')) { - explications.push("Prot\xE9g\xE9 par une arme de l'\xE9t\xE9 => +25 en DEF"); + explications.push("Protégé par une arme de l'été => +25 en DEF"); defense += 25; } return defense; } - // renvoie l'attribut cr\xE9\xE9 ou mis \xE0 jour + // renvoie l'attribut créé ou mis à jour function setAttrDuree(perso, attr, duree, evt, msg, secret) { let options = { maxVal: getInit(), @@ -12029,23 +12050,23 @@ var COFantasy = COFantasy || function() { return setTokenAttr(perso, attr, duree, evt, options); } - //Tous les bonus de DM normalement calcul\xE9s dans bonusAttaqueA + //Tous les bonus de DM normalement calculés dans bonusAttaqueA function bonusDMA(attaquant, weaponName, evt, explications, options) { if (options.pasDeDmg) return; options.bonusDM = 0; if (attributeAsBool(attaquant, 'baroudHonneurActif')) { - explications.push(nomPerso(attaquant) + " porte une derni\xE8re attaque et s'effondre"); + explications.push(nomPerso(attaquant) + " porte une dernière attaque et s'effondre"); mort(attaquant, function(m) { explications.push(m); }, evt); removeTokenAttr(attaquant, 'baroudHonneurActif', evt); } if (attributeAsBool(attaquant, 'reactionViolente')) { - explications.push("R\xE9action violente => +1d6 DM"); + explications.push("Réaction violente => +1d6 DM"); options.reactionViolente = true; } if (attributeAsBool(attaquant, 'drainDeForce')) { - explications.push("Force drain\xE9e => -2 aux DM"); + explications.push("Force drainée => -2 aux DM"); options.drainDeForce = true; } if (options.contact) { @@ -12056,11 +12077,11 @@ var COFantasy = COFantasy || function() { explications.push(msg); } if (attributeAsBool(attaquant, 'enrage')) { - explications.push("Enrag\xE9 => +1d6 DM"); + explications.push("Enragé => +1d6 DM"); options.enrage = true; } if (attributeAsBool(attaquant, 'rage')) { - explications.push("Enrag\xE9 => +2 DM"); + explications.push("Enragé => +2 DM"); options.rage = true; } let rageBerserk = tokenAttribute(attaquant, 'rageDuBerserk'); @@ -12074,7 +12095,7 @@ var COFantasy = COFantasy || function() { options.rageBerserk = 1; } } else if (attributeAsBool(attaquant, 'frenesieMinotaure')) { - explications.push("Fr\xE9n\xE9sie : +1d6 aux DM"); + explications.push("Frénésie : +1d6 aux DM"); options.rageBerserk = 1; } if (predicateAsBool(attaquant, 'ambidextreDuelliste')) { @@ -12144,7 +12165,7 @@ var COFantasy = COFantasy || function() { let gobant = persoOfIdName(attrGobe[0].get('current'), attaquant.token.get('pageid')); if (gobant === undefined) { - error("Attribut estGobePar mal form\xE9", attrGobe[0].get('current')); + error("Attribut estGobePar mal formé", attrGobe[0].get('current')); attrGobe[0].remove(); unlockToken(attaquant, evt); } else { @@ -12163,7 +12184,7 @@ var COFantasy = COFantasy || function() { let energieImpie = attributeAsInt(attaquant, 'energieImpie', 0); if (energieImpie) { options.bonusDM += energieImpie; - explications.push("\xC9nergie impie => +" + energieImpie + " DM"); + explications.push("Énergie impie => +" + energieImpie + " DM"); } if (options.arcComposite) { let force = modCarac(attaquant, 'force'); @@ -12178,7 +12199,7 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(attaquant, 'fievreux')) { options.fievreux = true; - explications.push("Fi\xE9vreu" + onGenre(attaquant, 'x', 'se') + " => -2 DM"); + explications.push("Fiévreu" + onGenre(attaquant, 'x', 'se') + " => -2 DM"); } if (options.expertDuCombatDM && !options.pasDeDmg) { let valDesExpert = options.rolls.expertDuCombatDM || rollDePlus(6); @@ -12205,7 +12226,7 @@ var COFantasy = COFantasy || function() { let masqueIntense = attributeAsInt(attaquant, 'masqueDuPredateurTempeteDeManaIntense', 0); bonusMasque += masqueIntense; options.bonusDM += bonusMasque; - explications.push("Masque du pr\xE9dateur : +" + bonusMasque + " aux DM"); + explications.push("Masque du prédateur : +" + bonusMasque + " aux DM"); if (masqueIntense) removeTokenAttr(attaquant, 'masqueDuPredateurTempeteDeManaIntense', evt); } else if (attributeAsBool(attaquant, 'masqueDuPredateurAmeLiee')) { @@ -12213,7 +12234,7 @@ var COFantasy = COFantasy || function() { getIntValeurOfEffet(attaquant, 'masqueDuPredateurAmeLiee', 1); if (bonusMasque > 0) { options.bonusDM += bonusMasque; - explications.push("Masque du pr\xE9dateur li\xE9 : +" + bonusMasque + " aux DM"); + explications.push("Masque du prédateur lié : +" + bonusMasque + " aux DM"); } } if (options.attaqueFlamboyante && options.contact) { @@ -12226,7 +12247,7 @@ var COFantasy = COFantasy || function() { let bonus = getIntValeurOfEffet(attaquant, 'detournerLeRegard', 2); let msg; if (bonus < 5) { - msg = "D\xE9tourne le regard"; + msg = "Détourne le regard"; } else { msg = "Ferme les yeux"; } @@ -12237,7 +12258,7 @@ var COFantasy = COFantasy || function() { return; } - //Bonus en Attaque qui ne d\xE9pendent pas du d\xE9fenseur + //Bonus en Attaque qui ne dépendent pas du défenseur //Remplit le champs options.bonusDM (en partant de 0) function bonusAttaqueA(attaquant, weaponName, evt, explications, options) { let attBonus = 0; @@ -12249,16 +12270,16 @@ var COFantasy = COFantasy || function() { attBonus += 2; if (options.tirDouble.stats && options.tirDouble.stats.name) { explications.push(nomPerso(attaquant) + " tire avec " + - weaponName + " et " + options.tirDouble.stats.name + " \xE0 la fois !"); + weaponName + " et " + options.tirDouble.stats.name + " à la fois !"); } else { explications.push(nomPerso(attaquant) + " tire avec 2 " + - weaponName + "s \xE0 la fois !"); + weaponName + "s à la fois !"); } } if (options.chance) { attBonus += options.chance; let pc = options.chance / 10; - explications.push(pc + " point" + ((pc > 1) ? "s" : "") + " de chance d\xE9pens\xE9 => +" + options.chance + " en Attaque"); + explications.push(pc + " point" + ((pc > 1) ? "s" : "") + " de chance dépensé => +" + options.chance + " en Attaque"); } if (options.semonce) { attBonus += 5; @@ -12276,7 +12297,7 @@ var COFantasy = COFantasy || function() { } if (options.attaqueAssuree) { attBonus += 5; - explications.push("Attaque assur\xE9e => +5 en Attaque et DM/2"); + explications.push("Attaque assurée => +5 en Attaque et DM/2"); } if (ficheAttributeAsBool(attaquant, 'attaque_dm_temp_check')) { options.attaqueDmTemp = true; @@ -12300,11 +12321,11 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(attaquant, 'criDuPredateur')) { attBonus += 1; - explications.push("Cri du pr\xE9dateur => +1 en attaque"); + explications.push("Cri du prédateur => +1 en attaque"); } if (attributeAsBool(attaquant, 'baroudHonneurActif')) { attBonus += 5; - explications.push(nomPerso(attaquant) + " porte une derni\xE8re attaque et s'effondre"); + explications.push(nomPerso(attaquant) + " porte une dernière attaque et s'effondre"); mort(attaquant, function(m) { explications.push(m); }, evt); @@ -12319,7 +12340,7 @@ var COFantasy = COFantasy || function() { let cavalierEm = predicateAsInt(attaquant, 'cavalierEmerite'); if (cavalierEm) { attBonus += cavalierEm; - let explCavalierEmerite = "avalier \xE9m\xE9rite => +" + cavalierEm + " en Attaque"; + let explCavalierEmerite = "avalier émérite => +" + cavalierEm + " en Attaque"; if (options.displayName) { explCavalierEmerite = nomPerso(attaquant) + " est un c" + explCavalierEmerite; } else { @@ -12343,15 +12364,15 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(attaquant, 'reactionViolente')) { attBonus += 2; if (options.pasDeDmg) - explications.push("R\xE9action violente => +2 en Attaque"); + explications.push("Réaction violente => +2 en Attaque"); else { - explications.push("R\xE9action violente => +2 en Attaque et +1d6 DM"); + explications.push("Réaction violente => +2 en Attaque et +1d6 DM"); options.reactionViolente = true; } } if (attributeAsBool(attaquant, 'drainDeForce')) { attBonus -= 2; - let msg = "Force drain\xE9e => -2 en Attaque"; + let msg = "Force drainée => -2 en Attaque"; if (options.pasDeDmg || !options.contact) explications.push(msg); else explications.push(msg + " et aux DM"); options.drainDeForce = true; @@ -12359,7 +12380,7 @@ var COFantasy = COFantasy || function() { let energieImpie = attributeAsInt(attaquant, 'energieImpie', 0); if (energieImpie) { attBonus += energieImpie; - let msg = "\xC9nergie impie => +" + energieImpie + " en Attaque"; + let msg = "Énergie impie => +" + energieImpie + " en Attaque"; if (!options.pasDeDmg) { msg += " et aux DM"; options.bonusDM += energieImpie; @@ -12379,21 +12400,21 @@ var COFantasy = COFantasy || function() { attBonus += 5; options.enrage = true; if (options.pasDeDmg) - explications.push("Enrag\xE9 => +5 en Attaque"); + explications.push("Enragé => +5 en Attaque"); else - explications.push("Enrag\xE9 => +5 en Attaque et +1d6 DM"); + explications.push("Enragé => +5 en Attaque et +1d6 DM"); } if (attributeAsBool(attaquant, 'rage')) { attBonus += 2; if (options.pasDeDmg) - explications.push("Enrag\xE9 => +2 en Attaque"); + explications.push("Enragé => +2 en Attaque"); else - explications.push("Enrag\xE9 => +2 en Attaque et +2 DM"); + explications.push("Enragé => +2 en Attaque et +2 DM"); options.rage = true; } if (attributeAsBool(attaquant, 'aspectDuDemon')) { attBonus += getIntValeurOfEffet(attaquant, 'aspectDuDemon', 2); - explications.push("Aspect de d\xE9mon => +2 en Attaque"); + explications.push("Aspect de démon => +2 en Attaque"); } let rageBerserk = tokenAttribute(attaquant, 'rageDuBerserk'); if (rageBerserk.length > 0) { @@ -12420,9 +12441,9 @@ var COFantasy = COFantasy || function() { } else if (attributeAsBool(attaquant, 'frenesieMinotaure')) { attBonus += 2; if (options.pasDeDmg) - explications.push("Fr\xE9n\xE9sie : +2 en Attaque"); + explications.push("Frénésie : +2 en Attaque"); else - explications.push("Fr\xE9n\xE9sie : +2 en Attaque et +1d6 aux DM"); + explications.push("Frénésie : +2 en Attaque et +1d6 aux DM"); options.rageBerserk = 1; } if (ficheAttributeAsBool(attaquant, 'attaque_risquee_check')) { @@ -12430,7 +12451,7 @@ var COFantasy = COFantasy || function() { } if (options.attaqueRisquee) { attBonus += 2; - explications.push("Attaque risqu\xE9e => +2 en Attaque"); + explications.push("Attaque risquée => +2 en Attaque"); if (!options.test) { setAttrDuree(attaquant, 'attaqueRisquee', 1, evt); } @@ -12489,7 +12510,7 @@ var COFantasy = COFantasy || function() { pv = parseInt(attaquant.token.get('bar1_value')); if (pv <= frenesie) { attBonus += 2; - explications.push("Fr\xE9n\xE9sie => +2 en Attaque"); + explications.push("Frénésie => +2 en Attaque"); } } if (predicateAsBool(attaquant, 'hausserLeTon')) { @@ -12533,18 +12554,18 @@ var COFantasy = COFantasy || function() { } if (attributeAsBool(attaquant, 'enerve')) { attBonus -= 2; - explications.push("Attaquant \xE9nerv\xE9 => -2 en Attaque"); + explications.push("Attaquant énervé => -2 en Attaque"); } if (attributeAsBool(attaquant, 'osBrises')) { attBonus -= 2; - explications.push("Des os sont bris\xE9s => -2 en Attaque"); + explications.push("Des os sont brisés => -2 en Attaque"); } let attrGobe = tokenAttribute(attaquant, 'estGobePar'); if (attrGobe.length > 0) { let gobant = persoOfIdName(attrGobe[0].get('current'), attaquant.token.get('pageid')); if (gobant === undefined) { - error("Attribut estGobePar mal form\xE9", attrGobe[0].get('current')); + error("Attribut estGobePar mal formé", attrGobe[0].get('current')); attrGobe[0].remove(); unlockToken(attaquant, evt); } else { @@ -12586,7 +12607,7 @@ var COFantasy = COFantasy || function() { } if (actif) { attBonus += 1; - explications.push("Arme de pr\xE9dil\xE9ction => +1 en Attaque"); + explications.push("Arme de prédiléction => +1 en Attaque"); } } if (options.arcComposite) { @@ -12609,7 +12630,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(attaquant, 'fievreux')) { attBonus -= 2; options.fievreux = true; - explications.push("Fi\xE9vreu" + onGenre(attaquant, 'x', 'se') + " => -2 en Att. et DM"); + explications.push("Fiévreu" + onGenre(attaquant, 'x', 'se') + " => -2 en Att. et DM"); } if (options.expertDuCombatTouche) { let valDesExpert = options.rolls.expertDuCombatTouche || rollDePlus(6); @@ -12682,7 +12703,7 @@ var COFantasy = COFantasy || function() { if (conditions > 0 && (!predicateAsBool(attaquant, 'marcheSylvestre') || conditions > 4)) { let msgConditions = "Conditions "; if (conditions < 5) msgConditions += "hostiles"; - else msgConditions += "extr\xEAmes"; + else msgConditions += "extrêmes"; msgConditions += " : -" + conditions + " en attaque"; explications.push(msgConditions); attBonus -= conditions; @@ -12713,15 +12734,20 @@ var COFantasy = COFantasy || function() { value: '1d6', }); } + if (estMortVivant(attaquant) && dansAuraDeProfanation(attaquant)) { + attBonus += 1; + options.bonusDM += 1; + explications.push("Aura de profanation => +1 Attaque et DM"); + } return attBonus; } - //Tous les bonus de DM normalement calcul\xE9s dans bonusAttaqueD + //Tous les bonus de DM normalement calculés dans bonusAttaqueD function bonusDMD(attaquant, target, portee, pageId, evt, explications, options) { let chasseurEmerite = predicateAsBool(attaquant, 'chasseurEmerite') && estAnimal(target); if (chasseurEmerite) { - let explChasseurEmerite = "hasseur \xE9m\xE9rite => +2 aux DM"; + let explChasseurEmerite = "hasseur émérite => +2 aux DM"; if (options.displayName) { explChasseurEmerite = nomPerso(attaquant) + ' est un c' + explChasseurEmerite; } else { @@ -12740,7 +12766,7 @@ var COFantasy = COFantasy || function() { }); }); if (ennemiJure) { - let explEnnemiJure = "Attaque sur ennemi jur\xE9 => + 1d6 aux DM"; + let explEnnemiJure = "Attaque sur ennemi juré => + 1d6 aux DM"; if (options.aoe) explEnnemiJure += " contre " + nomPerso(target); explications.push(explEnnemiJure); target.ennemiJure = true; @@ -12766,7 +12792,7 @@ var COFantasy = COFantasy || function() { let attrFeinte = tokenAttribute(target, 'feinte_' + nomPerso(attaquant)); if (attrFeinte.length > 0 && attrFeinte[0].get('current')) { let niveauTouche = attrFeinte[0].get('max'); - if (niveauTouche > 0) { //La feinte avait touch\xE9 cette cible + if (niveauTouche > 0) { //La feinte avait touché cette cible let msgFeinte = "Feinte => "; let faireMouche = predicateAsInt(attaquant, 'faireMouche', 0); if (faireMouche > 0) { @@ -12791,7 +12817,7 @@ var COFantasy = COFantasy || function() { let cibleAgrippee = persoOfIdName(a.get('current'), pageId); if (cibleAgrippee && cibleAgrippee.id == target.id && !attributeAsBool(cibleAgrippee, 'agrippeParUnDemon')) { - explications.push("Cible agripp\xE9e => +1d6 DM"); + explications.push("Cible agrippée => +1d6 DM"); target.estAgrippee = true; } }); @@ -12814,15 +12840,15 @@ var COFantasy = COFantasy || function() { } } if (predicateAsBool(attaquant, 'liberateurDeDorn') && estGeant(target)) { - explications.push("Lib\xE9rateur de Dorn => +2d6 DM"); + explications.push("Libérateur de Dorn => +2d6 DM"); target.cibleLiberateurDeDorn = true; } if (predicateAsBool(attaquant, 'liberateurDeKerserac') && (estGeant(target) || estInsecte(target) || estElfeNoir(target))) { - explications.push("Lib\xE9rateur de Kerserac => +1d6 DM"); + explications.push("Libérateur de Kerserac => +1d6 DM"); target.cibleLiberateurDeKerserac = true; } if (predicateAsBool(attaquant, 'liberateurDAnathazerin') && (estInsecte(target) || estElfeNoir(target))) { - explications.push("Lib\xE9rateur d'Anathazer\xEFn => +2d6 DM"); + explications.push("Libérateur d'Anathazerïn => +2d6 DM"); target.cibleLiberateurDAnathazerin = true; } let attrMeneurCible = tokenAttribute(target, 'meneurDHommesCible'); @@ -12832,7 +12858,7 @@ var COFantasy = COFantasy || function() { if (meneurDHommes && alliesParPerso[meneurDHommes.charId] && alliesParPerso[meneurDHommes.charId].has(attaquant.charId)) { target.cibleMeneurDHommes = true; - explications.push(nomPerso(meneurDHommes) + " a d\xE9sign\xE9 " + nomPerso(target) + + explications.push(nomPerso(meneurDHommes) + " a désigné " + nomPerso(target) + " comme la cible des attaques du groupe : +1d6 DM"); } } @@ -12848,22 +12874,22 @@ var COFantasy = COFantasy || function() { return; } - //Bonus d'attaque qui d\xE9pendent de la cible + //Bonus d'attaque qui dépendent de la cible function bonusAttaqueD(attaquant, target, portee, pageId, evt, explications, options) { let attBonus = 0; if (target.bonusAttaque) attBonus += target.bonusAttaque; if (getState(attaquant, 'aveugle')) { if (options.distance) { if (options.tirAveugle) { - explications.push("Attaquant aveugl\xE9, mais il sait tirer \xE0 l'aveugle"); + explications.push("Attaquant aveuglé, mais il sait tirer à l'aveugle"); } else { attBonus -= 10; - explications.push("Attaquant aveugl\xE9 => -10 en Attaque \xE0 distance"); + explications.push("Attaquant aveuglé => -10 en Attaque à distance"); } } else { if (!predicateAsBool(attaquant, 'radarMental') || estNonVivant(target)) { attBonus -= 5; - explications.push("Attaquant aveugl\xE9 => -5 en Attaque"); + explications.push("Attaquant aveuglé => -5 en Attaque"); } } } else if (attributeAsBool(attaquant, 'aveugleManoeuvre')) { @@ -12871,24 +12897,24 @@ var COFantasy = COFantasy || function() { attBonus -= 5; options.aveugleManoeuvre = true; if (options.pasDeDmg) - explications.push("Attaquant aveugl\xE9 => -5 en Attaque"); + explications.push("Attaquant aveuglé => -5 en Attaque"); else - explications.push("Attaquant aveugl\xE9 => -5 en Attaque et aux DM"); + explications.push("Attaquant aveuglé => -5 en Attaque et aux DM"); } } else if (getState(attaquant, 'invisible') && !attributeAsBool(target, 'detectionDeLInvisible')) { attBonus += 5; explications.push("Attaque venant d'un personnage invisible => +5 en Attaque"); } else if (options.distance && getState(attaquant, 'penombre')) { if (options.tirAveugle) { - explications.push("Attaquant dans la p\xE9nombre, mais il sait tirer \xE0 l'aveugle"); + explications.push("Attaquant dans la pénombre, mais il sait tirer à l'aveugle"); } else { attBonus -= 5; - explications.push("Attaquant dans la p\xE9nombre => -5 en Attaque \xE0 distance"); + explications.push("Attaquant dans la pénombre => -5 en Attaque à distance"); } } if (options.mainsDEnergie) { - if (options.aoe) error("Mains d'\xE9nergie n'est pas compatible avec les AOE", options.aoe); - // On v\xE9rifie si la cible porte une armure + if (options.aoe) error("Mains d'énergie n'est pas compatible avec les AOE", options.aoe); + // On vérifie si la cible porte une armure let targetArmorDef = 0; if (persoEstPNJ(target)) { if (ficheAttributeAsBool(target, 'defarmureon', false)) targetArmorDef = 5; @@ -12897,11 +12923,11 @@ var COFantasy = COFantasy || function() { } if (isNaN(targetArmorDef) || targetArmorDef === 0) { attBonus += 2; - explications.push("Mains d'\xE9nergie => +2 en Attaque (cible sans armure)"); + explications.push("Mains d'énergie => +2 en Attaque (cible sans armure)"); } else { let bonusMain = Math.min(5, 2 + targetArmorDef); attBonus += bonusMain; - explications.push("Mains d'\xE9nergie => +" + bonusMain + " en Attaque"); + explications.push("Mains d'énergie => +" + bonusMain + " en Attaque"); } } if (options.aoe === undefined && options.auto === undefined && portee > 0) { @@ -12913,7 +12939,7 @@ var COFantasy = COFantasy || function() { predicateAsBool(attaquant, 'chasseurEmerite') && estAnimal(target); if (chasseurEmerite) { attBonus += 2; - let explChasseurEmerite = "hasseur \xE9m\xE9rite => +2 en Attaque"; + let explChasseurEmerite = "hasseur émérite => +2 en Attaque"; if (options.displayName) { explChasseurEmerite = nomPerso(attaquant) + ' est un c' + explChasseurEmerite; } else { @@ -12935,7 +12961,7 @@ var COFantasy = COFantasy || function() { if (ennemiJure) { let ejSag = modCarac(attaquant, 'sagesse'); attBonus += ejSag; - let explEnnemiJure = "Attaque sur ennemi jur\xE9 => +" + ejSag + " en attaque"; + let explEnnemiJure = "Attaque sur ennemi juré => +" + ejSag + " en attaque"; if (!options.pasDeDmg) explEnnemiJure += " et +1d6 aux DM"; if (options.aoe) explEnnemiJure += " contre " + nomPerso(target); explications.push(explEnnemiJure); @@ -12970,9 +12996,9 @@ var COFantasy = COFantasy || function() { if (options.tueurDeGeants && estGeant(target)) { attBonus += 2; if (options.pasDeDmg) - explications.push("Tueur de g\xE9ant => +2 en Attaque"); + explications.push("Tueur de géant => +2 en Attaque"); else - explications.push("Tueur de g\xE9ant => +2 att. et 2d6 DM"); + explications.push("Tueur de géant => +2 att. et 2d6 DM"); target.tueurDeGeants = true; } if (options.tueurDe) { @@ -12996,7 +13022,7 @@ var COFantasy = COFantasy || function() { attBonus += bonusFeinte; let msgFeinte = "Feinte => +" + bonusFeinte + " en attaque"; let niveauTouche = attrFeinte[0].get('max'); - if (niveauTouche > 0) { //La feinte avait touch\xE9 cette cible + if (niveauTouche > 0) { //La feinte avait touché cette cible let faireMouche = predicateAsInt(attaquant, 'faireMouche', 0); if (faireMouche > 0) { if (options.contact && !options.pasDeDmg) { @@ -13026,7 +13052,7 @@ var COFantasy = COFantasy || function() { }); if (expose) { attBonus += 10; - explications.push("L'adversaire est expos\xE9 : +10"); + explications.push("L'adversaire est exposé : +10"); } } if (options.contact) { @@ -13035,7 +13061,7 @@ var COFantasy = COFantasy || function() { ficheAttributeAsInt(attaquant, 'force', 10) <= ficheAttributeAsInt(target, 'force', 10) && parseInt(attaquant.token.get("bar1_max")) <= parseInt(target.token.get("bar1_max"))) { attBonus -= 2; - explications.push("Effray\xE9 => -2 en Attaque"); + explications.push("Effrayé => -2 en Attaque"); } } let attrAgrippe = tokenAttribute(attaquant, 'agrippe'); @@ -13045,9 +13071,9 @@ var COFantasy = COFantasy || function() { !attributeAsBool(cibleAgrippee, 'agrippeParUnDemon')) { attBonus += 5; if (options.pasDeDmg) - explications.push("Cible agripp\xE9e => +5 em Attaque"); + explications.push("Cible agrippée => +5 em Attaque"); else - explications.push("Cible agripp\xE9e => +5 att. et 1d6 DM"); + explications.push("Cible agrippée => +5 att. et 1d6 DM"); target.estAgrippee = true; } }); @@ -13064,7 +13090,7 @@ var COFantasy = COFantasy || function() { _pageid: pageId, layer: 'objects' }); - //On compte les tokens au contact de l'attaquant et du d\xE9fenseur et alli\xE9s de l'attaquant + //On compte les tokens au contact de l'attaquant et du défenseur et alliés de l'attaquant let allies = alliesParPerso[attaquant.charId]; if (allies) { let alliesAuContact = 0; @@ -13122,7 +13148,7 @@ var COFantasy = COFantasy || function() { if (tm) { if (estDemon(attaquant)) { if (eclaireParFioleDeLumiere(attaquant, tm)) { - explications.push("Aveugl\xE9 par la fiole de lumi\xE8re => -2 en Attaque"); + explications.push("Aveuglé par la fiole de lumière => -2 en Attaque"); attBonus -= 2; } } else if (!eclaireParFioleDeLumiere(target, tm)) { @@ -13147,34 +13173,34 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(attaquant, 'liberateurDeDorn') && estGeant(target)) { attBonus += 2; if (options.pasDeDmg) { - explications.push("Lib\xE9rateur de Dorn => +2 en attaque"); + explications.push("Libérateur de Dorn => +2 en attaque"); } else { - explications.push("Lib\xE9rateur de Dorn => +2 en attaque et +2d6 DM"); + explications.push("Libérateur de Dorn => +2 en attaque et +2d6 DM"); target.cibleLiberateurDeDorn = true; } } if (predicateAsBool(attaquant, 'liberateurDeKerserac') && (estGeant(target) || estInsecte(target) || estElfeNoir(target))) { attBonus += 2; if (options.pasDeDmg) { - explications.push("Lib\xE9rateur de Kerserac => +2 en attaque"); + explications.push("Libérateur de Kerserac => +2 en attaque"); } else { - explications.push("Lib\xE9rateur de Kerserac => +2 en attaque et +1d6 DM"); + explications.push("Libérateur de Kerserac => +2 en attaque et +1d6 DM"); target.cibleLiberateurDeKerserac = true; } } if (predicateAsBool(attaquant, 'liberateurDAnathazerin') && (estInsecte(target) || estElfeNoir(target))) { attBonus += 2; if (options.pasDeDmg) { - explications.push("Lib\xE9rateur d'Anathazer\xEFn => +2 en attaque"); + explications.push("Libérateur d'Anathazerïn => +2 en attaque"); } else { - explications.push("Lib\xE9rateur d'Anathazer\xEFn => +2 en attaque et +2d6 DM"); + explications.push("Libérateur d'Anathazerïn => +2 en attaque et +2d6 DM"); target.cibleLiberateurDAnathazerin = true; } } if (predicateAsBool(attaquant, 'tenacite')) { let bonus = attributeAsInt(target, 'attributDeCombat_tenaciteDe' + nomPerso(attaquant), 0); if (bonus > 0) { - explications.push("T\xE9nacit\xE9 => +" + bonus + " en attaque"); + explications.push("Ténacité => +" + bonus + " en attaque"); attBonus += bonus; } } @@ -13186,7 +13212,7 @@ var COFantasy = COFantasy || function() { alliesParPerso[meneurDHommes.charId].has(attaquant.charId)) { attBonus += 2; if (!options.pasDeDmg) target.cibleMeneurDHommes = true; - explications.push(nomPerso(meneurDHommes) + " a d\xE9sign\xE9 " + nomPerso(target) + + explications.push(nomPerso(meneurDHommes) + " a désigné " + nomPerso(target) + " comme la cible des attaques du groupe : +2 attaque, +1d6 DM"); } } @@ -13252,14 +13278,14 @@ var COFantasy = COFantasy || function() { if (res.length === 0) { let ace = tokenAttribute(perso, classeEffet); if (ace.length > 0) { - error(nomPerso(perso) + " a une classe d'effets " + classeEffet + " mais pas d'effet associ\xE9", ace); + error(nomPerso(perso) + " a une classe d'effets " + classeEffet + " mais pas d'effet associé", ace); ace[0].remove(); } } return res; } - //Si le d\xE9passement de limite est possible, renvoie un nouveau depMana, sinon renvoie false + //Si le dépassement de limite est possible, renvoie un nouveau depMana, sinon renvoie false function depasseLimite(perso, nomAttr, msgImpossible, msg, evt, options) { if (options.depasseLimite) { options.mana = options.mana || 0; @@ -13276,8 +13302,8 @@ var COFantasy = COFantasy || function() { return false; } - //Retourne true si il existe une limite qui emp\xEAche de lancer le sort - //N'ajoute pas l'\xE9v\xE9nement \xE0 l'historique + //Retourne true si il existe une limite qui empêche de lancer le sort + //N'ajoute pas l'événement à l'historique //explications est optionnel function limiteRessources(personnage, options, defResource, msg, evt, explications) { let depMana = { @@ -13301,8 +13327,8 @@ var COFantasy = COFantasy || function() { } if (m > 0) { if (reglesOptionelles.mana.val.mana_totale.val) options.mana += m; - //Le plus coh\xE9rent avec la mana totale consiste \xE0 diviser ce malus par 3, - //arrondi au sup\xE9rieur + //Le plus cohérent avec la mana totale consiste à diviser ce malus par 3, + //arrondi au supérieur else options.mana += Math.ceil(m / 3); } } @@ -13311,7 +13337,7 @@ var COFantasy = COFantasy || function() { depMana = depenseManaPossible(personnage, options.mana, msg); if (!depMana) return true; } else { - error("Impossible de savoir qui doit d\xE9penser de la mana", options); + error("Impossible de savoir qui doit dépenser de la mana", options); return true; } } @@ -13320,7 +13346,7 @@ var COFantasy = COFantasy || function() { let utilisations; if (options.limiteParJour) { if (!personnage) { - error("Impossible de savoir \xE0 qui appliquer la limite journali\xE8re", options); + error("Impossible de savoir à qui appliquer la limite journalière", options); return true; } if (options.limiteParJourRessource) @@ -13389,7 +13415,7 @@ var COFantasy = COFantasy || function() { } else sendPerso(personnage, msgCombat, true); } } else { - error("Impossible de savoir \xE0 qui appliquer la limite par combat", options); + error("Impossible de savoir à qui appliquer la limite par combat", options); return true; } } @@ -13428,7 +13454,7 @@ var COFantasy = COFantasy || function() { } else sendPerso(personnage, msgCombat, options.secret); } } else { - error("Impossible de savoir \xE0 qui appliquer la limite par tour", options); + error("Impossible de savoir à qui appliquer la limite par tour", options); return true; } } @@ -13442,7 +13468,7 @@ var COFantasy = COFantasy || function() { setAttrDuree(personnage, options.tempsRecharge.effet, options.tempsRecharge.duree, evt); } } else { - error("Impossible de savoir \xE0 qui s'applique le temps de recharge", options); + error("Impossible de savoir à qui s'applique le temps de recharge", options); return true; } } @@ -13456,7 +13482,7 @@ var COFantasy = COFantasy || function() { } setTokenAttr(personnage, 'dose_' + options.dose, doses - 1, evt); } else { - error("Impossible de savoir qui doit d\xE9penser la dose", options); + error("Impossible de savoir qui doit dépenser la dose", options); return true; } } @@ -13470,7 +13496,7 @@ var COFantasy = COFantasy || function() { } setTokenAttr(personnage, nomAttr, currentAttr + 1, evt); } else { - error("Impossible de savoir \xE0 qui appliquer la limitation", options); + error("Impossible de savoir à qui appliquer la limitation", options); return true; } } @@ -13500,11 +13526,11 @@ var COFantasy = COFantasy || function() { if (personnage) { let test = testLimiteUtilisationsCapa(personnage, pred, 'tour', "ne peut plus utiliser " + pred + " ce tour", - "Action impossible, pas de pr\xE9dicat " + pred); + "Action impossible, pas de prédicat " + pred); if (test === undefined) return true; utiliseCapacite(personnage, test, evt); } else { - error("Impossible de savoir \xE0 qui appliquer la limitation du pr\xE9dicat " + pred, options); + error("Impossible de savoir à qui appliquer la limitation du prédicat " + pred, options); return true; } } @@ -13514,8 +13540,8 @@ var COFantasy = COFantasy || function() { //asynchrone //callback(resultat, crit, roll1, roll2): - // resultat peut \xEAtre 0, 1 ou 2 : 0 = match null, 1 le perso 1 gagne, 2 le perso 2 gagne. - // crit peut \xEAtre 1 si un des deux perso a fait une r\xE9ussite critique et pas l'autre, -1 si un des personnage a fait un \xE9chec critique et pas l'autre, et 0 sinon + // resultat peut être 0, 1 ou 2 : 0 = match null, 1 le perso 1 gagne, 2 le perso 2 gagne. + // crit peut être 1 si un des deux perso a fait une réussite critique et pas l'autre, -1 si un des personnage a fait un échec critique et pas l'autre, et 0 sinon function testOppose(rollId, perso1, carac1, options1, perso2, carac2, options2, explications, evt, callback) { if (carac2 === undefined) carac2 = carac1; let nom1 = nomPerso(perso1); @@ -13555,9 +13581,9 @@ var COFantasy = COFantasy || function() { let texte1 = "Jet " + deCarac(carac1) + " de " + nom1 + " : " + rt1.texte; if (reussite == 2) { if ((carac1 == 'FOR' || carac1 == 'DEX' || carac1 == 'CON') && - attributeAsBool(perso1, 'runeForgesort_\xE9nergie') && - attributeAsInt(perso1, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0) { - texte1 += "
    " + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + rollId + "_roll1", "Rune d'\xE9nergie"); + attributeAsBool(perso1, 'runeForgesort_énergie') && + attributeAsInt(perso1, 'limiteParCombat_runeForgesort_énergie', 1) > 0) { + texte1 += "
    " + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + rollId + "_roll1", "Rune d'énergie"); } if (!rt1.echecCritique && !rt2.critique) { let pcPerso1 = pointsDeChance(perso1); @@ -13587,9 +13613,9 @@ var COFantasy = COFantasy || function() { let texte2 = "Jet " + deCarac(carac2) + " de " + nom2 + " : " + rt2.texte; if (reussite == 1) { if ((carac2 == 'FOR' || carac2 == 'DEX' || carac2 == 'CON') && - attributeAsBool(perso2, 'runeForgesort_\xE9nergie') && - attributeAsInt(perso2, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0) { - texte2 += "
    " + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + rollId + "_roll2", "Rune d'\xE9nergie"); + attributeAsBool(perso2, 'runeForgesort_énergie') && + attributeAsInt(perso2, 'limiteParCombat_runeForgesort_énergie', 1) > 0) { + texte2 += "
    " + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + rollId + "_roll2", "Rune d'énergie"); } if (!rt2.echecCritique && !rt1.critique) { let pcPerso2 = pointsDeChance(perso2); @@ -13617,14 +13643,14 @@ var COFantasy = COFantasy || function() { explications.push(m); }); callback(reussite, crit, rt1.roll, rt2.roll); - }); //Fin du jet du deuxi\xE8me perso + }); //Fin du jet du deuxième perso }); //Fin du jet du premier perso } function bonusPlusViteQueSonOmbre(perso, arme) { let p = predicateAsBool(perso, 'plusViteQueSonOmbre'); if (!p) return 0; - // L'arme doit \xEAtre charg\xE9e + // L'arme doit être chargée if (arme.charge && attributeAsInt(perso, 'charge_' + arme.label, 0) === 0) return 0; if (p === true) { @@ -13643,7 +13669,7 @@ var COFantasy = COFantasy || function() { return 0; } - // prend en compte l'unit\xE9 de mesure utilis\xE9e sur la page + // prend en compte l'unité de mesure utilisée sur la page function ajouteUneLumiere(perso, nomLumiere, radius, dimRadius, evt) { radius = scaleDistance(perso, radius); if (dimRadius !== '') dimRadius = scaleDistance(perso, dimRadius); @@ -13654,7 +13680,7 @@ var COFantasy = COFantasy || function() { let brightLight = radius; if (udl) { if (isNaN(brightLight) || brightLight < 0) { - error("Lumi\xE8re avec un rayon n\xE9gatif", radius); + error("Lumière avec un rayon négatif", radius); return; } } @@ -13662,7 +13688,7 @@ var COFantasy = COFantasy || function() { if (ct.get('bar1_link') === '') attrName += "_" + ct.get('name'); if (ct.get('bar1_max')) { let lumiereSurPerso; - //Cas particulier o\xF9 le personnage est un vrai personnage qui ne fait pas de lumi\xE8re + //Cas particulier où le personnage est un vrai personnage qui ne fait pas de lumière if (!udl && !ct.get('light_radius')) { lumiereSurPerso = true; setToken(ct, 'light_radius', radius, evt); @@ -13707,7 +13733,7 @@ var COFantasy = COFantasy || function() { name: nomLumiere, }); if (tokLumiere === undefined) { - error("Probl\xE8me lors de la cr\xE9ation du token de lumi\xE8re", perso); + error("Problème lors de la création du token de lumière", perso); return; } evt.tokens = [tokLumiere]; @@ -13729,7 +13755,7 @@ var COFantasy = COFantasy || function() { setToken(tokLumiere, 'light_dimradius', dimRadius, evt); setToken(tokLumiere, 'light_otherplayers', true, evt); } - if (ct.get('bar1_max')) { //Lumi\xE8re li\xE9e \xE0 un token + if (ct.get('bar1_max')) { //Lumière liée à un token let attr = createObj('attribute', { characterid: perso.charId, name: attrName, @@ -13739,14 +13765,14 @@ var COFantasy = COFantasy || function() { evt.attributes = [{ attribute: attr, }]; - } else { //cible temporaire, \xE0 effacer + } else { //cible temporaire, à effacer ct.remove(); } } - //renvoie le nom de l'arme si l'arme est d\xE9j\xE0 tenue en main + //renvoie le nom de l'arme si l'arme est déjà tenue en main // options.seulementDroite permet de ne rengainer que l'arme droite - // options.deuxMains permet de prendre une arme \xE0 2 mains + // options.deuxMains permet de prendre une arme à 2 mains function degainerArme(perso, labelArme, evt, options) { let pageId = perso.pageId; if (pageId === undefined) { @@ -13764,11 +13790,11 @@ var COFantasy = COFantasy || function() { nouvelleArme = getWeaponStats(perso, labelArme); if (nouvelleArme && nouvelleArme.armeGauche) options.gauche = true; let nouvelleArmeGauche; - let labelArmeGauche; //d\xE9finie seulement si on d\xE9gaine l'arme gauche - // et toujours diff\xE9rent de labelArme + let labelArmeGauche; //définie seulement si on dégaine l'arme gauche + // et toujours différent de labelArme if (options.armeGaucheLabel) { if (options.armeGaucheLabel == labelArme) { - sendPerso("ne peut d\xE9gainer la m\xEAme arme dans les deux mains"); + sendPerso("ne peut dégainer la même arme dans les deux mains"); return; } if (options.gauche) { @@ -13778,7 +13804,7 @@ var COFantasy = COFantasy || function() { options.gauche = false; //vrai seulement si on ne sort que l'arme gauche nouvelleArme = getWeaponStats(perso, options.armeGaucheLabel); if (nouvelleArme && nouvelleArme.armeGauche) { - sendPerso("ne peut d\xE9gainer 2 armes gauches \xE0 la fois"); + sendPerso("ne peut dégainer 2 armes gauches à la fois"); return; } } else { @@ -13810,7 +13836,7 @@ var COFantasy = COFantasy || function() { if (labelArmeActuelleGauche == labelArme) rienAFaire = true; else { changementDePrise = true; - message += "prend son arme \xE0 deux mains"; + message += "prend son arme à deux mains"; attrArmeActuelle.set('max', labelArme); } } @@ -13820,24 +13846,24 @@ var COFantasy = COFantasy || function() { if (labelArmeActuelle == labelArme) { if (labelArmeActuelleGauche == labelArme) { changementDePrise = true; - message += "prend son arme \xE0 une main"; + message += "prend son arme à une main"; if (!labelArmeGauche) { attrArmeActuelle.set('max', ''); } } else { - if (labelArmeGauche) //on d\xE9gaine 2 armes + if (labelArmeGauche) //on dégaine 2 armes rienAFaire = labelArmeActuelleGauche == labelArmeGauche; else rienAFaire = true; } } } if (rienAFaire) { - //Pas besoin de d\xE9gainer. + //Pas besoin de dégainer. if (options.weaponStats) return options.weaponStats.name; if (nouvelleArme) return nouvelleArme.name; return; } - //On d\xE9gaine une nouvelle arme, il faut rengainer l'ancienne + //On dégaine une nouvelle arme, il faut rengainer l'ancienne if (labelArmeActuelle) { //dans ce cas, pas options.gauche ancienneArme = getWeaponStats(perso, labelArmeActuelle); if (ancienneArme === undefined) { @@ -13885,8 +13911,8 @@ var COFantasy = COFantasy || function() { } } else attrArmeActuelle = undefined; const estMook = perso.token && perso.token.get('bar1_link') === ''; - //Puis on d\xE9gaine - //mais on v\xE9rifie que l'arme existe, sinon c'est juste un ordre de rengainer + //Puis on dégaine + //mais on vérifie que l'arme existe, sinon c'est juste un ordre de rengainer if (nouvelleArme === undefined) { if (attrArmeActuelle) { if (options.seulementDroite && labelArmeActuelleGauche) { @@ -13905,7 +13931,7 @@ var COFantasy = COFantasy || function() { } if (nouvelleArmeGauche) { if (ficheAttributeAsInt(perso, 'defbouclieron', 0)) { - sendPerso(perso, "enl\xE8ve son bouclier", options.secret); + sendPerso(perso, "enlève son bouclier", options.secret); setFicheAttr(perso, 'defbouclieron', 0, evt, { default: 0 }); @@ -13913,7 +13939,7 @@ var COFantasy = COFantasy || function() { } if (nouvelleArme.deuxMains || options.deuxMains) { if (ficheAttributeAsInt(perso, 'defbouclieron', 0)) { - sendPerso(perso, "enl\xE8ve son bouclier", options.secret); + sendPerso(perso, "enlève son bouclier", options.secret); setFicheAttr(perso, 'defbouclieron', 0, evt, { default: 0 }); @@ -13965,17 +13991,17 @@ var COFantasy = COFantasy || function() { } if (options.messages) { if (changementDePrise) { - if (nouvelleArmeGauche) message += ", et d\xE9gaine " + nouvelleArmeGauche.name; + if (nouvelleArmeGauche) message += ", et dégaine " + nouvelleArmeGauche.name; } else { - message += "d\xE9gaine " + nouvelleArme.name; + message += "dégaine " + nouvelleArme.name; if (nouvelleArmeGauche) message += " et " + nouvelleArmeGauche.name; } options.messages.push(message); } else { if (changementDePrise) { - if (nouvelleArmeGauche) message += ", et d\xE9gaine " + nouvelleArmeGauche.name; + if (nouvelleArmeGauche) message += ", et dégaine " + nouvelleArmeGauche.name; } else { - message = "d\xE9gaine " + nouvelleArme.name; + message = "dégaine " + nouvelleArme.name; if (nouvelleArmeGauche) message += " et " + nouvelleArmeGauche.name; } sendPerso(perso, message, options.secret); @@ -14021,7 +14047,7 @@ var COFantasy = COFantasy || function() { }); return !regenPossible; } - //On enl\xE8ve les doublons de cibles qui partagent leurs PVs; + //On enlève les doublons de cibles qui partagent leurs PVs; function enleveDoublonsPartagePV(cibles) { let ciblesAvecPVsPartages = new Set(); //va aussi peupler le champ name des cibles @@ -14040,9 +14066,9 @@ var COFantasy = COFantasy || function() { ciblesAvecPVsPartages.add(cp); }); } else if (persoEstPNJ(target)) { - //cible la moins prioritaire, on l'enl\xE8ve si on trouve un autre repr\xE9sentant + //cible la moins prioritaire, on l'enlève si on trouve un autre représentant let representantPresent = cibles.find(function(target2, index2) { - if (index2 <= index) return false; //d\xE9j\xE0 trait\xE9 + if (index2 <= index) return false; //déjà traité if (target2.name === undefined) { let target2Char = getObj('character', target2.charId); if (target2Char === undefined) return false; @@ -14057,7 +14083,7 @@ var COFantasy = COFantasy || function() { //N'a pas de familier mais n'est pas un PNJ //On cherche si il existe un autre perso plus prioritaire. let representantFamilier = cibles.find(function(target2, index2) { - if (index2 < index) return false; //d\xE9j\xE0 trait\xE9 + if (index2 < index) return false; //déjà traité if (target2.name === undefined) { let target2Char = getObj('character', target2.charId); if (target2Char === undefined) return false; @@ -14071,8 +14097,8 @@ var COFantasy = COFantasy || function() { predicateAsBool(target2, 'guetteur'); }); if (representantFamilier) return false; - ciblePartagee.forEach(function(attr) { - ciblesAvecPVsPartages.add(attr.get('current')); + ciblePartagee.forEach(function(cp) { + ciblesAvecPVsPartages.add(cp); }); } } @@ -14100,11 +14126,11 @@ var COFantasy = COFantasy || function() { //Options automatically set by some attributes if (attributeAsBool(attaquant, 'paralysieRoublard')) { if (attributeAsBool(attaquant, 'enrage')) { - sendPerso(attaquant, "est trop enrag\xE9 pour sentir la douleur"); + sendPerso(attaquant, "est trop enragé pour sentir la douleur"); } else if (predicateAsBool(attaquant, 'proprioception')) { - sendPerso(attaquant, "est immunis\xE9 \xE0 la douleur"); + sendPerso(attaquant, "est immunisé à la douleur"); } else { - sendPerso(attaquant, "ne peut pas attaquer car il est paralys\xE9 de douleur"); + sendPerso(attaquant, "ne peut pas attaquer car il est paralysé de douleur"); attackCallback(options); return; } @@ -14151,7 +14177,7 @@ var COFantasy = COFantasy || function() { weaponStats.attDice = options.dm.dice; weaponStats.attDMBonusCommun = options.dm.bonus; } else if (weaponStats.batarde && weaponStats.deuxMains) { - let dm = parseDice(weaponStats.batarde, 'd\xE9g\xE2ts'); + let dm = parseDice(weaponStats.batarde, 'dégâts'); if (dm) { weaponStats.attNbDices = dm.nbDe; weaponStats.attDice = dm.dice; @@ -14198,7 +14224,7 @@ var COFantasy = COFantasy || function() { if (stats2.divers && stats2.divers.includes('d3')) stats2.attDice = 3; options.tirDouble.stats = stats2; } - //Pour les explosions, la port\xE9e est 0 mais avec un disque + //Pour les explosions, la portée est 0 mais avec un disque if (options.explosion) { if (options.aoe === undefined) { options.aoe = { @@ -14206,7 +14232,7 @@ var COFantasy = COFantasy || function() { rayon: portee }; } else if (options.aoe.type != 'disque') { - error("Option explosion ignor\xE9e, car l'attaque est une aoe qui n'est pas un disque", options); + error("Option explosion ignorée, car l'attaque est une aoe qui n'est pas un disque", options); } } if (portee > 0) { @@ -14233,9 +14259,9 @@ var COFantasy = COFantasy || function() { } options.contact = true; } - //Ce qui peut emp\xEAcher l'attaque quelles que soient les cibles + //Ce qui peut empêcher l'attaque quelles que soient les cibles if (options.avecd12 && ((estAffaibli(attaquant) && !predicateAsBool(attaquant, 'insensibleAffaibli')) || getState(attaquant, 'immobilise'))) { - sendPerso(attaquant, "ne peut pas utiliser cette capacit\xE9 quand il est affaibli."); + sendPerso(attaquant, "ne peut pas utiliser cette capacité quand il est affaibli."); attackCallback(options); return; } @@ -14250,7 +14276,7 @@ var COFantasy = COFantasy || function() { attackCallback(options); return; } - //Pour l'option grenaille implicite, il faut v\xE9rifier que toutes les charge de l'arme sont des charges de grenaille + //Pour l'option grenaille implicite, il faut vérifier que toutes les charge de l'arme sont des charges de grenaille let chargesArme = []; let attackLabel = weaponStats.label; if (attackLabel) { @@ -14318,18 +14344,18 @@ var COFantasy = COFantasy || function() { options.fx = options.fx || effet.id; } if (options.eclairDEnergie && !options.redo) { - //On augmente le nombre de d\xE9s de 1 et on utilise l'attaque magique + //On augmente le nombre de dés de 1 et on utilise l'attaque magique weaponStats.attNbDices++; weaponStats.attSkill = '@{ATKMAG}'; options.contondant = undefined; options.type = 'energie'; options.messages = options.messages || []; - options.messages.push("\xC9clair d'\xE9nergie !"); + options.messages.push("Éclair d'énergie !"); } - //D\xE9termination de la (ou des) cible(s) + //Détermination de la (ou des) cible(s) let nomCiblePrincipale; //Utilise pour le cas mono-cible let cibles = []; - if (options.redo) { //Dans ce cas les cibles sont pr\xE9cis\xE9es dans targetToken + if (options.redo) { //Dans ce cas les cibles sont précisées dans targetToken cibles = targetToken; if (cibles.length === 0) { error("Attaque sans cible", targetToken); @@ -14343,7 +14369,7 @@ var COFantasy = COFantasy || function() { let page; nomCiblePrincipale = targetToken.get('name'); if (options.aoe) { - //cas de la boule de feu qui fait un \xE9chec critique : on d\xE9place la cible si elle est artificielle + //cas de la boule de feu qui fait un échec critique : on déplace la cible si elle est artificielle if (!options.redo && (options.demiAuto || options.toucheDoubleDmg) && (!options.triche || options.triche == 'echecCritique') && targetToken.get('bar1_max') == 0) { // jshint ignore:line @@ -14423,12 +14449,12 @@ var COFantasy = COFantasy || function() { }; } if (targetToken.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir la ligne + //C'est juste un token utilisé pour définir la ligne if (options.fx) { spawnFxBetweenPoints(pta, ptt, options.fx, pageId); } cibles = []; - targetToken.remove(); //On l'enl\xE8ve, normalement plus besoin + targetToken.remove(); //On l'enlève, normalement plus besoin } let allToks = findObjs({ @@ -14445,7 +14471,7 @@ var COFantasy = COFantasy || function() { token: obj, charId: objCharId }; - if (nePeutPlusPrendreDM(cible, options)) return; //pas de d\xE9g\xE2ts aux morts + if (nePeutPlusPrendreDM(cible, options)) return; //pas de dégâts aux morts let distToTrajectory = distancePixTokenSegment(obj, pta, ptt); if (distToTrajectory > (obj.get('width') + obj.get('height')) / 4 + PIX_PER_UNIT / 4) return; @@ -14461,8 +14487,8 @@ var COFantasy = COFantasy || function() { { if (distanceTarget > portee) { sendPlayer(playerName, - "Le centre du disque vis\xE9 est trop loin pour " + weaponName + - " (distance " + distanceTarget + ", port\xE9e " + portee + ")", + "Le centre du disque visé est trop loin pour " + weaponName + + " (distance " + distanceTarget + ", portée " + portee + ")", playerId); attackCallback(options); return; @@ -14490,7 +14516,7 @@ var COFantasy = COFantasy || function() { } let t = attributeAsInt(cadavre, 'a0PVDepuis', 0); if (t < combat.tour - 1) { - sendPlayer(playerName, "La mort de " + nomPerso(cadavre) + " n'est pas assez r\xE9cente", playerId); + sendPlayer(playerName, "La mort de " + nomPerso(cadavre) + " n'est pas assez récente", playerId); attackCallback(options); return; } @@ -14510,7 +14536,7 @@ var COFantasy = COFantasy || function() { }); allToksDisque.forEach(function(obj) { if ((options.explosion || portee === 0) && - obj.id == tokenOrigine.id) return; //on ne se cible pas si le centre de l'aoe est soi-m\xEAme + obj.id == tokenOrigine.id) return; //on ne se cible pas si le centre de l'aoe est soi-même if (obj.get('bar1_max') == 0) return; // jshint ignore:line let objCharId = obj.get('represents'); if (objCharId === '') return; @@ -14518,7 +14544,7 @@ var COFantasy = COFantasy || function() { token: obj, charId: objCharId }; - if (nePeutPlusPrendreDM(cible, options)) return; //pas de d\xE9g\xE2ts aux morts + if (nePeutPlusPrendreDM(cible, options)) return; //pas de dégâts aux morts let distanceCentre = distanceCombat(targetToken, obj, pageId, { strict1: true @@ -14539,10 +14565,10 @@ var COFantasy = COFantasy || function() { cibles.push(cible); }); if (targetToken.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir le disque - targetToken.remove(); //On l'enl\xE8ve, normalement plus besoin + //C'est juste un token utilisé pour définir le disque + targetToken.remove(); //On l'enlève, normalement plus besoin } - // La nouvelle port\xE9e (pour ne rien \xE9liminer \xE0 l'\xE9tape suivante + // La nouvelle portée (pour ne rien éliminer à l'étape suivante portee += options.aoe.rayon; break; } @@ -14553,12 +14579,12 @@ var COFantasy = COFantasy || function() { } let vecCentre = vecteurUnitaire(pta, ptt); let cosAngle = Math.cos(options.aoe.angle * Math.PI / 360.0); - //Pour \xE9viter des artfacts d'arrondi: + //Pour éviter des artfacts d'arrondi: cosAngle = (Math.floor(cosAngle * 1000000)) / 1000000; if (targetToken.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir le cone + //C'est juste un token utilisé pour définir le cone cibles = []; - targetToken.remove(); //On l'enl\xE8ve, normalement plus besoin + targetToken.remove(); //On l'enlève, normalement plus besoin } page = page || getObj("page", pageId); murs = getWalls(page, pageId, murs); @@ -14577,12 +14603,12 @@ var COFantasy = COFantasy || function() { token: obj, charId: objCharId }; - if (nePeutPlusPrendreDM(cible, options)) return; //pas de d\xE9g\xE2ts aux morts + if (nePeutPlusPrendreDM(cible, options)) return; //pas de dégâts aux morts let pt = pointOfToken(obj); let vecObj = vecteurUnitaire(pta, pt); if (vecCentre.x * vecObj.x + vecCentre.y * vecObj.y < cosAngle) return; - // La distance sera compar\xE9e \xE0 la port\xE9e plus loin + // La distance sera comparée à la portée plus loin let objChar = getObj('character', objCharId); if (objChar === undefined) return; if (murs) { @@ -14600,16 +14626,16 @@ var COFantasy = COFantasy || function() { return; } } else { - if (tokenOrigine.id == targetToken.id && !options.echecTotal) { //m\xEAme token pour attaquant et cible + if (tokenOrigine.id == targetToken.id && !options.echecTotal) { //même token pour attaquant et cible sendPerso(attaquant, "s'attaque " + onGenre(attaquant, "lui", "elle") + - "-m\xEAme ? Probablement une erreur \xE0 la s\xE9lection de la cible. On annule"); + "-même ? Probablement une erreur à la sélection de la cible. On annule"); attackCallback(options); return; } let targetCharId = targetToken.get("represents"); if (targetCharId === "") { - error("Le token cibl\xE9 (" + nomCiblePrincipale + ") doit repr\xE9senter un personnage ", targetToken); + error("Le token ciblé (" + nomCiblePrincipale + ") doit représenter un personnage ", targetToken); attackCallback(options); return; } @@ -14635,7 +14661,7 @@ var COFantasy = COFantasy || function() { }); } } - //Les conditions qui peuvent emp\xEAcher l'attaque + //Les conditions qui peuvent empêcher l'attaque if (options.conditionAttaquant !== undefined) { if (!testCondition(options.conditionAttaquant, attaquant, cibles)) { sendPerso(attaquant, "ne peut pas utiliser " + weaponName); @@ -14643,7 +14669,7 @@ var COFantasy = COFantasy || function() { return; } } - //dernieresCiblesAttaquees contient en current les cibles attaqu\xE9es, et en max les cibles sur lesquelles on a fait des ripostes + //dernieresCiblesAttaquees contient en current les cibles attaquées, et en max les cibles sur lesquelles on a fait des ripostes let attrCiblesAttaquees = tokenAttribute(attaquant, 'dernieresCiblesAttaquees'); let ripostesDuTour = new Set(); if (attrCiblesAttaquees.length > 0) { @@ -14664,16 +14690,16 @@ var COFantasy = COFantasy || function() { return false; } if (options.seulementVivant && estNonVivant(target)) { - sendPlayer(playerName, "cette attaque n'affecte que les cr\xE9atures vivantes", playerId); + sendPlayer(playerName, "cette attaque n'affecte que les créatures vivantes", playerId); return false; } if (options.attaqueMentale) { if (predicateAsBool(target, 'sansEsprit')) { - sendPlayer(playerName, "cette attaque n'affecte que les cr\xE9atures pensantes", playerId); + sendPlayer(playerName, "cette attaque n'affecte que les créatures pensantes", playerId); return false; } if (predicateAsBool(target, 'vegetatif')) { - sendPlayer(playerName, "cette attaque n'affecte pas les cr\xE9atures v\xE9g etatives", playerId); + sendPlayer(playerName, "cette attaque n'affecte pas les créatures vég etatives", playerId); return false; } } @@ -14682,14 +14708,14 @@ var COFantasy = COFantasy || function() { return false; } if (attributeAsBool(attaquant, 'tenuADistanceManoeuvre(' + target.token.id + ')')) { - sendPerso(attaquant, "est tenu \xE0 distance de " + nomPerso(target) + ", " + onGenre(attaquant, "il", "elle") + " ne peut pas l'attaquer ce tour."); + sendPerso(attaquant, "est tenu à distance de " + nomPerso(target) + ", " + onGenre(attaquant, "il", "elle") + " ne peut pas l'attaquer ce tour."); return false; } if (charAttributeAsBool(target, 'armeeConjuree')) { return options.attaqueArmeeConjuree; } if (ripostesDuTour.has(target.token.id)) { - sendPerso(attaquant, "a d\xE9j\xE0 fait une riposte contre " + nomPerso(target)); + sendPerso(attaquant, "a déjà fait une riposte contre " + nomPerso(target)); return false; } if (options.ricochets) { @@ -14697,7 +14723,7 @@ var COFantasy = COFantasy || function() { return c.token.id == target.token.id; }); if (dejaTouche) { - sendPerso(attaquant, nomPerso(target) + " a d\xE9j\xE0 \xE9t\xE9 touch\xE9 par un pr\xE9c\xE9dent ricochet de cette attaque"); + sendPerso(attaquant, nomPerso(target) + " a déjà été touché par un précédent ricochet de cette attaque"); return false; } } @@ -14705,7 +14731,7 @@ var COFantasy = COFantasy || function() { }); if (cibles.length === 0) { if (options.aoe) { - sendPlayer(playerName, "aucune cible dans l'aire d'effet de " + weaponName + ", action annul\xE9e", + sendPlayer(playerName, "aucune cible dans l'aire d'effet de " + weaponName + ", action annulée", playerId); } attackCallback(options); @@ -14716,7 +14742,7 @@ var COFantasy = COFantasy || function() { let optDistance = {}; options.portee = portee; if (options.contact) optDistance.allonge = options.allonge; - // Si l'attaquant est mont\xE9, distance mesur\xE9e \xE0 partir de sa monture + // Si l'attaquant est monté, distance mesurée à partir de sa monture if (tokenOrigine.id == attackingToken.id) { let attrMonture = tokenAttribute(attaquant, 'monteSur'); if (attrMonture.length > 0) { @@ -14726,7 +14752,7 @@ var COFantasy = COFantasy || function() { } } cibles = cibles.filter(function(target) { - // Si la cible est mont\xE9e, distance mesur\xE9e vers sa monture + // Si la cible est montée, distance mesurée vers sa monture let pseudoTargetToken = target.token; let attrMonture = tokenAttribute(target, 'monteSur'); if (attrMonture.length > 0) { @@ -14740,7 +14766,7 @@ var COFantasy = COFantasy || function() { if (target.distance > portee && target.msgEsquiveFatale === undefined && !(target.chairACanon || target.intercepter)) { if (options.aoe || options.auto) return false; //distance stricte if (target.distance > (predicateAsBool(attaquant, 'tirParabolique') ? 3 : 2) * portee) return false; - // On peut aller jusqu'\xE0 2x portee si unique cible et jet d'attaque, 3x si le personnage a Tir Parabolique + // On peut aller jusqu'à 2x portee si unique cible et jet d'attaque, 3x si le personnage a Tir Parabolique return true; } if (target.distance === 0 && options.seulementDistance) { @@ -14750,7 +14776,7 @@ var COFantasy = COFantasy || function() { return true; }); } - //On enl\xE8ve les alli\xE9s si l'option saufAllies est active + //On enlève les alliés si l'option saufAllies est active if (options.saufAllies) { let allies = new Set(); allies = alliesParPerso[attaquant.charId] || allies; @@ -14759,7 +14785,7 @@ var COFantasy = COFantasy || function() { return !(allies.has(target.charId)); }); } - //On v\xE9rifie que les cibles sont assez proches les unes des autres + //On vérifie que les cibles sont assez proches les unes des autres if (options.ciblesDansDisque && cibles.length > 1) { let l1, l2, t1, t2; cibles.forEach(function(target) { @@ -14772,7 +14798,7 @@ var COFantasy = COFantasy || function() { }); let maxpix = options.ciblesDansDisque * PIX_PER_UNIT / computeScale(pageId); if ((l2 - l1) > 2 * maxpix || (t2 - t1) > 2 * maxpix) { - sendPlayer(playerName, "Cibles trop \xE9loign\xE9es les unes des autres"); + sendPlayer(playerName, "Cibles trop éloignées les unes des autres"); attackCallback(options); return; } @@ -14783,14 +14809,14 @@ var COFantasy = COFantasy || function() { x: (l1 + l2) / 2, y: (t1 + t2) / 2 }; - //C'est approch\xE9, mais s\xFBrement assez bon pour ce qui nous occupe + //C'est approché, mais sûrement assez bon pour ce qui nous occupe let tropLoin = cibles.some(function(target) { let pt = pointOfToken(target.token); attackCallback(options); return (distancePoints(centre, pt) > maxpix + 1); }); if (tropLoin) { - sendPlayer(playerName, "Cibles trop \xE9loign\xE9es les unes des autres"); + sendPlayer(playerName, "Cibles trop éloignées les unes des autres"); attackCallback(options); return; } @@ -14798,16 +14824,16 @@ var COFantasy = COFantasy || function() { } if (cibles.length === 0) { if (options.aoe) { - sendPlayer(playerName, "aucune cible dans l'aire d'effet de " + weaponName + ", action annul\xE9e", + sendPlayer(playerName, "aucune cible dans l'aire d'effet de " + weaponName + ", action annulée", playerId); return; } if (!options.seulementDistance) { - sendPerso(attaquant, "est hors de port\xE9e de " + nomCiblePrincipale + " pour une attaque utilisant " + weaponName + ", action annul\xE9e"); + sendPerso(attaquant, "est hors de portée de " + nomCiblePrincipale + " pour une attaque utilisant " + weaponName + ", action annulée"); } return; } - //On enl\xE8ve les doublons de cibles qui partagent leurs PVs; + //On enlève les doublons de cibles qui partagent leurs PVs; cibles = enleveDoublonsPartagePV(cibles); let evt = options.evt || { type: "Attaque", @@ -14826,7 +14852,7 @@ var COFantasy = COFantasy || function() { evt.action = evt.action || { options: JSON.parse(JSON.stringify(options)) //pour la chance etc. }; - //On met \xE0 jour l'arme en main, si n\xE9cessaire + //On met à jour l'arme en main, si nécessaire if (weaponStats.arme || weaponStats.armeGauche || (weaponStats.divers && weaponStats.divers.toLowerCase().includes('arme'))) { options.weaponStats = weaponStats; options.messages = options.messages || []; @@ -14837,7 +14863,7 @@ var COFantasy = COFantasy || function() { if (options.contact && weaponStats.arme && predicateAsBool(attaquant, 'frappeDuVide')) { if (attributeAsBool(attaquant, 'limiteParTour_frappeDuVidePossible')) options.frappeDuVide = true; - //Il faut noter la premi\xE8re attaque au contact + //Il faut noter la première attaque au contact setTokenAttr(attaquant, 'limiteParCombat_dejaFrappeContact', true, evt); } let riposte = predicateAsBool(attaquant, 'riposte'); @@ -14845,7 +14871,7 @@ var COFantasy = COFantasy || function() { if (attaqueEnMeute > 0) options.attaqueEnMeute = attaqueEnMeute; options.lienEpique = predicateAsBool(attaquant, 'lienEpique'); if (riposte || options.attaqueEnMeute || options.lienEpique) { - //Dans ce cas, il faut stoquer les cibles attaqu\xE9es + //Dans ce cas, il faut stoquer les cibles attaquées //(dans le cas de riposte, pour ne pas les re-proposer en riposte let listeCibles = cibles.map(function(target) { @@ -14859,7 +14885,7 @@ var COFantasy = COFantasy || function() { } else { setTokenAttr(attaquant, 'dernieresCiblesAttaquees', listeCibles, evt); } - } else { //L'attribut existe d\xE9j\xE0 + } else { //L'attribut existe déjà attrCiblesAttaquees = attrCiblesAttaquees[0]; evt.attributes = evt.attributes || []; let attaquesDuTour = attrCiblesAttaquees.get('current'); @@ -14884,7 +14910,7 @@ var COFantasy = COFantasy || function() { let explications = []; if (options.messages) explications = [...options.messages]; if (options.magieRapide) explications.push("Magie rapide"); - //On fait les tests pour les cibles qui b\xE9n\xE9ficieraient d'un sanctuaire + //On fait les tests pour les cibles qui bénéficieraient d'un sanctuaire let ciblesATraiter = cibles.length; let cibleTraitee = function() { ciblesATraiter--; @@ -14906,10 +14932,10 @@ var COFantasy = COFantasy || function() { let testId = 'sanctuaire_' + cible.token.id; testCaracteristique(attaquant, 'SAG', 15, testId, options, evt, function(tr) { if (tr.reussite) { - cible.messages.push(nomPerso(attaquant) + " r\xE9ussit \xE0 passer outre le sanctuaire de " + nomPerso(cible) + " (jet de SAG " + tr.texte + "≥15)" + tr.modifiers); + cible.messages.push(nomPerso(attaquant) + " réussit à passer outre le sanctuaire de " + nomPerso(cible) + " (jet de SAG " + tr.texte + "≥15)" + tr.modifiers); cibleTraitee(); } else { - let msgRate = "ne peut se r\xE9soudre \xE0 attaquer " + nomPerso(cible) + " (sanctuaire, jet de SAG " + tr.texte + "< 15)" + tr.rerolls + tr.modifiers; + let msgRate = "ne peut se résoudre à attaquer " + nomPerso(cible) + " (sanctuaire, jet de SAG " + tr.texte + "< 15)" + tr.rerolls + tr.modifiers; sendPerso(attaquant, msgRate); attaqueImpossible = true; } @@ -14918,14 +14944,14 @@ var COFantasy = COFantasy || function() { cibleTraitee(); } }; - // Attaque de Disparition avec jet oppos\xE9 + // Attaque de Disparition avec jet opposé if (options.disparition) { - //L'immunit\xE9 aux attaques sournoise est test\xE9e plus loin et ne devrait - //pas emp\xEAcher le bonus de +5 \xE0 l'attaque. + //L'immunité aux attaques sournoise est testée plus loin et ne devrait + //pas empêcher le bonus de +5 à l'attaque. let rollId = 'disparition_' + cible.token.id; let options1 = {...options }; - options1.competence = 'discr\xE9tion'; + options1.competence = 'discrétion'; let options2 = {...options }; options2.competence = 'perception'; @@ -14933,13 +14959,13 @@ var COFantasy = COFantasy || function() { cible.messages, evt, function(resultat, crit, rt1, rt2) { if (resultat != 2) { - cible.messages.push(nomPerso(attaquant) + " r\xE9apparait \xE0 c\xF4t\xE9 de " + nomPerso(cible) + " et lui porte une attaque mortelle !"); + cible.messages.push(nomPerso(attaquant) + " réapparait à côté de " + nomPerso(cible) + " et lui porte une attaque mortelle !"); // rajout des bonus de sournoise options.bonusAttaque = (options.bonusAttaque || 0) + 5; options.sournoise = options.sournoise || 0; options.sournoise += options.disparition; } else { - cible.messages.push(nomPerso(cible) + " rep\xE8re " + nomPerso(attaquant) + " \xE0 temps pour r\xE9agir."); + cible.messages.push(nomPerso(cible) + " repère " + nomPerso(attaquant) + " à temps pour réagir."); } evalSanctuaire(); }); //fin de testOppose (asynchrone) @@ -14951,16 +14977,16 @@ var COFantasy = COFantasy || function() { explications.push("Tentative d'acrobatie pour surprendre " + nomPerso(cible)); testCaracteristique(attaquant, 'DEX', 15, rollId, rollOptions, evt, function(tr, expl) { - explications.push("R\xE9sultat : " + tr.texte + tr.modifiers); + explications.push("Résultat : " + tr.texte + tr.modifiers); expl.forEach(function(m) { explications.push(m); }); if (tr.reussite) { - explications.push("R\xE9ussite : " + nomPerso(attaquant) + " peut faire une attaque sournoise"); + explications.push("Réussite : " + nomPerso(attaquant) + " peut faire une attaque sournoise"); options.sournoise = options.sournoise || 0; options.sournoise += options.attaqueAcrobatique; } else { - explications.push("Rat\xE9, " + nomPerso(attaquant) + " r\xE9alise une attaque normale" + tr.rerolls); + explications.push("Raté, " + nomPerso(attaquant) + " réalise une attaque normale" + tr.rerolls); } evalSanctuaire(); }); @@ -14968,7 +14994,7 @@ var COFantasy = COFantasy || function() { }); } - // On affiche les options d'attaque \xE0 droite + // On affiche les options d'attaque à droite function afficherOptionsAttaque(perso, opt_display) { let action_opts = '!cof-options-d-attaque --target ' + perso.token.id; let text_opts = ''; @@ -14981,11 +15007,11 @@ var COFantasy = COFantasy || function() { } if (ficheAttributeAsInt(perso, 'attaque_risquee_check')) { if (text_opts !== '') text_opts += '
    '; - text_opts += "Risqu\xE9e"; + text_opts += "Risquée"; } if (ficheAttributeAsInt(perso, 'attaque_assuree_check')) { if (text_opts !== '') text_opts += '
    '; - text_opts += "Assur\xE9e"; + text_opts += "Assurée"; } if (ficheAttributeAsInt(perso, 'attaque_dm_temp_check')) { if (text_opts !== '') text_opts += '
    '; @@ -15022,7 +15048,7 @@ var COFantasy = COFantasy || function() { let rawList; if (persoEstPNJ(perso)) rawList = extractRepeating(perso, 'pnjatk'); else rawList = extractRepeating(perso, 'armes'); - let liste = {}; //liste tri\xE9e par label d'attaque + let liste = {}; //liste triée par label d'attaque for (let pref in rawList) { let ra = rawList[pref]; if (ra.armelabel === undefined) ra.armelabel = 0; @@ -15047,7 +15073,7 @@ var COFantasy = COFantasy || function() { let rang = parseInt(ra.actionrang); if (isNaN(rang) || rang < 0) rang = 0; if (actions[rang]) { - error("Plusieurs actions de m\xEAme rang " + rang + " dans la liste d'actions du tour", ra); + error("Plusieurs actions de même rang " + rang + " dans la liste d'actions du tour", ra); continue; } actions[rang] = ra; @@ -15056,11 +15082,11 @@ var COFantasy = COFantasy || function() { return actions; } - // on r\xE9cup\xE8re la valeur de l'action dont chaque Macro #/Ability % est mis dans un tableau 'action' + // on récupère la valeur de l'action dont chaque Macro #/Ability % est mis dans un tableau 'action' //Pour chaque action, on a une commande, un texte et des options. //On appelle f(commande, texte, macros, attackStats) - // le dernier argument est optionnel, et n'est l\xE0 que pour \xE9viter d'avoir \xE0 recalculer attackStats - //actionsDuTour peut \xEAtre un nombre entre 0 et 4 (listes sur la fiche), ou + // le dernier argument est optionnel, et n'est là que pour éviter d'avoir à recalculer attackStats + //actionsDuTour peut être un nombre entre 0 et 4 (listes sur la fiche), ou // une ability function treatActions(perso, actionsDuTour, abilities, f) { let actions; // La liste des actions @@ -15121,7 +15147,7 @@ var COFantasy = COFantasy || function() { } else { actionCode = action.trim(); if (actionCode === '') return; - if (actionCode.startsWith('//')) return; //Ligne comment\xE9e + if (actionCode.startsWith('//')) return; //Ligne commentée } let actionCommands = actionCode.split(' '); actionCommands = actionCommands.filter(function(c) { @@ -15198,7 +15224,7 @@ var COFantasy = COFantasy || function() { case '!options': found = true; if (actionCommands.length > 1) { - options = actionCode.substring(8); //d\xE9marre par ' ' + options = actionCode.substring(8); //démarre par ' ' } break; case '!attaques': @@ -15246,8 +15272,8 @@ var COFantasy = COFantasy || function() { if (found) { actionsAAfficher = true; } else { - // Si on n'a toujours rien trouv\xE9, on ajoute un petit log - log('Ability et macro non trouv\xE9 : ' + actionCode); + // Si on n'a toujours rien trouvé, on ajoute un petit log + log('Ability et macro non trouvé : ' + actionCode); } }); } @@ -15272,7 +15298,7 @@ var COFantasy = COFantasy || function() { } else if (action == 'Attaques en traitre') { actions = findListeActions(attaquant, 'AttaqueEnTraitre', abilities); if (actions === undefined) - actions = findListeActions(attaquant, 'Attaques en tra\xEEtre', abilities); + actions = findListeActions(attaquant, 'Attaques en traître', abilities); } } let actionsOpportunite = []; @@ -15296,7 +15322,7 @@ var COFantasy = COFantasy || function() { }); actionsOpportunite.reverse(); } else { - //On affiche l'attaque avec l'arme en main + les attaques naturelles coch\xE9es + //On affiche l'attaque avec l'arme en main + les attaques naturelles cochées let listeAttaques = listAllAttacks(attaquant); for (let label in listeAttaques) { let arme = listeAttaques[label]; @@ -15318,14 +15344,14 @@ var COFantasy = COFantasy || function() { retarde: true, }; afficherOptionsAttaque(attaquant, opt_display); - //On cr\xE9e un display sans le header + //On crée un display sans le header let display = startFramedDisplay(undefined, "Attaque " + type + " possible", attaquant, opt_display); cibles.forEach(function(target) { - if (target.name === undefined) { //TODO v\xE9rifier que c'est utile + if (target.name === undefined) { //TODO vérifier que c'est utile let targetChar = getObj('character', target.charId); if (targetChar === undefined) { - error('Impossible de trouver le personnage repr\xE9sentant ' + nomPerso(target), target); + error('Impossible de trouver le personnage représentant ' + nomPerso(target), target); return; } target.name = targetChar.get('name'); @@ -15347,15 +15373,15 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, bouton(cmd, action.text, attaquant)); }); }); - // on envoie la liste aux joueurs qui g\xE8rent l'attaquant + // on envoie la liste aux joueurs qui gèrent l'attaquant let playerIds = getPlayerIds(attaquant); playerIds.forEach(function(playerid) { addFramedHeader(display, playerid, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); if (playerIds.length === 0) { addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } @@ -15403,15 +15429,15 @@ var COFantasy = COFantasy || function() { function immuniseAsphyxie(target, expliquer) { if (predicateAsBool(target, 'creatureArtificielle') || estNonVivant(target)) { - if (expliquer) expliquer("L'asphyxie est sans effet sur une cr\xE9ature non-vivante"); + if (expliquer) expliquer("L'asphyxie est sans effet sur une créature non-vivante"); return true; } if (estDemon(target)) { - if (expliquer) expliquer("L'asphyxie est sans effet sur un d\xE9mon"); + if (expliquer) expliquer("L'asphyxie est sans effet sur un démon"); return true; } if (predicateAsBool(target, 'vegetatif')) { - if (expliquer) expliquer("L'asphyxie est sans effet sur une cr\xE9ature v\xE9g\xE9tative"); + if (expliquer) expliquer("L'asphyxie est sans effet sur une créature végétative"); return true; } return false; @@ -15434,9 +15460,9 @@ var COFantasy = COFantasy || function() { // Fonction asynchrone // displayRes est optionnel, et peut avoir 2 arguments - // - un texte affichant le jet de d\xE9g\xE2ts - // - la valeur finale des d\xE9g\xE2ts inflig\xE9s - // crit est un bool\xE9en, il augmente de 1 (ou options.critCoef) le coefficient (option.dmgCoef) et active certains effets + // - un texte affichant le jet de dégâts + // - la valeur finale des dégâts infligés + // crit est un booléen, il augmente de 1 (ou options.critCoef) le coefficient (option.dmgCoef) et active certains effets function dealDamage(target, dmg, otherDmg, evt, crit, options, explications, displayRes) { if (options === undefined) options = {}; let expliquer = function(msg) { @@ -15452,7 +15478,7 @@ var COFantasy = COFantasy || function() { (options.aoe === undefined && attributeAsBool(target, 'formeGazeuse')) || (predicateAsBool(target, 'apparition') && !options.energiePositive)) { - expliquer("L'attaque passe \xE0 travers de " + nomPerso(target)); + expliquer("L'attaque passe à travers de " + nomPerso(target)); if (displayRes) displayRes('0', 0, 0); return 0; } @@ -15477,7 +15503,7 @@ var COFantasy = COFantasy || function() { options.aoe.type == 'cone' && predicateAsBool(options.attaquant, 'ennemiDuBatonDesRunesMortes') && predicateAsBool(target, 'batonDesRunesMortes') && attributeAsBool(target, 'runeLizura')) { - expliquer("Lizura => immunit\xE9 au souffle de " + nomPerso(options.attaquant)); + expliquer("Lizura => immunité au souffle de " + nomPerso(options.attaquant)); if (displayRes) displayRes('0', 0, 0); return 0; } @@ -15488,7 +15514,7 @@ var COFantasy = COFantasy || function() { if (target.diviseDmg) diviseDmg *= target.diviseDmg; if (options.attaquant && predicateAsBool(options.attaquant, 'creatureDeLHiver') && predicateAsBool(target, 'armeDeLEte')) { diviseDmg += 4; - expliquer("L'arme de l'\xE9t\xE9 divise les d\xE9g\xE2ts de l'attaque"); + expliquer("L'arme de l'été divise les dégâts de l'attaque"); } if (options.attaqueEnEtantGobe) diviseDmg *= 2; if (options.sortilege && predicateAsBool(target, 'esquiveDeLaMagie')) @@ -15506,25 +15532,25 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(target, 'armureLourdeGuerrier') && ficheAttributeAsBool(target, 'defarmureon', false) && ficheAttributeAsInt(target, 'defarmure', 0) >= 7) { - expliquer("L'armure lourde de " + nomPerso(target) + " lui permet d'ignorer les d\xE9g\xE2ts critiques"); + expliquer("L'armure lourde de " + nomPerso(target) + " lui permet d'ignorer les dégâts critiques"); } else if (predicateAsBool(target, 'immuniteAuxCritiques')) { - expliquer("Le succ\xE8s critique est sans effet"); + expliquer("Le succès critique est sans effet"); } else { if (options.critCoef) critCoef = options.critCoef; if (target.critCoef) critCoef += target.critCoef; dmgCoef += critCoef; if (predicateAsBool(target, 'armureProtection') && ficheAttributeAsBool(target, 'defarmureon', false)) { - expliquer("L'armure de protection de " + nomPerso(target) + " le prot\xE8ge du critique"); + expliquer("L'armure de protection de " + nomPerso(target) + " le protège du critique"); diviseDmg++; } else if (predicateAsBool(target, 'bouclierProtection') && ficheAttributeAsInt(target, 'defbouclieron', 0)) { - expliquer("Le bouclier de protection de " + nomPerso(target) + " le prot\xE8ge du critique"); + expliquer("Le bouclier de protection de " + nomPerso(target) + " le protège du critique"); diviseDmg++; } else if (predicateAsBool(target, 'anneauProtection')) { - expliquer("L'anneau de protection de " + nomPerso(target) + " le prot\xE8ge du critique"); + expliquer("L'anneau de protection de " + nomPerso(target) + " le protège du critique"); diviseDmg++; } if (predicateAsBool(target, 'bouclierProtection') && ficheAttributeAsBool(target, 'defbouclieron', false)) { - expliquer("Le bouclier de protection de " + nomPerso(target) + " le prot\xE8ge du critique"); + expliquer("Le bouclier de protection de " + nomPerso(target) + " le protège du critique"); diviseDmg++; } } @@ -15590,13 +15616,13 @@ var COFantasy = COFantasy || function() { dmgTotal = x.dmgTotal; } addToDmgTotal(0, dmgTotal, dmg, expliquer, evt); - //On trie les DM suppl\xE9mentaires selon leur type + //On trie les DM supplémentaires selon leur type let dmgParType = {}; otherDmg.forEach(function(d) { if (_.has(dmgParType, d.type)) dmgParType[d.type].push(d); else dmgParType[d.type] = [d]; }); - // Dommages de m\xEAme type que le principal, mais \xE0 part, donc non affect\xE9s par les critiques + // Dommages de même type que le principal, mais à part, donc non affectés par les critiques let mainDmgType = dmg.type; let dmgExtra = dmgParType[mainDmgType]; if (dmgExtra && dmgExtra.length > 0 && !immuniseAuType(target, mainDmgType, options.attaquant)) { @@ -15630,8 +15656,8 @@ var COFantasy = COFantasy || function() { // Effets quand on rentre en combat // attaquant est optionnel - // exlications doit \xEAtre d\xE9fini - // ne rajoute pas evt \xE0 l'historique + // exlications doit être défini + // ne rajoute pas evt à l'historique // revoie stateCOF.combat, garanti non false function entrerEnCombat(attaquant, cibles, explications, evt) { let selected = []; @@ -15674,7 +15700,7 @@ var COFantasy = COFantasy || function() { return initiative(selected, evt); //ne recalcule pas l'init } - //capa est le nom d'un pr\xE9dicat. Si le pr\xE9dicat est num\xE9rique, cela donne + //capa est le nom d'un prédicat. Si le prédicat est numérique, cela donne //la limite, sinon la limite est 1 // retourne // - utilisations: les nombre d'utilisations restantes, @@ -15696,7 +15722,7 @@ var COFantasy = COFantasy || function() { attribut = attribut[0]; utilisations = parseInt(attribut.get('current')); if (isNaN(utilisations)) { - error("Resource pour " + capa + " mal form\xE9e", attribut); + error("Resource pour " + capa + " mal formée", attribut); return; } } @@ -15886,7 +15912,7 @@ var COFantasy = COFantasy || function() { return attCar + ficheAttributeAsInt(attaquant, 'niveau', 1) + attDiv; } - //Retourne le label de l'attaque \xE0 l'arme de jet. + //Retourne le label de l'attaque à l'arme de jet. function estAussiArmeDeJet(options) { if (options.startsWith('-')) options = ' ' + options; options = options.split(' --'); @@ -15981,7 +16007,7 @@ var COFantasy = COFantasy || function() { }, }); } else { - let exprDuree = parseDice(value, 'dur\xE9e'); + let exprDuree = parseDice(value, 'durée'); let duree = randomInteger(6); if (exprDuree) { if (exprDuree.nbDe <= 0) { @@ -16008,7 +16034,7 @@ var COFantasy = COFantasy || function() { } else { error("Type de poison " + typePoison + " non reconnu.", poisonAttr); } - explications.push("L'arme est empoisonn\xE9e"); + explications.push("L'arme est empoisonnée"); return defPoison; } @@ -16021,7 +16047,7 @@ var COFantasy = COFantasy || function() { let nombreMunitionsEmpoisonnees = parseInt(infosPoisonMunitions.substring(index + 1)); if (!isNaN(seuil) && !isNaN(nombreMunitionsEmpoisonnees) && nombreMunitionsEmpoisonnees > 0) { let defPoison = effetPoison(poisonAttr, seuil, attaquant, explications, options); - explications.push("L'arme est empoisonn\xE9e"); + explications.push("L'arme est empoisonnée"); if (nombreMunitionsEmpoisonnees == 1) { evt.deletedAttributes = evt.deletedAttributes || []; evt.deletedAttributes.push(poisonAttr); @@ -16038,15 +16064,15 @@ var COFantasy = COFantasy || function() { } } - //N'ajoute pas evt \xE0 l'historique + //N'ajoute pas evt à l'historique function resoudreAttaque(attaquant, cibles, attackLabel, weaponName, weaponStats, playerId, pageId, evt, explications, options, chargesArme) { let attackingCharId = attaquant.charId; let attackingToken = attaquant.token; let attackerTokName = nomPerso(attaquant); - attaquant.additionalDmg = [...options.additionalDmg]; // Reset du calcul des dommages additionnels li\xE9s \xE0 l'attaquant + attaquant.additionalDmg = [...options.additionalDmg]; // Reset du calcul des dommages additionnels liés à l'attaquant let sujetAttaquant = onGenre(attaquant, 'il', 'elle'); if (options.contact) { - //Prise en compte du corps \xE9l\xE9mentaire + //Prise en compte du corps élémentaire let typeCorpsElem = predicateAsBool(attaquant, 'corpsElementaire'); if (typeCorpsElem && typeCorpsElem !== true) { let nbDes = predicateAsInt(attaquant, 'nbCorpsElementaire', 1); @@ -16061,7 +16087,7 @@ var COFantasy = COFantasy || function() { // Les armes de jet if (weaponStats.armeDeJet && !estMook && !(options.ricochets && options.ricochets.cibles.length > 0)) { if (weaponStats.nbArmesDeJet < 1) { - sendPerso(attaquant, "plus de " + weaponName + " \xE0 lancer."); + sendPerso(attaquant, "plus de " + weaponName + " à lancer."); return; } let attrName = weaponStats.prefixe + 'armejetqte'; @@ -16077,12 +16103,12 @@ var COFantasy = COFantasy || function() { if (attr.length > 0) { attr = attr[0]; if (attr.length > 1) { - error("Plus d'un attribut pour la quantit\xE9 d'armes de jet", attr); + error("Plus d'un attribut pour la quantité d'armes de jet", attr); attr[1].remove(); } max = parseInt(attr.get('max')); if (isNaN(max) || max < 1) { - error("Maximum de " + weaponName + " mal form\xE9, v\xE9rifier sur la fiche", attr); + error("Maximum de " + weaponName + " mal formé, vérifier sur la fiche", attr); max = 1; } evt.attributes.push({ @@ -16101,19 +16127,19 @@ var COFantasy = COFantasy || function() { attribute: attr, }); } - //On cherche si l'arme de jet est empoison\xE9e + //On cherche si l'arme de jet est empoisonée let poisonAttr = tokenAttribute(attaquant, 'enduitDePoison_' + attackLabel); effetPoisonSurMunitions(poisonAttr, attaquant, explications, options, evt); let restant = weaponStats.nbArmesDeJet; if (randomInteger(100) < weaponStats.tauxDePerte) { if (weaponStats.tauxDePerte < 100) - explications.push(weaponName + " n'est pas r\xE9cup\xE9rable"); + explications.push(weaponName + " n'est pas récupérable"); attr.set('max', max - 1); options.armeDeJetPerdue = true; } restant--; attr.set('current', restant); - if (!options.armeDeJetPerdue) { //pr\xE9pare pour un \xE9ventuel retour en main + if (!options.armeDeJetPerdue) { //prépare pour un éventuel retour en main options.attrArmeDeJet = { attribute: attr, restant: restant @@ -16122,33 +16148,33 @@ var COFantasy = COFantasy || function() { if (restant === 0) { degainerArmeLancee(attaquant, attackLabel, evt); } - explications.push("Il reste " + restant + " " + weaponName + " \xE0 " + attackerTokName); + explications.push("Il reste " + restant + " " + weaponName + " à " + attackerTokName); } } if (options.aussiArmeDeJet && !estMook) { let armeAssociee = getWeaponStats(attaquant, options.aussiArmeDeJet); if (armeAssociee && armeAssociee.armeDeJet) { if (armeAssociee.nbArmesDeJet < 1) { - sendPerso(attaquant, "a d\xE9j\xE0 lanc\xE9 tous ses " + weaponName); + sendPerso(attaquant, "a déjà lancé tous ses " + weaponName); return; } } else { - error("L'arme de label " + options.aussiArmeDeJet + " n'est pas une arme de jet, option ignor\xE9e", armeAssociee); + error("L'arme de label " + options.aussiArmeDeJet + " n'est pas une arme de jet, option ignorée", armeAssociee); } } // Munitions if (options.munition) { if (estMook) { - error("Les munitions ne sont pas support\xE9es pour les tokens qui ne sont pas li\xE9es \xE0 un personnage", attackingToken); + error("Les munitions ne sont pas supportées pour les tokens qui ne sont pas liées à un personnage", attackingToken); } - if (options.munition.nom) { //Ancienne variante, obsol\xE8te depuis mars 2023 + if (options.munition.nom) { //Ancienne variante, obsolète depuis mars 2023 let munitionsAttr = findObjs({ _type: 'attribute', _characterid: attackingCharId, name: 'munition_' + options.munition.nom }); if (munitionsAttr.length === 0) { - sendPerso(attaquant, ": Pas de munition nomm\xE9e " + options.munition.nom); + sendPerso(attaquant, ": Pas de munition nommée " + options.munition.nom); return; } munitionsAttr = munitionsAttr[0]; @@ -16161,7 +16187,7 @@ var COFantasy = COFantasy || function() { } let munitionsMax = parseInt(munitionsAttr.get('max')); if (isNaN(munitionsMax)) { - error("Attribut de munitions mal form\xE9", munitionsMax); + error("Attribut de munitions mal formé", munitionsMax); return; } evt.attributes = evt.attributes || []; @@ -16170,7 +16196,7 @@ var COFantasy = COFantasy || function() { current: munitions, max: munitionsMax }); - //On cherche si la munition est empoisonn\xE9e + //On cherche si la munition est empoisonnée let poisonAttr = tokenAttribute(attaquant, 'enduitDePoison_munition_' + options.munition.nom); effetPoisonSurMunitions(poisonAttr, attaquant, explications, options, evt); munitions--; @@ -16180,12 +16206,12 @@ var COFantasy = COFantasy || function() { if (randomInteger(100) < options.munition.taux) munitionsMax--; } explications.push("Il reste " + munitions + " " + - options.munition.nom.replace(/_/g, ' ') + " \xE0 " + attackerTokName); + options.munition.nom.replace(/_/g, ' ') + " à " + attackerTokName); munitionsAttr.set('current', munitions); munitionsAttr.set('max', munitionsMax); } else { //Utilisation d'une munition de la fiche let m = options.munition; - let typeMunition = fieldAsString(m, 'typemunition', 'Fl\xE8che'); + let typeMunition = fieldAsString(m, 'typemunition', 'Flèche'); let nom = fieldAsString(m, 'nommunition', typeMunition); let munitions = fieldAsInt(m, 'qtemunition', 1); if (munitions < 1 || (options.tirDouble && munitions < 2)) { @@ -16195,7 +16221,7 @@ var COFantasy = COFantasy || function() { return; } let label = fieldAsString(m, 'labelmunition', '0'); - //On cherche si la munition est empoisonn\xE9e + //On cherche si la munition est empoisonnée let poisonAttr = tokenAttribute(attaquant, 'enduitDePoison_munition_' + label); effetPoisonSurMunitions(poisonAttr, attaquant, explications, options, evt); let munitionsMax = fieldAsInt(m, 'qtemunition_max', munitions); @@ -16219,8 +16245,8 @@ var COFantasy = COFantasy || function() { } else { msgm += "reste " + munitions + " "; } - msgm += nom + " \xE0 " + attackerTokName; - if (taux < 100 && perte > 0) msgm += ", et la munition utilis\xE9e n'est pas r\xE9cup\xE9rable"; + msgm += nom + " à " + attackerTokName; + if (taux < 100 && perte > 0) msgm += ", et la munition utilisée n'est pas récupérable"; explications.push(msgm); evt.attributes = evt.attributes || []; let name = m.prefixe + 'qtemunition'; @@ -16253,7 +16279,7 @@ var COFantasy = COFantasy || function() { } } } - // Armes charg\xE9es + // Armes chargées if (options.semonce === undefined && options.tirDeBarrage === undefined) { if (attackLabel && weaponStats && weaponStats.charge) { let currentCharge = 0; @@ -16261,7 +16287,7 @@ var COFantasy = COFantasy || function() { currentCharge = parseInt(chargesArme[0].get('current')); } if (isNaN(currentCharge) || currentCharge < 1) { - sendPerso(attaquant, "ne peut pas attaquer avec " + weaponName + " car elle n'est pas charg\xE9e"); + sendPerso(attaquant, "ne peut pas attaquer avec " + weaponName + " car elle n'est pas chargée"); return; } if (options.tirDouble && @@ -16269,7 +16295,7 @@ var COFantasy = COFantasy || function() { currentCharge < 2) { sendPerso(attaquant, "ne peut pas faire de tir double avec ses" + weaponName + "s car " + - sujetAttaquant + " n'en a pas au moins 2 charg\xE9es"); + sujetAttaquant + " n'en a pas au moins 2 chargées"); return; } evt.attributes = evt.attributes || []; @@ -16278,7 +16304,7 @@ var COFantasy = COFantasy || function() { if (chargesGrenaille.length > 0) { let currentChargeGrenaille = parseInt(chargesGrenaille[0].get('current')); if (isNaN(currentChargeGrenaille) || currentChargeGrenaille < 1) { - sendPerso(attaquant, "ne peut pas attaquer avec " + weaponName + " car elle n'est pas charg\xE9e en grenaille"); + sendPerso(attaquant, "ne peut pas attaquer avec " + weaponName + " car elle n'est pas chargée en grenaille"); return; } if (options.tirDouble && @@ -16286,7 +16312,7 @@ var COFantasy = COFantasy || function() { currentChargeGrenaille < 2) { sendPerso(attaquant, "ne peut pas faire de tir double de grenaille avec ses" + weaponName + "s car " + - sujetAttaquant + " n'en a pas au moins 2 charg\xE9es de grenaille"); + sujetAttaquant + " n'en a pas au moins 2 chargées de grenaille"); return; } evt.attributes.push({ @@ -16307,7 +16333,7 @@ var COFantasy = COFantasy || function() { if (options.tirDouble && (!options.tirDouble.stats || options.tirDouble.label == attackLabel)) currentCharge -= 2; else currentCharge -= 1; - //Si l'arme n'est plus charg\xE9e, on peut perdre le bonus d'initiative + //Si l'arme n'est plus chargée, on peut perdre le bonus d'initiative if (currentCharge === 0 && bonusPlusViteQueSonOmbre(attaquant, weaponStats)) { updateNextInit(attaquant); @@ -16325,7 +16351,7 @@ var COFantasy = COFantasy || function() { if (chargesSecondeArme.length > 0) { let currentCharge2 = parseInt(chargesSecondeArme[0].get('current')); if (isNaN(currentCharge2) || currentCharge2 < 1) { - sendPerso(attaquant, "ne peut pas faire de tir double avec " + secondNom + " car ce n'est pas charg\xE9"); + sendPerso(attaquant, "ne peut pas faire de tir double avec " + secondNom + " car ce n'est pas chargé"); return; } evt.attributes = evt.attributes || []; @@ -16334,7 +16360,7 @@ var COFantasy = COFantasy || function() { if (chargesGrenaille2.length > 0) { let currentChargeGrenaille2 = parseInt(chargesGrenaille2[0].get('current')); if (isNaN(currentChargeGrenaille2) || currentChargeGrenaille2 < 1) { - sendPerso(attaquant, "ne peut pas faire de tir double avec " + secondNom + " car ce n'est pas charg\xE9 en grenaille"); + sendPerso(attaquant, "ne peut pas faire de tir double avec " + secondNom + " car ce n'est pas chargé en grenaille"); return; } evt.attributes.push({ @@ -16358,9 +16384,9 @@ var COFantasy = COFantasy || function() { } // Effets quand on rentre en combat entrerEnCombat(attaquant, cibles, explications, evt); - // On commence par le jet d'attaque de base : juste le ou les d\xE9s d'attaque - // et le modificateur d'arme et de caract\xE9ritiques qui apparaissent dans - // la description de l'attaque. Il faut quand m\xEAme tenir compte des + // On commence par le jet d'attaque de base : juste le ou les dés d'attaque + // et le modificateur d'arme et de caractéritiques qui apparaissent dans + // la description de l'attaque. Il faut quand même tenir compte des // chances de critique let crit = critEnAttaque(attaquant, weaponStats, options); let dice = 20; @@ -16376,7 +16402,7 @@ var COFantasy = COFantasy || function() { } } else if (getState(attaquant, 'immobilise')) { dice = 12; - explications.push("Attaquant immobilis\xE9 => D12 au lieu de D20 en Attaque"); + explications.push("Attaquant immobilisé => D12 au lieu de D20 en Attaque"); } else if (attributeAsBool(attaquant, 'mortMaisNAbandonnePas')) { dice = 12; explications.push("Attaquant mort mais n'abandonne pas => D12 au lieu de D20 en Attaque"); @@ -16400,7 +16426,7 @@ var COFantasy = COFantasy || function() { if (options.avantage !== undefined) { if (options.avantage > 0) nbDe = options.avantage; else { - nbDe = 2 - options.avantage; //d\xE9savantage + nbDe = 2 - options.avantage; //désavantage plusFort = false; } } @@ -16417,7 +16443,7 @@ var COFantasy = COFantasy || function() { // toEvaluateAttack inlines // 0: attack roll // 1: attack skill expression - // 2: d\xE9 de poudre + // 2: dé de poudre let toEvaluateAttack = attackExpression(attaquant, nbDe, dice, crit, plusFort, weaponStats); if (options.poudre) toEvaluateAttack += " [[1d20]]"; @@ -16456,17 +16482,17 @@ var COFantasy = COFantasy || function() { retarde: options.secret, auto: options.auto || options.ouvertureMortelle }); - // Cas des armes \xE0 poudre + // Cas des armes à poudre if (options.poudre && !predicateAsBool(attaquant, 'chimiste')) { let poudreNumber = rollNumber(afterEvaluateAttack[2]); let dePoudre = rollsAttack.inlinerolls[poudreNumber].results.total; explications.push( - "D\xE9 de poudre : " + buildinline(rollsAttack.inlinerolls[poudreNumber])); + "Dé de poudre : " + buildinline(rollsAttack.inlinerolls[poudreNumber])); if (dePoudre === 1) { evt.succes = false; if (d20roll === 1) { explications.push( - weaponName + " explose ! L'arme est compl\xE8tement d\xE9truite"); + weaponName + " explose ! L'arme est complètement détruite"); sendChat("", "[[2d6]]", function(res) { let rolls = res[0]; let explRoll = rolls.inlinerolls[0]; @@ -16487,7 +16513,7 @@ var COFantasy = COFantasy || function() { } else { explications.push( "La poudre explose dans " + weaponName + - ". L'arme est inutilisable jusqu'\xE0 la fin du combat"); + ". L'arme est inutilisable jusqu'à la fin du combat"); sendChat("", "[[1d6]]", function(res) { let rolls = res[0]; let explRoll = rolls.inlinerolls[0]; @@ -16524,7 +16550,7 @@ var COFantasy = COFantasy || function() { options.projection = true; } } - //Modificateurs en Attaque qui ne d\xE9pendent pas de la cible + //Modificateurs en Attaque qui ne dépendent pas de la cible let attBonusCommun = 0; if (!options.auto) { attBonusCommun = @@ -16535,7 +16561,7 @@ var COFantasy = COFantasy || function() { } if (options.traquenard) { if (attributeAsBool(attaquant, 'traquenardImpossible')) { - sendPerso(attaquant, "ne peut pas faire de traquenard, car ce n'est pas sa premi\xE8re attaque du combat"); + sendPerso(attaquant, "ne peut pas faire de traquenard, car ce n'est pas sa première attaque du combat"); return; } options.traquenard = persoInit(attaquant, evt); @@ -16543,27 +16569,27 @@ var COFantasy = COFantasy || function() { if (predicateAsBool(attaquant, 'traquenard') && !attributeAsBool(attaquant, 'traquenardImpossible')) { setTokenAttr(attaquant, 'traquenardImpossible', true, evt); } - if (options.feinte) explications.push("Mais c'\xE9tait une feinte..."); + if (options.feinte) explications.push("Mais c'était une feinte..."); let mainDmgType = options.type || 'normal'; if (options.sortilege) options.ignoreObstacles = true; let echecCritique; - //Calcul des cibles touch\xE9es + //Calcul des cibles touchées //(et on ajuste le jet pour la triche) let ciblesTouchees = []; let count = cibles.length; cibles.forEach(function(target) { - // reset les champs de target qui vont \xEAtre recalcul\xE9s + // reset les champs de target qui vont être recalculés target.additionalDmg = []; target.effets = []; target.dmgCoef = 0; target.critCoef = 0; target.diviseDmg = 1; if (attributeAsBool(attaquant, 'menaceManoeuvre(' + target.token.id + ')')) { - explications.push(nomPerso(attaquant) + " attaque " + nomPerso(target) + " malgr\xE9 la menace. " + nomPerso(target) + " a droit \xE0 une attaque au contact gratuite."); + explications.push(nomPerso(attaquant) + " attaque " + nomPerso(target) + " malgré la menace. " + nomPerso(target) + " a droit à une attaque au contact gratuite."); removeTokenAttr(attaquant, 'menaceManoeuvre(' + target.token.id + ')', evt); setTokenAttr(attaquant, 'attaqueMalgreMenace(' + target.token.id + ')', 1, evt); } else if (attributeAsBool(attaquant, 'menaceManoeuvre(' + target.token.id + ',crit)')) { - explications.push(nomPerso(attaquant) + " attaque " + nomPerso(target) + " malgr\xE9 la menace. " + nomPerso(target) + " a droit \xE0 une attaque au contact gratuite (DM x 2 !)."); + explications.push(nomPerso(attaquant) + " attaque " + nomPerso(target) + " malgré la menace. " + nomPerso(target) + " a droit à une attaque au contact gratuite (DM x 2 !)."); removeTokenAttr(attaquant, 'menaceManoeuvre(' + target.token.id + ',crit)', evt); setTokenAttr(attaquant, 'attaqueMalgreMenace(' + target.token.id + ')', 2, evt); } @@ -16587,7 +16613,7 @@ var COFantasy = COFantasy || function() { target.percute = target.percute || options.percute; target.maxDmg = target.maxDmg || options.maxDmg; target.kiai = target.kiai || options.kiai; - //Les bonus d'attaque qui d\xE9pendent de la cible + //Les bonus d'attaque qui dépendent de la cible let bad = 0; if (!options.auto) bad = bonusAttaqueD(attaquant, target, weaponStats.portee, pageId, evt, target.messages, options); @@ -16596,7 +16622,7 @@ var COFantasy = COFantasy || function() { let amm = 'attaqueMalgreMenace(' + attaquant.token.id + ')'; if (options.contact && cibles.length == 1) { if (attributeAsBool(target, amm)) { - target.messages.push('Attaque automatique suite \xE0 une menace ignor\xE9e'); + target.messages.push('Attaque automatique suite à une menace ignorée'); options.auto = true; if (attributeAsInt(target, amm, 1) > 1) options.dmFoisDeux = true; target.additionalDmg.push({ @@ -16615,9 +16641,9 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '2' + options.d6 }); - target.messages.push(attackerTokName + " fait un traquenard \xE0 " + nomPerso(target)); + target.messages.push(attackerTokName + " fait un traquenard à " + nomPerso(target)); } else { - target.messages.push(attackerTokName + " n'est pas assez rapide pour faire un traquenard \xE0 " + nomPerso(target)); + target.messages.push(attackerTokName + " n'est pas assez rapide pour faire un traquenard à " + nomPerso(target)); } } let defautCuirasse = @@ -16650,7 +16676,7 @@ var COFantasy = COFantasy || function() { } let touche = true; let critique = false; - // Calcule si touch\xE9, et les messages de d\xE9gats et attaque + // Calcule si touché, et les messages de dégats et attaque if (options.auto) { addAttackSound("soundAttackSucces", weaponStats.divers, options); } else if (!options.interposer) { @@ -16714,7 +16740,7 @@ var COFantasy = COFantasy || function() { if (target.chatimentDuMale) { target.chatimentDuMaleRoll = target.chatimentDuMaleRoll || randomInteger(dice); target.chatimentDuMaleLowRoll = target.chatimentDuMaleRoll; - target.messages.push("B\xE9n\xE9diction de Ma\xEBdra => relance \xE0 " + target.chatimentDuMaleRoll + " du jet d'attaque contre un m\xE2le"); + target.messages.push("Bénédiction de Maëdra => relance à " + target.chatimentDuMaleRoll + " du jet d'attaque contre un mâle"); if (target.chatimentDuMaleRoll > targetd20roll) { targetd20roll = target.chatimentDuMaleRoll; target.chatimentDuMaleLowRoll = target.d20roll; @@ -16727,11 +16753,11 @@ var COFantasy = COFantasy || function() { if (getState(target, 'paralyse')) { paralyse = true; if (!options.attaqueAssuree) - target.messages.push("Cible paralys\xE9e => r\xE9ussite critique automatique"); + target.messages.push("Cible paralysée => réussite critique automatique"); } else if (getState(target, 'mort')) { paralyse = true; if (!options.attaqueAssuree) - target.messages.push("Cible inconsciente => r\xE9ussite critique automatique"); + target.messages.push("Cible inconsciente => réussite critique automatique"); } if (targetd20roll >= 15) { if (predicateAsBool(attaquant, 'champion')) @@ -16750,13 +16776,13 @@ var COFantasy = COFantasy || function() { setTokenAttr(attaquant, 'etreinteImmole', idName(target), evt); setTokenAttr(target, 'etreinteImmolePar', idName(attaquant), evt); setState(target, 'immobilise', true, evt); - target.messages.push(nomPerso(attaquant) + " \xE9treint " + nomPerso(target) + " et s'immole !"); + target.messages.push(nomPerso(attaquant) + " étreint " + nomPerso(target) + " et s'immole !"); target.etreinteImmole = true; } if (options.etreinteScorpion) { setTokenAttr(attaquant, 'etreinteScorpionSur', idName(target), evt); setTokenAttr(target, 'etreinteScorpionPar', idName(attaquant), evt); - target.messages.push(nomPerso(attaquant) + " \xE9treint " + nomPerso(target) + " !"); + target.messages.push(nomPerso(attaquant) + " étreint " + nomPerso(target) + " !"); } if (targetd20roll >= 16 && options.contact) { let ecraser = predicateAsBool(attaquant, 'ecraser'); @@ -16777,7 +16803,7 @@ var COFantasy = COFantasy || function() { } let faireMouche; if (targetd20roll == 1 && options.chance === undefined) { - attackResult = " => \xE9chec critique"; + attackResult = " => échec critique"; attackResult += addAttackImg("imgAttackEchecCritique", weaponStats.divers, options); addAttackSound('soundAttackEchecCritique', weaponStats.divers, options); if (options.demiAuto) { @@ -16796,7 +16822,7 @@ var COFantasy = COFantasy || function() { } else if ((paralyse || options.ouvertureMortelle || targetd20roll == 20 || (targetd20roll >= target.crit && attackRoll >= defense) || (reglesOptionelles.divers.val.coups_critiques_etendus.val && attackRoll > defense + 9)) && !options.attaqueAssuree) { - attackResult = " => r\xE9ussite critique"; + attackResult = " => réussite critique"; attackResult += addAttackImg("imgAttackSuccesCritique", weaponStats.divers, options); addAttackSound('soundAttackSuccesCritique', weaponStats.divers, options); touche = true; @@ -16813,12 +16839,12 @@ var COFantasy = COFantasy || function() { } resetTenacite(attaquant, target, evt); } else if (options.champion || targetd20roll == 20 || paralyse) { - attackResult = " => succ\xE8s"; + attackResult = " => succès"; attackResult += addAttackImg("imgAttackSuccesChampion", weaponStats.divers, options); addAttackSound("soundAttackSuccesChampion", weaponStats.divers, options); resetTenacite(attaquant, target, evt); } else if (attackRoll < defense && targetd20roll < target.crit) { - attackResult = " => \xE9chec"; + attackResult = " => échec"; attackResult += addAttackImg("imgAttackEchec", weaponStats.divers, options); addAttackSound('soundAttackEchec', weaponStats.divers, options); evt.succes = false; @@ -16834,8 +16860,8 @@ var COFantasy = COFantasy || function() { } else touche = false; increaseTenacite(attaquant, target, evt); } else if (targetd20roll % 2 && attributeAsBool(target, 'clignotement')) { - target.messages.push(nomPerso(target) + " dispara\xEEt au moment o\xF9 l'attaque aurait du l" + onGenre(target, 'e', 'a') + " toucher"); - attackResult = " => \xE9chec"; + target.messages.push(nomPerso(target) + " disparaît au moment où l'attaque aurait du l" + onGenre(target, 'e', 'a') + " toucher"); + attackResult = " => échec"; attackResult += addAttackImg("imgAttackEchecClignotement", weaponStats.divers, options); addAttackSound('soundAttackEchecClignotement', weaponStats.divers, options); target.clignotement = true; @@ -16849,8 +16875,8 @@ var COFantasy = COFantasy || function() { target.dmgCoef--; evt.succes = false; } else touche = false; - } else { // Touch\xE9 normal - attackResult = " => succ\xE8s"; + } else { // Touché normal + attackResult = " => succès"; attackResult += addAttackImg("imgAttackSucces", weaponStats.divers, options); addAttackSound("soundAttackSucces", weaponStats.divers, options); resetTenacite(attaquant, target, evt); @@ -16863,7 +16889,7 @@ var COFantasy = COFantasy || function() { else if (attBonus < 0) bonusTexte += attBonus; if (ficheAttributeAsBool(attaquant, 'jets_caches', false)) { attRollValue = attackRoll; - sendChat('COF', "/w GM Jet cach\xE9 d'attaque : " + buildinline(rollsAttack.inlinerolls[attRollNumber]) + bonusTexte); + sendChat('COF', "/w GM Jet caché d'attaque : " + buildinline(rollsAttack.inlinerolls[attRollNumber]) + bonusTexte); } else { attRollValue = buildinline(rollsAttack.inlinerolls[attRollNumber]) + bonusTexte; } @@ -16919,7 +16945,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '2' + options.d6 }); - target.messages.push("Ch\xE2timent du m\xE2le => +2d6 DM"); + target.messages.push("Châtiment du mâle => +2d6 DM"); } } if (predicateAsBool(attaquant, 'batonDesRunesMortes') && attributeAsBool(attaquant, 'runeMelianil')) { @@ -16931,7 +16957,7 @@ var COFantasy = COFantasy || function() { target.messages.push("Melianil => +1d6 DM"); } if (attributeAsBool(target, 'momentDePerfection')) { - target.messages.push("Gr\xE2ce \xE0 son instant de perfection, " + nomPerso(target) + " \xE9vite le coup !"); + target.messages.push("Grâce à son instant de perfection, " + nomPerso(target) + " évite le coup !"); touche = false; evt.succes = false; } @@ -16944,7 +16970,7 @@ var COFantasy = COFantasy || function() { } } else { //Effet si on ne touche pas if (attributeAsBool(attaquant, 'momentDePerfection')) { - target.messages.push("Gr\xE2ce \xE0 son instant de perfection, " + nomPerso(attaquant) + " touche !"); + target.messages.push("Grâce à son instant de perfection, " + nomPerso(attaquant) + " touche !"); touche = true; evt.succes = true; } else { @@ -16996,18 +17022,18 @@ var COFantasy = COFantasy || function() { let id = target.rollImageDecalee; if (id.val > 4) { target.touche = false; - target.messages.push(id.roll + ": l'attaque passe \xE0 travers l'image de " + nomPerso(target)); + target.messages.push(id.roll + ": l'attaque passe à travers l'image de " + nomPerso(target)); } else { - target.messages.push(id.roll + ": malgr\xE9 l'image l\xE9g\xE8rement d\xE9cal\xE9e de " + nomPerso(target) + " l'attaque touche"); + target.messages.push(id.roll + ": malgré l'image légèrement décalée de " + nomPerso(target) + " l'attaque touche"); } } else if (predicateAsBool(target, 'estUneIllusion')) { target.touche = false; - target.messages.push(nomPerso(target) + " disparait et se mat\xE9rialise un peu plus loin"); + target.messages.push(nomPerso(target) + " disparait et se matérialise un peu plus loin"); } } if (target.touche) { ciblesTouchees.push(target); - //Possibilit\xE9s d'annuler l'attaque + //Possibilités d'annuler l'attaque if (!options.pasDeDmg && isActive(target) && attributeAsBool(target, 'runeForgesort_protection') && attributeAsInt(target, 'limiteParCombat_runeForgesort_protection', 1) > 0) { @@ -17016,7 +17042,7 @@ var COFantasy = COFantasy || function() { options.preDmg[target.token.id].runeForgesort_protection = true; } if (!options.auto) { - //Seulement si elle n'est pas automatiquement r\xE9ussie + //Seulement si elle n'est pas automatiquement réussie if (isActive(target)) { if (!options.pasDeDmg && options.contact && !options.ignoreTouteRD) { @@ -17075,7 +17101,7 @@ var COFantasy = COFantasy || function() { } if (!options.aoe && capaciteDisponible(target, 'esquiveFatale', 'combat')) { if (target.ennemisAuContact === undefined) { - error(nomPerso(target) + " a la possibilit\xE9 d'une esquive fatale, mais les ennemis au contact ne sont pas calcul\xE9s", target); + error(nomPerso(target) + " a la possibilité d'une esquive fatale, mais les ennemis au contact ne sont pas calculés", target); } else { let ciblesEsquiveFatale = target.ennemisAuContact.filter(function(tok) { return (tok.id != attaquant.token.id); @@ -17131,7 +17157,7 @@ var COFantasy = COFantasy || function() { options.preDmg[target.token.id] = options.preDmg[target.token.id] || {}; options.preDmg[target.token.id].chairACanon = target.chairACanon; } - //Interception par un alli\xE9 + //Interception par un allié let alliesAvecInterception = []; if (target.alliesAuContact === undefined) { let allies = alliesParPerso[target.charId] || new Set(); @@ -17158,6 +17184,7 @@ var COFantasy = COFantasy || function() { charId: ci }; if (!isActive(perso)) return; + if (getState(perso, 'renverse')) return; if (persoImmobilise(perso) && distanceCombat(tok, attaquant.token, pageId) > 0) return; @@ -17180,7 +17207,7 @@ var COFantasy = COFantasy || function() { alliesAvecInterception.push(perso); }); } - //On enl\xE8ve les alli\xE9s qui sont cibles de l'attaque + //On enlève les alliés qui sont cibles de l'attaque alliesAvecInterception = alliesAvecInterception.filter(function(p) { return cibles.every(function(c) { return c.token.id != p.token.id; @@ -17214,11 +17241,11 @@ var COFantasy = COFantasy || function() { } resolvePreDmgOptions(attaquant, ciblesTouchees, echecCritique, attackLabel, weaponStats, d20roll, display, options, evt, explications, pageId, cibles); } - }, true); //comme on est dans une boucle qui d\xE9pend de la cible, inTarget doit \xEAtre vrai - }); //fin de d\xE9termination de toucher des cibles + }, true); //comme on est dans une boucle qui dépend de la cible, inTarget doit être vrai + }); //fin de détermination de toucher des cibles }); // fin du jet d'attaque asynchrone } catch (e) { - error("Erreur pendant l'\xE9valuation de " + toEvaluateAttack + " du test d'attaque", weaponStats); + error("Erreur pendant l'évaluation de " + toEvaluateAttack + " du test d'attaque", weaponStats); log(e.name + ": " + e.message); } } @@ -17229,11 +17256,11 @@ var COFantasy = COFantasy || function() { function stringOfEtat(etat, perso) { if (etat == 'invisible') return etat; - else if (etat == 'penombre') return "dans la p\xE9nombre"; + else if (etat == 'penombre') return "dans la pénombre"; else if (etat == 'chef') return "est un leader"; let etext = etat; if (etat.endsWith('e')) { - etext = etat.substring(0, etat.length - 1) + '\xE9'; + etext = etat.substring(0, etat.length - 1) + 'é'; } if (perso === undefined) return etext; return etext + eForFemale(perso); @@ -17326,7 +17353,7 @@ var COFantasy = COFantasy || function() { function computeAttackDice(d, maxDmg, options) { if (isNaN(d) || d < 0) { - error("D\xE9 d'attaque incorrect", d); + error("Dé d'attaque incorrect", d); return 0; } let attDice = d; @@ -17385,7 +17412,7 @@ var COFantasy = COFantasy || function() { if (attCarBonus < 1) attCarBonus = ''; else attCarBonus = " +" + attCarBonus; } else { - target.messages.push(nomPerso(target) + " semble immunis\xE9 aux armes ordinaires"); + target.messages.push(nomPerso(target) + " semble immunisé aux armes ordinaires"); attNbDicesCible = 0; attCarBonus = ''; attDMBonus = ''; @@ -17396,7 +17423,7 @@ var COFantasy = COFantasy || function() { return addOrigin(attaquant.name, attNbDicesCible + symbde + attDiceCible + attCarBonus + attDMBonus); } - //retourne le mod de la caract\xE9ristique x, undefined si ce n'en est pas une + //retourne le mod de la caractéristique x, undefined si ce n'en est pas une function computeCarValue(perso, x) { switch (x) { case '@{FOR}': @@ -17470,7 +17497,7 @@ var COFantasy = COFantasy || function() { } sides = sides.split('|'); if (side < 0 || side >= sides.length) { - error("Le token de " + nomPerso(perso) + " n'a pas de face num\xE9ro " + side, sides); + error("Le token de " + nomPerso(perso) + " n'a pas de face numéro " + side, sides); return; } let oldSide = token.get('currentSide'); @@ -17482,44 +17509,44 @@ var COFantasy = COFantasy || function() { return oldSide; } - //Met un effet temporaire sur target. L'effet temporaire est sp\xE9cifi\xE9 dans ef + //Met un effet temporaire sur target. L'effet temporaire est spécifié dans ef // - effet : le nom de l'effet - // - whisper : true si on doit chuchoter l'effet, undefined si on n'affiche pas (mais dans ce cas, target.messages doit \xEAtre d\xE9fini) - // - duree : true si c'est un effet \xE0 dur\xE9e en tours - // - effetIndetermine : true si l'effet a une dur\xE9e ind\xE9termin\xE9e (pas combat) - // - accumuleDuree : si la dur\xE9e peut s'accumuler - // - typeDmg : le type de d\xE9g\xE2ts associ\xE9 \xE0 l'effet, si pertinent + // - whisper : true si on doit chuchoter l'effet, undefined si on n'affiche pas (mais dans ce cas, target.messages doit être défini) + // - duree : true si c'est un effet à durée en tours + // - effetIndetermine : true si l'effet a une durée indéterminée (pas combat) + // - accumuleDuree : si la durée peut s'accumuler + // - typeDmg : le type de dégâts associé à l'effet, si pertinent // - message : la structure de messages (venant de messageEffetTemp ou autre) - // - dm : l'effet fait des d\xE9g\xE2ts + // - dm : l'effet fait des dégâts // - visible : l'effet est visible - // - prejudiciable : l'effet est pr\xE9judiciable (et donc cible de d\xE9livrance) - // - statusMarker : marker associ\xE9 \xE0 l'effet + // - prejudiciable : l'effet est préjudiciable (et donc cible de délivrance) + // - statusMarker : marker associé à l'effet // - pasDeMessageDActivation : pour ne pas afficher le message d'activation - // - image : lien d'une image \xE0 afficher - // - valeur : valeur associ\xE9e \xE0 l'effet - // - valeurMax : champ max de l'attribut valeur associ\xE9 \xE0 l'effet - // - saveParTour : caract\xE9ristiques du save par tour, si besoin. - // - saveActifParTour : caract\xE9ristiques du save actif par tour, si besoin. - // - attaquant : la personne \xE0 l'origine de l'effet - // - options : des options \xE0 mettre dans l'attribut d'options - // - tokenSide : change le c\xF4t\xE9 du token \xE0 cette face + // - image : lien d'une image à afficher + // - valeur : valeur associée à l'effet + // - valeurMax : champ max de l'attribut valeur associé à l'effet + // - saveParTour : caractéristiques du save par tour, si besoin. + // - saveActifParTour : caractéristiques du save actif par tour, si besoin. + // - attaquant : la personne à l'origine de l'effet + // - options : des options à mettre dans l'attribut d'options + // - tokenSide : change le côté du token à cette face function setEffetTemporaire(target, ef, duree, evt, options) { if (ef.effet == 'dedoublement') { if (attributeAsBool(target, 'dedouble') || attributeAsBool(target, 'dedoublement')) { if (ef.whisper !== undefined) { - whisperChar(target.charId, "a d\xE9j\xE0 \xE9t\xE9 d\xE9doubl\xE9 pendant ce combat"); + whisperChar(target.charId, "a déjà été dédoublé pendant ce combat"); } else { - target.messages.push(nomPerso(target) + " a d\xE9j\xE0 \xE9t\xE9 d\xE9doubl\xE9 pendant ce combat"); + target.messages.push(nomPerso(target) + " a déjà été dédoublé pendant ce combat"); } return; } let dedoubleMsg = - "Un double translucide de " + nomPerso(target) + " appara\xEEt."; + "Un double translucide de " + nomPerso(target) + " apparaît."; if (ef.attaquant) { dedoubleMsg += " Il est aux ordres de " + nomPerso(ef.attaquant); } - if (stateCOF.options.affichage.val.duree_effets.val) dedoubleMsg += " (" + duree + " tour" + ((duree>1)?'s':'') +")"; + if (stateCOF.options.affichage.val.duree_effets.val) dedoubleMsg += " (" + duree + " tour" + ((duree > 1) ? 's' : '') + ")"; if (ef.whisper !== undefined) { if (ef.whisper === true) { whisperChar(target.charId, dedoubleMsg); @@ -17542,12 +17569,12 @@ var COFantasy = COFantasy || function() { if (estImmuniseAEffet(target, ef.effet)) { if (ef.whisper !== undefined) { if (ef.whisper === true) { - whisperChar(target.charId, "ne peut pas \xEAtre affect\xE9 par l'effet de " + ef.effet); + whisperChar(target.charId, "ne peut pas être affecté par l'effet de " + ef.effet); } else { - sendChar(target.charId, ef.whisper + "ne peut pas \xEAtre affect\xE9 par l'effet de " + ef.effet); + sendChar(target.charId, ef.whisper + "ne peut pas être affecté par l'effet de " + ef.effet); } } else { - target.messages.push(nomPerso(target) + " ne peut pas \xEAtre affect\xE9 par l'effet de " + ef.effet); + target.messages.push(nomPerso(target) + " ne peut pas être affecté par l'effet de " + ef.effet); } return; } @@ -17595,7 +17622,7 @@ var COFantasy = COFantasy || function() { accumuleAttr.set('current', duree + ',' + dureeAccumulee); } } - return; //Pas besoin de r\xE9appliquer, effet toujours en cours + return; //Pas besoin de réappliquer, effet toujours en cours } } let targetMsg = ''; @@ -17659,7 +17686,7 @@ var COFantasy = COFantasy || function() { setState(target, 'invisible', true, evt); break; case 'aspectDuDemon': - //On retire l'autre aspect du N\xE9cromancien si il est pr\xE9sent + //On retire l'autre aspect du Nécromancien si il est présent finDEffetDeNom(target, "aspectDeLaSuccube", evt); break; case 'aspectDeLaSuccube': @@ -17750,10 +17777,10 @@ var COFantasy = COFantasy || function() { } } - // Applique toutes les options de preDmg d\xE9j\xE0 s\xE9lectionn\xE9es - // Retourne vrai si l'option "continuer" a d\xE9j\xE0 \xE9t\xE9 choisie + // Applique toutes les options de preDmg déjà sélectionnées + // Retourne vrai si l'option "continuer" a déjà été choisie function resolvePreDmgOptions(attaquant, ciblesTouchees, echecCritique, attackLabel, weaponStats, d20roll, display, options, evt, explications, pageId, cibles) { - //Sauvegarde de l'\xE9tat pour pouvoir relancer au niveau de cette fonction + //Sauvegarde de l'état pour pouvoir relancer au niveau de cette fonction evt.action.currentOptions = options; evt.action.echecCritique = echecCritique; evt.action.attackLabel = attackLabel; @@ -17818,7 +17845,7 @@ var COFantasy = COFantasy || function() { if (preDmgToken.evitementGenerique && preDmgToken.evitementGenerique.length > 0) { let nbEvitementsGenerique = preDmgToken.evitementGenerique.length; let finaliseTargetPreDmg = function(msg, generalMsg) { - if (generalMsg !== '' && !continuer && !termineCible) { // rerolls uniquement si pas termin\xE9 + if (generalMsg !== '' && !continuer && !termineCible) { // rerolls uniquement si pas terminé explications.push(msg + generalMsg); } else { cible.messages.push(msg); @@ -17849,7 +17876,7 @@ var COFantasy = COFantasy || function() { }); if (regardPetrifiant && attributeAsBool(attaquant, 'detournerLeRegard') && getIntValeurOfEffet(attaquant, 'detournerLeRegard', 2) > 4) { - sendPerso(attaquant, "aper\xE7oit " + nomPerso(regardPetrifiant) + " \xE0 travers ses paupi\xE8res !"); + sendPerso(attaquant, "aperçoit " + nomPerso(regardPetrifiant) + " à travers ses paupières !"); let seuil = predicateAsInt(regardPetrifiant, 'regardPetrifiant', 0, 16) - 4; let commande = '!cof-effet petrifie --save CON ' + seuil + ' --lanceur ' + regardPetrifiant.token.id + ' --target ' + attaquant.token.id; @@ -17903,7 +17930,7 @@ var COFantasy = COFantasy || function() { let source = drains.find(function(d) { let sa = d.split(':'); if (sa.length != 2) { - log("Drain de sang mal form\xE9 : " + drains); + log("Drain de sang mal formé : " + drains); return false; } return attr.some(function(a) { @@ -17945,7 +17972,7 @@ var COFantasy = COFantasy || function() { }); let attackerTokName = nomPerso(attaquant); if (ciblesTouchees.length === 0 || options.test || options.feinte) { - //\xC9valuation finale pour le cas o\xF9 l'attaque a rat\xE9 + //Évaluation finale pour le cas où l'attaque a raté evalITE(attaquant, undefined, d20roll, options, 1, evt, explications, options, function() { if (options.attrArmeDeJet) { if (options.retourneEnMain) { @@ -17963,7 +17990,7 @@ var COFantasy = COFantasy || function() { options.attrArmeDeJet.attribute.set('current', options.attrArmeDeJet.restant + 1); explications.push(attackerTokName + " rattrape " + weaponStats.name); } else { - explications.push("Rat\xE9 ! Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " \xE0 " + attackerTokName); + explications.push("Raté ! Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " à " + attackerTokName); if (options.attrArmeDeJet.restant === 0) { degainerArmeLancee(attaquant, attackLabel, evt); } @@ -17975,7 +18002,7 @@ var COFantasy = COFantasy || function() { options.attrArmeDeJet.attribute.set('current', options.attrArmeDeJet.restant + 1); explications.push(weaponStats.name + " retourne dans la main de son lanceur"); } else { - explications.push("Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " \xE0 " + attackerTokName); + explications.push("Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " à " + attackerTokName); if (options.attrArmeDeJet.restant === 0) { degainerArmeLancee(attaquant, attackLabel, evt); } @@ -17988,12 +18015,12 @@ var COFantasy = COFantasy || function() { const attackingCharId = attaquant.charId; const attackingToken = attaquant.token; options.attaquant = attaquant; - //Les d\xE9g\xE2ts - //D\xE9g\xE2ts insrits sur la ligne de l'arme + //Les dégâts + //Dégâts insrits sur la ligne de l'arme let mainDmgType = options.type || 'normal'; let attNbDices = weaponStats.attNbDices; if (isNaN(attNbDices) || attNbDices < 0) { - error("D\xE9s de l'attaque incorrect", attNbDices); + error("Dés de l'attaque incorrect", attNbDices); return; } if (attNbDices) { @@ -18010,7 +18037,7 @@ var COFantasy = COFantasy || function() { } } } - // Les autres modifications aux d\xE9g\xE2ts qui ne d\xE9pendent pas de la cible + // Les autres modifications aux dégâts qui ne dépendent pas de la cible let attDMBonusCommun = ''; if (options.armeMagiquePlus) { attDMBonusCommun += " + " + options.armeMagiquePlus; @@ -18083,7 +18110,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '1' + options.d6, }); - explications.push("M\xEAme pas mal => +1" + options.d6 + " DM"); + explications.push("Même pas mal => +1" + options.d6 + " DM"); } if (!options.auto && options.attaqueEnPuissance) { attaquant.additionalDmg.push({ @@ -18113,18 +18140,18 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '1' + options.d6 }); - explications.push("Attaque \xE0 outrance => +1d6 DM"); + explications.push("Attaque à outrance => +1d6 DM"); } else { attaquant.additionalDmg.push({ type: mainDmgType, value: '2' + options.d6 }); - explications.push("Attaque \xE0 outrance => +2d6 DM"); + explications.push("Attaque à outrance => +2d6 DM"); } } if (attaquant.bonusCapitaine) attDMBonusCommun += " +" + attaquant.bonusCapitaine; - // Les autres sources de d\xE9g\xE2ts + // Les autres sources de dégâts if (options.distance) { if (options.semonce) { attaquant.additionalDmg.push({ @@ -18141,7 +18168,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(attaquant, 'forceDeGeant')) { let bonusForceDeGeant = getIntValeurOfEffet(attaquant, 'forceDeGeant', 2); attDMBonusCommun += "+" + bonusForceDeGeant; - explications.push("Force de g\xE9ant => +" + bonusForceDeGeant + " aux DM"); + explications.push("Force de géant => +" + bonusForceDeGeant + " aux DM"); } if (options.frappeDuVide) { attaquant.additionalDmg.push({ @@ -18230,7 +18257,7 @@ var COFantasy = COFantasy || function() { explications.push(msgChampion); } ///////////////////////////////////////////////////////////////// - //Tout ce qui d\xE9pend de la cible + //Tout ce qui dépend de la cible let ciblesCount = ciblesTouchees.length; //Pour l'asynchronie let attaquesEnTraitrePossibles = {}; let finCibles = function() { @@ -18247,7 +18274,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, expl, 80); }); if (target.osBrises) { - addLineToFramedDisplay(display, nomPerso(target) + " a des os bris\xE9s "); + addLineToFramedDisplay(display, nomPerso(target) + " a des os brisés "); setTokenAttr(target, 'osBrises', true, evt); } }); @@ -18256,15 +18283,15 @@ var COFantasy = COFantasy || function() { let voleur = persoOfId(vid); if (voleur === undefined) continue; if (capaciteDisponible(voleur, 'attaqueEnTraitre')) { - displayAttaqueOpportunite(vid, attaquesEnTraitrePossibles[vid], "en tra\xEEtre", 'Attaques en traitre', '--decrLimitePredicatParTour attaqueEnTraitre'); + displayAttaqueOpportunite(vid, attaquesEnTraitrePossibles[vid], "en traître", 'Attaques en traitre', '--decrLimitePredicatParTour attaqueEnTraitre'); } } } }; - //Le lien \xE9pique (+1d6 DM si les 2 attaquent la m\xEAme cible + //Le lien épique (+1d6 DM si les 2 attaquent la même cible let attaqueParLienEpique = new Set(); if (options.lienEpique) { - //On cherche les autres personnages avec le m\xEAme lien \xE9pique + //On cherche les autres personnages avec le même lien épique let allChars = findObjs({ type: 'character' }); @@ -18281,7 +18308,7 @@ var COFantasy = COFantasy || function() { }); } ciblesTouchees.forEach(function(target) { - //l'\xE9valuation finale des conditions quand on sait si l'attaque a touch\xE9. + //l'évaluation finale des conditions quand on sait si l'attaque a touché. evalITE(attaquant, target, d20roll, options, 1, evt, explications, options, function() { target.attaquant = attaquant; if (options.attrArmeDeJet) { @@ -18289,7 +18316,7 @@ var COFantasy = COFantasy || function() { options.attrArmeDeJet.attribute.set('current', options.attrArmeDeJet.restant + 1); explications.push(weaponStats.name + " retourne dans la main de son lanceur"); } else { - explications.push("Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " \xE0 " + attackerTokName); + explications.push("Il reste " + options.attrArmeDeJet.restant + " " + weaponStats.name + " à " + attackerTokName); if (options.attrArmeDeJet.restant === 0) { degainerArmeLancee(attaquant, attackLabel, evt); } @@ -18298,7 +18325,7 @@ var COFantasy = COFantasy || function() { } if (options.enveloppe !== undefined) { if (options.enveloppe.type == 'etreinte' && attributeAsBool(target, 'armureDEau')) { - target.messages.push("L'armure d'eau emp\xEAche " + nomPerso(target) + " d'\xEAtre \xE9treint"); + target.messages.push("L'armure d'eau empêche " + nomPerso(target) + " d'être étreint"); } else { let ligneEnveloppe = nomPerso(attaquant) + " peut "; let commandeEnvelopper = @@ -18306,7 +18333,7 @@ var COFantasy = COFantasy || function() { options.enveloppe.difficulte + ' ' + options.enveloppe.type + ' ' + options.enveloppe.expression; let verbeEnv = 'envelopper'; - if (options.enveloppe.type == 'etreinte') verbeEnv = '\xE9treindre'; + if (options.enveloppe.type == 'etreinte') verbeEnv = 'étreindre'; ligneEnveloppe += boutonSimple(commandeEnvelopper, verbeEnv); ligneEnveloppe += nomPerso(target); target.messages.push(ligneEnveloppe); @@ -18314,7 +18341,7 @@ var COFantasy = COFantasy || function() { } if (options.agripper) { if (attributeAsBool(target, 'armureDEau')) { - target.messages.push("L'armure d'eau emp\xEAche " + nomPerso(target) + " d'\xEAtre aggrip\xE9"); + target.messages.push("L'armure d'eau empêche " + nomPerso(target) + " d'être aggripé"); } else { let immobilise = estAussiGrandQue(attaquant, target); setTokenAttr(attaquant, 'agrippe', idName(target), evt); @@ -18322,7 +18349,7 @@ var COFantasy = COFantasy || function() { maxVal: immobilise }); if (immobilise) setState(target, 'immobilise', true, evt); - target.messages.push("est agripp\xE9"); + target.messages.push("est agrippé"); } } if (options.devorer) { @@ -18331,13 +18358,13 @@ var COFantasy = COFantasy || function() { let cmdAttaqueGratuite = '!cof-attack ' + attaquant.token.id + ' ' + target.token.id + ' ' + attackLabel; target.messages.push(boutonSimple(cmdAttaqueGratuite, 'Attaque gratuite')); } else { - target.messages.push(nomPerso(attaquant) + " a droit \xE0 une attaque gratuite contre " + nomPerso(target)); + target.messages.push(nomPerso(attaquant) + " a droit à une attaque gratuite contre " + nomPerso(target)); } let attackerForce = valAttribute(attaquant, 'FOR', 'force'); let targetForce = valAttribute(target, 'FOR', 'force'); if (targetForce <= attackerForce) { if (attributeAsBool(target, 'armureDEau')) { - target.messages.push("L'armure d'eau emp\xEAche " + nomPerso(target) + " d'\xEAtre saisi"); + target.messages.push("L'armure d'eau empêche " + nomPerso(target) + " d'être saisi"); } else { setState(target, 'renverse', true, evt); setState(target, 'immobilise', true, evt); @@ -18347,7 +18374,7 @@ var COFantasy = COFantasy || function() { } } if (options.attaqueViolente) { - target.messages.push(nomPerso(attaquant) + " fait une attaque violente. Jet de force oppos\xE9 pour voir si " + nomPerso(target) + " se fait projeter"); + target.messages.push(nomPerso(attaquant) + " fait une attaque violente. Jet de force opposé pour voir si " + nomPerso(target) + " se fait projeter"); target.effets.push({ attaqueViolente: true, save: true @@ -18356,25 +18383,25 @@ var COFantasy = COFantasy || function() { if (options.ecraser) { target.messages.push(nomPerso(attaquant) + " saisit " + nomPerso(target) + " entre ses bras puissants"); if (options.ecraser === true) { - error("Il faudrait pr\xE9ciser un label pour \xE9craser", options.ecraser); + error("Il faudrait préciser un label pour écraser", options.ecraser); } else { let cmdEcraser = '!cof-attack ' + attaquant.token.id + ' ' + target.token.id + ' ' + options.ecraser; - target.messages.push("et l'" + boutonSimple(cmdEcraser, '\xE9crase') + "."); + target.messages.push("et l'" + boutonSimple(cmdEcraser, 'écrase') + "."); } if (attributeAsBool(target, 'armureDEau')) { - target.messages.push("L'armure d'eau emp\xEAche " + nomPerso(target) + " d'\xEAtre saisi"); + target.messages.push("L'armure d'eau empêche " + nomPerso(target) + " d'être saisi"); } else { setTokenAttr(attaquant, 'ecrase', idName(target), evt); setTokenAttr(target, 'estEcrasePar', idName(attaquant), evt); } } if (options.saisirEtBroyer) { - target.messages.push(nomPerso(attaquant) + " soul\xE8ve " + nomPerso(target) + " gesticulant" + eForFemale(target)); + target.messages.push(nomPerso(attaquant) + " soulève " + nomPerso(target) + " gesticulant" + eForFemale(target)); if (attackLabel) { let cmdAttaqueGratuiteSaisi = '!cof-attack ' + attaquant.token.id + ' ' + target.token.id + ' ' + attackLabel + ' --bonusAttaque 5'; target.messages.push(boutonSimple(cmdAttaqueGratuiteSaisi, 'Attaque gratuite')); } else { - target.messages.push(nomPerso(attaquant) + " a droit \xE0 une attaque gratuite contre " + nomPerso(target)); + target.messages.push(nomPerso(attaquant) + " a droit à une attaque gratuite contre " + nomPerso(target)); } if (valAttribute(target, 'FOR', 'force') < valAttribute(attaquant, 'FOR', 'force')) { options.rolls = options.rolls || []; @@ -18391,7 +18418,7 @@ var COFantasy = COFantasy || function() { type: 'normal', value: Math.floor(distanceSaisiProjete.val) }); - target.messages.push(nomPerso(target) + " est projet\xE9" + eForFemale(target) + " sur " + distanceSaisiProjete.roll + " m\xE8tres"); + target.messages.push(nomPerso(target) + " est projeté" + eForFemale(target) + " sur " + distanceSaisiProjete.roll + " mètres"); } } if (options.projection && taillePersonnage(attaquant, 4) > taillePersonnage(target, 4)) { @@ -18425,10 +18452,10 @@ var COFantasy = COFantasy || function() { type: 'normal', value: dmgProjection }); - target.messages.push(nomPerso(target) + " est projet\xE9 sur " + distanceProjetee + " m\xE8tres"); + target.messages.push(nomPerso(target) + " est projeté sur " + distanceProjetee + " mètres"); } if (options.gober && taillePersonnage(attaquant, 4) > taillePersonnage(target, 4)) { - //On utilise la liste d'effets pour pouvoir g\xE9rer les jets asynchrones + //On utilise la liste d'effets pour pouvoir gérer les jets asynchrones target.effets.push({ gober: true, save: true @@ -18443,14 +18470,14 @@ var COFantasy = COFantasy || function() { type: 'normal', value: '2d6' }); - target.messages.push("\xC9ventration => +2d6 DM"); + target.messages.push("Éventration => +2d6 DM"); } } else { setTokenAttr(attaquant, 'limiteParTour_eventrationReussie', target.token.id, evt); } } let attDMBonus = attDMBonusCommun; - //Les modificateurs de d\xE9g\xE2ts qui d\xE9pendent de la cible + //Les modificateurs de dégâts qui dépendent de la cible if (target.tempDmg) { let forceTarg = modCarac(target, 'force'); if (forceTarg < 0) { @@ -18462,7 +18489,7 @@ var COFantasy = COFantasy || function() { if (options.pressionMortelle || target.pressionMortelle) { let pMortelle = tokenAttribute(target, 'pressionMortelle'); if (pMortelle.length === 0) { - sendPerso(attaquant, "essaie une pression mortelle, mais aucun point vital de " + nomPerso(target) + " n'a encore \xE9t\xE9 affect\xE9"); + sendPerso(attaquant, "essaie une pression mortelle, mais aucun point vital de " + nomPerso(target) + " n'a encore été affecté"); ciblesCount--; return; } @@ -18475,7 +18502,7 @@ var COFantasy = COFantasy || function() { let modDex = modCarac(attaquant, 'dexterite'); if (target.distance <= 5 * modDex) { attDMBonus += " + " + tirPrecis; - target.messages.push("Tir pr\xE9cis : +" + tirPrecis + " DM"); + target.messages.push("Tir précis : +" + tirPrecis + " DM"); } } } @@ -18483,7 +18510,7 @@ var COFantasy = COFantasy || function() { if (target.sournoise) sournoise += target.sournoise; if (target.critique && sournoise === 0 && predicateAsBool(attaquant, 'botteSecrete')) { sournoise = predicateAsInt(attaquant, 'attaqueSournoise', 1); - target.messages.push("Botte secr\xE8te !"); + target.messages.push("Botte secrète !"); } if (sournoise) { let limiteSournoisesParTour = predicateAsInt(attaquant, 'sournoisesParTour', 1); @@ -18493,7 +18520,7 @@ var COFantasy = COFantasy || function() { } else { setTokenAttr(attaquant, 'limiteParTour_sournoises', nbSournoises - 1, evt); if (predicateAsBool(target, 'immuniteAuxSournoises')) { - target.messages.push(nomPerso(target) + " est immunis\xE9" + eForFemale(target) + " aux attaques sournoises"); + target.messages.push(nomPerso(target) + " est immunisé" + eForFemale(target) + " aux attaques sournoises"); } else { if (options.ouvertureMortelle) { target.messages.push("Ouverture mortelle => + 2 x " + sournoise + options.d6 + " DM"); @@ -18503,13 +18530,13 @@ var COFantasy = COFantasy || function() { } let valueSournoise = sournoise + options.d6; if (predicateAsBool(target, 'armureProtection') && ficheAttributeAsBool(target, 'defarmureon', false)) { - target.messages.push("L'armure de protection de " + nomPerso(target) + " r\xE9duit l'attaque sournoise"); + target.messages.push("L'armure de protection de " + nomPerso(target) + " réduit l'attaque sournoise"); valueSournoise = "ceil(" + valueSournoise + "/2)"; } else if (predicateAsBool(target, 'bouclierProtection') && ficheAttributeAsInt(target, 'defbouclieron', 0)) { - target.messages.push("Le bouclier de protection de " + nomPerso(target) + " r\xE9duit l'attaque sournoise"); + target.messages.push("Le bouclier de protection de " + nomPerso(target) + " réduit l'attaque sournoise"); valueSournoise = "ceil(" + valueSournoise + "/2)"; } else if (predicateAsBool(target, 'anneauProtection')) { - target.messages.push("L'anneau de protection de " + nomPerso(target) + " r\xE9duit l'attaque sournoise"); + target.messages.push("L'anneau de protection de " + nomPerso(target) + " réduit l'attaque sournoise"); valueSournoise = "ceil(" + valueSournoise + "/2)"; } target.additionalDmg.push({ @@ -18537,7 +18564,7 @@ var COFantasy = COFantasy || function() { } if (predicateAsBool(attaquant, 'chasseurDeSorciere') && predicateAsBool(target, 'necromancien')) { attDMBonus += "+2"; - target.messages.push("Chasseur de sorci\xE8re => +2 en DM"); + target.messages.push("Chasseur de sorcière => +2 en DM"); } if (target.ennemiJure) { target.additionalDmg.push({ @@ -18592,7 +18619,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '1' + options.d6 }); - target.messages.push("Lien \xE9pique => + 1" + options.d6 + " DM"); + target.messages.push("Lien épique => + 1" + options.d6 + " DM"); } if (target.feinte) { let value = target.feinte + options.d6; @@ -18616,7 +18643,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '2d6' }); - target.messages.push("Cible \xE9norme => +2d6 DM"); + target.messages.push("Cible énorme => +2d6 DM"); } } if (options.contact && weaponStats.deuxMains && targetTaille > 4) { @@ -18626,18 +18653,18 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: '1d6' }); - target.messages.push("Arme tenue \xE0 2 mains => +1d6 DM"); + target.messages.push("Arme tenue à 2 mains => +1d6 DM"); } else if (targetTaille > 5) { target.additionalDmg.push({ type: mainDmgType, value: '2d6' }); - target.messages.push("Arme tenue \xE0 2 mains et cible \xE9norme => +2d6 DM"); + target.messages.push("Arme tenue à 2 mains et cible énorme => +2d6 DM"); } } if (predicateAsBool(attaquant, 'grosMonstreGrosseArme')) { options.puissant = true; - target.messages.push("Gros Monstre, grosse arme => d\xE9g\xE2ts de base augment\xE9s"); + target.messages.push("Gros Monstre, grosse arme => dégâts de base augmentés"); } } if (attributeAsBool(target, 'hemorragie') && !options.sortilege && !options.armeNaturelle) { @@ -18647,7 +18674,7 @@ var COFantasy = COFantasy || function() { value: '1d6', drainDeSang: sourceDrain }); - target.messages.push("H\xE9morragie => +1d6 DM"); + target.messages.push("Hémorragie => +1d6 DM"); } if (!options.pasDeDmg) { let loupParmiLesLoups = predicateAsInt(attaquant, 'loupParmiLesLoups', 0); @@ -18668,7 +18695,7 @@ var COFantasy = COFantasy || function() { }); target.messages.push("Laissez-le moi ! => +1d6 DM"); } - //Bonus aux DMs dus au d\xE9fi samoura\xEF + //Bonus aux DMs dus au défi samouraï let defiSamouraiAttr = tokenAttribute(attaquant, 'defiSamourai'); if (defiSamouraiAttr.length > 0) { defiSamouraiAttr = defiSamouraiAttr[0]; @@ -18689,7 +18716,7 @@ var COFantasy = COFantasy || function() { type: mainDmgType, value: bonusDefi }); - target.messages.push(attackerTokName + " b\xE9n\xE9ficie d'un bonus de +" + bonusDefi + " aux DMs contre " + nomPerso(target)); + target.messages.push(attackerTokName + " bénéficie d'un bonus de +" + bonusDefi + " aux DMs contre " + nomPerso(target)); } } if (options.vicieux) { @@ -18722,7 +18749,7 @@ var COFantasy = COFantasy || function() { } //Additional damage let additionalDmg = attaquant.additionalDmg.concat(target.additionalDmg); - //On enl\xE8ve les DM qui ne passent pas les conditions + //On enlève les DM qui ne passent pas les conditions additionalDmg = additionalDmg.filter(function(dmSpec) { if (dmSpec.conditions === undefined) return true; return dmSpec.conditions.every(function(cond) { @@ -18773,7 +18800,7 @@ var COFantasy = COFantasy || function() { mainDmgRollExpr += " + " + dmSpec.value; return false; }); - // On ajoute le jet pour les d\xE9g\xE2ts de critiques suppl\xE9mentaires + // On ajoute le jet pour les dégâts de critiques supplémentaires if (target.critique && options.additionalCritDmg) { options.additionalCritDmg.forEach(function(dmSpec) { extraDmgRollExpr += " [[" + dmSpec.value + "]]"; @@ -18790,9 +18817,9 @@ var COFantasy = COFantasy || function() { value: mainDmgRollExpr }; // toEvaluateDmg inlines - // 0 : roll de d\xE9g\xE2ts principaux - // 1+ : les rolls de d\xE9g\xE2ts suppl\xE9mentaires - // 1+nb d\xE9g\xE2ts suppl\xE9mentaires + : rolls de d\xE9g\xE2ts critiques + // 0 : roll de dégâts principaux + // 1+ : les rolls de dégâts supplémentaires + // 1+nb dégâts supplémentaires + : rolls de dégâts critiques let toEvaluateDmg = "[[" + mainDmgRollExpr + "]]" + extraDmgRollExpr; sendChat('', toEvaluateDmg, function(resDmg) { let rollsDmg = target.rollsDmg || resDmg[0]; @@ -18814,8 +18841,8 @@ var COFantasy = COFantasy || function() { dmSpec.total = dmSpec.total || rRoll.results.total; let addDmType = dmSpec.type || 'normal'; dmSpec.display = dmSpec.display || buildinline(rRoll, addDmType, options.magique); - } else { //l'expression de DM additionel est mal form\xE9e - error("Expression de d\xE9g\xE2ts de critiques mal form\xE9e : " + options.additionalCritDmg[i].value, options.additionalCritDmg[i]); + } else { //l'expression de DM additionel est mal formée + error("Expression de dégâts de critiques mal formée : " + options.additionalCritDmg[i].value, options.additionalCritDmg[i]); } }); if (target.additionalCritDmg.length === 0) delete target.additionalCritDmg; @@ -18828,28 +18855,28 @@ var COFantasy = COFantasy || function() { dmSpec.total = dmSpec.total || rRoll.results.total; let addDmType = dmSpec.type; dmSpec.display = dmSpec.display || buildinline(rRoll, addDmType, options.magique); - } else { //l'expression de DM additionel est mal form\xE9e - error("Expression de d\xE9g\xE2ts suppl\xE9mentaires mal form\xE9e : " + additionalDmg[i].value, additionalDmg[i]); + } else { //l'expression de DM additionel est mal formée + error("Expression de dégâts supplémentaires mal formée : " + additionalDmg[i].value, additionalDmg[i]); } }); if (options.expertDuCombatDMSpec) { correctAdditionalDmg.push(options.expertDuCombatDMSpec); } additionalDmg = correctAdditionalDmg; - if (target.touche) { //Devrait \xEAtre inutile ? + if (target.touche) { //Devrait être inutile ? if (options.tirDeBarrage) - target.messages.push("Tir de barrage : undo si la cible d\xE9cide de ne pas bouger"); + target.messages.push("Tir de barrage : undo si la cible décide de ne pas bouger"); if (options.pointsVitaux) - target.messages.push(attackerTokName + " vise des points vitaux mais ne semble pas faire de d\xE9g\xE2ts"); + target.messages.push(attackerTokName + " vise des points vitaux mais ne semble pas faire de dégâts"); if (options.pressionMortelle || target.pressionMortelle) { removeTokenAttr(target, 'pressionMortelle', evt); - target.messages.push(attackerTokName + " lib\xE8re la pression des points vitaux, l'effet est d\xE9vastateur !"); + target.messages.push(attackerTokName + " libère la pression des points vitaux, l'effet est dévastateur !"); spawnFx(target.token.get('left'), target.token.get('top'), 'bomb-death', pageId); } - if (options.pasDeDmg === undefined) { //si l'attaque fait des DM, possibilit\xE9 d'attaque en tra\xEEtre + if (options.pasDeDmg === undefined) { //si l'attaque fait des DM, possibilité d'attaque en traître if (attaquant.alliesAvecAttaqueEnTraitre === undefined) { attaquant.alliesAvecAttaqueEnTraitre = []; - //On cherche tous les alli\xE9s ayant l'attaque en traitre + //On cherche tous les alliés ayant l'attaque en traitre const allies = alliesParPerso[attaquant.charId] || new Set(); allies.forEach(function(ci) { if (!charPredicateAsBool(ci, 'attaqueEnTraitre')) return; @@ -18882,7 +18909,7 @@ var COFantasy = COFantasy || function() { } }); } - // change l'\xE9tat de la cible, si sp\xE9cifi\xE9 + // change l'état de la cible, si spécifié if (target.enflamme) { let enflammePuissance = 1; if (options.puissant) enflammePuissance = 2; @@ -18912,7 +18939,7 @@ var COFantasy = COFantasy || function() { } // Draw effect, if any if (options.fx) { - //Pour les cones, on fait un seul effet, car c'est bien g\xE9r\xE9. + //Pour les cones, on fait un seul effet, car c'est bien géré. if (!options.aoe || options.aoe.type != 'cone') { let tokenOrigine = attackingToken; if (options.origineDeLAttaque) @@ -18932,29 +18959,10 @@ var COFantasy = COFantasy || function() { spawnFx(target.token.get('left'), target.token.get('top'), options.targetFx, pageId); } target.rollsDmg = rollsDmg; - let affaiblissements = options.affaiblissementsCarac; - if (target.affaiblissementsCarac) { - if (affaiblissements) - affaiblissements = affaiblissements.concat(target.affaiblissementsCarac); - else affaiblissements = target.affaiblissementsCarac; - } - if (affaiblissements) { - let expliquer = function(s) { - target.messages.push(s); - }; - affaiblissements.forEach(function(aff) { - let carac = aff.carac; - if (carac == 'random') { - let id = 'affaiblissement' + aff.val + '_' + target.token.id; - carac = randomCaracForId(id, options); - } - affaiblirCaracPerso(target, carac, aff.val, expliquer, evt); - }); - } // Compte le nombre de saves pour la synchronisation - // (On ne compte pas les psave, g\xE9r\xE9s dans dealDamage) + // (On ne compte pas les psave, gérés dans dealDamage) let saves = 0; - //ajoute les \xE9tats sans save \xE0 la cible + //ajoute les états sans save à la cible let etats = options.etats; if (target.etats) { if (etats) etats = etats.concat(target.etats); @@ -18983,7 +18991,7 @@ var COFantasy = COFantasy || function() { } if (ce.typeDmg && immuniseAuType(target, ce.typeDmg, attaquant)) { if (!target['msgImmunite_' + ce.typeDmg]) { - target.messages.push(nomPerso(target) + " ne semble pas affect\xE9" + eForFemale(target) + " par " + stringOfType(ce.typeDmg)); + target.messages.push(nomPerso(target) + " ne semble pas affecté" + eForFemale(target) + " par " + stringOfType(ce.typeDmg)); target['msgImmunite_' + ce.typeDmg] = true; } return; @@ -18992,7 +19000,7 @@ var COFantasy = COFantasy || function() { setState(target, ce.etat, true, evt); let msgEtat; if (ce.etat == 'mort') - msgEtat = 'tu\xE9' + eForFemale(target); + msgEtat = 'tué' + eForFemale(target); else msgEtat = stringOfEtat(ce.etat, target); target.messages.push(nomPerso(target) + " est " + msgEtat + " par l'attaque"); @@ -19009,14 +19017,14 @@ var COFantasy = COFantasy || function() { } else { if (ce.condition.type == "moins") { target.messages.push( - "Gr\xE2ce \xE0 sa " + ce.condition.text + ", " + nomPerso(target) + + "Grâce à sa " + ce.condition.text + ", " + nomPerso(target) + " n'est pas " + stringOfEtat(ce.etat, target)); } } }); } let savesEffets = 0; - // Ajoute les effets sans save \xE0 la cible + // Ajoute les effets sans save à la cible let effets = options.effets; if (target.effets) { if (effets) effets = effets.concat(target.effets); @@ -19050,7 +19058,7 @@ var COFantasy = COFantasy || function() { (estElfe(target) || (predicateAsInt(target, 'voieDeLArchange', 1) > 2 && attributeAsBool(target, 'formeDAnge'))) ) { - target.messages.push(nomPerso(target) + " est immunis\xE9 \xE0 la paralysie des goules"); + target.messages.push(nomPerso(target) + " est immunisé à la paralysie des goules"); return; } if (ef.effet == 'affaibliTemp' && estMortVivant(attaquant) && predicateAsInt(target, 'voieDeLArchange', 1) > 2 && attributeAsBool(target, 'formeDAnge')) { @@ -19064,7 +19072,7 @@ var COFantasy = COFantasy || function() { } if (ef.typeDmg && immuniseAuType(target, ef.typeDmg, attaquant)) { if (!target['msgImmunite_' + ef.typeDmg]) { - target.messages.push(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(ef.typeDmg)); + target.messages.push(nomPerso(target) + " ne semble pas affecté par " + stringOfType(ef.typeDmg)); target['msgImmunite_' + ef.typeDmg] = true; } return; @@ -19073,17 +19081,43 @@ var COFantasy = COFantasy || function() { setEffetTemporaire(target, ef, ef.duree, evt, options); }); } - // Tout ce qui se passe apr\xE8s les saves (autres que saves de diminution des dmg + //Les affaiblissements + let saveAffaiblissements = 0; + let affaiblissements = options.affaiblissementsCarac; + if (target.affaiblissementsCarac) { + if (affaiblissements) + affaiblissements = affaiblissements.concat(target.affaiblissementsCarac); + else affaiblissements = target.affaiblissementsCarac; + } + if (affaiblissements) { + let expliquer = function(s) { + target.messages.push(s); + }; + affaiblissements.forEach(function(aff) { + if (aff.save) { + saves++; + saveAffaiblissements++; + return; + } + let carac = aff.carac; + if (carac == 'random') { + let id = 'affaiblissement' + aff.val + '_' + target.token.id; + carac = randomCaracForId(id, options); + } + affaiblirCaracPerso(target, carac, aff.val, expliquer, evt); + }); + } + // Tout ce qui se passe après les saves (autres que saves de diminution des dmg let afterSaves = function() { if (saves > 0) return; //On n'a pas encore fait tous les saves if (target.utiliseRuneProtection) { target.messages.push(nomPerso(target) + " utilise sa Rune de Protection pour annuler les dommages"); addToAttributeAsInt(target, 'limiteParCombat_runeForgesort_protection', 1, -1, evt); - // Pas de d\xE9g\xE2ts, donc pas d'appel \xE0 dealDamage + // Pas de dégâts, donc pas d'appel à dealDamage finCibles(); } else if (options.pasDeDmg || (additionalDmg.length === 0 && mainDmgRoll.total === 0 && attNbDices === 0)) { - // Pas de d\xE9g\xE2ts, donc pas d'appel \xE0 dealDamage + // Pas de dégâts, donc pas d'appel à dealDamage finCibles(); } else { dealDamage(target, mainDmgRoll, additionalDmg, evt, target.critique, @@ -19094,12 +19128,12 @@ var COFantasy = COFantasy || function() { if (suce === 0) { setTokenAttr(attaquant, 'bufDEF', -3, evt); target.messages.push( - attackerTokName + " s'agrippe \xE0 " + nomPerso(target) + - " et commence \xE0 lui sucer le sang"); + attackerTokName + " s'agrippe à " + nomPerso(target) + + " et commence à lui sucer le sang"); } if (suce + dmg >= 6) { target.messages.push( - "Repus, " + attackerTokName + " se d\xE9tache et s'envole"); + "Repus, " + attackerTokName + " se détache et s'envole"); target.messages.push(nomPerso(target) + " se sent un peu faible..."); setState(target, 'affaibli', true, evt); let defbuf = attributeAsInt(attaquant, 'bufDEF', 0); @@ -19112,7 +19146,7 @@ var COFantasy = COFantasy || function() { setTokenAttr(attaquant, 'strigeSuce', suce + dmg, evt); if (suce > 0) target.messages.push( - attackerTokName + " continue \xE0 sucer le sang de " + nomPerso(target)); + attackerTokName + " continue à sucer le sang de " + nomPerso(target)); } } if (dmgDrain || (dmg > 0 && (options.vampirise || target.vampirise))) { @@ -19142,7 +19176,7 @@ var COFantasy = COFantasy || function() { if ((estMortVivant(attaquant) && predicateAsInt(target, 'voieDeLArchange', 1) > 2 && attributeAsBool(target, 'formeDAnge')) || (predicateAsBool(attaquant, 'vampire') && predicateAsBool(target, 'immuniteAbsorptionVampire')) ) { - target.messages.push(nomPerso(target) + "n'est pas affect\xE9" + eForFemale(target) + " par l'absorption d'\xE9nergie"); + target.messages.push(nomPerso(target) + "n'est pas affecté" + eForFemale(target) + " par l'absorption d'énergie"); } else { soigneToken(attaquant, absorptionEnergie, evt, function(soins) { target.messages.push( @@ -19166,7 +19200,7 @@ var COFantasy = COFantasy || function() { target.dmgMessage = "DM : "; if (ficheAttributeAsBool(attaquant, 'jets_caches', false)) { target.dmgMessage += dmg; - sendChat('COF', "/w GM Jet cach\xE9 de dommages : " + dmgDisplay); + sendChat('COF', "/w GM Jet caché de dommages : " + dmgDisplay); } else { target.dmgMessage += dmgDisplay; } @@ -19215,7 +19249,7 @@ var COFantasy = COFantasy || function() { target.messages, function(dmgDisplay, dmg, dmgDrain) { let dmgMsg = - "D\xE9charge \xE9lectrique sur " + attackerTokName + " : " + + "Décharge électrique sur " + attackerTokName + " : " + dmgDisplay; target.messages.push(dmgMsg); finCibles(); @@ -19262,7 +19296,7 @@ var COFantasy = COFantasy || function() { target.messages, function(dmgDisplay, dmg, dmgDrain) { let dmgMsg = - "" + attackerTokName + " est glac\xE9 : " + + "" + attackerTokName + " est glacé : " + dmgDisplay + " DM"; target.messages.push(dmgMsg); finCibles(); @@ -19326,17 +19360,17 @@ var COFantasy = COFantasy || function() { let expliquer = function(msg) { target.messages.push(msg); }; - //Ajoute les \xE9tats avec save \xE0 la cible + //Ajoute les états avec save à la cible let etatsAvecSave = function() { - if (savesEffets > 0) return; //On n'a pas encore fini avec les effets + if (savesEffets > 0 || saveAffaiblissements > 0) return; //On n'a pas encore fini avec les effets et les affaiblissements if (etats && saves > 0) { etats.forEach(function(ce, index) { if (ce.save) { if (testCondition(ce.condition, attaquant, [target], d20roll, options)) { - let msgPour = " pour r\xE9sister \xE0 un effet"; + let msgPour = " pour résister à un effet"; let msgEtat; if (ce.etat == 'mort') - msgEtat = 'tu\xE9' + eForFemale(target); + msgEtat = 'tué' + eForFemale(target); else msgEtat = stringOfEtat(ce.etat, target); let msgRate = ", " + nomPerso(target) + " est " + msgEtat + " par l'attaque"; @@ -19371,7 +19405,7 @@ var COFantasy = COFantasy || function() { } else { if (ce.condition.type == "moins") { target.messages.push( - "Gr\xE2ce \xE0 sa " + ce.condition.text + ", " + nomPerso(target) + + "Grâce à sa " + ce.condition.text + ", " + nomPerso(target) + " n'est pas " + stringOfEtat(ce.etat, target)); } saves--; @@ -19381,8 +19415,9 @@ var COFantasy = COFantasy || function() { }); } else afterSaves(); }; - // Ajoute les effets avec save \xE0 la cible + // Ajoute les effets avec save à la cible let effetsAvecSave = function() { + if (saveAffaiblissements > 0) return; //On n'a pas encore fini avec les affaiblissements if (effets && savesEffets > 0) { effets.forEach(function(ef, index) { if (ef.save) { @@ -19392,13 +19427,13 @@ var COFantasy = COFantasy || function() { options, target.messages, evt, function(resultat, crit, rt1, rt2) { if (resultat == 2) { - target.messages.push(nomPerso(target) + " est enti\xE8rement aval\xE9 par " + attackerTokName); + target.messages.push(nomPerso(target) + " est entièrement avalé par " + attackerTokName); setTokenAttr(attaquant, 'aGobe', idName(target), evt); setTokenAttr(target, 'estGobePar', idName(attaquant), evt); moveTokenWithUndo(target.token, attaquant.token.get('left'), attaquant.token.get('top'), evt); } else { if (resultat === 0) diminueMalediction(attaquant, evt); - target.messages.push(nomPerso(target) + " n'est pas aval\xE9."); + target.messages.push(nomPerso(target) + " n'est pas avalé."); } saves--; savesEffets--; @@ -19411,14 +19446,14 @@ var COFantasy = COFantasy || function() { function(resultat, crit, rt1, rt2) { if (resultat == 2) { let distance = rollDePlus(6); - target.messages.push(nomPerso(target) + " est projet\xE9" + eForFemale(target) + " \xE0 " + - distance.roll + " m\xE8tres et tombe au sol"); + target.messages.push(nomPerso(target) + " est projeté" + eForFemale(target) + " à " + + distance.roll + " mètres et tombe au sol"); setState(target, 'renverse', true, evt); if (attackLabel) { let cmdAttaqueGratuite = '!cof-attack ' + attaquant.token.id + ' ' + target.token.id + ' ' + attackLabel; target.messages.push(boutonSimple(cmdAttaqueGratuite, 'Attaque gratuite')); } else { - target.messages.push(nomPerso(attaquant) + " a droit \xE0 une attaque gratuite contre " + nomPerso(target)); + target.messages.push(nomPerso(attaquant) + " a droit à une attaque gratuite contre " + nomPerso(target)); } } else { if (resultat === 0) diminueMalediction(attaquant, evt); @@ -19431,7 +19466,7 @@ var COFantasy = COFantasy || function() { } else { if (ef.typeDmg && immuniseAuType(target, ef.typeDmg, attaquant)) { if (!target['msgImmunite_' + ef.typeDmg]) { - target.messages.push(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(ef.typeDmg)); + target.messages.push(nomPerso(target) + " ne semble pas affecté par " + stringOfType(ef.typeDmg)); target['msgImmunite_' + ef.typeDmg] = true; } saves--; @@ -19441,7 +19476,7 @@ var COFantasy = COFantasy || function() { } let msgPour = " pour "; if (ef.msgSave) msgPour += ef.msgSave; - else msgPour += "r\xE9sister \xE0 un effet"; + else msgPour += "résister à un effet"; let msgRate = ", " + nomPerso(target) + " "; if (ef.duree && ef.message) { msgRate += messageActivation(target, ef.message); @@ -19472,7 +19507,7 @@ var COFantasy = COFantasy || function() { if (reussite && duree && ef.save.demiDuree) { reussite = false; duree = Math.ceil(duree / 2); - if (stateCOF.options.affichage.val.duree_effets.val) expliquer("La dur\xE9e est r\xE9duite \xE0 " + duree + " tours"); + if (stateCOF.options.affichage.val.duree_effets.val) expliquer("La durée est réduite à " + duree + " tours"); } if (!reussite) { ef.attaquant = attaquant; @@ -19494,15 +19529,15 @@ var COFantasy = COFantasy || function() { options, target.messages, evt, function(resultat, crit, rt1, rt2) { if (resultat == 2) { - target.messages.push(nomPerso(target) + " est pi\xE9tin\xE9 par " + attackerTokName + ", dommages doubl\xE9s"); + target.messages.push(nomPerso(target) + " est piétiné par " + attackerTokName + ", dommages doublés"); setState(target, 'renverse', true, evt); target.dmgCoef = (target.dmgCoef || 0) + 1; target.touche++; if (target.percute) { - target.messages.push(nomPerso(target) + " est projet\xE9 \xE0 " + + target.messages.push(nomPerso(target) + " est projeté à " + rollDePlus(6, { bonus: 1 - }).roll + " m\xE8tres"); + }).roll + " mètres"); effets = effets || []; effets.push({ effet: 'etourdiTemp', @@ -19521,19 +19556,56 @@ var COFantasy = COFantasy || function() { } } else { if (resultat === 0) diminueMalediction(attaquant, evt); - target.messages.push(nomPerso(target) + " n'est pas pi\xE9tin\xE9."); + target.messages.push(nomPerso(target) + " n'est pas piétiné."); } effetsAvecSave(); }); } else effetsAvecSave(); }; - // Peut faire peur \xE0 la cible + let affaiblissementsAvecSave = function() { + if (affaiblissements && saveAffaiblissements > 0) { + let expliquer = function(s) { + target.messages.push(s); + }; + affaiblissements.forEach(function(aff) { + if (!aff.save) { + return; + } + let carac = aff.carac; + if (carac == 'random') { + let id = 'affaiblissement' + aff.val + '_' + target.token.id; + carac = randomCaracForId(id, options); + } + let saveOpts = { + msgPour: " pour résister à un affaiblissement de " + carac, + msgRate: ", raté.", + attaquant, + rolls: options.rolls, + sortilege: options.sortilege, + chanceRollId: options.chanceRollId, + type: options.type, + necromancie: estNecromancie(options), + }; + let saveId = 'affaiblissement' + carac + "_" + target.token.id; + save(aff.save, target, saveId, expliquer, saveOpts, evt, + function(reussite, rollText) { + if (!reussite) { + affaiblirCaracPerso(target, carac, aff.val, expliquer, evt); + } + saves--; + saveAffaiblissements--; + effetPietinement(); + }); + }); + } else effetPietinement(); + }; + // Peut faire peur à la cible if (options.peur) { peurOneToken(target, options.peur.seuil, options.peur.duree, { resisteAvecForce: true - }, target.messages, evt, effetPietinement); - } else effetPietinement(); + }, target.messages, evt, affaiblissementsAvecSave); + } else affaiblissementsAvecSave(); } else { evt.succes = false; finCibles(); @@ -19556,12 +19628,12 @@ var COFantasy = COFantasy || function() { let msg; switch (d12roll) { case 1: - msg = "\xC9chec total : "; + msg = "Échec total : "; if (estMag) { - msg += "le lanceur de sort perd le contr\xF4le de la magie qu'il canalise et subit 1d4 dommages en retour par rang du sort lanc\xE9. "; + msg += "le lanceur de sort perd le contrôle de la magie qu'il canalise et subit 1d4 dommages en retour par rang du sort lancé. "; msg += boutonCritique("!cof-dmg ?{Rang du sort}d4 --ignoreRD"); } else { - msg += "l'attaquant se blesse lui-m\xEAme et s'inflige la moiti\xE9 des d\xE9g\xE2ts de son attaque. L'attaquant ne peut plus attaquer ce tour. "; + msg += "l'attaquant se blesse lui-même et s'inflige la moitié des dégâts de son attaque. L'attaquant ne peut plus attaquer ce tour. "; msg += boutonCritique("!cof-bouton-echec-total " + evt.id); } return msg; @@ -19575,38 +19647,38 @@ var COFantasy = COFantasy || function() { } else { difficulte = 12; } - msg = "Bouscul\xE9 (FOR) : l'attaquant est d\xE9s\xE9quilibr\xE9 par son attaque "; + msg = "Bousculé (FOR) : l'attaquant est déséquilibré par son attaque "; msg += boutonCritique("!cof-set-state renverse true --save FOR " + difficulte); return msg; case 3: if (avecArme) { - msg = "Maladresse (DEX) : l'attaquant laisse \xE9chapper son arme qui tombe hors de port\xE9e imm\xE9diate."; + msg = "Maladresse (DEX) : l'attaquant laisse échapper son arme qui tombe hors de portée immédiate."; msg += boutonCritique("!cof-degainer --save DEX 12"); return msg; } - msg = "D\xE9s\xE9quilibr\xE9 (DEX) : l'attaquant est Ralenti pendant 3 tours."; + msg = "Déséquilibré (DEX) : l'attaquant est Ralenti pendant 3 tours."; msg += boutonCritique("!cof-effet-temp ralentiTemp 3 --save DEX 12"); return msg; case 4: - msg = "Coup de mou (CON) : l'attaquant est affaibli pendant 3 tours, ou jusqu'\xE0 ce qu'il consacre un tour ou 1 PR pour se r\xE9tablir."; + msg = "Coup de mou (CON) : l'attaquant est affaibli pendant 3 tours, ou jusqu'à ce qu'il consacre un tour ou 1 PR pour se rétablir."; msg += boutonCritique("!cof-effet-temp affaibliTemp 3 --save CON 12"); return msg; case 5: if (estCac) { - msg = "Erreur tactique (INT) : le personnage provoque une attaque (gratuite) d\x2019un adversaire \xE0 son contact."; + msg = "Erreur tactique (INT) : le personnage provoque une attaque (gratuite) d’un adversaire à son contact."; msg += boutonCritique("!cof-jet INT 12"); } else if (estMag) { - msg = "Aveugl\xE9 (INT) : le personnage ne contr\xF4le pas sa puissance et une partie de celle-ci \xE9met un flash qui l'aveugle temporairement."; + msg = "Aveuglé (INT) : le personnage ne contrôle pas sa puissance et une partie de celle-ci émet un flash qui l'aveugle temporairement."; msg += boutonCritique("!cof-effet-temp aveugleTemp 3 --save INT 12 --saveParTour CON 12"); } else { - //TODO : Impl\xE9menter un bouton "mauvais calcul" r\xE9alisant une attaque automatique sur un des Obstacle - msg = "Mauvais calcul (INT) : le personnage a une chance de toucher une autre cible sur la trajectoire de son tir. D\xE9terminer la cible au hasard et relancer une attaque sur cette nouvelle cible."; + //TODO : Implémenter un bouton "mauvais calcul" réalisant une attaque automatique sur un des Obstacle + msg = "Mauvais calcul (INT) : le personnage a une chance de toucher une autre cible sur la trajectoire de son tir. Déterminer la cible au hasard et relancer une attaque sur cette nouvelle cible."; msg += boutonCritique("!cof-jet INT 12"); } return msg; case 6: if (estCac) { - msg = "Expos\xE9 (SAG) : l'adversaire dispose d'un bonus de +10 \xE0 la touche pendant un round."; + msg = "Exposé (SAG) : l'adversaire dispose d'un bonus de +10 à la touche pendant un round."; cibles.forEach(function(cible) { msg += boutonCritique("!cof-effet-temp expose 1 --valeur " + cible.token.id + " --save SAG 12"); }); @@ -19616,11 +19688,11 @@ var COFantasy = COFantasy || function() { } return msg; case 7: - msg = "Ridicule (CHA) : le personnage fait un faux mouvement \xE0 la fois douloureux et ridicule, il subit l\x2019\xE9tat \xE9tourdi pendant un round pour reprendre contenance. "; + msg = "Ridicule (CHA) : le personnage fait un faux mouvement à la fois douloureux et ridicule, il subit l’état étourdi pendant un round pour reprendre contenance. "; msg += boutonCritique("!cof-effet-temp etourdiTemp 1 --save CHA 12"); return msg; case 8: - msg = "Inconfort : Une pi\xE8ce d\x2019armure bouge et elle devient plus g\xEAnante que protectrice. Malus en DEF et en attaque pour le reste du combat => Cuir : -1, Maille : -2, Plaque -3. "; + msg = "Inconfort : Une pièce d’armure bouge et elle devient plus gênante que protectrice. Malus en DEF et en attaque pour le reste du combat => Cuir : -1, Maille : -2, Plaque -3. "; msg += boutonCritique("!cof-effet-combat inconfort --valeur ?{Malus ?|-1,1|-2,2|-3,3} --save CHA 12"); return msg; default: @@ -19630,16 +19702,17 @@ var COFantasy = COFantasy || function() { function montrerResultatsAttaque(msg) { if (stateCOF.currentAttackDisplay) { - sendChat('', endFramedDisplay(stateCOF.currentAttackDisplay)); + sendFramedDisplay(stateCOF.currentAttackDisplay); stateCOF.currentAttackDisplay = undefined; if (stateCOF.afterDisplay) { - stateCOF.afterDisplay.forEach(function(d) { + let ad = stateCOF.afterDisplay; + stateCOF.afterDisplay = undefined; //on efface avant au cas où le script crash + ad.forEach(function(d) { sendPerso(d.destinataire, d.msg, true); }); - stateCOF.afterDisplay = undefined; } } else { - sendPlayer(msg, "Pas de r\xE9sultat d'attaque \xE0 montrer"); + sendPlayer(msg, "Pas de résultat d'attaque à montrer"); } } @@ -19660,41 +19733,42 @@ var COFantasy = COFantasy || function() { }; addLineToFramedDisplay(display, boutonSimple('!cof-montrer-resultats-attaque', "Montrer aux joueurs")); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } } if (options === undefined || !options.secret) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else { let playerIds = getPlayerIds(perso); playerIds.forEach(function(playerid) { addFramedHeader(display, playerid, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); autres.forEach(function(target) { let addPlayers = getPlayerIds(target); addPlayers.forEach(function(nid) { if (!playerIds.includes(nid)) { playerIds.push(nid); addFramedHeader(display, nid, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }); }); } if (stateCOF.afterDisplay) { - stateCOF.afterDisplay.forEach(function(d) { + let ad = stateCOF.afterDisplay; + stateCOF.afterDisplay = undefined; + ad.forEach(function(d) { sendPerso(d.destinataire, d.msg, true); }); - stateCOF.afterDisplay = undefined; } } //Affichage final d'une attaque - // attaquant est optionnel, mais si il est pr\xE9sent, cibles doit \xEAtre un tableau et options un objet + // attaquant est optionnel, mais si il est présent, cibles doit être un tableau et options un objet function finaliseDisplay(display, explications, evt, attaquant, cibles, options, echecCritique) { echecCritique = echecCritique || false; explications.forEach(function(expl) { @@ -19722,7 +19796,7 @@ var COFantasy = COFantasy || function() { line += "
    " + boutonSimple( "!cof-devier-les-coups " + evt.id + ' --target ' + target.token.id, - "d\xE9vier les coups"); + "dévier les coups"); nbBoutons++; } if (preDmgToken.paradeDeProjectiles) { @@ -19763,7 +19837,7 @@ var COFantasy = COFantasy || function() { } if (preDmgToken.resistanceALaMagieBarbare && preDmgToken.resistanceALaMagieBarbare !== 'reroll') { action = "!cof-resister-a-la-magie " + target.token.id + ' ' + evt.id; - line += "
    " + boutonSimple(action, "tenter de r\xE9sister \xE0 la magie"); + line += "
    " + boutonSimple(action, "tenter de résister à la magie"); nbBoutons++; } if (preDmgToken.cercleDeProtection && preDmgToken.cercleDeProtectionDe && @@ -19782,7 +19856,7 @@ var COFantasy = COFantasy || function() { } if (preDmgToken.chairACanon) { preDmgToken.chairACanon.forEach(function(tok) { - line += "
    " + boutonSimple("!cof-chair-a-canon " + target.token.id + ' ' + tok.id + ' ' + evt.id, "utiliser " + tok.get('name') + " comme chair \xE0 canon"); + line += "
    " + boutonSimple("!cof-chair-a-canon " + target.token.id + ' ' + tok.id + ' ' + evt.id, "utiliser " + tok.get('name') + " comme chair à canon"); nbBoutons++; }); } @@ -19846,9 +19920,9 @@ var COFantasy = COFantasy || function() { if (pc > 0 && !echecCritique) { addLineToFramedDisplay(display, boutonSimple("!cof-bouton-chance " + evt.id, "Chance") + " (reste " + pc + " PC)"); } - if (attributeAsBool(perso, 'runeForgesort_\xE9nergie') && - attributeAsInt(perso, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0) { - addLineToFramedDisplay(display, boutonSimple("!cof-bouton-rune-energie " + evt.id, "Rune d'\xE9nergie")); + if (attributeAsBool(perso, 'runeForgesort_énergie') && + attributeAsInt(perso, 'limiteParCombat_runeForgesort_énergie', 1) > 0) { + addLineToFramedDisplay(display, boutonSimple("!cof-bouton-rune-energie " + evt.id, "Rune d'énergie")); } if (capaciteDisponible(perso, 'petitVeinard', 'combat')) { addLineToFramedDisplay(display, boutonSimple("!cof-bouton-petit-veinard " + evt.id, "Petit veinard")); @@ -19879,7 +19953,7 @@ var COFantasy = COFantasy || function() { boutonSimple("!cof-bouton-pousser-kiai " + evt.id, "Kiai")); } if (capaciteDisponible(perso, 'petitVeinard', 'combat')) { - addLineToFramedDisplay(display, boutonSimple("!cof-bouton-petit-veinard " + evt.id, "Petit veinard") + " pour relancer un d\xE9"); + addLineToFramedDisplay(display, boutonSimple("!cof-bouton-petit-veinard " + evt.id, "Petit veinard") + " pour relancer un dé"); } } if (options && options.contact && cibles && attaquant && @@ -19913,7 +19987,7 @@ var COFantasy = COFantasy || function() { attaquant.ennemisAuContact = tokensEnnemis; } if (attaquant.ennemisAuContact.length > 0) { - let msgEnchainement = nomPerso(attaquant) + " a droit \xE0 une attaque au contact gratuite contre "; + let msgEnchainement = nomPerso(attaquant) + " a droit à une attaque au contact gratuite contre "; let sep = ""; let armeEnMain = tokenAttribute(attaquant, 'armeEnMain'); let act; @@ -20037,7 +20111,7 @@ var COFantasy = COFantasy || function() { } sendPerso(attaquant, "Plus de cible sur laquelle ricocher et trop loin pour un retour en main", true); } - } else { //on a rat\xE9, il faut remettre le rounMarker \xE0 sa place + } else { //on a raté, il faut remettre le rounMarker à sa place if (stateCOF.options.affichage.val.init_dynamique.val) { threadSync++; activateRoundMarker(threadSync, attaquant.token); @@ -20056,7 +20130,7 @@ var COFantasy = COFantasy || function() { } } - // RD sp\xE9cifique au type + // RD spécifique au type function typeRD(rd, dmgType) { if (dmgType === undefined || dmgType == 'normal') return 0; return (rd[dmgType] || 0); @@ -20067,7 +20141,7 @@ var COFantasy = COFantasy || function() { let proba1 = probaSucces(de, seuil, 1); return 1 - (1 - proba1) * (1 - proba1); } - if (seuil < 2) seuil = 2; // 1 est toujours un \xE9chec + if (seuil < 2) seuil = 2; // 1 est toujours un échec else if (seuil > 20) seuil = 20; return ((de - seuil) + 1) / de; } @@ -20137,23 +20211,43 @@ var COFantasy = COFantasy || function() { return carac1; } - //s repr\xE9sente le save, avec une carac, une carac2 optionnelle et un seuil + function dansAuraDeProfanation(perso) { + if (perso.dansAuraDeProfanation !== undefined) + return perso.dansAuraDeProfanation; + let pageId = perso.token.get('pageid'); + let tokens = findObjs({ + _type: 'graphic', + _subtype: 'token', + layer: 'objects', + _pageid: pageId + }); + let res = tokens.some(function(token) { + let p = persoOfToken(token); + if (!p) return false; + if (distanceCombat(perso.token, token, pageId) > 6) return false; + if (getState(p, 'mort')) return false; + return predicateAsBool(p, 'auraDeProfanation'); + }); + perso.dansAuraDeProfanation = res; + return res; + } + //s représente le save, avec une carac, une carac2 optionnelle et un seuil //expliquer est une fonction qui prend en argument un string et le publie // options peut contenir les champs : - // - msgPour : message d'explication \xE0 afficher avant le jet - // - msgReussite : message \xE0 afficher en cas de r\xE9ussite - // - msgRate : message \xE0 afficher si l'action rate - // - silencieuxSiPasAffecte: ne rien afficher pour les cibles immunis\xE9es - // - regard: l'attaque vient d'un regard, on peut d\xE9tourner les yeux + // - msgPour : message d'explication à afficher avant le jet + // - msgReussite : message à afficher en cas de réussite + // - msgRate : message à afficher si l'action rate + // - silencieuxSiPasAffecte: ne rien afficher pour les cibles immunisées + // - regard: l'attaque vient d'un regard, on peut détourner les yeux // - attaquant : le {charId, token} de l'attaquant contre lequel le save se fait (si il y en a un) - // - type : le type de d\xE9g\xE2ts contre lequel on fait le save + // - type : le type de dégâts contre lequel on fait le save // - hideSaveTitle : cache le titre du save // - bonus : bonus au jet de save // s peut contenir: - // - carac : la caract\xE9ristique \xE0 utiliser pour le save - // - carac2 : caract\xE9ristique alternative - // - seuil : la difficult\xE9 du jet de sauvegarde - // - contact : la difficult\xE9 si la cible est au contact de options.attaquant + // - carac : la caractéristique à utiliser pour le save + // - carac2 : caractéristique alternative + // - seuil : la difficulté du jet de sauvegarde + // - contact : la difficulté si la cible est au contact de options.attaquant // - fauchage // - entrave (pour les action qui immobilisent, ralentissent ou paralysent) // - necromancie @@ -20161,7 +20255,7 @@ var COFantasy = COFantasy || function() { function save(s, target, saveId, expliquer, options, evt, afterSave) { if (options.type && immuniseAuType(target, options.type, options.attaquant)) { if (!target['msgImmunite_' + options.type] && !options.silencieuxSiPasAffecte) { - expliquer(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(options.type)); + expliquer(nomPerso(target) + " ne semble pas affecté par " + stringOfType(options.type)); target['msgImmunite_' + options.type] = true; } afterSave(true, ''); @@ -20177,7 +20271,7 @@ var COFantasy = COFantasy || function() { } if (predicateAsBool(target, 'vegetatif')) { if (!options.silencieuxSiPasAffecte) - expliquer(nomPerso(target) + " est une cr\xE9ature v\xE9g\xE9tative."); + expliquer(nomPerso(target) + " est une créature végétative."); afterSave(true, ''); return; } @@ -20192,12 +20286,12 @@ var COFantasy = COFantasy || function() { } if (s.fauchage) { if (s.fauchage <= taillePersonnage(target, 4)) { - expliquer(nomPerso(target) + " est trop grand pour \xEAtre fauch\xE9."); + expliquer(nomPerso(target) + " est trop grand pour être fauché."); afterSave(true, ''); return; } if (predicateAsBool(target, 'inderacinable')) { - expliquer(nomPerso(target) + " est ind\xE9racinable."); + expliquer(nomPerso(target) + " est indéracinable."); afterSave(true, ''); return; } @@ -20206,7 +20300,7 @@ var COFantasy = COFantasy || function() { if (getState(target, 'mort') || getState(target, 'assomme') || getState(target, 'paralyse') || getState(target, 'endormi')) { if (!options.silencieuxSiPasAffecte) - expliquer(nomPerso(target) + " n'est pas en \xE9tat d'\xE9viter l'effet."); + expliquer(nomPerso(target) + " n'est pas en état d'éviter l'effet."); afterSave(false, ''); } } @@ -20220,23 +20314,23 @@ var COFantasy = COFantasy || function() { } if (s.entrave && predicateAsBool(target, 'actionLibre')) { bonus += 5; - expliquer("Action libre => +5 pour r\xE9sister aux entraves"); + expliquer("Action libre => +5 pour résister aux entraves"); } if (options.necromancie && attributeAsBool(target, 'sangDeLArbreCoeur')) { bonus += 5; - expliquer("Sang de l'Arbre-Coeur => +5 pour r\xE9sister \xE0 la n\xE9cromancie"); + expliquer("Sang de l'Arbre-Coeur => +5 pour résister à la nécromancie"); } if (options.type == 'poison') { if (predicateAsBool(target, 'liberateurDAnathazerin')) { bonus += 2; - expliquer("Lib\xE9rateur d'Anathazer\xEFn => +2 pour r\xE9sister au poison"); + expliquer("Libérateur d'Anathazerïn => +2 pour résister au poison"); } if (predicateAsBool(target, 'peauDEcorceAvancee') && attributeAsBool(target, 'peauDEcorce')) { let bonusPeau = getIntValeurOfEffet(target, 'peauDEcorce', 2); if (bonusPeau == 2 && predicateAsInt(target, 'voieDesForets', 0) > 3) bonusPeau = 4; bonus += bonusPeau; - expliquer("Peau d'\xE9corce am\xE9lior\xE9e => +" + bonusPeau + " pour r\xE9sister au poison"); + expliquer("Peau d'écorce améliorée => +" + bonusPeau + " pour résister au poison"); } } let bonusAttrs = []; @@ -20255,13 +20349,13 @@ var COFantasy = COFantasy || function() { switch (getIntValeurOfEffet(target, 'detournerLeRegard', 2)) { case 1: seuil -= 3; - expliquer("d\xE9tourne un peu le regard => -3 \xE0 la difficult\xE9"); + expliquer("détourne un peu le regard => -3 à la difficulté"); break; case 2: case 3: case 4: seuil -= 6; - expliquer("d\xE9tourne le regard => -6 \xE0 la difficult\xE9"); + expliquer("détourne le regard => -6 à la difficulté"); break; default: expliquer(nomPerso(target) + " ferme les yeux"); @@ -20271,7 +20365,7 @@ var COFantasy = COFantasy || function() { } } let carac = s.carac; - //Cas o\xF9 le save peut se faire au choix parmis 2 caracs + //Cas où le save peut se faire au choix parmis 2 caracs if (s.carac2) { carac = meilleureCarac(carac, s.carac2, target, seuil); } @@ -20288,6 +20382,14 @@ var COFantasy = COFantasy || function() { } if (options.energiePositive) { bonusPreds.push('bonusSaveContre_positif'); + //Recherche de token avec aura de profanation + if (dansAuraDeProfanation(target)) { + bonus += 3; + expliquer("Aura de profanation => +3 au save"); + } + } else if (estMortVivant(target) && dansAuraDeProfanation(target)) { + bonus += 1; + expliquer("Aura de profanation => +1 au save"); } if (!options.hideSaveTitle) { let title = " Jet " + deCarac(carac) + " " + seuil; @@ -20313,11 +20415,11 @@ var COFantasy = COFantasy || function() { smsg += '">' + tr.texte + '
    '; } if (tr.reussite) { - smsg += " => r\xE9ussite"; + smsg += " => réussite"; if (options.msgReussite) smsg += options.msgReussite; smsg += tr.modifiers; } else { - smsg += " => \xE9chec"; + smsg += " => échec"; if (options.msgRate) smsg += options.msgRate; smsg += tr.rerolls + tr.modifiers; } @@ -20348,7 +20450,7 @@ var COFantasy = COFantasy || function() { return; } if ((sav.carac == 'CON' || sav.carac2 == 'CON') && estNonVivant(target)) { - expliquer("Les cr\xE9atures non-vivantes sont immnunis\xE9es aux attaques qui demandent un test de constitution"); + expliquer("Les créatures non-vivantes sont immnunisées aux attaques qui demandent un test de constitution"); afterSave({ succes: true, dmgDisplay: '0', @@ -20368,8 +20470,8 @@ var COFantasy = COFantasy || function() { return; } let saveOpts = { - msgPour: " pour r\xE9duire les d\xE9g\xE2ts", - msgReussite: ", d\xE9g\xE2ts divis\xE9s par 2", + msgPour: " pour réduire les dégâts", + msgReussite: ", dégâts divisés par 2", attaquant: ps.attaquant, rolls: ps.rolls, chanceRollId: ps.chanceRollId, @@ -20377,8 +20479,8 @@ var COFantasy = COFantasy || function() { energiePositive: ps.energiePositive }; if (totalSave) { - saveOpts.msgPour = " pour \xE9viter les d\xE9g\xE2ts"; - saveOpts.msgReussite = ", d\xE9g\xE2ts \xE9vit\xE9s"; + saveOpts.msgPour = " pour éviter les dégâts"; + saveOpts.msgReussite = ", dégâts évités"; } let saveId = 'parseSave_' + target.token.id; save(sav, target, saveId, expliquer, saveOpts, evt, @@ -20437,7 +20539,7 @@ var COFantasy = COFantasy || function() { if (r === '') return; let rds; let index = r.indexOf(':'); - if (index > 0) { //RD \xE0 un type particulier + if (index > 0) { //RD à un type particulier let type = r.substring(0, index); if (type == 'rdt' || type == 'sauf') return; if (type == 'magie') type = 'magique'; @@ -20448,7 +20550,7 @@ var COFantasy = COFantasy || function() { return; } index = r.indexOf('/'); - if (index > 0) { //RD sauf \xE0 des types + if (index > 0) { //RD sauf à des types rds = parseInt(r.substring(0, index)); if (isNaN(rds) || rds === 0) return; let sauf = r.substring(index + 1); @@ -20523,7 +20625,7 @@ var COFantasy = COFantasy || function() { case 'acide': return "l'acide"; case 'electrique': - return "l'\xE9lectricit\xE9"; + return "l'électricité"; case 'soniqe': return "le son"; case 'maladie': @@ -20540,7 +20642,7 @@ var COFantasy = COFantasy || function() { case 'FOR': return "la force"; case 'DEX': - return "la dext\xE9rit\xE9"; + return "la dextérité"; case 'CON': return "la constitution"; case 'INT': @@ -20566,7 +20668,7 @@ var COFantasy = COFantasy || function() { (predicateAsBool(target, 'protectionDMZone') || predicateAsBool(target, 'protectionDMZone_' + dmgType))) { divide(); - expliquer(nomPerso(target) + " est prot\xE9g\xE9 contre les d\xE9g\xE2ts de zone"); + expliquer(nomPerso(target) + " est protégé contre les dégâts de zone"); } if (predicateOrAttributeAsBool(target, 'resistanceA_' + dmgType) || predicateAsBool(target, 'diviseEffet_' + dmgType)) { divide(); @@ -20618,7 +20720,7 @@ var COFantasy = COFantasy || function() { divide(); } if (options.vampirise && predicateOrAttributeAsBool(target, 'controleSanguin')) { - expliquer(nomPerso(target) + " contr\xF4le parfaitement son sang"); + expliquer(nomPerso(target) + " contrôle parfaitement son sang"); divide(); } } @@ -20628,9 +20730,9 @@ var COFantasy = COFantasy || function() { return options.aoe && !options.sortilege && options.aoe.type == 'cone' && options.attaquant && estDraconique(options.attaquant); } - //On a d\xE9termin\xE9 les DM du type principal(possiblement apr\xE8s save des dmgExtra, maintenant on applique les r\xE9sistances, puis on ajoute les DM d'autres types + //On a déterminé les DM du type principal(possiblement après save des dmgExtra, maintenant on applique les résistances, puis on ajoute les DM d'autres types function dealDamageAfterDmgExtra(target, mainDmgType, dmgTotal, dmgDisplay, showTotal, dmgParType, dmgExtra, crit, options, evt, expliquer, displayRes) { - if (options.pointsVitaux && dmgTotal > 0) { //d\xE9g\xE2ts retard\xE9s pour une pression mortelle + if (options.pointsVitaux && dmgTotal > 0) { //dégâts retardés pour une pression mortelle let pMortelle = tokenAttribute(target, 'pressionMortelle'); let dmgPMort = dmgTotal; let numberPMort = 1; @@ -20655,7 +20757,7 @@ var COFantasy = COFantasy || function() { } if (dmgTotal > 0 && immuniseAuType(target, mainDmgType, options.attaquant)) { if (expliquer && !target['msgImmunite_' + mainDmgType]) { - expliquer(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(mainDmgType)); + expliquer(nomPerso(target) + " ne semble pas affecté par " + stringOfType(mainDmgType)); target['msgImmunite_' + mainDmgType] = true; } dmgTotal = 0; @@ -20668,6 +20770,8 @@ var COFantasy = COFantasy || function() { if (options.tranchant && rd.tranchant) rdMain += rd.tranchant; if (options.percant && rd.percant) rdMain += rd.percant; if (options.contondant && rd.contondant) rdMain += rd.contondant; + } else if ((mainDmgType == 'poison' || mainDmgType == 'feu' || mainDmgType == 'froid') && !options.magique && rd.nature && !dmgNaturel(options)) { + rdMain += rd.nature; } if (options.asphyxie) rdMain += rd.asphyxie; if (rd.drain && (options.vampirise || target.vampirise) && mainDmgType != 'drain') { @@ -20762,13 +20866,13 @@ var COFantasy = COFantasy || function() { else dmSuivis[tv] = 0; }); }); - // Autres sources de d\xE9g\xE2ts + // Autres sources de dégâts // On compte d'abord les autres sources, pour la synchronisation let count = 0; for (let dt in dmgParType) { if (immuniseAuType(target, dt, options.attaquant)) { if (expliquer && !target['msgImmunite_' + dt]) { - expliquer(nomPerso(target) + " ne semble pas affect\xE9 par " + stringOfType(dt)); + expliquer(nomPerso(target) + " ne semble pas affecté par " + stringOfType(dt)); target['msgImmunite_' + dt] = true; } delete dmgParType[dt]; @@ -20780,7 +20884,7 @@ var COFantasy = COFantasy || function() { if (dmgType == mainDmgType) { count -= dmgParType[dmgType].length; if (count === 0) dealDamageAfterOthers(target, crit, options, evt, expliquer, displayRes, dmgTotal, dmgDisplay, showTotal, dmSuivis); - return; //type principal d\xE9j\xE0 g\xE9r\xE9 + return; //type principal déjà géré } showTotal = true; let dm = 0; @@ -20822,6 +20926,8 @@ var COFantasy = COFantasy || function() { if (options.tranchant && rd.tranchant) rdl += rd.tranchant; if (options.percant && rd.percant) rdl += rd.percant; if (options.contondant && rd.contondant) rdl += rd.contondant; + } else if ((dmgType == 'poison' || dmgType == 'feu' || dmgType == 'froid') && !options.magique && rd.nature && !dmgNaturel(options)) { + rdl += rd.nature; } if (target.ignoreMoitieRD) rdl = parseInt(rdl / 2); if (target.ignoreRD) { @@ -20898,15 +21004,15 @@ var COFantasy = COFantasy || function() { } } - //Appel\xE9 quand on met \xE0 0 PV + //Appelé quand on met à 0 PV function mort(personnage, expliquer, evt) { - if (getState(personnage, 'mort')) return; //d\xE9j\xE0 mort + if (getState(personnage, 'mort')) return; //déjà mort if (predicateAsBool(personnage, 'energieDeLaMort')) { let duree = rollDePlus(6, { bonus: 5 }); - sendChat('', '/w GM ' + nomPerso(personnage) + ' r\xE9appara\xEEtra dans ' + duree.roll + ' tours.'); - let effet = 'messageRetarde(r\xE9apparition)'; + sendChat('', '/w GM ' + nomPerso(personnage) + ' réapparaîtra dans ' + duree.roll + ' tours.'); + let effet = 'messageRetarde(réapparition)'; setAttrDuree(personnage, effet, duree.val - 1, evt); setToken(personnage.token, 'layer', 'gmlayer', evt); if (personnage.attaquant) { @@ -20922,9 +21028,9 @@ var COFantasy = COFantasy || function() { let explications = []; dealDamage(personnage.attaquant, dmg, [], evt, false, {}, explications, function(dmgDisplay, dmgFinal, dmgDrain) { - setTokenAttr(personnage, effet + 'Valeur', nomPerso(personnage) + " r\xE9apparait avec " + dmgFinal + " PV en plus.", evt); + setTokenAttr(personnage, effet + 'Valeur', nomPerso(personnage) + " réapparait avec " + dmgFinal + " PV en plus.", evt); let attName = nomPerso(personnage); - let msg = "se transforme en brume noire qui traverse " + attName + " de part en part avant de dispara\xEEtre dans une paroi en poussant un hululement inhumain. le froid de la mort inflige " + dmgDisplay + " DM \xE0 " + attName; + let msg = "se transforme en brume noire qui traverse " + attName + " de part en part avant de disparaître dans une paroi en poussant un hululement inhumain. le froid de la mort inflige " + dmgDisplay + " DM à " + attName; if (expliquer) { expliquer(nomPerso(personnage) + ' ' + msg); } else { @@ -20979,11 +21085,11 @@ var COFantasy = COFantasy || function() { switch (charRace) { case 'insecte': case 'ankheg': - case 'araign\xE9e': + case 'araignée': case 'araignee': - case 'gu\xEApe': + case 'guêpe': case 'libellule': - case 'scarab\xE9e': + case 'scarabée': case 'scorpion': case 'strige': return true; @@ -20992,8 +21098,8 @@ var COFantasy = COFantasy || function() { } } - // retourne les nombre de PR restant, undefined si les PR ne sont pas d\xE9finis - // current, max, et si d\xE9fini, attribut + // retourne les nombre de PR restant, undefined si les PR ne sont pas définis + // current, max, et si défini, attribut function pointsDeRecuperation(perso) { if (!ficheAttributeAsBool(perso, 'option_pr', true)) return; let attrPR = charAttribute(perso.charId, 'pr', { @@ -21027,7 +21133,7 @@ var COFantasy = COFantasy || function() { }; } - // pr doit \xEAtre d\xE9fini, et pr.current > 0 + // pr doit être défini, et pr.current > 0 function enleverPointDeRecuperation(perso, pr, evt) { evt.attributes = evt.attributes || []; let attrPR; @@ -21075,18 +21181,18 @@ var COFantasy = COFantasy || function() { let pr = pointsDeRecuperation(target); if (!pr) return; if (pr.current > 0) { - expliquer("Les d\xE9g\xE2ts sont si importants que " + nomPerso(target) + " perd 1 PR"); + expliquer("Les dégâts sont si importants que " + nomPerso(target) + " perd 1 PR"); enleverPointDeRecuperation(target, pr, evt); } else if (getState(target, 'blesse')) { if (getState(target, 'mort')) { - expliquer("Avec la blessure grave, c'est vraiment la fin, " + nomPerso(target) + " ne se rel\xE8vera plus..."); + expliquer("Avec la blessure grave, c'est vraiment la fin, " + nomPerso(target) + " ne se relèvera plus..."); } else { - expliquer("Les d\xE9g\xE2ts sont trop importants, et " + nomPerso(target) + " s'effondre"); + expliquer("Les dégâts sont trop importants, et " + nomPerso(target) + " s'effondre"); mort(target, expliquer, evt); } } else { setState(target, 'blesse', true, evt); - expliquer("Les d\xE9g\xE2ts occasionnent une blessure grave !"); + expliquer("Les dégâts occasionnent une blessure grave !"); } } } @@ -21121,7 +21227,7 @@ var COFantasy = COFantasy || function() { attrs[0].set('current', newCur); } - function finDEffetDeNom(perso, effet, evt, options) { //Supprime l'effet si pr\xE9sent + function finDEffetDeNom(perso, effet, evt, options) { //Supprime l'effet si présent let attrs = tokenAttribute(perso, effet); if (attrs.length === 0) return; attrs = attrs[0]; @@ -21143,9 +21249,9 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(args[2]); if (evt === undefined) { - error("Impossible de trouver l'\xE9v\xE9nement qui a caus\xE9 la mort", args); + error("Impossible de trouver l'événement qui a causé la mort", args); evt = { - type: "Mettre \xE0 0 PV" + type: "Mettre à 0 PV" }; addEvent(evt); } @@ -21165,13 +21271,13 @@ var COFantasy = COFantasy || function() { } updateCurrentBar(target, 1, 0, evt); if (predicateAsBool(target, 'baroudHonneur')) { - let msgBarroud = nomPerso(target) + " devrait \xEAtre mort"; + let msgBarroud = nomPerso(target) + " devrait être mort"; msgBarroud += eForFemale(target) + ", mais "; - msgBarroud += onGenre(target, 'il', 'elle') + " continue \xE0 se battre !"; + msgBarroud += onGenre(target, 'il', 'elle') + " continue à se battre !"; expliquer(msgBarroud); setTokenAttr(target, 'baroudHonneurActif', true, evt); } else if (predicateAsBool(target, 'increvable') && attributeAsInt(target, 'limiteParCombat__increvable', predicateAsInt(target, 'increvable', 1)) > 0) { - let msgIncrevable = nomPerso(target) + " devrait \xEAtre mort"; + let msgIncrevable = nomPerso(target) + " devrait être mort"; msgIncrevable += eForFemale(target) + ", mais "; msgIncrevable += onGenre(target, 'il', 'elle') + " est increvable !"; expliquer(msgIncrevable); @@ -21180,25 +21286,25 @@ var COFantasy = COFantasy || function() { setTokenAttr(target, 'increvableActif', true, evt); } else if ((attributeAsBool(target, 'enrage') || predicateAsBool(target, 'durACuire')) && !attributeAsBool(target, 'aAgiAZeroPV')) { - let msgAgitZ = nomPerso(target) + " devrait \xEAtre mort"; + let msgAgitZ = nomPerso(target) + " devrait être mort"; msgAgitZ += eForFemale(target) + ", mais "; - msgAgitZ += onGenre(target, 'il', 'elle') + " continue \xE0 se battre !"; + msgAgitZ += onGenre(target, 'il', 'elle') + " continue à se battre !"; expliquer(msgAgitZ); if (!attributeAsBool(target, 'agitAZeroPV')) setAttrDuree(target, 'agitAZeroPV', 1, evt); } else if (predicateAsBool(target, 'nAbandonneJamais')) { if (attributeAsBool(target, 'mortMaisNAbandonnePas')) { - expliquer(nomPerso(target) + " est dans un \xE9tat lamentable, mais continue \xE0 bouger. Il faudrait une action limit\xE9e pour le r\xE9duire en miettes."); + expliquer(nomPerso(target) + " est dans un état lamentable, mais continue à bouger. Il faudrait une action limitée pour le réduire en miettes."); } else { - expliquer(nomPerso(target) + " est pratiquement d\xE9truit, mais continue \xE0 bouger !"); + expliquer(nomPerso(target) + " est pratiquement détruit, mais continue à bouger !"); setTokenAttr(target, 'mortMaisNAbandonnePas', true, evt); setState(target, 'ralenti', true, evt); } } else if (predicateAsBool(target, 'exsangue') && !attributeAsBool(target, 'etatExsangue')) { let msg; if (expliquer) { - expliquer(nomPerso(target) + " continue \xE0 agir malgr\xE9 son \xE9tat"); - } else msg = "continue \xE0 agir malgr\xE9 son \xE9tat"; + expliquer(nomPerso(target) + " continue à agir malgré son état"); + } else msg = "continue à agir malgré son état"; setTokenAttr(target, 'etatExsangue', true, evt, { msg }); @@ -21217,7 +21323,7 @@ var COFantasy = COFantasy || function() { let defierLaMort = charAttributeAsInt(target, 'defierLaMort', 10); let rollId = 'defierLaMort_' + target.token.id; let saveOpts = { - msgPour: " pour d\xE9fier la mort", + msgPour: " pour défier la mort", msgReussite: ", conserve 1 PV", rolls: options.rolls, chanceRollId: options.chanceRollId @@ -21239,7 +21345,7 @@ var COFantasy = COFantasy || function() { } postBarUpdateForDealDamage(target, dmgTotal, pvPerdus, bar1, tempDmg, dmgDisplay, showTotal, dmDrains, displayRes, evt, expliquer); }); - //On arr\xEAte l\xE0, car tout le reste est fait dans la continuation du save. + //On arrête là, car tout le reste est fait dans la continuation du save. return; } mettreAZeroPV(target, pvMax, evt, expliquer); @@ -21287,7 +21393,7 @@ var COFantasy = COFantasy || function() { if (rd > 0 && !options.aoe && options.attaquant && predicateAsBool(options.attaquant, 'ventreMou')) { let taille = taillePersonnage(target, 4); if (taille > 4) { - if (target.messages) target.messages.push("Ventre mou => L'attaque ignore la RD d\xFBe \xE0 la taille"); + if (target.messages) target.messages.push("Ventre mou => L'attaque ignore la RD dûe à la taille"); rd -= 3 * (taille - 4); if (taille > 6) rd--; if (rd < 0) rd = 0; @@ -21308,7 +21414,7 @@ var COFantasy = COFantasy || function() { else if (attributeAsBool(target, 'petrifie')) rd += 20; if (attributeAsBool(target, 'mutationSilhouetteMassive')) rd += 3; if (crit) { - let rdCrit = predicateAsInt(target, 'RD_critique', 0); //pour la compatibilit\xE9 + let rdCrit = predicateAsInt(target, 'RD_critique', 0); //pour la compatibilité if (ficheAttributeAsBool(target, 'casque_on', false)) rdCrit += ficheAttributeAsInt(target, 'casque_rd', 0); rd += rdCrit; @@ -21341,7 +21447,7 @@ var COFantasy = COFantasy || function() { } if (target.extraRDBouclier) { rd += target.extraRDBouclier; - expliquer(nomPerso(target) + " d\xE9vie le coup avec son bouclier"); + expliquer(nomPerso(target) + " dévie le coup avec son bouclier"); } if (target.ignoreTouteRD) rd = 0; else if (target.ignoreMoitieRD) rd = parseInt(rd / 2); @@ -21362,17 +21468,17 @@ var COFantasy = COFantasy || function() { if (dmgTotal <= rd) expliquer("La rune de protection absorbe tous les dommages"); else expliquer("La rune de protection encaisse " + target.utiliseRuneProtectionMax + " dommages"); } - //RD PeauDePierre \xE0 prendre en compte en dernier + //RD PeauDePierre à prendre en compte en dernier if (!target.defautCuirasse && !target.ignoreTouteRD && rd < dmgTotal && attributeAsBool(target, 'peauDePierreMag')) { let peauDePierreMagValeur = tokenAttribute(target, 'peauDePierreMagValeur'); if (peauDePierreMagValeur.length === 0) { - error("compteur de Peau de Pierre non trouv\xE9", target); + error("compteur de Peau de Pierre non trouvé", target); } else { peauDePierreMagValeur = peauDePierreMagValeur[0]; let rdPeauDePierreMax = parseInt(peauDePierreMagValeur.get('current')); let peauDePierreAbsorbe = parseInt(peauDePierreMagValeur.get('max')); if (isNaN(rdPeauDePierreMax) || isNaN(peauDePierreAbsorbe) || rdPeauDePierreMax < 1 || peauDePierreAbsorbe < 1) { - error("compteur de Peau de Pierre mal form\xE9", peauDePierreMagValeur); + error("compteur de Peau de Pierre mal formé", peauDePierreMagValeur); finDEffetDeNom(target, "peauDePierreMag", evt); } else { let rdPeauDePierreMag = rdPeauDePierreMax; @@ -21425,7 +21531,7 @@ var COFantasy = COFantasy || function() { }); } if (predicateAsBool(target, 'commandant')) { - //On cherche si il y a au moins 4 cr\xE9atures sous ses ordres \xE0 moins de 10 m + //On cherche si il y a au moins 4 créatures sous ses ordres à moins de 10 m let pageId = target.token.get('pageid'); let tokens = findObjs({ @@ -21482,7 +21588,7 @@ var COFantasy = COFantasy || function() { options.memePasMal += dmgTotal; dmgTotal = 0; } - expliquer("M\xEAme pas mal : ignore " + options.memePasMal + " PVs et peut enrager"); + expliquer("Même pas mal : ignore " + options.memePasMal + " PVs et peut enrager"); let mpm = attributeAsInt(target, 'memePasMalIgnore', 0); setTokenAttr(target, 'memePasMalIgnore', mpm + options.memePasMal, evt); setAttrDuree(target, 'memePasMalBonus', 3, evt); @@ -21542,7 +21648,7 @@ var COFantasy = COFantasy || function() { showTotal = true; dmgTotal = 1; if (dmSuivis.drain && dmSuivis.drain > 0) dmSuivis.drain = 1; - expliquer("La nu\xE9e est constitu\xE9e de tr\xE8s nombreuses cibles, l'attaque ne lui fait qu'1 DM"); + expliquer("La nuée est constituée de très nombreuses cibles, l'attaque ne lui fait qu'1 DM"); } if (options.attaquant && options.arme && dmgTotal > 0 && predicateAsBool(options.attaquant, 'blessureSanglante') && @@ -21568,9 +21674,9 @@ var COFantasy = COFantasy || function() { }; let sujet = onGenre(target, 'il', 'elle'); let saveOpts = { - msgPour: " pour se lib\xE9rer de la domination", - msgReussite: ", " + sujet + " se lib\xE8re de la domination", - msgRate: ", " + sujet + " reste sous domination malgr\xE9 les d\xE9g\xE2ts", + msgPour: " pour se libérer de la domination", + msgReussite: ", " + sujet + " se libère de la domination", + msgRate: ", " + sujet + " reste sous domination malgré les dégâts", rolls: options.rolls, chanceRollId: options.chanceRollId }; @@ -21596,7 +21702,7 @@ var COFantasy = COFantasy || function() { } enlevePVStatueDeBois(target, pvPerdus, evt); } else { - //On enl\xE8ve les points de vie + //On enlève les points de vie let pvTemporaires = attributeAsInt(target, 'PVTemporaires', 0); if (bar1 > 0 && bar1 + pvTemporaires <= dmgTotal && predicateAsBool(target, 'instinctDeSurvieHumain')) { @@ -21611,7 +21717,7 @@ var COFantasy = COFantasy || function() { dmgDisplay += " / 2"; showTotal = true; } - expliquer("L'instinct de survie aide \xE0 r\xE9duire une attaque fatale"); + expliquer("L'instinct de survie aide à réduire une attaque fatale"); } pvPerdus = dmgTotal; if (pvTemporaires > 0) { @@ -21626,18 +21732,18 @@ var COFantasy = COFantasy || function() { } else { bar1 = bar1 - dmgTotal; } - if (crit) { //Vuln\xE9rabilit\xE9 aux critiues + if (crit) { //Vulnérabilité aux critiues let vulnerableCritique = predicateAsInt(target, 'vulnerableCritique', 0); if (vulnerableCritique > 0) { if (randomInteger(100) <= vulnerableCritique) { - expliquer("Le coup critique le fait voler en \xE9clats"); + expliquer("Le coup critique le fait voler en éclats"); if (bar1 > 0) { dmgTotal += bar1; pvPerdus += bar1; bar1 = 0; } } else { - expliquer("Le coup critique fait vibrer l'adversaire, mais il r\xE9siste."); + expliquer("Le coup critique fait vibrer l'adversaire, mais il résiste."); } } } @@ -21645,7 +21751,7 @@ var COFantasy = COFantasy || function() { predicateAsBool(target, 'peutEnrager') && !attributeAsBool(target, 'enrage')) { setTokenAttr(target, 'enrage', true, evt); - expliquer(nomPerso(target) + " devient enrag\xE9" + eForFemale(target) + "."); + expliquer(nomPerso(target) + " devient enragé" + eForFemale(target) + "."); finDEffetDeNom(target, 'apeureTemp', evt); finDEffetDeNom(target, 'peurEtourdi', evt); setState(target, 'apeure', false, evt); @@ -21690,7 +21796,7 @@ var COFantasy = COFantasy || function() { if (bar1 <= 0) { if (predicateAsBool(target, 'sergent') && !attributeAsBool(target, 'attributDeCombat_sergentUtilise')) { - expliquer(nomPerso(target) + " \xE9vite l'attaque in-extremis"); + expliquer(nomPerso(target) + " évite l'attaque in-extremis"); setTokenAttr(target, 'attributDeCombat_sergentUtilise', true, evt); pvPerdus = 0; } else if (target.attackRoll && @@ -21713,8 +21819,8 @@ var COFantasy = COFantasy || function() { } else { weaponStatsIncrevable = enMain; } - } else { //attaque \xE0 distance - weaponStatsIncrevable.name = "Attaque \xE0 distance"; + } else { //attaque à distance + weaponStatsIncrevable.name = "Attaque à distance"; weaponStatsIncrevable.attSkill = '@{ATKTIR}'; } let optionsIncrevable = {...options @@ -21733,7 +21839,7 @@ var COFantasy = COFantasy || function() { } } else if (getState(target, 'immobilise')) { dice = 12; - expliquer(nomPerso(target) + " immobilis\xE9 => D12 au lieu de D20 en Attaque"); + expliquer(nomPerso(target) + " immobilisé => D12 au lieu de D20 en Attaque"); } else if (attributeAsBool(target, 'mortMaisNAbandonnePas')) { dice = 12; expliquer(nomPerso(target) + " mort mais n'abandonne pas => D12 au lieu de D20 en Attaque"); @@ -21771,12 +21877,12 @@ var COFantasy = COFantasy || function() { let msgIncrevable = "Increvable : " + nomPerso(target) + " fait " + attRollValue; //TODO: afficher les explications de calcul des bonus d'attaque ? if (attackRollAttaquant < target.attackRoll) { - expliquer(msgIncrevable + " < " + target.attackRoll + " => \xE9chec "); + expliquer(msgIncrevable + " < " + target.attackRoll + " => échec "); prendreUnCoupMortel(target, dmgTotal, pvPerdus, bar1, pvmax, tempDmg, dmgDisplay, showTotal, dmSuivis.drain, displayRes, options, evt, expliquer); return; } - //L'attaque est \xE9vit\xE9e - expliquer(msgIncrevable + " > " + target.attackRoll + " => l'attaque est \xE9vit\xE9e ! "); + //L'attaque est évitée + expliquer(msgIncrevable + " > " + target.attackRoll + " => l'attaque est évitée ! "); postBarUpdateForDealDamage(target, dmgTotal, 0, bar1, tempDmg, dmgDisplay, showTotal, dmSuivis.drain, displayRes, evt, expliquer); }); @@ -21798,7 +21904,7 @@ var COFantasy = COFantasy || function() { } function postBarUpdateForDealDamage(target, dmgTotal, pvPerdus, bar1, tempDmg, dmgDisplay, showTotal, dmDrains, displayRes, evt, expliquer) { - if (bar1 > 0 && tempDmg >= bar1) { //assomm\xE9 + if (bar1 > 0 && tempDmg >= bar1) { //assommé setState(target, 'assomme', true, evt); } let attrsLienDeSang = tokenAttribute(target, "lienDeSangVers"); @@ -21812,7 +21918,7 @@ var COFantasy = COFantasy || function() { }; let personnageLie = persoOfId(attrsLienDeSang[0].get("current")); if (personnageLie) { - expliquer("Le lien de sang inflige " + lienDuSangDmg + " d\xE9g\xE2ts \xE0 " + personnageLie.token.get("name")); + expliquer("Le lien de sang inflige " + lienDuSangDmg + " dégâts à " + personnageLie.token.get("name")); dealDamage(personnageLie, r, [], evt, false); } } @@ -22012,8 +22118,8 @@ var COFantasy = COFantasy || function() { return toEvaluate.replace(/@{/g, "@{" + name + "|"); } - // Retourne le diam\xE8tre d'un disque inscrit dans un carr\xE9 de surface - // \xE9quivalente \xE0 celle du token + // Retourne le diamètre d'un disque inscrit dans un carré de surface + // équivalente à celle du token function tokenSizeAsCircle(token) { const surface = token.get('width') * token.get('height'); return Math.sqrt(surface); @@ -22074,11 +22180,11 @@ var COFantasy = COFantasy || function() { let pt1 = pointOfToken(tok1); let pt2 = pointOfToken(tok2); let distToTrajectory = distancePixTokenSegment(obj, pt1, pt2); - // On mod\xE9lise le token comme un disque + // On modélise le token comme un disque let rayonObj = tokenSizeAsCircle(obj) / 2; if (distToTrajectory > rayonObj) return; liste_obstacles.push(obj.get("name")); - // On calcule un malus proportionnel \xE0 l'arc \xE0 traverser + // On calcule un malus proportionnel à l'arc à traverser // Pour l'instant, malus = 1 si distance = PIX_PER_UNIT let longueurArc = 2 * Math.sqrt(rayonObj * rayonObj - distToTrajectory * distToTrajectory); let mToken = longueurArc / PIX_PER_UNIT; @@ -22093,7 +22199,7 @@ var COFantasy = COFantasy || function() { else mObstacle = Math.round(mObstacle); let res = mPortee + mObstacle; if (mObstacle > 0) { - log("Obstacle" + ((liste_obstacles.length > 1) ? "s" : "") + " trouv\xE9 : " + liste_obstacles.join(', ')); + log("Obstacle" + ((liste_obstacles.length > 1) ? "s" : "") + " trouvé : " + liste_obstacles.join(', ')); let msgObstacles = 'Obstacle' + ((liste_obstacles.length > 1) ? 's' : '') + ' sur le trajet => -' + mObstacle + ' en Attaque
    '; if (liste_obstacles.length > 0) msgObstacles += '' + liste_obstacles.join(', ') + ''; @@ -22123,12 +22229,12 @@ var COFantasy = COFantasy || function() { }); } - // Fait foo sur tous les tokens repr\xE9sentant charId, ayant l'effet donn\xE9, et correspondant au nom d'attribut. Pour le cas o\xF9 le token doit \xEAtre li\xE9 au personnage, on ne prend qu'un seul token, sauf si les options indiquent autrement (soit option.tousLesTokens, soit une fonction options.filterAffected) + // Fait foo sur tous les tokens représentant charId, ayant l'effet donné, et correspondant au nom d'attribut. Pour le cas où le token doit être lié au personnage, on ne prend qu'un seul token, sauf si les options indiquent autrement (soit option.tousLesTokens, soit une fonction options.filterAffected) // Ne fonctionne correctement que pour les attributs sans _ function iterTokensOfAttribute(charId, pageId, attrName, attrNameComplet, foo, options) { options = options || {}; - let total = 1; //Nombre de tokens affect\xE9s, pour g\xE9rer l'asynchronie si besoin - if (attrNameComplet == attrName) { //token li\xE9 au character + let total = 1; //Nombre de tokens affectés, pour gérer l'asynchronie si besoin + if (attrNameComplet == attrName) { //token lié au character let tokens; if (pageId) { tokens = @@ -22173,7 +22279,7 @@ var COFantasy = COFantasy || function() { if (options.filterAffected(tok)) foo(tok, total); }); } else foo(tokens[0], 1); - } else { //token non li\xE9 au character + } else { //token non lié au character let tokenName = attrNameComplet.substring(attrNameComplet.indexOf('_') + 1); let tNames; if (pageId) { @@ -22220,7 +22326,7 @@ var COFantasy = COFantasy || function() { let character = getObj('character', charId); let charName = "d'id " + charId; if (character) charName = character.get('name'); - error("Attention, il y a plusieurs tokens nomm\xE9s " + tokenName, total); + error("Attention, il y a plusieurs tokens nommés " + tokenName, total); log(" tokens instances du personnage " + charName, total); } } @@ -22251,7 +22357,7 @@ var COFantasy = COFantasy || function() { token.set('showplayers_aura2', true); } else { let status = ''; - // Cas des tokens personnalis\xE9s + // Cas des tokens personnalisés if (statusForInitEnemy && statusForInitAlly) { // ennemi => rouge status = statusForInitEnemy; @@ -22264,7 +22370,7 @@ var COFantasy = COFantasy || function() { } } - //Ne rajoute pas evt \xE0 l'historique + //Ne rajoute pas evt à l'historique function setActiveToken(combat, tokenId, evt) { let pageId; if (combat) pageId = combat.pageId; @@ -22309,10 +22415,10 @@ var COFantasy = COFantasy || function() { if (tokenId) { let perso = persoOfId(tokenId, tokenId); if (perso) { - //On remet \xE0 0 la liste des cibles attaqu\xE9es par le personnage + //On remet à 0 la liste des cibles attaquées par le personnage removeDernieresCiblesAttaquees(perso, evt); let token = perso.token; - // personnage li\xE9 au Token + // personnage lié au Token affectToken(token, 'statusmarkers', token.get('statusmarkers'), evt); affectToken(token, 'aura2_radius', token.get('aura2_radius'), evt); affectToken(token, 'aura2_color', token.get('aura2_color'), evt); @@ -22329,7 +22435,7 @@ var COFantasy = COFantasy || function() { onGenre(perso, 'Il', 'Elle') + " ne fait rien ce tour"); removeTokenFlagAura(token); } else { - //Trouver la cr\xE9ature la plus proche + //Trouver la créature la plus proche let closestToken; pageId = token.get('pageid'); let toksOnPage = findObjs({ @@ -22374,7 +22480,7 @@ var COFantasy = COFantasy || function() { } } } - //On enl\xE8ve aussi les \xE9tats qui ne durent qu'un tour + //On enlève aussi les états qui ne durent qu'un tour let defenseTotale = tokenAttribute(perso, 'defenseTotale'); if (defenseTotale.length > 0) { defenseTotale = defenseTotale[0]; @@ -22402,7 +22508,7 @@ var COFantasy = COFantasy || function() { const charId = a.get('characterid'); let m = parseInt(a.get('max')); if (isNaN(m) || m < 0) { - error("Erreur dans les quantit\xE9s d'arme de jet", a); + error("Erreur dans les quantités d'arme de jet", a); a.remove(); return; } @@ -22415,7 +22521,7 @@ var COFantasy = COFantasy || function() { }); if (!msgAffiche.has(charId)) { msgAffiche.add(charId); - whisperChar(charId, "r\xE9cup\xE8re ses armes de jet"); + whisperChar(charId, "récupère ses armes de jet"); } a.set('current', m); } @@ -22432,7 +22538,7 @@ var COFantasy = COFantasy || function() { const charId = a.get('characterid'); let m = parseInt(a.get('max')); if (isNaN(m) || m < 0) { - error("Erreur dans les quantit\xE9s de munitions", a); + error("Erreur dans les quantités de munitions", a); a.remove(); return; } @@ -22445,7 +22551,7 @@ var COFantasy = COFantasy || function() { }); if (!msgAffiche.has(charId)) { msgAffiche.add(charId); - whisperChar(charId, "r\xE9cup\xE8re ses munitions"); + whisperChar(charId, "récupère ses munitions"); } a.set('current', m); } @@ -22458,10 +22564,10 @@ var COFantasy = COFantasy || function() { let combat = stateCOF.combat; if (!combat) { log("Pas en combat"); - sendChat("GM", "/w GM Le combat est d\xE9j\xE0 termin\xE9"); + sendChat("GM", "/w GM Le combat est déjà terminé"); return; } - sendChat("GM", "Le combat est termin\xE9"); + sendChat("GM", "Le combat est terminé"); let evt = { type: 'fin_combat', initiativepage: Campaign().get('initiativepage'), @@ -22512,18 +22618,18 @@ var COFantasy = COFantasy || function() { attrs = removeAllAttributes('meneurDHommesCible', evt, attrs); attrs = removeAllAttributes('energieImpie', evt, attrs); // Autres attributs - // On r\xE9cup\xE8re les munitions r\xE9cup\xE9rables - resetAttr(attrs, 'munition', evt, "r\xE9cup\xE8re ses munitions"); //obsol\xE8te depuis mars 2023. + // On récupère les munitions récupérables + resetAttr(attrs, 'munition', evt, "récupère ses munitions"); //obsolète depuis mars 2023. recupererMunitions(attrs, evt); recupererArmesDeJet(attrs, evt); - //Utilisation automatique de second souffle, si pas utilis\xE9 + //Utilisation automatique de second souffle, si pas utilisé let tokens = findObjs({ // Les tokens sur la page du combat _type: 'graphic', _subtype: 'token', _pageid: combat.pageId, }); - let persosDuCombat = []; //peupl\xE9 la premi\xE8re fois qu'on regarde les tokens - let persoParCharId = {}; //Pour ne garder qu'un jeu de pr\xE9dicat par charId + let persosDuCombat = []; //peuplé la première fois qu'on regarde les tokens + let persoParCharId = {}; //Pour ne garder qu'un jeu de prédicat par charId tokens.forEach(function(token) { let charId = token.get('represents'); if (charId === '' || charId === undefined) return; @@ -22550,11 +22656,11 @@ var COFantasy = COFantasy || function() { let jetSoins = rollDePlus(10, { bonus: bonus }); - let msg = ' reprend son souffle et r\xE9cup\xE8re '; + let msg = ' reprend son souffle et récupère '; let soins = jetSoins.val; if (pv + soins > pvDebut) { soins = pvDebut - pv; - msg += soins + " PV (le jet \xE9tait " + jetSoins.roll + ")"; + msg += soins + " PV (le jet était " + jetSoins.roll + ")"; } else { msg += jetSoins.roll + " PVs"; } @@ -22565,11 +22671,11 @@ var COFantasy = COFantasy || function() { }); attrs = removeAllAttributes('secondSouffleUtilise', evt, attrs); attrs = removeAllAttributes('PVsDebutCombat', evt, attrs); - // On diminue l'\xE9bri\xE9t\xE9 des personnages sous vapeurs \xE9thyliques + // On diminue l'ébriété des personnages sous vapeurs éthyliques allAttributesNamed(attrs, 'vapeursEthyliques').forEach(function(attr) { let veCharId = attr.get('characterid'); if (veCharId === undefined || veCharId === '') { - error("Attribut sans personnage associ\xE9", attr); + error("Attribut sans personnage associé", attr); return; } iterTokensOfAttribute(veCharId, combat.pageId, @@ -22580,7 +22686,7 @@ var COFantasy = COFantasy || function() { token: tok }; removeTokenAttr(perso, 'niveauEbriete', evt, { - msg: "d\xE9sao\xFBle" + msg: "désaoûle" }); }); }); @@ -22592,7 +22698,7 @@ var COFantasy = COFantasy || function() { degainerArme(perso, '', evt); } }); - // On remet en main l'arme par d\xE9faut si elle est pr\xE9cis\xE9e + // On remet en main l'arme par défaut si elle est précisée persosDuCombat.forEach(function(perso) { if (!isActive(perso)) return; let persoTest = persoParCharId[perso.charId]; @@ -22630,7 +22736,7 @@ var COFantasy = COFantasy || function() { ilds.forEach(function(ild) { let douleur = parseInt(ild.get('current')); if (isNaN(douleur)) { - error("La douleur ignor\xE9e n'est pas un nombre", douleur); + error("La douleur ignorée n'est pas un nombre", douleur); return; } let charId = ild.get('characterid'); @@ -22654,7 +22760,7 @@ var COFantasy = COFantasy || function() { pvAttr = pvAttr[0]; let pv = parseInt(pvAttr.get('current')); if (isNaN(pv)) { - error("PV mal form\xE9s ", pvAttr); + error("PV mal formés ", pvAttr); return; } evt.attributes.push({ @@ -22665,13 +22771,13 @@ var COFantasy = COFantasy || function() { if (newPv < 0) newPv = 0; pvAttr.set('current', newPv); if (pv > 0 && newPv === 0) { - sendChar(charId, "s'\xE9croule. Il semble sans vie. La douleur qu'il avait ignor\xE9e l'a finalement rattrap\xE9...", true); + sendChar(charId, "s'écroule. Il semble sans vie. La douleur qu'il avait ignorée l'a finalement rattrapé...", true); } else { let tempDmg = ficheAttributeAsInt(charId, 'DMTEMP', 0); if (pv > tempDmg && newPv <= tempDmg) { - sendChar(charId, "s'\xE9croule, assomm\xE9. La douleur qu'il avait ignor\xE9e l'a finalement rattrap\xE9...", true); + sendChar(charId, "s'écroule, assommé. La douleur qu'il avait ignorée l'a finalement rattrapé...", true); } else { - sendChar(charId, "subit le contrecoup de la douleur qu'il avait ignor\xE9e", true); + sendChar(charId, "subit le contrecoup de la douleur qu'il avait ignorée", true); } } } else { // ignorer la douleur d'un token @@ -22683,11 +22789,11 @@ var COFantasy = COFantasy || function() { name: tokName }); if (tokensIld.length === 0) { - error("Pas de token nomm\xE9 " + tokName + " qui aurait ignor\xE9 la douleur", ild); + error("Pas de token nommé " + tokName + " qui aurait ignoré la douleur", ild); return; } if (tokensIld.length > 1) { - sendChar(charId, "a plusieurs tokens nomm\xE9s " + tokName + ". Un seul d'entre eux subira l'effet d'ignorer la douleur", true); + sendChar(charId, "a plusieurs tokens nommés " + tokName + ". Un seul d'entre eux subira l'effet d'ignorer la douleur", true); } let tokPv = parseInt(tokensIld[0].get('bar1_value')); let tokNewPv = tokPv - douleur; @@ -22714,7 +22820,7 @@ var COFantasy = COFantasy || function() { } //Attributs qu'on veut enlever en dernier let removedLaterAttrs = []; - // fin des effets temporaires (dur\xE9e en tours, ou dur\xE9e = combat) + // fin des effets temporaires (durée en tours, ou durée = combat) attrs.forEach(function(obj) { let attrName = obj.get('name'); let charId = obj.get('characterid'); @@ -22768,7 +22874,7 @@ var COFantasy = COFantasy || function() { }, { tousLesTokens: true }); - //Pas besoin de d\xE9truire l'attribut, ce sera fait plus loin + //Pas besoin de détruire l'attribut, ce sera fait plus loin } evt.deletedAttributes.push(obj); obj.remove(); @@ -22831,7 +22937,7 @@ var COFantasy = COFantasy || function() { } //Asynchrone - // ne rajoute pas evt \xE0 l'historique + // ne rajoute pas evt à l'historique function soinsEcuyers(ecuyers, manquePV, playerId, evt) { ecuyers.forEach(function(ec) { const ecuyer = ec.perso; @@ -22841,11 +22947,11 @@ var COFantasy = COFantasy || function() { name: ecuyerDe }); if (charChevalier.length === 0) { - error("Pas de chevalier " + ecuyerDe + " pour l'\xE9cuyer " + nomPerso(ecuyer), ec); + error("Pas de chevalier " + ecuyerDe + " pour l'écuyer " + nomPerso(ecuyer), ec); return; } if (charChevalier.length > 1) { - error("Plusieurs personnages nomm\xE9s " + ecuyerDe + ". Attention aux ambiguit\xE9s."); + error("Plusieurs personnages nommés " + ecuyerDe + ". Attention aux ambiguités."); } charChevalier = charChevalier[0].id; let maxASoigner = modCarac(charChevalier, 'charisme') + 1; @@ -22869,17 +22975,17 @@ var COFantasy = COFantasy || function() { } alliesASoigner.push(cible); } - }); //fin de d\xE9termination des cibles + }); //fin de détermination des cibles if (chevalier === undefined && monture === undefined && - (maxASoigner < 1 || alliesASoigner.length === 0)) { //Personne \xE0 soigner + (maxASoigner < 1 || alliesASoigner.length === 0)) { //Personne à soigner return; } - //TODO: utiliser l'id d'un player qui contr\xF4le le chevalier - let display = startFramedDisplay(playerId, "Services d'\xE9cuyer", ecuyer); + //TODO: utiliser l'id d'un player qui contrôle le chevalier + let display = startFramedDisplay(playerId, "Services d'écuyer", ecuyer); let finSoin = function() { nbCibles--; if (nbCibles === 0) { - if (display) sendChat("", endFramedDisplay(display)); + if (display) sendFramedDisplay(display); } }; let soigneUneCible = function(c) { @@ -22891,17 +22997,17 @@ var COFantasy = COFantasy || function() { if (c.token.id == ecuyer.token.id) { msgSoin = 'se soigne de '; } else { - msgSoin = nomPerso(c) + " r\xE9cup\xE8re "; + msgSoin = nomPerso(c) + " récupère "; } if (s < soins) - msgSoin += s + " PV. (Le r\xE9sultat du jet \xE9tait " + soinTxt + ")"; + msgSoin += s + " PV. (Le résultat du jet était " + soinTxt + ")"; else msgSoin += soinTxt + " PV."; addLineToFramedDisplay(display, msgSoin); }; soigneToken(c, soins, evt, printTrue); finSoin(); }); //fin du sendChat - }; // fin de d\xE9finition de soigneCible + }; // fin de définition de soigneCible let peutToutSoigner = (alliesASoigner.length <= maxASoigner); if (peutToutSoigner) nbCibles += alliesASoigner.length; else if (maxASoigner > 0) nbCibles++; //pour ne pas finir avant d'imprimer les boutons @@ -22921,7 +23027,7 @@ var COFantasy = COFantasy || function() { }); finSoin(); } - }); //fin iteration sur les \xE9cuyers + }); //fin iteration sur les écuyers } function parseOptions(msg) { @@ -22929,7 +23035,7 @@ var COFantasy = COFantasy || function() { if (msg.selected && msg.selected.length > 0) { let firstSelected = getObj('graphic', msg.selected[0]._id); if (firstSelected === undefined) { - error("Un token s\xE9lectionn\xE9 n'est pas trouv\xE9 en interne", msg.selected); + error("Un token sélectionné n'est pas trouvé en interne", msg.selected); return; } pageId = firstSelected.get('pageid'); @@ -22963,7 +23069,7 @@ var COFantasy = COFantasy || function() { break; case 'lanceur': if (cmd.length < 2) { - error("Il faut pr\xE9ciser l'id ou le nom du lanceur", arg); + error("Il faut préciser l'id ou le nom du lanceur", arg); return; } options.lanceur = persoOfId(cmd[1], cmd[1], pageId); @@ -23011,7 +23117,7 @@ var COFantasy = COFantasy || function() { cout = parseInt(cmd[1]); } if (isNaN(cout) || cout < 0) { - error("Co\xFBt en mana incorrect", cmd); + error("Coût en mana incorrect", cmd); return; } options.mana = options.mana || 0; @@ -23026,7 +23132,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { cout = parseInt(cmd[1]); if (isNaN(cout) || cout < 0) { - error("Le co\xFBt de la magie rapide n'est pas un entier positif", cmd); + error("Le coût de la magie rapide n'est pas un entier positif", cmd); cout = 1; } } @@ -23045,19 +23151,19 @@ var COFantasy = COFantasy || function() { } let rang = parseInt(cmd[1]); if (isNaN(rang) || rang < 1) { - error("Le rang doit \xEAtre un nombre positif"); + error("Le rang doit être un nombre positif"); return; } options.rang = rang; break; case 'limiteParJour': if (cmd.length < 2) { - error("Il manque la limite journali\xE8re", cmd); + error("Il manque la limite journalière", cmd); return; } let limiteParJour = parseInt(cmd[1]); if (isNaN(limiteParJour) || limiteParJour < 1) { - error("La limite journali\xE8re doit \xEAtre un nombre positif", cmd); + error("La limite journalière doit être un nombre positif", cmd); return; } options.limiteParJour = limiteParJour; @@ -23068,24 +23174,24 @@ var COFantasy = COFantasy || function() { return; case 'depasseLimite': if (cmd.length < 2) { - error("Il manque le co\xFBt en mana pour depasser la limite", cmd); + error("Il manque le coût en mana pour depasser la limite", cmd); return; } let depasse = parseInt(cmd[1]); if (isNaN(depasse) || depasse < 1) { - error("Le co\xFBt de d\xE9passement doit \xEAtre un nombre positif", cmd); + error("Le coût de dépassement doit être un nombre positif", cmd); return; } options.depasseLimite = depasse; return; case 'limiteSoinsParJour': if (cmd.length < 2) { - error("Il manque la limite de soins journali\xE8re", cmd); + error("Il manque la limite de soins journalière", cmd); return; } let limiteSoinsParJour = parseInt(cmd[1]); if (isNaN(limiteSoinsParJour) || limiteSoinsParJour < 1) { - error("La limite de soins journali\xE8re doit \xEAtre un nombre positif", cmd); + error("La limite de soins journalière doit être un nombre positif", cmd); return; } options.limiteSoinsParJour = limiteSoinsParJour; @@ -23096,12 +23202,12 @@ var COFantasy = COFantasy || function() { return; case 'limiteCibleParJour': if (cmd.length < 2) { - error("Il manque la limite journali\xE8re", cmd); + error("Il manque la limite journalière", cmd); return; } let limiteCibleParJour = parseInt(cmd[1]); if (isNaN(limiteCibleParJour) || limiteCibleParJour < 1) { - error("La limite journali\xE8re doit \xEAtre un nombre positif", cmd); + error("La limite journalière doit être un nombre positif", cmd); return; } options.limiteCibleParJour = limiteCibleParJour; @@ -23117,7 +23223,7 @@ var COFantasy = COFantasy || function() { } let limiteParCombat = parseInt(cmd[1]); if (isNaN(limiteParCombat) || limiteParCombat < 1) { - error("La limite par combat doit \xEAtre un nombre positif", cmd); + error("La limite par combat doit être un nombre positif", cmd); return; } options.limiteParCombat = limiteParCombat; @@ -23128,16 +23234,16 @@ var COFantasy = COFantasy || function() { return; case 'tempsRecharge': if (cmd.length < 3) { - error("Il manque un argument \xE0 l'option --tempsRecharge", cmd); + error("Il manque un argument à l'option --tempsRecharge", cmd); return; } if (!estEffetTemp(cmd[1])) { - error("Le premier argument de l'option --tempsRecharge doit \xEAtre un effet temporaire r\xE9pertori\xE9", cmd); + error("Le premier argument de l'option --tempsRecharge doit être un effet temporaire répertorié", cmd); return; } let tr = parseInt(cmd[2]); if (isNaN(tr)) { - error("Le deuxi\xE8me argument de l'option --tempsRecharge doit \xEAtre un nombre", cmd); + error("Le deuxième argument de l'option --tempsRecharge doit être un nombre", cmd); return; } options.tempsRecharge = { @@ -23162,7 +23268,7 @@ var COFantasy = COFantasy || function() { portee = parseInt(cmd[1]); } if (isNaN(portee) || portee < 0) { - error("Port\xE9e incorrecte", cmd); + error("Portée incorrecte", cmd); return; } options.portee = portee; @@ -23185,21 +23291,21 @@ var COFantasy = COFantasy || function() { return; case 'decrAttribute': if (cmd.length < 2) { - error("Erreur interne d'une commande g\xE9n\xE9r\xE9e par bouton", opts); + error("Erreur interne d'une commande générée par bouton", opts); return; } let attr = getObj('attribute', cmd[1]); if (attr === undefined && options.lanceur) { attr = tokenAttribute(options.lanceur, cmd[1]); if (attr.length === 0) { - log("Attribut \xE0 changer perdu"); + log("Attribut à changer perdu"); log(cmd); return; } attr = attr[0]; } if (attr === undefined) { - log("Attribut \xE0 changer perdu"); + log("Attribut à changer perdu"); log(cmd); return; } @@ -23250,14 +23356,14 @@ var COFantasy = COFantasy || function() { break; case "classeEffet": if (cmd.length < 2) { - sendChat("COF", "Il manque un argument \xE0 l'option --classeEffet"); + sendChat("COF", "Il manque un argument à l'option --classeEffet"); return; } options.classeEffet = cmd[1]; return; case 'message': if (cmd.length < 2) { - error("Il manque le message apr\xE8s --message", cmd); + error("Il manque le message après --message", cmd); return; } options.messages = options.messages || []; @@ -23265,7 +23371,7 @@ var COFantasy = COFantasy || function() { return; case 'messageMJ': if (cmd.length < 2) { - error("Il manque le message apr\xE8s --messageMJ", cmd); + error("Il manque le message après --messageMJ", cmd); return; } options.messagesMJ = options.messagesMJ || []; @@ -23273,14 +23379,14 @@ var COFantasy = COFantasy || function() { return; case 'image': if (cmd.length < 2) { - error("Il manque le nom de l'imageapr\xE8s --image", cmd); + error("Il manque le nom de l'imageaprès --image", cmd); return; } options.image = cmd[1].replace(':', ':'); return; case 'son': if (cmd.length < 2) { - error("Il manque le nom du son apr\xE8s --son", cmd); + error("Il manque le nom du son après --son", cmd); return; } options.son = cmd.slice(1).join(' '); @@ -23306,7 +23412,7 @@ var COFantasy = COFantasy || function() { return; case 'etat': if (cmd.length < 2) { - error("Il manque le nom de l'\xE9tat et sa valeur apr\xE8s --etat", cmd); + error("Il manque le nom de l'état et sa valeur après --etat", cmd); return; } options.etats = options.etats || {}; @@ -23326,7 +23432,7 @@ var COFantasy = COFantasy || function() { case 'dm': let t = cmd[0]; if (options[t]) { - error(t + " d\xE9j\xE0 d\xE9fini", opts); + error(t + " déjà défini", opts); return; } if (cmd.length < 2) { @@ -23349,7 +23455,7 @@ var COFantasy = COFantasy || function() { } else { let base = parseInt(cmd[1]); if (isNaN(base)) { - error("L'argument de --magieEnArmure doit \xEAtre un nombre ou mana", cmd); + error("L'argument de --magieEnArmure doit être un nombre ou mana", cmd); return; } options.magieEnArmure = { @@ -23362,12 +23468,12 @@ var COFantasy = COFantasy || function() { return; case 'tokenSide': if (cmd.length < 2) { - error("Il faut pr\xE9ciser le cot\xE9 de token \xE0 utiliser", cmd); + error("Il faut préciser le coté de token à utiliser", cmd); return; } let side = parseInt(cmd[1]); if (isNaN(side) || side < 0) { - error("Le cot\xE9 de token doit \xEAtre un nombre positif", cmd); + error("Le coté de token doit être un nombre positif", cmd); return; } options.tokenSide = side; @@ -23379,11 +23485,11 @@ var COFantasy = COFantasy || function() { return options; } - //Si il y a des effets \xE0 dur\xE9e ind\xE9termin\xE9es, les rappeler au MJ, avec un bouton pour facilement y mettre fin si n\xE9cessaire + //Si il y a des effets à durée indéterminées, les rappeler au MJ, avec un bouton pour facilement y mettre fin si nécessaire function proposerFinEffetsIndetermines() { - //On commence par les \xE9tats globaux + //On commence par les états globaux if (stateCOF.tenebresMagiques) { - sendPlayer('GM', boutonSimple("!cof-tenebres-magiques fin", "Mettre fin") + "aux t\xE9n\xE8bres magiques ?"); + sendPlayer('GM', boutonSimple("!cof-tenebres-magiques fin", "Mettre fin") + "aux ténèbres magiques ?"); } if (stateCOF.effetAuD20) { for (let ev in stateCOF.effetAuD20) { @@ -23399,7 +23505,7 @@ var COFantasy = COFantasy || function() { estEffetIndetermine(name); }); if (attrs.length === 0) return; - const display = startFramedDisplay(undefined, "Effets \xE0 dur\xE9e ind\xE9termin\xE9e actifs", undefined, { + const display = startFramedDisplay(undefined, "Effets à durée indéterminée actifs", undefined, { chuchote: 'gm' }); let attrsParPerso = {}; @@ -23463,7 +23569,7 @@ var COFantasy = COFantasy || function() { } attrsParPerso[charId].effets.push(ef); return; - } // on a un attribut de token non li\xE9 + } // on a un attribut de token non lié let pn = attrName.indexOf('_'); if (pn < 1) return; ef.nom = attrName.substring(0, pn - 1); @@ -23517,11 +23623,11 @@ var COFantasy = COFantasy || function() { }); addLineToFramedDisplay(display, line); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } - // Remise \xE0 z\xE9ro de toutes les limites journali\xE8res - // N'ajoute pas evt \xE0 l'historique + // Remise à zéro de toutes les limites journalières + // N'ajoute pas evt à l'historique function jour(persos, evt, options) { let attrs; attrs = removeAllAttributes('pressionMortelle', evt); @@ -23535,14 +23641,14 @@ var COFantasy = COFantasy || function() { attrs = removeAllAttributes('immunise24HA', evt, attrs); attrs = removeAllAttributes('testsRatesDuTour', evt, attrs); attrs = removeAllAttributes('pointsDeViolence', evt, attrs); - //Les \xE9lixirs + //Les élixirs attrs = removeAllAttributes('elixirsACreer', evt, attrs); attrs = proposerRenouveauElixirs(evt, attrs, options); //Les runes attrs = proposerRenouveauRunes(evt, attrs, options); - //Les plantes m\xE9dicinales - attrs = removeAllAttributes('dose_Plante m\xE9dicinale', evt, attrs); - attrs = removeConsommables('Plante m\xE9dicinale', evt, attrs); + //Les plantes médicinales + attrs = removeAllAttributes('dose_Plante médicinale', evt, attrs); + attrs = removeConsommables('Plante médicinale', evt, attrs); //La perte de substance persos.forEach(function(perso) { if (predicateAsBool(perso, 'perteDeSubstance')) { @@ -23550,8 +23656,8 @@ var COFantasy = COFantasy || function() { let msg = nomPerso(perso) + " a maintenant " + perteDeSubstance; msg += " jour" + ((perteDeSubstance > 1) ? 's' : '') + " de perte de substance.
    "; if (!predicateAsBool(perso, 'ancreInvincible')) { - msg += " Demander un jet de CHA difficult\xE9 " + perteDeSubstance; - msg += " ou " + onGenre(perso, 'il', 'elle') + " dispara\xEEt pendant "; + msg += " Demander un jet de CHA difficulté " + perteDeSubstance; + msg += " ou " + onGenre(perso, 'il', 'elle') + " disparaît pendant "; let nj = rollDePlus(6); msg += nj.roll + " heure" + ((nj.val > 1) ? 's' : '') + '.'; } @@ -23584,13 +23690,13 @@ var COFantasy = COFantasy || function() { let attrName = attr.get('name'); let carac = attr.get('current'); if (!isCarac(carac)) { - error("Save par jour " + attrName + " mal form\xE9", carac); + error("Save par jour " + attrName + " mal formé", carac); finalize(); return; } let seuil = parseInt(attr.get('max')); if (isNaN(seuil)) { - error("Save par jour " + attrName + " mal form\xE9", seuil); + error("Save par jour " + attrName + " mal formé", seuil); finalize(); return; } @@ -23622,7 +23728,7 @@ var COFantasy = COFantasy || function() { name: attrName }); if (attrEffet === undefined || attrEffet.length === 0) { - error("Save sans effet associ\xE9 " + attrName, attr); + error("Save sans effet associé " + attrName, attr); findObjs({ _type: 'attribute', _characterid: charId, @@ -23641,11 +23747,11 @@ var COFantasy = COFantasy || function() { let sujet = onGenre(perso, 'il', 'elle'); let met = messageEffetIndetermine[effetC]; if (met === undefined) met = { - fin: "r\xE9siste \xE0 l'effet", + fin: "résiste à l'effet", actf: "reste sous l'emprise de l'effet" }; let saveOpts = { - msgPour: " pour ne plus \xEAtre sous l'effet " + effetC, + msgPour: " pour ne plus être sous l'effet " + effetC, msgReussite: ", " + sujet + ' ' + messageFin(perso, met), msgRate: ", " + sujet + ' ' + messageActif(perso, met), rolls: options.rolls, @@ -23676,7 +23782,7 @@ var COFantasy = COFantasy || function() { }); //fin boucle attrSave } - //La caract\xE9ristique sans affaiblissement + //La caractéristique sans affaiblissement function caracNormale(perso, carac) { let res = ficheAttributeAsInt(perso, carac, 10); if (!persoEstPNJ(perso)) return res; @@ -23712,7 +23818,7 @@ var COFantasy = COFantasy || function() { attributeAsInt(perso, 'affaiblissementde' + carac, 0); } - //N'ajoute pas evt \xE0 l'historique + //N'ajoute pas evt à l'historique function diminueAffaiblissement(perso, carac, valeur, evt, malus) { if (valeur < 1) return; let nomAttr = 'affaiblissementde' + carac; @@ -23740,7 +23846,7 @@ var COFantasy = COFantasy || function() { } let pvMaxNormaux = attributeAsInt(perso, 'pvMaxNormaux', 0); if (pvMaxNormaux < pvmax) { - error("Les PV max sont inf\xE9rieurs \xE0 la valeur normale", pvMaxNormaux); + error("Les PV max sont inférieurs à la valeur normale", pvMaxNormaux); return; } if (valeur == malus || (valeur == malus - 1 && caracNormale(perso, 'consititution') % 2 == 1)) { @@ -23767,7 +23873,7 @@ var COFantasy = COFantasy || function() { } } } else if (valeur == malus) { - //Au cas o\xF9, on v\xE9rifie le pv max + //Au cas où, on vérifie le pv max let pvMaxNormaux = attributeAsInt(perso, 'pvMaxNormaux', 0); if (pvMaxNormaux > 0) { let pvmax = parseInt(perso.token.get("bar1_max")); @@ -23825,7 +23931,7 @@ var COFantasy = COFantasy || function() { let speaksAs = player.get('speakingas'); if (speaksAs !== '') fromMsg = speaksAs; } - sendChat(fromMsg, "Un nouveau jour se l\xE8ve"); + sendChat(fromMsg, "Un nouveau jour se lève"); if (stateCOF.combat) sortirDuCombat(); jour(persos, evt, options); if (options.repos) { @@ -23842,8 +23948,8 @@ var COFantasy = COFantasy || function() { if (msg.content.includes(' --reposLong')) reposLong = true; getSelected(msg, function(selection, playerId) { if (selection.length === 0) { - sendPlayer(msg, "!cof-recuperer sans s\xE9lection de tokens", playerId); - log("!cof-recuperer requiert des tokens s\xE9lectionn\xE9s"); + sendPlayer(msg, "!cof-recuperer sans sélection de tokens", playerId); + log("!cof-recuperer requiert des tokens sélectionnés"); return; } let persos = []; @@ -23871,8 +23977,8 @@ var COFantasy = COFantasy || function() { let allCaracs = ['force', 'dexterite', 'constitution', 'intelligence', 'sagesse', 'charisme']; - //Asynchrone (jets de d\xE9s) - // ne rajoute pas evt \xE0 l'historique + //Asynchrone (jets de dés) + // ne rajoute pas evt à l'historique function recuperation(persos, reposLong, playerId, evt, options) { options = options || {}; let manquePV = []; @@ -23919,7 +24025,7 @@ var COFantasy = COFantasy || function() { let hasMana = false; let dmTemp = bar2; let estMook = token.get('bar1_link') === ''; - if (manaAttr.length > 0) { // R\xE9cup\xE9ration des points de mana + if (manaAttr.length > 0) { // Récupération des points de mana let manaMax = parseInt(manaAttr[0].get('max')); hasMana = !isNaN(manaMax) && manaMax > 0; if (hasMana) { @@ -23930,7 +24036,7 @@ var COFantasy = COFantasy || function() { } } } - if (!isNaN(dmTemp) && dmTemp > 0) { // r\xE9cup\xE9ration de DM temp + if (!isNaN(dmTemp) && dmTemp > 0) { // récupération de DM temp if (reposLong) dmTemp = 0; else dmTemp = Math.max(0, dmTemp - 10); if (hasMana) { @@ -23946,18 +24052,18 @@ var COFantasy = COFantasy || function() { return; } if (bar1 >= pvmax && !reposLong) { - //Plus rien \xE0 faire si pas un repos long + //Plus rien à faire si pas un repos long sendPerso(perso, "n'a pas besoin de repos"); finalize(); return; } if (reposLong) { - //R\xE9cup\xE9ration des affaiblissements de carac si repos long + //Récupération des affaiblissements de carac si repos long allCaracs.forEach(function(carac) { let malus = attributeAsInt(perso, 'affaiblissementde' + carac, 0); if (malus > 0) { diminueAffaiblissement(perso, carac, 1, evt, malus); - sendPerso(perso, "r\xE9cup\xE8re un point " + deCarac(carac)); + sendPerso(perso, "récupère un point " + deCarac(carac)); } }); if (bar1 >= pvmax && (!pr || pr.current == pr.max)) { @@ -23965,19 +24071,19 @@ var COFantasy = COFantasy || function() { return; } if (bar1 < pvmax && predicateAsBool(perso, 'montureMagique')) { - //La monture magique r\xE9cup\xE8re tous ses PV durant la nuit + //La monture magique récupère tous ses PV durant la nuit updateCurrentBar(perso, 1, pvmax, evt); - sendPerso(perso, "r\xE9cup\xE8re tous ses PV"); + sendPerso(perso, "récupère tous ses PV"); finalize(); return; } } - //La r\xE9cup\xE9ration de PV ou de PR + //La récupération de PV ou de PR let dVie = ficheAttributeAsInt(perso, "DV", 0); if (dVie < 4) { if (bar1 < pvmax) manquePV.push(perso); finalize(); - return; //Si pas de d\xE9 de vie, alors pas de PR. + return; //Si pas de dé de vie, alors pas de PR. } if (limiteRessources(perso, options, 'repos', 'repos', evt)) { if (bar1 < pvmax) manquePV.push(perso); @@ -23985,18 +24091,18 @@ var COFantasy = COFantasy || function() { return; } let message; - if (reposLong && pr && pr.current < pr.max) { // on r\xE9cup\xE8re un PR + if (reposLong && pr && pr.current < pr.max) { // on récupère un PR //Sauf si on a une blessure gave if (getState(perso, 'blesse')) { - let testId = 'gu\xE9rir_blessure_' + perso.token.id; + let testId = 'guérir_blessure_' + perso.token.id; testCaracteristique(perso, 'CON', 8, testId, options, evt, function(tr) { - sendPerso(perso, "fait un jet de CON pour gu\xE9rir de sa blessure"); + sendPerso(perso, "fait un jet de CON pour guérir de sa blessure"); let m = "/direct " + onGenre(perso, 'Il', 'Elle') + " fait " + tr.texte; if (tr.reussite) { - sendChar(charId, m + "≥ 8, son \xE9tat s'am\xE9liore nettement." + tr.modifiers, true); + sendChar(charId, m + "≥ 8, son état s'améliore nettement." + tr.modifiers, true); setState(perso, 'blesse', false, evt); } else { - let msgRate = m + "< 8, son \xE9tat reste pr\xE9occupant." + tr.rerolls + tr.modifiers; + let msgRate = m + "< 8, son état reste préoccupant." + tr.rerolls + tr.modifiers; sendChar(charId, msgRate, true); } finalize(); @@ -24005,25 +24111,25 @@ var COFantasy = COFantasy || function() { } let affAttr = rajouterPointDeRecuperation(perso, evt, pr); if (affAttr === undefined) { - error("Pas de point de r\xE9cup\xE9ration \xE0 rajouter et pourtant pas au max", token); + error("Pas de point de récupération à rajouter et pourtant pas au max", token); finalize(); return; } message = - "Au cours de la nuit, les points de r\xE9cup\xE9ration de " + nomPerso(perso) + - " passent de " + (pr.current - 1) + " \xE0 " + pr.current; + "Au cours de la nuit, les points de récupération de " + nomPerso(perso) + + " passent de " + (pr.current - 1) + " à " + pr.current; sendChar(charId, message, true); if (bar1 < pvmax) manquePV.push(perso); finalize(); return; } if (!reposLong && pr) { - if (pr.current === 0) { //pas possible de r\xE9cup\xE9rer - message = " a besoin d'une nuit compl\xE8te pour r\xE9cup\xE9rer"; + if (pr.current === 0) { //pas possible de récupérer + message = " a besoin d'une nuit complète pour récupérer"; sendPerso(perso, message); finalize(); return; - } else { //d\xE9pense d'un PR + } else { //dépense d'un PR enleverPointDeRecuperation(perso, pr, evt); pr.current--; } @@ -24058,10 +24164,10 @@ var COFantasy = COFantasy || function() { if (reposLong) { message = "Au cours de la nuit, "; } else { - message = "Apr\xE8s 5 minutes de repos, "; + message = "Après 5 minutes de repos, "; } - message += "r\xE9cup\xE8re " + buildinline(roll) + "+" + bonus + " PV."; - if (pr) message += " Il lui reste " + pr.current + " points de r\xE9cup\xE9ration"; + message += "récupère " + buildinline(roll) + "+" + bonus + " PV."; + if (pr) message += " Il lui reste " + pr.current + " points de récupération"; sendPerso(perso, message); finalize(); }); @@ -24088,8 +24194,8 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected, playerId) { if (selected === undefined) { - sendPlayer(msg, "!cof-recharger sans s\xE9lection de tokens", playerId); - log("!cof-recharger requiert des tokens s\xE9lectionn\xE9s"); + sendPlayer(msg, "!cof-recharger sans sélection de tokens", playerId); + log("!cof-recharger requiert des tokens sélectionnés"); return; } iterSelected(selected, function(perso) { @@ -24116,7 +24222,7 @@ var COFantasy = COFantasy || function() { attrs = attrs[0]; currentCharge = parseInt(attrs.get('current')); if (isNaN(currentCharge)) { - error("charge mal form\xE9e", attrs); + error("charge mal formée", attrs); currentCharge = 0; } } @@ -24138,7 +24244,7 @@ var COFantasy = COFantasy || function() { } else attrGrenaille = attrGrenaille[0]; currentChargeGrenaille = parseInt(attrGrenaille.get('current')); if (isNaN(currentChargeGrenaille)) { - error("charge de grenaille mal form\xE9e", attrGrenaille); + error("charge de grenaille mal formée", attrGrenaille); return; } if (currentChargeGrenaille > currentCharge) currentChargeGrenaille = currentCharge; @@ -24171,7 +24277,7 @@ var COFantasy = COFantasy || function() { } else attrGrenaille = attrGrenaille[0]; currentChargeGrenaille = parseInt(attrGrenaille.get('current')); if (isNaN(currentChargeGrenaille)) { - error("charge de grenaille mal form\xE9e", attrGrenaille); + error("charge de grenaille mal formée", attrGrenaille); return; } if (currentChargeGrenaille < currentCharge) { @@ -24187,7 +24293,7 @@ var COFantasy = COFantasy || function() { attrGrenaille = attrGrenaille[0]; currentChargeGrenaille = parseInt(attrGrenaille.get('current')); if (isNaN(currentChargeGrenaille)) { - error("charge de grenaille mal form\xE9e", attrGrenaille); + error("charge de grenaille mal formée", attrGrenaille); return; } if (currentChargeGrenaille > 0) { @@ -24202,9 +24308,9 @@ var COFantasy = COFantasy || function() { } } if (maxCharge == 1) { - sendPerso(perso, arme.name + " est d\xE9j\xE0 charg\xE9"); + sendPerso(perso, arme.name + " est déjà chargé"); } else { - sendPerso(perso, "a d\xE9j\xE0 tous ses " + arme.name + " charg\xE9s"); + sendPerso(perso, "a déjà tous ses " + arme.name + " chargés"); } }); }); @@ -24220,12 +24326,12 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let action = evt.action; if (!action) { - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); return; } let perso = evt.personnage; @@ -24233,7 +24339,7 @@ var COFantasy = COFantasy || function() { if (args.length > 2) { let roll = action.rolls[args[2]]; if (roll === undefined) { - error("Erreur interne du bouton de chance : roll non identifi\xE9", args); + error("Erreur interne du bouton de chance : roll non identifié", args); return; } if (roll.token === undefined) { @@ -24244,7 +24350,7 @@ var COFantasy = COFantasy || function() { rollId = args[2]; } if (perso === undefined) { - error("Erreur interne du bouton de chance : l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton de chance : l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24253,7 +24359,7 @@ var COFantasy = COFantasy || function() { } let chance = pointsDeChance(perso); if (chance <= 0) { - sendPerso(perso, "n'a plus de point de chance \xE0 d\xE9penser..."); + sendPerso(perso, "n'a plus de point de chance à dépenser..."); return; } let evtChance = { @@ -24263,7 +24369,7 @@ var COFantasy = COFantasy || function() { chance--; undoEvent(evt); setFicheAttr(perso, 'pc', chance, evtChance, { - msg: " a d\xE9pens\xE9 un point de chance. Il lui en reste " + chance + msg: " a dépensé un point de chance. Il lui en reste " + chance }); action.options = action.options || {}; if (rollId) { @@ -24273,7 +24379,7 @@ var COFantasy = COFantasy || function() { action.options.chance = (action.options.chance + 10) || 10; } if (!redoEvent(evt, action, perso)) - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); addEvent(evtChance); } @@ -24286,19 +24392,19 @@ var COFantasy = COFantasy || function() { } const evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let perso = evt.personnage; let rollId; if (args.length > 2) { if (!evt.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let roll = evt.action.rolls[args[2]]; if (roll === undefined) { - error("Erreur interne du bouton de chance : roll non identifi\xE9", args); + error("Erreur interne du bouton de chance : roll non identifié", args); return; } if (roll.token === undefined) { @@ -24309,7 +24415,7 @@ var COFantasy = COFantasy || function() { rollId = args[2]; } if (perso === undefined) { - error("Erreur interne du bouton de prouesse : l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton de prouesse : l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24345,7 +24451,7 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evtProuesse, false, {}, explications, function(dmgDisplay, dmg) { - sendPerso(perso, "r\xE9alise une prouesse et perd " + dmgDisplay + " PV"); + sendPerso(perso, "réalise une prouesse et perd " + dmgDisplay + " PV"); explications.forEach(function(expl) { sendPerso(perso, expl); }); @@ -24359,7 +24465,7 @@ var COFantasy = COFantasy || function() { } if (redoEvent(evt, action, perso)) return; } - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); } //!cof-pacte-sanglant [evt.id] [3|5] [rollId] @@ -24371,7 +24477,7 @@ var COFantasy = COFantasy || function() { } const evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let bonus = parseInt(args[2]); @@ -24383,12 +24489,12 @@ var COFantasy = COFantasy || function() { let rollId; if (args.length > 3) { if (!evt.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let roll = evt.action.rolls[args[3]]; if (roll === undefined) { - error("Erreur interne du bouton de pacte sanglant : roll non identifi\xE9", args); + error("Erreur interne du bouton de pacte sanglant : roll non identifié", args); return; } if (roll.token === undefined) { @@ -24399,7 +24505,7 @@ var COFantasy = COFantasy || function() { rollId = args[3]; } if (perso === undefined) { - error("Erreur interne du bouton de pacte sanglant : l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton de pacte sanglant : l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24408,7 +24514,7 @@ var COFantasy = COFantasy || function() { } let valPacteSanglant = predicateAsInt(perso, 'pacteSanglant', 0); if (valPacteSanglant < bonus) { - sendPerso(perso, "ne peut pas faire \xE7a !"); + sendPerso(perso, "ne peut pas faire ça !"); return; } let action = evt.action; @@ -24437,7 +24543,7 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evtPacteSanglant, false, {}, explications, function(dmgDisplay, dmg) { - sendPerso(perso, "r\xE9alise un Pacte sanglant et perd " + dmgDisplay + " PV"); + sendPerso(perso, "réalise un Pacte sanglant et perd " + dmgDisplay + " PV"); explications.forEach(function(expl) { sendPerso(perso, expl); }); @@ -24450,7 +24556,7 @@ var COFantasy = COFantasy || function() { } if (redoEvent(evt, action, perso)) return; } - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); } //!cof-pacte-sanglant [evt.id] [3|5] [targetId] @@ -24462,11 +24568,11 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } if (!evt.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let bonus = parseInt(args[2]); @@ -24476,7 +24582,7 @@ var COFantasy = COFantasy || function() { } let perso = persoOfId([args[3]]); if (perso === undefined) { - error("Erreur interne du bouton de pacte sanglant (DEF) : pas de cible trouv\xE9e", args); + error("Erreur interne du bouton de pacte sanglant (DEF) : pas de cible trouvée", args); return; } if (!peutController(msg, perso)) { @@ -24485,7 +24591,7 @@ var COFantasy = COFantasy || function() { } let valPacteSanglant = predicateAsInt(perso, 'pacteSanglant', 0); if (valPacteSanglant < bonus) { - sendPerso(perso, "ne peut pas faire \xE7a !"); + sendPerso(perso, "ne peut pas faire ça !"); return; } let action = evt.action; @@ -24513,7 +24619,7 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evtPacteSanglant, false, {}, explications, function(dmgDisplay, dmg) { - sendPerso(perso, "r\xE9alise un Pacte sanglant et perd " + dmgDisplay + " PV"); + sendPerso(perso, "réalise un Pacte sanglant et perd " + dmgDisplay + " PV"); explications.forEach(function(expl) { sendPerso(perso, expl); }); @@ -24522,7 +24628,7 @@ var COFantasy = COFantasy || function() { options.pacteSanglantDef[perso.token.id] = (options.pacteSanglantDef[perso.token.id] + bonus) || bonus; if (redoEvent(evt, action, perso)) return; } - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); } //!cof-tour-force [evt.id] [rollId] @@ -24534,19 +24640,19 @@ var COFantasy = COFantasy || function() { } const evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let perso = evt.personnage; let rollId; if (args.length > 2) { if (!evt.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let roll = evt.action.rolls[args[2]]; if (roll === undefined) { - error("Erreur interne du bouton de tour de force : roll non identifi\xE9", args); + error("Erreur interne du bouton de tour de force : roll non identifié", args); return; } if (roll.token === undefined) { @@ -24557,7 +24663,7 @@ var COFantasy = COFantasy || function() { rollId = args[2]; } if (perso === undefined) { - error("Erreur interne du bouton de tour de force : l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton de tour de force : l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24566,7 +24672,7 @@ var COFantasy = COFantasy || function() { } let attrTourDeForce = predicateAsBool(perso, 'tourDeForce'); if (!attrTourDeForce) { - sendPerso(perso, "ne peut pas faire \xE7a !"); + sendPerso(perso, "ne peut pas faire ça !"); return; } let action = evt.action; @@ -24593,7 +24699,7 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evtTourDeForce, false, {}, explications, function(dmgDisplay, dmg) { - sendPerso(perso, "r\xE9alise un Tour de force et perd " + dmgDisplay + " PV"); + sendPerso(perso, "réalise un Tour de force et perd " + dmgDisplay + " PV"); explications.forEach(function(expl) { sendPerso(perso, expl); }); @@ -24606,7 +24712,7 @@ var COFantasy = COFantasy || function() { } if (redoEvent(evt, action, perso)) return; } - error("Type d'\xE9v\xE8nement pas encore g\xE9r\xE9 pour la chance", evt); + error("Type d'évènement pas encore géré pour la chance", evt); } //Renvoie true si redo possible, false sinon @@ -24665,7 +24771,7 @@ var COFantasy = COFantasy || function() { action.testINT, action.infosAdditionelles, options); return true; case 'enveloppement': - case '\xE9treinte': + case 'étreinte': doEnveloppement(action.attaquant, action.cible, action.difficulte, action.type, action.exprDM, options); return true; case 'injonction': @@ -24757,12 +24863,12 @@ var COFantasy = COFantasy || function() { } let evt = findEvent(args[1]); if (evt === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let perso = evt.personnage; if (perso === undefined) { - error("Erreur interne du bouton d'\xE9chec total: l'\xE9venement n'a pas de personnage", evt); + error("Erreur interne du bouton d'échec total: l'évenement n'a pas de personnage", evt); return; } if (!peutController(msg, perso)) { @@ -24771,14 +24877,14 @@ var COFantasy = COFantasy || function() { } let action = evt.action; if (!action || evt.type != "Attaque") { - error("Erreur interne du bouton d'\xE9chec total: l'\xE9v\xE8nement n'est pas une attaque", evt); + error("Erreur interne du bouton d'échec total: l'évènement n'est pas une attaque", evt); return; } let evtEchecTotal = { type: 'echecTotal' }; addEvent(evtEchecTotal); - // Attaquer avec les m\xEAmes options, vider redo et preDmg \xE9ventuels + // Attaquer avec les mêmes options, vider redo et preDmg éventuels let options = action.options; options.auto = true; options.echecTotal = true; @@ -24800,11 +24906,11 @@ var COFantasy = COFantasy || function() { if (limiteRessources(perso, { limiteParCombat: rangExpertDuCombat * 2, limiteParTour: limiteParTour - }, "expertDuCombat", "a atteint sa limite de d\xE9 d'expert du combat", evt)) { + }, "expertDuCombat", "a atteint sa limite de dé d'expert du combat", evt)) { addEvent(evt); return false; } - sendPerso(perso, "utilise un d\xE9 d'expert du combat"); + sendPerso(perso, "utilise un dé d'expert du combat"); return true; } @@ -24813,19 +24919,19 @@ var COFantasy = COFantasy || function() { //!cof-expert-combat-dm function expertDuCombat(msg) { if (!stateCOF.combat) { - sendPlayer(msg, "On ne peut utiliser les d\xE9s d'expert du combat qu'en combat"); + sendPlayer(msg, "On ne peut utiliser les dés d'expert du combat qu'en combat"); return; } let cmd = msg.content.split(' '); let evtARefaire; const evt = { - type: "D\xE9 d'expert du combat (touche)", + type: "Dé d'expert du combat (touche)", attributes: [] }; - if (cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 1) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; @@ -24835,7 +24941,7 @@ var COFantasy = COFantasy || function() { return; } if (perso === undefined) { - error("Erreur interne du bouton expert de combat : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton expert de combat : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -24851,11 +24957,11 @@ var COFantasy = COFantasy || function() { else if (cmd[0].includes("-dm")) action.options.expertDuCombatDM = action.options.expertDuCombatDM + 1 || 1; if (!redoEvent(evtARefaire, action, perso)) - error("Type d'\xE9v\xE8nement pas support\xE9 par le bouton Rune d'Energie", evt); - } else { //Juste pour v\xE9rifier l'attribut et le diminuer + error("Type d'évènement pas supporté par le bouton Rune d'Energie", evt); + } else { //Juste pour vérifier l'attribut et le diminuer getSelected(msg, function(selection) { if (selection.length === 0) { - sendPlayer(msg, 'Pas de token s\xE9lectionn\xE9 pour !cof-bouton-expert-combat-touche'); + sendPlayer(msg, 'Pas de token sélectionné pour !cof-bouton-expert-combat-touche'); return; } iterSelected(selection, function(perso) { @@ -24875,17 +24981,17 @@ var COFantasy = COFantasy || function() { } let evtARefaire = findEvent(args[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou \xE9te annul\xE9e", args); + error("L'action est trop ancienne ou éte annulée", args); return; } let action = evtARefaire.action; if (action === undefined) { - error("Le dernier \xE9v\xE8nement n'est pas une action", args); + error("Le dernier évènement n'est pas une action", args); return; } let perso = persoOfId([args[2]]); if (perso === undefined) { - error("Erreur interne du bouton d'expert du combat (DEF) : pas de cible trouv\xE9e", args); + error("Erreur interne du bouton d'expert du combat (DEF) : pas de cible trouvée", args); return; } if (!peutController(msg, perso)) { @@ -24906,37 +25012,37 @@ var COFantasy = COFantasy || function() { } function persoUtiliseRuneEnergie(perso, evt) { - let attr = tokenAttribute(perso, 'runeForgesort_\xE9nergie'); + let attr = tokenAttribute(perso, 'runeForgesort_énergie'); if (attr.length < 1 || attr[0].get('current') < 1) { - sendPerso(perso, "n'a pas de rune d'\xE9nergie"); + sendPerso(perso, "n'a pas de rune d'énergie"); return false; } if (limiteRessources(perso, { limiteParCombat: 1 - }, "runeForgesort_\xE9nergie", "a d\xE9j\xE0 utilis\xE9 sa rune d'\xE9nergie durant ce combat", evt)) { + }, "runeForgesort_énergie", "a déjà utilisé sa rune d'énergie durant ce combat", evt)) { addEvent(evt); return false; } - sendPerso(perso, "utilise sa rune d'\xE9nergie pour relancer un d20 sur un test d'attaque, de FOR, DEX ou CON"); + sendPerso(perso, "utilise sa rune d'énergie pour relancer un d20 sur un test d'attaque, de FOR, DEX ou CON"); return true; } //!cof-bouton-rune-energie function runeEnergie(msg) { if (!stateCOF.combat) { - sendPlayer(msg, "On ne peut utiliser les runes d'\xE9nergie qu'en combat"); + sendPlayer(msg, "On ne peut utiliser les runes d'énergie qu'en combat"); return; } let cmd = msg.content.split(' '); let evtARefaire; const evt = { - type: "Rune d'\xE9nergie", + type: "Rune d'énergie", attributes: [] }; - if (cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 1) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; @@ -24949,7 +25055,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 2) { let roll = action.rolls[cmd[2]]; if (roll === undefined) { - error("Erreur interne du bouton de chance : roll non identifi\xE9", cmd); + error("Erreur interne du bouton de chance : roll non identifié", cmd); return; } if (roll.token === undefined) { @@ -24961,7 +25067,7 @@ var COFantasy = COFantasy || function() { evt.rollId = rollId; } if (perso === undefined) { - error("Erreur interne du bouton de rune d'\xE9nergie : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton de rune d'énergie : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -24970,7 +25076,7 @@ var COFantasy = COFantasy || function() { } let carac = action.caracteristque; if (carac == 'SAG' || carac == 'INT' || carac == 'CHA') { - sendPerso(perso, "ne peut pas utiliser la rune d'\xE9nergie pour un test " + deCarac(carac)); + sendPerso(perso, "ne peut pas utiliser la rune d'énergie pour un test " + deCarac(carac)); return; } if (!persoUtiliseRuneEnergie(perso, evt)) return; @@ -24979,11 +25085,11 @@ var COFantasy = COFantasy || function() { if (rollId) delete action.rolls[rollId]; else if (action.rolls && action.rolls.attack) delete action.rolls.attack; if (!redoEvent(evtARefaire, action, perso)) - error("Type d'\xE9v\xE8nement pas support\xE9 par le bouton Rune d'Energie", evt); - } else { //Juste pour v\xE9rifier l'attribut et le diminuer + error("Type d'évènement pas supporté par le bouton Rune d'Energie", evt); + } else { //Juste pour vérifier l'attribut et le diminuer getSelected(msg, function(selection) { if (selection.length === 0) { - sendPlayer(msg, 'Pas de token s\xE9lectionn\xE9 pour !cof-rune-energie'); + sendPlayer(msg, 'Pas de token sélectionné pour !cof-rune-energie'); return; } iterSelected(selection, function(perso) { @@ -24998,7 +25104,7 @@ var COFantasy = COFantasy || function() { let attrName = permanent ? 'runeDePuissance' + labelArme : "runeForgesort_puissance(" + labelArme + ")"; let arme = getAttackName(labelArme, perso); if (arme === undefined) { - error(perso.tokNname + " n'a pas d'arme associ\xE9e au label " + labelArme, perso); + error(perso.tokNname + " n'a pas d'arme associée au label " + labelArme, perso); return false; } if (!permanent && tokenAttribute(perso, attrName).length === 0) { @@ -25007,7 +25113,7 @@ var COFantasy = COFantasy || function() { } if (limiteRessources(perso, { limiteParCombat: 1 - }, attrName, "a d\xE9j\xE0 utilis\xE9 sa rune de puissance durant ce combat", evt)) { + }, attrName, "a déjà utilisé sa rune de puissance durant ce combat", evt)) { addEvent(evt); return false; } @@ -25024,7 +25130,7 @@ var COFantasy = COFantasy || function() { } let cmd = msg.content.split(' '); if (cmd.length < 2) { - error("Il faut sp\xE9cifier le label de l'arme sur laquelle la rune de puissance est inscrite", cmd); + error("Il faut spécifier le label de l'arme sur laquelle la rune de puissance est inscrite", cmd); return; } let labelArme = cmd[1]; @@ -25033,15 +25139,15 @@ var COFantasy = COFantasy || function() { type: "Rune de puissance", attributes: [] }; - if (cmd.length > 2) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 2) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[2]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; if (perso === undefined) { - error("Erreur interne du bouton de rune de puissance : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton de rune de puissance : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -25074,10 +25180,10 @@ var COFantasy = COFantasy || function() { default: return; } - } else { //Juste pour v\xE9rifier l'attribut et le diminuer + } else { //Juste pour vérifier l'attribut et le diminuer getSelected(msg, function(selection, playerId) { if (selection.length === 0) { - sendPlayer(msg, 'Pas de token s\xE9lectionn\xE9 pour !cof-rune-puissance', playerId); + sendPlayer(msg, 'Pas de token sélectionné pour !cof-rune-puissance', playerId); return; } iterSelected(selection, function(perso) { @@ -25101,12 +25207,12 @@ var COFantasy = COFantasy || function() { } let evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; if (perso === undefined) { - error("Erreur interne du bouton de kiai : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton de kiai : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -25148,7 +25254,7 @@ var COFantasy = COFantasy || function() { } } - //Devrait \xEAtre appel\xE9 seulement depuis un bouton + //Devrait être appelé seulement depuis un bouton //!cof-esquive-fatale evtid target_id function doEsquiveFatale(msg) { let cmd = msg.content.split(' '); @@ -25158,12 +25264,12 @@ var COFantasy = COFantasy || function() { attributes: [] }; if (cmd.length < 3) { - error("Il manque des arguments \xE0 !cof-esquive-fatale", cmd); + error("Il manque des arguments à !cof-esquive-fatale", cmd); return; } evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'attaque est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'attaque est trop ancienne ou a été annulée", cmd); return; } let action = evtARefaire.action; @@ -25173,7 +25279,7 @@ var COFantasy = COFantasy || function() { } let perso = action.cibles[0]; if (perso === undefined) { - error("Erreur interne du bouton de 'esquive fatale : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton de 'esquive fatale : l'évenement n'a pas de personnage", evtARefaire); return; } let adversaire = persoOfId(cmd[2]); @@ -25192,7 +25298,7 @@ var COFantasy = COFantasy || function() { } let ennemisAuContact = perso.ennemisAuContact; if (ennemisAuContact === undefined) { - error("Ennemis au contact non d\xE9finis", perso); + error("Ennemis au contact non définis", perso); } else { let i = ennemisAuContact.find(function(tok) { return (tok.id == adversaire.token.id); @@ -25206,12 +25312,12 @@ var COFantasy = COFantasy || function() { sendPlayer(msg, "pas le droit d'utiliser ce bouton"); return; } - let testEsquiveFatale = testLimiteUtilisationsCapa(perso, 'esquiveFatale', 'combat', "a d\xE9j\xE0 fait une esquive fatale durant ce combat", "ne sait pas faire d'esquive fatale"); + let testEsquiveFatale = testLimiteUtilisationsCapa(perso, 'esquiveFatale', 'combat', "a déjà fait une esquive fatale durant ce combat", "ne sait pas faire d'esquive fatale"); if (testEsquiveFatale === undefined) { return; } utiliseCapacite(perso, testEsquiveFatale, evt); - //On va refaire compl\xE8tement l'attaque + //On va refaire complètement l'attaque undoEvent(evtARefaire); addEvent(evt); adversaire.msgEsquiveFatale = nomPerso(perso) + " esquive l'attaque qui touche " + nomPerso(adversaire); @@ -25221,21 +25327,21 @@ var COFantasy = COFantasy || function() { redoEvent(evtARefaire, action); } - //Soit juste !cof-intercepter (en s\xE9lectionnant le chevalier) + //Soit juste !cof-intercepter (en sélectionnant le chevalier) //Soit depuis un bouton !cof-intercepter evtid cibleid function intercepter(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } let fromEvtId; if (cmd.length > 1) { fromEvtId = cmd[1]; //Appel depuis le bouton if (cmd.length < 3) { - error("Bouton d'interception mal form\xE9", cmd); + error("Bouton d'interception mal formé", cmd); return; } } @@ -25243,10 +25349,10 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(chevalier) { let character = getObj('character', chevalier.charId); if (character === undefined) { - error("L'argument de !cof-intercepter n'est pas une id de token valide (personnage non d\xE9fini)", msg.content); + error("L'argument de !cof-intercepter n'est pas une id de token valide (personnage non défini)", msg.content); return; } - let test = testLimiteUtilisationsCapa(chevalier, 'intercepter', 'tour', "a d\xE9j\xE0 intercept\xE9 une attaque ce tour", "ne sait pas utiliser intercepter les attaques"); + let test = testLimiteUtilisationsCapa(chevalier, 'intercepter', 'tour', "a déjà intercepté une attaque ce tour", "ne sait pas utiliser intercepter les attaques"); if (test === undefined) { return; } @@ -25254,7 +25360,7 @@ var COFantasy = COFantasy || function() { let attaque; let originalTarget; let evtARefaire; - if (fromEvtId) { //On a utilis\xE9 un bouton + if (fromEvtId) { //On a utilisé un bouton if (!peutController(msg, chevalier)) { sendPlayer(msg, "pas le droit d'utiliser ce bouton"); return; @@ -25288,15 +25394,15 @@ var COFantasy = COFantasy || function() { attaque = evtARefaire.action; } if (attaque === undefined) { - sendPlayer(msg, "La derni\xE8re action trouv\xE9e n'est pas une attaque, impossible d'intercepter"); + sendPlayer(msg, "La dernière action trouvée n'est pas une attaque, impossible d'intercepter"); return; } if (attaque.cibles.length === 0) { - sendPlayer(msg, "la derni\xE8re attaque n'a touch\xE9 aucune cible, impossible d'intercepter"); + sendPlayer(msg, "la dernière attaque n'a touché aucune cible, impossible d'intercepter"); return; } if (attaque.cibles.length > 1) { - sendPlayer(msg, "la derni\xE8re attaque a touch\xE9 plus d'une cible, impossible d'intercepter"); + sendPlayer(msg, "la dernière attaque a touché plus d'une cible, impossible d'intercepter"); return; } originalTarget = attaque.cibles[0]; @@ -25323,19 +25429,19 @@ var COFantasy = COFantasy || function() { }); } - //simplement prendre les DM \xE0 la place d'un autre + //simplement prendre les DM à la place d'un autre function interposer(msg) { getSelected(msg, function(selected, playerId) { iterSelected(selected, function(cible) { let charId = cible.charId; let character = getObj('character', charId); if (character === undefined) { - error("L'argument de !cof-interposer n'est pas une id de token valide (personnage non d\xE9fini)", msg.content); + error("L'argument de !cof-interposer n'est pas une id de token valide (personnage non défini)", msg.content); return; } cible.name = character.get('name'); //TODO: utile ? if (attributeAsBool(cible, 'interposer')) { - sendPerso(cible, " a d\xE9j\xE0 intercept\xE9 une attaque ce tour"); + sendPerso(cible, " a déjà intercepté une attaque ce tour"); return; } let attaque; @@ -25344,20 +25450,20 @@ var COFantasy = COFantasy || function() { attaque = lastAct.action; } if (attaque === undefined) { - sendPlayer(msg, "la derni\xE8re action trouv\xE9e n'est pas une attaque, impossible d'intercepter"); + sendPlayer(msg, "la dernière action trouvée n'est pas une attaque, impossible d'intercepter"); return; } if (attaque.cibles.length === 0) { - sendPlayer(msg, "la derni\xE8re attaque n'a touch\xE9 aucune cible, impossible de s'interposer"); + sendPlayer(msg, "la dernière attaque n'a touché aucune cible, impossible de s'interposer"); return; } if (attaque.cibles.length > 1) { - sendPlayer(msg, "la derni\xE8re attaque a touch\xE9 plus d'une cible, impossible de s'interposer en utilisant le script"); + sendPlayer(msg, "la dernière attaque a touché plus d'une cible, impossible de s'interposer en utilisant le script"); return; } let target = attaque.cibles[0]; if (target === undefined) { - error("Le token de la derni\xE8re attaque est ind\xE9fini", attaque); + error("Le token de la dernière attaque est indéfini", attaque); return; } let targetName = nomPerso(target); @@ -25374,7 +25480,7 @@ var COFantasy = COFantasy || function() { let pvApres = target.token.get('bar1_value'); // On annule l'ancienne action undoEvent(); - // On calcule ensuite les pv perdus, et on les applique au d\xE9fenseur + // On calcule ensuite les pv perdus, et on les applique au défenseur let pvPerdus = target.token.get('bar1_value') - pvApres; // Puis on refait en changeant la cible let options = attaque.options; @@ -25392,7 +25498,7 @@ var COFantasy = COFantasy || function() { getSelected(msg, function(selected, playerId) { iterSelected(selected, function(cible) { if (attributeAsBool(cible, 'exemplaire')) { - sendPerso(cible, " a d\xE9j\xE0 montr\xE9 l'exemple \xE0 ce tour"); + sendPerso(cible, " a déjà montré l'exemple à ce tour"); return; } let attaque; @@ -25403,20 +25509,20 @@ var COFantasy = COFantasy || function() { } } if (attaque === undefined) { - sendPlayer(msg, "la derni\xE8re action trouv\xE9e n'est pas une attaque rat\xE9e, impossible de montrer l'exemple", + sendPlayer(msg, "la dernière action trouvée n'est pas une attaque ratée, impossible de montrer l'exemple", playerId); return; } let attackerName = nomPerso(attaque.attaquant); if (attackerName === undefined) { - error("Le token de la derni\xE8re attaque est ind\xE9fini", attaque); + error("Le token de la dernière attaque est indéfini", attaque); return; } const evt = { type: "Montrer l'exemple" }; setTokenAttr(cible, 'exemplaire', true, evt, { - msg: "montre l'exemple \xE0 " + attackerName + msg: "montre l'exemple à " + attackerName }); // On annule l'ancienne action undoEvent(); @@ -25439,16 +25545,16 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2 || (cmd[1] != "rate" && cmd[1] != "touche")) { - error("Il manque l'option rate ou touche \xE0 Intervention Divine", msg); + error("Il manque l'option rate ou touche à Intervention Divine", msg); return; } getSelected(msg, function(selected) { iterSelected(selected, function(pretre) { - let testIntervention = testLimiteUtilisationsCapa(pretre, 'interventionDivine', 'combat', "a d\xE9j\xE0 fait une intervention divine ce combat", "ne sait pas faire d'intervention divine"); + let testIntervention = testLimiteUtilisationsCapa(pretre, 'interventionDivine', 'combat', "a déjà fait une intervention divine ce combat", "ne sait pas faire d'intervention divine"); if (testIntervention === undefined) { return; } @@ -25486,9 +25592,9 @@ var COFantasy = COFantasy || function() { }); } - //!cof-petit-veinard (avec un token s\xE9lectionn\xE9) + //!cof-petit-veinard (avec un token sélectionné) //!cof-bouton-petit-veinard evtid - //sans argument, diminue juste l'attribut, sinon relance l'\xE9v\xE9nement + //sans argument, diminue juste l'attribut, sinon relance l'événement function petitVeinard(msg) { if (!stateCOF.combat) { sendPlayer(msg, "On ne peut utiliser petit veinard qu'en combat"); @@ -25498,7 +25604,7 @@ var COFantasy = COFantasy || function() { if (msgOptions === undefined) return; let cmd = msgOptions.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } let evtARefaire; @@ -25506,22 +25612,22 @@ var COFantasy = COFantasy || function() { type: "Petit veinard", attributes: [] }; - if (cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 1) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let perso = evtARefaire.personnage; let rollId; if (cmd.length > 2) { if (!evtARefaire.action) { - error("Le dernier \xE9v\xE8nement n'est pas une action", msg.content); + error("Le dernier évènement n'est pas une action", msg.content); return; } let roll = evtARefaire.action.rolls[cmd[2]]; if (roll === undefined) { - error("Erreur interne du bouton de chance : roll non identifi\xE9", msg.content); + error("Erreur interne du bouton de chance : roll non identifié", msg.content); return; } if (roll.token === undefined) { @@ -25532,7 +25638,7 @@ var COFantasy = COFantasy || function() { rollId = cmd[2]; } if (perso === undefined) { - error("Erreur interne du bouton petit veinard : l'\xE9venement n'a pas de personnage", evtARefaire); + error("Erreur interne du bouton petit veinard : l'évenement n'a pas de personnage", evtARefaire); return; } if (!peutController(msg, perso)) { @@ -25544,7 +25650,7 @@ var COFantasy = COFantasy || function() { error("Impossible de relancer l'action", evtARefaire); return; } - let testPetitVeinard = testLimiteUtilisationsCapa(perso, 'petitVeinard', 'combat', "a d\xE9j\xE0 tent\xE9 sa chance pour ce combat", "n'est pas un petit veinard"); + let testPetitVeinard = testLimiteUtilisationsCapa(perso, 'petitVeinard', 'combat', "a déjà tenté sa chance pour ce combat", "n'est pas un petit veinard"); if (testPetitVeinard === undefined) { return; } @@ -25554,19 +25660,19 @@ var COFantasy = COFantasy || function() { if (rollId) delete action.rolls[rollId]; else if (action.rolls && action.rolls.attack) delete action.rolls.attack; if (!redoEvent(evtARefaire, action, perso)) - error("Type d'\xE9v\xE8nement pas support\xE9 par le bouton Petit Veinard", evt); - } else { //Juste pour v\xE9rifier l'attribut et le diminuer + error("Type d'évènement pas supporté par le bouton Petit Veinard", evt); + } else { //Juste pour vérifier l'attribut et le diminuer getSelected(msg, function(selection, playerId) { if (selection.length === 0) { - sendPlayer(msg, 'Pas de token s\xE9lectionn\xE9 pour !cof-petit-veinard', playerId); + sendPlayer(msg, 'Pas de token sélectionné pour !cof-petit-veinard', playerId); return; } iterSelected(selection, function(perso) { - let testPetitVeinard = testLimiteUtilisationsCapa(perso, 'petitVeinard', 'combat', "a d\xE9j\xE0 tent\xE9 sa chance pour ce combat", "n'est pas un petit veinard"); + let testPetitVeinard = testLimiteUtilisationsCapa(perso, 'petitVeinard', 'combat', "a déjà tenté sa chance pour ce combat", "n'est pas un petit veinard"); if (testPetitVeinard === undefined) { return; } - sendPerso(perso, "peut relancer un d\xE9"); + sendPerso(perso, "peut relancer un dé"); utiliseCapacite(perso, testPetitVeinard, evt); }); //fin iterSelected addEvent(evt); @@ -25579,7 +25685,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } let testSurprise; @@ -25591,8 +25697,8 @@ var COFantasy = COFantasy || function() { let ciblesSelectionnees; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "!cof-surprise sans s\xE9lection de token", playerId); - log("!cof-surprise requiert de s\xE9lectionner des tokens"); + sendPlayer(msg, "!cof-surprise sans sélection de token", playerId); + log("!cof-surprise requiert de sélectionner des tokens"); return; } ciblesSelectionnees = selected; @@ -25606,7 +25712,7 @@ var COFantasy = COFantasy || function() { if (cibles.length > 0) { doSurprise(cibles, testSurprise, ciblesSelectionnees, options); } else { - error("Pas de cible valable s\xE9lectionn\xE9e pour la surprise", msg.content); + error("Pas de cible valable sélectionnée pour la surprise", msg.content); } } @@ -25629,12 +25735,12 @@ var COFantasy = COFantasy || function() { if (testSurprise === undefined) { display = startFramedDisplay(options.playerId, "Surprise !"); } else { - display = startFramedDisplay(options.playerId, "Test de surprise difficult\xE9 " + testSurprise); + display = startFramedDisplay(options.playerId, "Test de surprise difficulté " + testSurprise); } let tokensToProcess = cibles.length; let sendEvent = function() { if (tokensToProcess == 1) { - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } tokensToProcess--; }; @@ -25650,12 +25756,12 @@ var COFantasy = COFantasy || function() { if (compagnonPresent(perso, 'surveillance')) { bonusSurprise += 5; setTokenAttr(perso, 'bonusInitEmbuscade', 5, evt); - bonusMessages.push(name + " garde un temps d'avance gr\xE2ce \xE0 son compagnon animal : +5"); + bonusMessages.push(name + " garde un temps d'avance grâce à son compagnon animal : +5"); initPerso(perso, evt, true); } if (attributeAsBool(perso, 'sixiemeSens')) { bonusSurprise += 5; - bonusMessages.push(name + " a un sixi\xE8me sens : +5"); + bonusMessages.push(name + " a un sixième sens : +5"); } if (testSurprise !== undefined) { let testId = 'surprise_' + perso.token.id; @@ -25668,9 +25774,9 @@ var COFantasy = COFantasy || function() { testCaracteristique(perso, 'SAG', testSurprise, testId, optionsTest, evt, function(tr, explications) { let result; - if (tr.reussite) result = "r\xE9ussi." + tr.modifiers; + if (tr.reussite) result = "réussi." + tr.modifiers; else { - result = "rat\xE9, " + name + " est surpris"; + result = "raté, " + name + " est surpris"; result += eForFemale(perso); result += tr.rerolls + tr.modifiers; setState(perso, 'surpris', true, evt); @@ -25693,7 +25799,7 @@ var COFantasy = COFantasy || function() { }); } - function interchangeable(attackingToken, target, pageId) { //d\xE9termine si il y a assez de tokens + function interchangeable(attackingToken, target, pageId) { //détermine si il y a assez de tokens let token = target.token; let res = { result: false, @@ -25721,7 +25827,7 @@ var COFantasy = COFantasy || function() { let d = distanceCombat(attackingToken, tok); return (d === 0); }); - } else { // cible \xE0 distance, on garde celles au contact de la cible + } else { // cible à distance, on garde celles au contact de la cible res.targets = tokens.filter(function(tok) { let d = distanceCombat(token, tok); return (d === 0); @@ -25758,8 +25864,8 @@ var COFantasy = COFantasy || function() { }, nombre: 0 }; - // Appel\xE9 uniquement apr\xE8s le "ready" et lorsqu'on modifie un handout (fonctionne apr\xE8s l'ajout et la destruction d'un handout) - // Du coup, alliesParPerso est toujours \xE0 jour + // Appelé uniquement après le "ready" et lorsqu'on modifie un handout (fonctionne après l'ajout et la destruction d'un handout) + // Du coup, alliesParPerso est toujours à jour function changeHandout(hand, prev) { if (prev && prev.name && prev.name.startsWith("Equipe ")) { const handouts = findObjs({ @@ -25772,7 +25878,7 @@ var COFantasy = COFantasy || function() { } } - //pour se d\xE9barasser des balises html + //pour se débarasser des balises html // et avoir un tableau de lignes function linesOfNote(note) { note = note.trim(); @@ -25797,7 +25903,7 @@ var COFantasy = COFantasy || function() { return c.get('name').trim() == name; }); if (charsWithName.length === 0) { - log(name + " dans l'\xE9quipe " + nomEquipe + " est inconnu"); + log(name + " dans l'équipe " + nomEquipe + " est inconnu"); return; } if (charsWithName.length > 1) { @@ -25806,7 +25912,7 @@ var COFantasy = COFantasy || function() { }); if (nonArch.length > 0) charsWithName = nonArch; if (charsWithName.length > 1) { - log(name + " dans l'\xE9quipe " + nomEquipe + " est en double"); + log(name + " dans l'équipe " + nomEquipe + " est en double"); } } charsWithName.forEach(function(character) { @@ -25834,7 +25940,7 @@ var COFantasy = COFantasy || function() { //On ajoute les familiers }); }); //end hand.get('notes') - } else if (handName == 'Comp\xE9tences' || handName == 'Competences') { + } else if (handName == 'Compétences' || handName == 'Competences') { listeCompetences = { FOR: { list: [], @@ -25863,23 +25969,23 @@ var COFantasy = COFantasy || function() { nombre: 0 }; hand.get('notes', function(note) { // asynchronous - var carac; //La carac dont on sp\xE9cifie les comp\xE9tences actuellement - var lignes = linesOfNote(note); + let carac; //La carac dont on spécifie les compétences actuellement + let lignes = linesOfNote(note); lignes.forEach(function(ligne) { ligne = ligne.trim(); - var header = ligne.split(':'); + let header = ligne.split(':'); if (header.length > 1) { - var c = header.shift().trim().toUpperCase(); + let c = header.shift().trim().toUpperCase(); if (!isCarac(c)) return; carac = c; ligne = header.join(':').trim(); } if (ligne.length === 0) return; if (carac === undefined) { - error("Comp\xE9tences sans caract\xE9ristique associ\xE9e", note); + error("Compétences sans caractéristique associée", note); return; } - var comps = ligne.split(/, |\/| /); + let comps = ligne.split(/, |\/| /); comps.forEach(function(comp) { if (comp.length === 0) return; comp = comp.replace(/_/g, ' '); @@ -25912,7 +26018,7 @@ var COFantasy = COFantasy || function() { } //options peut contenir: - // - ligneOptions : une cha\xEEne de caract\xE8res \xE0 ajouter aux attaques + // - ligneOptions : une chaîne de caractères à ajouter aux attaques // - target : l'id de la cible des attaques // - nePasAfficherArmes : quand on affiche plus tard l'arme en main function listeAttaquesVisibles(perso, options) { @@ -25920,7 +26026,7 @@ var COFantasy = COFantasy || function() { let ligneOptions = options.ligneOptions || ''; let target = options.target || '@{target|token_id}'; let ligne = ''; - //Cherche toutes les attaques \xE0 afficher + //Cherche toutes les attaques à afficher let attaques = listAllAttacks(perso); let attaquesTriees = []; let attaquesNonTriees = {}; @@ -25928,7 +26034,7 @@ var COFantasy = COFantasy || function() { let att = attaques[attLabel]; if (fieldAsInt(att, 'armeactionvisible', 1) === 0) continue; if (options.nePasAfficherArmes && estArme(att)) continue; - //V\xE9rification que des options n'emp\xEAchent pas l'utilisation de l'attaque + //Vérification que des options n'empêchent pas l'utilisation de l'attaque let attackOptions = ' ' + fieldAsString(att, 'armeoptions', ''); if (actionImpossible(perso, attackOptions.split(' --'), attLabel)) continue; //On regarde aussi si c'est une arme de jet @@ -25947,14 +26053,14 @@ var COFantasy = COFantasy || function() { for (let label in attaquesNonTriees) { ligne += attaquesNonTriees[label] + '
    '; } - //On ajoute aussi les lancers de feu gr\xE9geois, si il y en a - let attrFeuxGregeois = tokenAttribute(perso, 'elixir_feu_gr\xE9geois'); + //On ajoute aussi les lancers de feu grégeois, si il y en a + let attrFeuxGregeois = tokenAttribute(perso, 'elixir_feu_grégeois'); if (attrFeuxGregeois.length > 0) { attrFeuxGregeois = attrFeuxGregeois[0]; let feuxGregeois = parseInt(attrFeuxGregeois.get('current')); if (feuxGregeois > 0) { let command = attrFeuxGregeois.get('max').trim(); - ligne += bouton(command, 'Feu gr\xE9geois', perso, { + ligne += bouton(command, 'Feu grégeois', perso, { ressource: attrFeuxGregeois }); ligne += " (reste " + feuxGregeois + ")
    "; @@ -26017,13 +26123,13 @@ var COFantasy = COFantasy || function() { return res; } - //Si listActions est fourni, \xE7a peut faire r\xE9f\xE9rence \xE0 une ability + //Si listActions est fourni, ça peut faire référence à une ability //dont le nom commence et termine par #, contenant une liste d'actions - //\xE0 afficher - //sinon, fait r\xE9f\xE9rence \xE0 une des listes d'action de la fiche + //à afficher + //sinon, fait référence à une des listes d'action de la fiche function turnAction(perso, playerId, listActions) { const pageId = perso.token.get('pageid'); - // Toutes les Abilities du personnage li\xE9 au Token + // Toutes les Abilities du personnage lié au Token const abilities = findObjs({ _type: 'ability', _characterid: perso.charId, @@ -26050,7 +26156,7 @@ var COFantasy = COFantasy || function() { if (actionsDuTour === 0) { if (!isActive(perso)) { if (!getState(perso, 'surpris') || !compagnonPresent(perso, 'surveillance')) { - sendPerso(perso, "ne peut pas agir \xE0 ce tour"); + sendPerso(perso, "ne peut pas agir à ce tour"); return true; } } @@ -26066,23 +26172,24 @@ var COFantasy = COFantasy || function() { } } } - //actionDuTour peut \xEAtre undefined, pour la liste par d\xE9faut + //actionDuTour peut être undefined, pour la liste par défaut let actionsAAfficher; let ligne = ''; let command = ''; if (actionsParDefaut && !stateCOF.chargeFantastique && attributeAsBool(perso, 'hate')) { - ligne += "Effet de h\xE2te : une action d'attaque ou de mouvement en plus
    "; + ligne += "Effet de hâte : une action d'attaque ou de mouvement en plus
    "; } if (actionsParDefaut && !stateCOF.chargeFantastique && attributeAsBool(perso, 'reactionViolente')) { - ligne += "Crise de folie : doit attaquer la personne qui l'a provoqu\xE9 et ceux qui l'en emp\xEAchent.
    "; + ligne += "Crise de folie : doit attaquer la personne qui l'a provoqué et ceux qui l'en empêchent.
    "; ligne += boutonSimple('!cof-fin-reaction-violente ' + perso.token.id, "Prendre sur soi"); } - //Les d\xE9g\xE2ts aux personnages envelopp\xE9s par perso + //Les dégâts aux personnages enveloppés par perso let attrs_enveloppe = tokenAttribute(perso, 'enveloppe'); attrs_enveloppe.forEach(function(a) { let cible = persoOfIdName(a.get('current'), pageId); if (cible === undefined) { - error("Attribut d'enveloppe mal form\xE9 ou obsol\xE8te", a.get('current')); + error("Attribut d'enveloppe mal formé ou obsolète", a.get('current')); + a.remove(); return; } let enveloppeDM = a.get('max'); @@ -26095,21 +26202,37 @@ var COFantasy = COFantasy || function() { command = abEnveloppe.get('action').trim(); command = replaceAction(command, perso); command = command.replace(new RegExp(escapeRegExp('@{target|token_id}'), 'g'), cible.token.id); - ligne += bouton(command, "Infliger DMS \xE0 " + nomPerso(cible), perso) + '
    '; + ligne += bouton(command, "Infliger DMS à " + nomPerso(cible), perso) + '
    '; } } else if (enveloppeDM.startsWith('label ')) { actionsAAfficher = true; command = '!cof-attack ' + perso.token.id + ' ' + cible.token.id + ' ' + enveloppeDM.substring(6) + ' --auto --acide --effet paralyseTemp [[2d6]] --save CON 15'; - ligne += bouton(command, "Infliger DMs \xE0 " + nomPerso(cible), perso) + '
    '; + ligne += bouton(command, "Infliger DMs à " + nomPerso(cible), perso) + '
    '; } else if (enveloppeDM.startsWith('etreinte ')) { actionsAAfficher = true; enveloppeDM = enveloppeDM.substring(9); - command = '!cof-attack ' + perso.token.id + ' ' + cible.token.id + ' --dm ' + enveloppeDM + ' --auto --nom \xE9treinte '; - ligne += bouton(command, "Infliger DMs \xE0 " + nomPerso(cible), perso) + '
    '; + command = '!cof-attack ' + perso.token.id + ' ' + cible.token.id + ' --dm ' + enveloppeDM + ' --auto --nom étreinte '; + ligne += bouton(command, "Infliger DMs à " + nomPerso(cible), perso) + '
    '; } //else pas reconnu - //On ajoute aussi un bouton pour lib\xE9rer + //On ajoute aussi un bouton pour libérer command = '!cof-echapper-enveloppement libere --target ' + cible.token.id; - ligne += boutonSimple(command, "Lib\xE9rer " + nomPerso(cible)) + '
    '; + ligne += boutonSimple(command, "Libérer " + nomPerso(cible)) + '
    '; + }); + //Bouton pour libérer une personne qu'on agrippe + let attrs_agrippe = tokenAttribute(perso, 'agrippe'); + attrs_agrippe = + attrs_agrippe.concat( + tokenAttribute(perso, 'etreinteImmole'), + tokenAttribute(perso, 'etreinteScorpionSur'), + tokenAttribute(perso, 'devore')); + attrs_agrippe.forEach(function(a) { + let cible = persoOfIdName(a.get('current'), pageId); + if (cible === undefined) { + a.remove(); + return; + } + command = '!cof-liberer-agrippe ' + cible.token.id + ' libere'; + ligne += boutonSimple(command, "Libérer " + nomPerso(cible)) + '
    '; }); let gobePar; let attrGobePar = tokenAttribute(perso, 'estGobePar'); @@ -26122,18 +26245,18 @@ var COFantasy = COFantasy || function() { if (!gobePar && attributeAsBool(perso, 'enveloppePar')) { actionsAAfficher = true; command = '!cof-echapper-enveloppement --target ' + perso.token.id; - ligne += boutonSimple(command, 'Se lib\xE9rer') + '
    '; + ligne += boutonSimple(command, 'Se libérer') + '
    '; } else if (getState(perso, 'enseveli')) { actionsAAfficher = true; ligne += boutonSaveState(perso, 'enseveli') + '
    '; } else if (!gobePar && attributeAsBool(perso, 'etreinteScorpionPar')) { actionsAAfficher = true; command = '!cof-liberer-agrippe ' + perso.token.id; - ligne += boutonSimple(command, 'Se lib\xE9rer') + "de l'\xE9treinte du scorpion
    "; + ligne += boutonSimple(command, 'Se libérer') + "de l'étreinte du scorpion
    "; } else if (!gobePar && attributeAsBool(perso, 'estEcrasePar')) { actionsAAfficher = true; command = '!cof-liberer-ecrase ' + perso.token.id; - ligne += boutonSimple(command, 'Se lib\xE9rer') + "de l'\xE9treinte
    "; + ligne += boutonSimple(command, 'Se libérer') + "de l'étreinte
    "; } else { //On affiche les actions normales if (stateCOF.combat && stateCOF.combat.armeesDesMorts && !gobePar) { let combattreArmee = false; @@ -26141,7 +26264,7 @@ var COFantasy = COFantasy || function() { if (aid == perso.token.id) continue; let persoArmee = stateCOF.combat.armeesDesMorts[aid]; if (!persoArmee || !persoArmee.token) { - error("Erreur dans l'arm\xE9e des morts", stateCOF.combat.armeesDesMorts); + error("Erreur dans l'armée des morts", stateCOF.combat.armeesDesMorts); delete stateCOF.combat.armeesDesMorts[aid]; continue; } @@ -26163,12 +26286,12 @@ var COFantasy = COFantasy || function() { if (!gobePar && (attributeAsBool(perso, 'estAgrippePar') || attributeAsBool(perso, 'estDevorePar'))) { actionsAAfficher = true; command = '!cof-liberer-agrippe ' + perso.token.id; - ligne += bouton(command, 'Se lib\xE9rer', perso) + '(action de mvt)
    '; + ligne += bouton(command, 'Se libérer', perso) + '(action de mvt)
    '; } if (!gobePar && attributeAsBool(perso, 'etreinteImmolePar')) { actionsAAfficher = true; command = '!cof-liberer-agrippe ' + perso.token.id; - ligne += bouton(command, 'Se lib\xE9rer', perso) + ' (action limit\xE9e)
    '; + ligne += bouton(command, 'Se libérer', perso) + ' (action limitée)
    '; } //Actions pour les saves actifs let attrs = findObjs({ @@ -26207,7 +26330,7 @@ var COFantasy = COFantasy || function() { let cible = persoOfIdName(a.get('current')); if (cible) { let commande = "!cof-attack " + perso.token.id + ' ' + cible.token.id + ' ' + ecraser; - ligne += boutonSimple(commande, '\xC9craser') + ' ' + nomPerso(cible) + '
    '; + ligne += boutonSimple(commande, 'Écraser') + ' ' + nomPerso(cible) + '
    '; } else { a.remove(); } @@ -26236,7 +26359,7 @@ var COFantasy = COFantasy || function() { c = command + " Morsure --toucher " + atk + " --dm 1d6+" + force; ligne += bouton(c, 'Morsure', perso) + '
    '; } - //On cherche si il y a une arm\xE9e conjur\xE9e \xE0 attaquer + //On cherche si il y a une armée conjurée à attaquer let attrs_armee = findObjs({ _type: 'attribute', @@ -26271,42 +26394,42 @@ var COFantasy = COFantasy || function() { if (allies.has(perso.charId)) return; allTokens.forEach(function(t) { if (t.get('represents') == aacid) { - //teste si dans un carr\xE9 de 20 m de cot\xE9 autour de l'arm\xE9e. + //teste si dans un carré de 20 m de coté autour de l'armée. let tx = t.get('left'); let ty = t.get('top'); if (tx < pxp && tx > pxm && ty < pyp && ty > pym) { command = '!cof-attack ' + perso.token.id + ' ' + t.id + - " Attaque de l'arm\xE9e --dm " + + " Attaque de l'armée --dm " + (ficheAttributeAsInt(perso, 'niveau', 1) + 1) + " --auto --attaqueArmeeConjuree --allonge 20"; - ligne += bouton(command, "Attaque de l'arm\xE9e", perso) + '
    '; + ligne += bouton(command, "Attaque de l'armée", perso) + '
    '; } } }); }); } - //Les soins pour les \xE9l\xE9mentaires + //Les soins pour les élémentaires if (predicateAsBool(perso, 'corpsElementaire')) { command = '!cof-soin 5'; - ligne += bouton(command, "R\xE9g\xE9n\xE9ration", perso) + " si source \xE9l\xE9mentaire proche
    "; + ligne += bouton(command, "Régénération", perso) + " si source élémentaire proche
    "; } - //Regard p\xE9trifiant + //Regard pétrifiant let regardPetrifiant = predicateAsInt(perso, 'regardPetrifiant', 0, 16); if (regardPetrifiant) { let c = '!cof-effet petrifie --lanceur ' + perso.token.id + ' --target @{target|token_id} --regard --save CON '; - ligne += boutonSimple(c + (regardPetrifiant - 4), "Regard p\xE9trifiant") + + ligne += boutonSimple(c + (regardPetrifiant - 4), "Regard pétrifiant") + boutonSimple(c + regardPetrifiant, "(inconscient)") + '
    '; } - //Violence cibl\xE9e + //Violence ciblée if (predicateAsBool(perso, 'violenceCiblee') && !attributeAsBool(perso, 'reactionViolente')) { let pointsDeViolence = attributeAsInt(perso, 'pointsDeViolence', 0); if (pointsDeViolence > 0) { let attr = tokenAttribute(perso, 'pointsDeViolence')[0]; command = "!cof-effet-temp reactionViolente [[1d4]] --decrAttribute " + attr.id + " --target " + perso.token.id; - ligne += boutonSimple(command, 'Violence cibl\xE9e') + '
    '; + ligne += boutonSimple(command, 'Violence ciblée') + '
    '; } } - //Les attaques de la fiche \xE0 afficher dans la liste d'actions + //Les attaques de la fiche à afficher dans la liste d'actions const montrerAttaques = ficheAttributeAsInt(perso, 'montrerattaques', 1); const afficherAttaquesFiche = actionsParDefaut || @@ -26319,7 +26442,7 @@ var COFantasy = COFantasy || function() { attackOptions.nePasAfficherArmes = true; ligne += listeAttaquesVisibles(perso, attackOptions); } - //L'arme en main et d\xE9gainer, si besoin + //L'arme en main et dégainer, si besoin if (montrerArmeEnMain && armesAutorisees) { let { listeAttaques, @@ -26350,7 +26473,7 @@ var COFantasy = COFantasy || function() { else nomCommande += ' (1M)'; } if (attributeAsBool(perso, 'paradeCroisee')) { - //On conna\xEEtra vraiment l'arme au moment de faire l'attaque + //On connaîtra vraiment l'arme au moment de faire l'attaque command += '-1'; if (labelArmeGauche && listeAttaques[labelArmeGauche]) { @@ -26372,11 +26495,11 @@ var COFantasy = COFantasy || function() { if (perso.armeGauche) { ligneArmeGauche = bouton("!cof-attack @{selected|token_id} @{target|token_id} " + labelArmeGauche, perso.armeGauche.name, perso); } - //Maintenant on propose de d\xE9gainer + //Maintenant on propose de dégainer if (armeVisible) { let degainer = "!cof-degainer ?{Arme?|"; let armeADegainer; - //Prise en compte des pr\xE9dicats pour ce qu'on veut voir en premier + //Prise en compte des prédicats pour ce qu'on veut voir en premier let i = 1; let labelsVus = new Set(); while (true) { @@ -26390,12 +26513,12 @@ var COFantasy = COFantasy || function() { if (label == labelArmePrincipale || labelGauche == labelArmeGauche) continue; let arme = armes[label]; if (arme === undefined) { - error("Impossible de trouver l'arme de label " + label + " mentionn\xE9e dans le pr\xE9dicat actionDegainer" + (i - 1), armes); + error("Impossible de trouver l'arme de label " + label + " mentionnée dans le prédicat actionDegainer" + (i - 1), armes); continue; } let armeGauche = armes[labelGauche]; if (armeGauche === undefined) { - error("Impossible de trouver l'arme de label " + labelGauche + " mentionn\xE9e dans le pr\xE9dicat actionDegainer" + (i - 1), armes); + error("Impossible de trouver l'arme de label " + labelGauche + " mentionnée dans le prédicat actionDegainer" + (i - 1), armes); continue; } degainer += arme.armenom + " et " + armeGauche.armenom + "," + label + ' ' + labelGauche + "|"; @@ -26409,7 +26532,7 @@ var COFantasy = COFantasy || function() { if (labels == labelArmePrincipale || labels == labelArmeGauche) continue; let arme = armes[labels]; if (arme === undefined) { - error("Impossible de trouver l'arme de label " + labels + " mentionn\xE9e dans le pr\xE9dicat actionDegainer" + (i - 1), armes); + error("Impossible de trouver l'arme de label " + labels + " mentionnée dans le prédicat actionDegainer" + (i - 1), armes); continue; } labelsVus.add(labels); @@ -26461,7 +26584,7 @@ var COFantasy = COFantasy || function() { else degainer += "son arme"; degainer += ",&#32;}"; } else if (armeADegainer.unique) { - //Dans ce cas, pas de choix, juste une arme \xE0 d\xE9gainer + //Dans ce cas, pas de choix, juste une arme à dégainer degainer = '!cof-degainer ' + armeADegainer.label; } else { degainer = degainer.substr(0, degainer.length - 1) + '}'; @@ -26470,7 +26593,7 @@ var COFantasy = COFantasy || function() { if (ligneArmePrincipale) ligneArmePrincipale += bouton(degainer, ';', perso); else - ligneArmePrincipale = bouton(degainer, 'D\xE9gainer', perso); + ligneArmePrincipale = bouton(degainer, 'Dégainer', perso); if (armeADegainer.unique && !labelArmePrincipale && !labelArmeGauche) ligneArmePrincipale += armeADegainer.nom; } else { @@ -26497,22 +26620,22 @@ var COFantasy = COFantasy || function() { ligne += bouton(command, 'Second souffle', perso) + '
    '; } } - //Changement de phase pour intangibilit\xE9 avec changement de phase + //Changement de phase pour intangibilité avec changement de phase if (attributeAsBool(perso, 'intangiblePuissant')) { if (attributeAsInt(perso, 'intangibleValeur', 1)) { command = "!cof-set-attribute intangibleValeur 0 --target " + perso.token.id + " --message redevient tangible"; ligne += boutonSimple(command, "Redevenir tangible") + '
    '; } else { - command = "!cof-set-attribute intangibleValeur 1 --target " + perso.token.id + " --message devient l\xE9g\xE8rement translucide"; + command = "!cof-set-attribute intangibleValeur 1 --target " + perso.token.id + " --message devient légèrement translucide"; ligne += boutonSimple(command, "Redevenir intangible") + '
    '; } } if (attributeAsBool(perso, 'intangibleInvisiblePuissant')) { if (attributeAsInt(perso, 'intangibleInvisibleValeur', 1)) { - command = "!cof-set-attribute intangibleInvisibleValeur 0 --etat invisible false --target " + perso.token.id + " --message r\xE9appara\xEEt"; + command = "!cof-set-attribute intangibleInvisibleValeur 0 --etat invisible false --target " + perso.token.id + " --message réapparaît"; ligne += boutonSimple(command, "Redevenir tangible") + '
    '; } else { - command = "!cof-set-attribute intangibleInvisibleValeur 1 --etat invisible true --target " + perso.token.id + " --message dispara\xEEt"; + command = "!cof-set-attribute intangibleInvisibleValeur 1 --etat invisible true --target " + perso.token.id + " --message disparaît"; ligne += boutonSimple(command, "Redevenir intangible") + '
    '; } } @@ -26540,7 +26663,7 @@ var COFantasy = COFantasy || function() { if (caracDM > 0) command += '+' + caracDM; else if (caracDM < 0) command += caracDM; command += "--energie --magique --limiteParTour 1 runeIsulys --effet affaibli 1"; - ligne += bouton(command, "Rayon d'\xE9nergie", perso) + '
    '; + ligne += bouton(command, "Rayon d'énergie", perso) + '
    '; } command = "!cof-gerer-runes-mortes " + perso.token.id; ligne += boutonSimple(command, "Gestion des runes mortes") + '
    '; @@ -26550,8 +26673,8 @@ var COFantasy = COFantasy || function() { command = "!cof-attendre ?{Nouvelle initiative}"; ligne += bouton(command, 'Attendre', perso) + '
    '; if (!gobePar && !charAttributeAsBool(perso, 'armeeConjuree')) { - command = "!cof-action-defensive ?{Action d\xE9fensive|simple|totale}"; - ligne += bouton(command, 'Se d\xE9fendre', perso) + '
    '; + command = "!cof-action-defensive ?{Action défensive|simple|totale}"; + ligne += bouton(command, 'Se défendre', perso) + '
    '; let manoeuvreDuelliste = predicateAsBool(perso, 'manoeuvreDuelliste'); if (manoeuvreDuelliste) { command = "!cof-manoeuvre @{selected|token_id} @{target|token_id} ?{Manoeuvre?|bloquer|desarmer|renverser|tenirADistance|repousser}"; @@ -26577,9 +26700,9 @@ var COFantasy = COFantasy || function() { } } if (actionsAAfficher) { - // on envoie la liste aux joueurs qui g\xE8rent le personnage dont le token est li\xE9 + // on envoie la liste aux joueurs qui gèrent le personnage dont le token est lié let lastPlayerid; - // on r\xE9cup\xE8re les players_ids qui controllent le Token + // on récupère les players_ids qui controllent le Token let playerIds; if (playerId) playerIds = [playerId]; else playerIds = getPlayerIds(perso); @@ -26587,7 +26710,7 @@ var COFantasy = COFantasy || function() { lastPlayerid = playerid; let display = startFramedDisplay(playerid, title, perso, opt_display); addLineToFramedDisplay(display, ligne); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); // En prime, on l'envoie au MJ, si besoin let envoieAuMJ = playerIds.length === 0; @@ -26598,9 +26721,9 @@ var COFantasy = COFantasy || function() { } if (envoieAuMJ) { opt_display.chuchote = 'gm'; - var display = startFramedDisplay(lastPlayerid, title, perso, opt_display); + const display = startFramedDisplay(lastPlayerid, title, perso, opt_display); addLineToFramedDisplay(display, ligne); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } return actionsAAfficher; @@ -26620,7 +26743,7 @@ var COFantasy = COFantasy || function() { let actions = turnAction(perso, playerId, liste); if (!actions) { let l = liste || ''; - sendPerso(perso, "n'a pas de liste d'actions " + l + " d\xE9finie"); + sendPerso(perso, "n'a pas de liste d'actions " + l + " définie"); } }); }); @@ -26709,7 +26832,7 @@ var COFantasy = COFantasy || function() { return res; } - //ne rajoute pas evt \xE0 l'historique + //ne rajoute pas evt à l'historique function setTurnOrder(to, evt) { if (to.pasAgi.length > 0) { to.pasAgi.sort(function(a, b) { @@ -26717,8 +26840,8 @@ var COFantasy = COFantasy || function() { if (b.id == "-1") return -1; if (a.pr < b.pr) return 1; if (b.pr < a.pr) return -1; - // Priorit\xE9 aux joueurs - // Premier crit\xE8re : la barre de PV des joueurs est li\xE9e + // Priorité aux joueurs + // Premier critère : la barre de PV des joueurs est liée let tokenA = getObj('graphic', a.id); if (tokenA === undefined) return 1; let tokenB = getObj('graphic', b.id); @@ -26728,7 +26851,7 @@ var COFantasy = COFantasy || function() { return 1; } if (tokenB.get('bar1_link') === '') return -1; - // Deuxi\xE8me crit\xE8re : les joueurs ont un DV + // Deuxième critère : les joueurs ont un DV let charIdA = tokenA.get('represents'); if (charIdA === '') return 1; let charIdB = tokenB.get('represents'); @@ -26748,7 +26871,7 @@ var COFantasy = COFantasy || function() { return 1; } if (dvB === 0) return -1; - //Entre joueurs, priorit\xE9 \xE0 la plus grosse sagesse + //Entre joueurs, priorité à la plus grosse sagesse let sagA = caracCourante(persoA, 'sagesse'); let sagB = caracCourante(persoB, 'sagesse'); if (sagA < sagB) return 1; @@ -26770,17 +26893,17 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected) { if (selected === undefined || selected.length === 0) { - error("La fonction !cof-attendre : rien \xE0 faire, pas de token selectionn\xE9", msg); + error("La fonction !cof-attendre : rien à faire, pas de token selectionné", msg); return; } let cmd = msg.content.split(' '); if (cmd.length < 2) { - error("Attendre jusqu'\xE0 quelle initiative ?", cmd); + error("Attendre jusqu'à quelle initiative ?", cmd); return; } let newInit = parseInt(cmd[1]); if (isNaN(newInit) || newInit < 1) { - error("On ne peut attendre que jusqu'\xE0 une initiative de 1", cmd); + error("On ne peut attendre que jusqu'à une initiative de 1", cmd); newInit = 1; } let evt = { @@ -26795,7 +26918,7 @@ var COFantasy = COFantasy || function() { return (elt.id == token.id); }); if (tokenPos == -1) { // token ne peut plus agir - sendPerso(perso, " a d\xE9j\xE0 agit ce tour"); + sendPerso(perso, " a déjà agit ce tour"); return; } if (newInit < to.pasAgi[tokenPos].pr) { @@ -26803,7 +26926,7 @@ var COFantasy = COFantasy || function() { sendPerso(perso, " attend un peu avant d'agir..."); updateNextInit(perso); } else { - sendPerso(perso, " a d\xE9j\xE0 une initiative inf\xE9rieure \xE0 " + newInit); + sendPerso(perso, " a déjà une initiative inférieure à " + newInit); } }); setTurnOrder(to, evt); @@ -26811,22 +26934,22 @@ var COFantasy = COFantasy || function() { }); } - // Affiche des informations sur le personnage s\xE9lectionn\xE9 + // Affiche des informations sur le personnage sélectionné function statut(msg) { getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Dans !cof-statut : rien \xE0 faire, pas de token selectionn\xE9", msg); + error("Dans !cof-statut : rien à faire, pas de token selectionné", msg); return; } iterSelected(selected, function(perso) { - //Au cas o\xF9 + //Au cas où unlockToken(perso); const token = perso.token; const charId = perso.charId; const name = nomPerso(perso); let lie = true; if (token.get('bar1_link') === '') lie = false; - const display = startFramedDisplay(playerId, "\xC9tat de " + name, perso, { + const display = startFramedDisplay(playerId, "État de " + name, perso, { chuchote: true }); const estPNJ = persoEstPNJ(perso); @@ -26846,7 +26969,7 @@ var COFantasy = COFantasy || function() { hasMana = !isNaN(manaMax) && manaMax > 0; } let dmTemp = parseInt(token.get('bar2_value')); - if (hasMana) { //ne peut pas \xEAtre un PNJ + if (hasMana) { //ne peut pas être un PNJ if (lie) { dmTemp = ficheAttributeAsInt(perso, 'DMTEMP', 0); } else { @@ -26865,7 +26988,7 @@ var COFantasy = COFantasy || function() { } let douleurIgnoree = attributeAsInt(perso, 'douleurIgnoree', 0); if (douleurIgnoree > 0) { - line = "a ignor\xE9 " + douleurIgnoree + " pv dans ce combat."; + line = "a ignoré " + douleurIgnoree + " pv dans ce combat."; addLineToFramedDisplay(display, line); } let aDV = ficheAttributeAsInt(perso, 'DV', 0); @@ -26873,7 +26996,7 @@ var COFantasy = COFantasy || function() { let pr = pointsDeRecuperation(perso); if (pr) { line = - "Points de r\xE9cup\xE9ration : " + pr.current + " / " + pr.max; + "Points de récupération : " + pr.current + " / " + pr.max; addLineToFramedDisplay(display, line); } if (ficheAttributeAsInt(perso, 'option_pc', 1)) { @@ -26919,7 +27042,7 @@ var COFantasy = COFantasy || function() { if (att.armespec && predicateOfRaw(att.armespec).charge) { let charge = attributeAsInt(perso, 'charge_' + armeLabel, 0); if (charge === 0) { - line = nomArme + " n'est pas charg\xE9"; + line = nomArme + " n'est pas chargé"; } else { let na = fullAttributeName(perso, 'chargeGrenaille_' + armeLabel); let grenaille = attrsChar.find(function(a) { @@ -26930,7 +27053,7 @@ var COFantasy = COFantasy || function() { if (isNaN(grenaille) || grenaille < 0) grenaille = 0; } else grenaille = 0; if (charge == 1) { - line = nomArme + " est charg\xE9"; + line = nomArme + " est chargé"; if (grenaille) line += " de grenaille"; } else if (charge > 1) { line = nomArme + " contient encore " + charge + " charges"; @@ -26945,7 +27068,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, line); } else if (armeEnMain == armeLabel) { if (armeEnMainGauche == armeLabel) { - addLineToFramedDisplay(display, "tient " + nomArme + " \xE0 2 mains."); + addLineToFramedDisplay(display, "tient " + nomArme + " à 2 mains."); } else { addLineToFramedDisplay(display, "tient " + nomArme + " en main."); } @@ -26963,8 +27086,8 @@ var COFantasy = COFantasy || function() { if (attrEnveloppe.length > 0) { let cube = persoOfIdName(attrEnveloppe[0].get('current')); if (cube) { - let actE = "est envelopp\xE9 dans "; - if ((attrEnveloppe[0].get('max') + '').startsWith('etreinte')) actE = "est prisonnier de l'\xE9treinte de "; + let actE = "est enveloppé dans "; + if ((attrEnveloppe[0].get('max') + '').startsWith('etreinte')) actE = "est prisonnier de l'étreinte de "; addLineToFramedDisplay(display, actE + cube.tokName); } } @@ -26975,7 +27098,7 @@ var COFantasy = COFantasy || function() { let defenseMontree; let bufDef = attributeAsInt(perso, 'bufDEF', 0); if (bufDef > 0) { - addLineToFramedDisplay(display, "D\xE9fense temporairement modifi\xE9e de " + bufDef + " (DEF " + defense + ")"); + addLineToFramedDisplay(display, "Défense temporairement modifiée de " + bufDef + " (DEF " + defense + ")"); defenseMontree = true; } for (let etat in cof_states) { @@ -26995,22 +27118,22 @@ var COFantasy = COFantasy || function() { let possedeArmure = ficheAttributeAsInt(perso, 'defarmure', 0) > 0; if (possedeArmure) addLineToFramedDisplay(display, "Ne porte pas son armure"); if (predicateAsInt(perso, 'vetementsSacres', 0) > 0) { - if (possedeArmure) addLineToFramedDisplay(display, " mais b\xE9n\xE9ficie de ses v\xEAtements sacr\xE9s (DEF " + defense + ")"); - else addLineToFramedDisplay(display, "porte des v\xEAtements sacr\xE9s (DEF " + defense + ")"); + if (possedeArmure) addLineToFramedDisplay(display, " mais bénéficie de ses vêtements sacrés (DEF " + defense + ")"); + else addLineToFramedDisplay(display, "porte des vêtements sacrés (DEF " + defense + ")"); defenseMontree = true; } if (predicateAsInt(perso, 'armureDeVent', 0) > 0) { - if (possedeArmure) addLineToFramedDisplay(display, " mais b\xE9n\xE9ficie de son armure de vent (DEF " + defense + ")"); - else addLineToFramedDisplay(display, "b\xE9n\xE9ficie de son armure de vent (DEF " + defense + ")"); + if (possedeArmure) addLineToFramedDisplay(display, " mais bénéficie de son armure de vent (DEF " + defense + ")"); + else addLineToFramedDisplay(display, "bénéficie de son armure de vent (DEF " + defense + ")"); defenseMontree = true; } } if (ficheAttributeAsInt(perso, 'defbouclieron', 0) === 0 && - ficheAttributeAsInt(perso, 'defbouclier', 0)) + ficheAttributeAsBool(perso, 'defbouclier', false)) addLineToFramedDisplay(display, "Ne porte pas son bouclier"); if (ficheAttributeAsInt(perso, 'casque_rd', 0)) { if (ficheAttributeAsBool(perso, 'casque_on', false)) { - let b = boutonSimple('!cof-set-attribute casque_on false --message enl\xE8ve son casque --target ' + perso.token.id, "l'enlever"); + let b = boutonSimple('!cof-set-attribute casque_on false --message enlève son casque --target ' + perso.token.id, "l'enlever"); addLineToFramedDisplay(display, "Porte son casque :" + b); } else { let b = boutonSimple('!cof-set-attribute casque_on true --message met son casque --target ' + perso.token.id, "le mettre"); @@ -27042,7 +27165,7 @@ var COFantasy = COFantasy || function() { if (stateCOF.options.affichage.val.duree_effets.val || playerIsGM(playerId)) { let effetVal = attr.get('current'); if (parseInt(effetVal)) { - explEffetMsg += " (" + effetVal + " tour" + ((effetVal>1)?'s':'') + ")"; + explEffetMsg += " (" + effetVal + " tour" + ((effetVal > 1) ? 's' : '') + ")"; } else { explEffetMsg += " (tour final)"; } @@ -27067,7 +27190,7 @@ var COFantasy = COFantasy || function() { } let perteDeSubstance = parseInt(attr.get('current')); if (isNaN(perteDeSubstance) || perteDeSubstance < 1) { - error("Attribut de perte de substance mal form\xE9", attr); + error("Attribut de perte de substance mal formé", attr); return; } if (playerIsGM(playerId)) { @@ -27076,21 +27199,21 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, m); } if (perteDeSubstance < 3) { - addLineToFramedDisplay(display, "Dans le noir, on peut distinguer les lumi\xE8res vives au travers de son corps"); + addLineToFramedDisplay(display, "Dans le noir, on peut distinguer les lumières vives au travers de son corps"); } else if (perteDeSubstance < 5) { - addLineToFramedDisplay(display, "Le soleil diffuse \xE0 travers le corps \xE0 contre-jour"); + addLineToFramedDisplay(display, "Le soleil diffuse à travers le corps à contre-jour"); } else if (perteDeSubstance < 7) { - addLineToFramedDisplay(display, "On peut distinguer les objets \xE0 travers ses mains, et sa couleur s'estompe"); + addLineToFramedDisplay(display, "On peut distinguer les objets à travers ses mains, et sa couleur s'estompe"); } else if (perteDeSubstance < 10) { addLineToFramedDisplay(display, "Est translucide comme une eau sale"); } else if (perteDeSubstance < 15) { addLineToFramedDisplay(display, "Est aussi transparent que de l'eau et n'a plus faim ni soif"); } else { - addLineToFramedDisplay(display, "A perdu sa substance : impossible de tenir un objet et possibilit\xE9 de passer \xE0 travers des obstacles"); + addLineToFramedDisplay(display, "A perdu sa substance : impossible de tenir un objet et possibilité de passer à travers des obstacles"); } } }); - //ancienne version de munitions, obsol\xE8te depuis mars 2023 + //ancienne version de munitions, obsolète depuis mars 2023 allAttributesNamed(attrsChar, 'munition').forEach(function(attr) { let attrName = attr.get('name'); let underscore = attrName.indexOf('_'); @@ -27105,7 +27228,7 @@ var COFantasy = COFantasy || function() { let postureMsg = "a une posture "; switch (posture.substr(-3, 3)) { case 'DEF': - postureMsg += "d\xE9fensive"; + postureMsg += "défensive"; break; case 'ATT': postureMsg += "offensive"; @@ -27118,10 +27241,10 @@ var COFantasy = COFantasy || function() { postureMsg += " mais "; switch (posture.substr(0, 3)) { case 'DEF': - postureMsg += "risqu\xE9e"; + postureMsg += "risquée"; break; case 'ATT': - postureMsg += "moins pr\xE9cise"; + postureMsg += "moins précise"; break; case 'DM_': postureMsg += "moins puissante"; @@ -27132,7 +27255,7 @@ var COFantasy = COFantasy || function() { } let attaqueAOutrance = attributeAsInt(perso, 'attaqueAOutrance', 0); if (attaqueAOutrance) { - let attaqueAOutranceMsg = "attaque \xE0 outrance "; + let attaqueAOutranceMsg = "attaque à outrance "; switch (attaqueAOutrance) { case 2: attaqueAOutranceMsg += "(-2 DEF, +1D6 DM)"; @@ -27153,10 +27276,10 @@ var COFantasy = COFantasy || function() { if (soinsLegers < rangSoin) { soinsRestants = rangSoin - soinsLegers; if (soinsRestants > 1) soins = 's'; - msgSoins = "peut encore faire " + soinsRestants + " soin" + soins + " l\xE9ger" + soins; + msgSoins = "peut encore faire " + soinsRestants + " soin" + soins + " léger" + soins; addLineToFramedDisplay(display, msgSoins); } else { - addLineToFramedDisplay(display, "ne peut plus faire de soin l\xE9ger aujourd'hui"); + addLineToFramedDisplay(display, "ne peut plus faire de soin léger aujourd'hui"); } if (rangSoin > 1) { let soinsModeres = attributeAsInt(perso, 'soinsModeres', 0); @@ -27164,18 +27287,18 @@ var COFantasy = COFantasy || function() { soinsRestants = rangSoin - soinsModeres; if (soinsRestants > 1) soins = 's'; else soins = ''; - msgSoins = "peut encore faire " + soinsRestants + " soin" + soins + " mod\xE9r\xE9" + soins; + msgSoins = "peut encore faire " + soinsRestants + " soin" + soins + " modéré" + soins; addLineToFramedDisplay(display, msgSoins); } else { - addLineToFramedDisplay(display, "ne peut plus faire de soin mod\xE9r\xE9 aujourd'hui"); + addLineToFramedDisplay(display, "ne peut plus faire de soin modéré aujourd'hui"); } } if (rangSoin > 3) { - let soinsGuerison = attributeAsInt(perso, 'limiteParJour_gu\xE9rison', 1); + let soinsGuerison = attributeAsInt(perso, 'limiteParJour_guérison', 1); if (soinsGuerison > 0) { - addLineToFramedDisplay(display, "peut encore faire " + soinsGuerison + " gu\xE9rison" + (soinsGuerison > 1 ? 's' : '') + " aujourd'hui"); + addLineToFramedDisplay(display, "peut encore faire " + soinsGuerison + " guérison" + (soinsGuerison > 1 ? 's' : '') + " aujourd'hui"); } else { - addLineToFramedDisplay(display, "ne peut plus faire de gu\xE9rison aujourd'hui"); + addLineToFramedDisplay(display, "ne peut plus faire de guérison aujourd'hui"); } } } @@ -27185,7 +27308,7 @@ var COFantasy = COFantasy || function() { } let bonusCouvert = attributeAsInt(perso, 'bonusCouvert'); if (bonusCouvert) { - addLineToFramedDisplay(display, "est \xE0 couvert (+" + bonusCouvert + " DEF)"); + addLineToFramedDisplay(display, "est à couvert (+" + bonusCouvert + " DEF)"); } if (!defenseMontree) { let defenseAffichee = 10; @@ -27198,7 +27321,7 @@ var COFantasy = COFantasy || function() { defenseAffichee += modCarac(perso, 'dexterite'); } if (defense != defenseAffichee) - addLineToFramedDisplay(display, "D\xE9fense actuelle : " + defense); + addLineToFramedDisplay(display, "Défense actuelle : " + defense); } let predicatExpertDuCombat = predicateAsInt(perso, "expertDuCombat", 0); if (stateCOF.combat && predicatExpertDuCombat > 0) { @@ -27210,11 +27333,11 @@ var COFantasy = COFantasy || function() { else nbDesExpertDuCombat_tour_max = 1; let nbDesExpertDuCombat_tour = Math.min(nbDesExpertDuCombat_combat, attributeAsInt(perso, "limiteParTour_expertDuCombat", nbDesExpertDuCombat_tour_max)); - addLineToFramedDisplay(display, "D\xE9s d'expertise du combat :
    " + + addLineToFramedDisplay(display, "Dés d'expertise du combat :
    " + "Tour : " + nbDesExpertDuCombat_tour + "/" + nbDesExpertDuCombat_tour_max + "
    " + "Combat : " + nbDesExpertDuCombat_combat + "/" + nbDesExpertDuCombat_combat_max + "
    "); } - //Affaiblissements de caract\xE9ristiques + //Affaiblissements de caractéristiques allCaracs.forEach(function(carac) { let malus = attributeAsInt(perso, 'affaiblissementde' + carac, 0); if (malus > 0) { @@ -27223,7 +27346,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, ligne); } }); - //Violence cibl\xE9e + //Violence ciblée if (predicateAsBool(perso, 'violenceCiblee')) { let pointsDeViolence = attributeAsInt(perso, 'pointsDeViolence', 0); if (pointsDeViolence > 0) { @@ -27231,7 +27354,7 @@ var COFantasy = COFantasy || function() { } } if (attributeAsBool(perso, 'lumiere')) { - addLineToFramedDisplay(display, "\xE9claire ou fait de la lumi\xE8re"); + addLineToFramedDisplay(display, "éclaire ou fait de la lumière"); } let autresAttributs = predicatesNamed(perso, 'attributsDeStatut'); autresAttributs.forEach(function(attr) { @@ -27248,12 +27371,12 @@ var COFantasy = COFantasy || function() { }); }); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); //fin du iterSelected }); } - //retourne l'id du suivant si le token actuel \xE9tait en t\xEAte de liste + //retourne l'id du suivant si le token actuel était en tête de liste function removeFromTurnTracker(perso, evt) { removeDernieresCiblesAttaquees(perso, evt); let tokenId = perso.token.id; @@ -27337,14 +27460,14 @@ var COFantasy = COFantasy || function() { } if (buf === 0) return; let message = ""; - if (buf > 0) message = "voit sa d\xE9fense augmenter"; - else message = "voit sa d\xE9fense baisser"; + if (buf > 0) message = "voit sa défense augmenter"; + else message = "voit sa défense baisser"; let evt = { type: 'other' }; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof--buf-def", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof--buf-def", playerId); } iterSelected(selected, function(perso) { setTokenAttr(perso, 'bufDEF', buf, evt, { @@ -27353,7 +27476,7 @@ var COFantasy = COFantasy || function() { setToken(perso.token, 'status_blue', buf, evt); }); if (evt.attributes.length === 0) { - error("Pas de cible valide s\xE9lectionn\xE9e pour !cod-buf-def", msg); + error("Pas de cible valide sélectionnée pour !cod-buf-def", msg); return; } addEvent(evt); @@ -27366,11 +27489,11 @@ var COFantasy = COFantasy || function() { }; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof-remove-buf-def", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof-remove-buf-def", playerId); } iterSelected(selected, function(perso) { removeTokenAttr(perso, 'bufDEF', evt, { - msg: "retrouve sa d\xE9fense normale" + msg: "retrouve sa défense normale" }); setToken(perso.token, 'status_blue', false, evt); }); @@ -27437,16 +27560,18 @@ var COFantasy = COFantasy || function() { options.nature = true; return; case 'vampirise': - var vampirise = 100; - if (opt.length > 1) { - vampirise = parseInt(opt[1]); - if (isNaN(vampirise)) { - error("Il faut un pourcentage entier comme argument \xE0 --vampirise", opt); - vampirise = 100; + { + let vampirise = 100; + if (opt.length > 1) { + vampirise = parseInt(opt[1]); + if (isNaN(vampirise)) { + error("Il faut un pourcentage entier comme argument à --vampirise", opt); + vampirise = 100; + } } + options.vampirise = vampirise; + return; } - options.vampirise = vampirise; - return; case "ignoreRD": if (opt.length < 2) { options.ignoreTouteRD = true; @@ -27454,7 +27579,7 @@ var COFantasy = COFantasy || function() { } options.ignoreRD = parseInt(opt[1]); if (isNaN(options.ignoreRD) || options.ignoreRD < 1) { - log("Pas un nombre positif apr\xE8s --ignoreRD, interpr\xE9t\xE9 comme ignore toute la RD"); + log("Pas un nombre positif après --ignoreRD, interprété comme ignore toute la RD"); options.ignoreRD = undefined; options.ignoreTouteRD = true; } @@ -27462,7 +27587,7 @@ var COFantasy = COFantasy || function() { case 'attaquant': { if (opt.length < 2) { - error("Manque l'id de l'attaquant, option ignor\xE9e", optArgs); + error("Manque l'id de l'attaquant, option ignorée", optArgs); return; } const attaquant = persoOfId(opt[1]); @@ -27470,12 +27595,12 @@ var COFantasy = COFantasy || function() { options.attaquant = attaquant; return; } - error("Attaquant non trouv\xE9", opt); + error("Attaquant non trouvé", opt); return; } case 'titre': if (opt.length < 2) { - error("Il manque le message apr\xE8s --message", text); + error("Il manque le message après --message", text); return; } options.titre = opt.slice(1).join(' '); @@ -27490,13 +27615,13 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("cof-dmg prend les d\xE9gats en argument, avant les options", + error("cof-dmg prend les dégats en argument, avant les options", msg.content); return; } getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "pas de cible trouv\xE9e, action annul\xE9e", playerId); + sendPlayer(msg, "pas de cible trouvée, action annulée", playerId); return; } options.aoe = true; @@ -27507,7 +27632,7 @@ var COFantasy = COFantasy || function() { }); cibles = enleveDoublonsPartagePV(cibles); if (options.return) return; - //L'expression \xE0 lancer est tout ce qui est entre le premier blanc et le premier -- + //L'expression à lancer est tout ce qui est entre le premier blanc et le premier -- let debutDmgRollExpr = msg.content.indexOf(' ') + 1; let dmgRollExpr = msg.content.substring(debutDmgRollExpr); let finDmgRollExpr = msg.content.indexOf(' --'); @@ -27549,7 +27674,7 @@ var COFantasy = COFantasy || function() { addEvent(evt); } evt.action = { - titre: "D\xE9g\xE2ts", + titre: "Dégâts", playerId: playerId, playerName: playerName, cibles: cibles, @@ -27557,12 +27682,12 @@ var COFantasy = COFantasy || function() { options: options }; if (options.lanceur && limiteRessources(options.lanceur, options, 'dmg', 'dmg', evt)) return; - let action = "D\xE9g\xE2ts. "; + let action = "Dégâts. "; if (options.titre) action += options.titre + "
    "; if (options.partialSave) { action += - " Jet de " + options.partialSave.carac + " difficult\xE9 " + options.partialSave.seuil + - " pour r\xE9duire les d\xE9g\xE2ts"; + " Jet de " + options.partialSave.carac + " difficulté " + options.partialSave.seuil + + " pour réduire les dégâts"; } let display = startFramedDisplay(playerId, action); let tokensToProcess = cibles.length; @@ -27570,9 +27695,9 @@ var COFantasy = COFantasy || function() { let finalDisplay = function() { if (tokensToProcess == 1) { if (someDmgDone) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else { - sendPlayer(playerName, "Aucune cible valide n'a \xE9t\xE9 s\xE9lection\xE9e"); + sendPlayer(playerName, "Aucune cible valide n'a été sélectionée"); } } tokensToProcess--; @@ -27585,7 +27710,7 @@ var COFantasy = COFantasy || function() { dmg.total = dmg.roll.inlinerolls[dmgRollNumber].results.total; dmg.display = buildinline(dmg.roll.inlinerolls[dmgRollNumber], dmg.type, options.magique); cibles.forEach(function(perso) { - if (getState(perso, 'mort')) { //pas de d\xE9g\xE2ts aux morts + if (getState(perso, 'mort')) { //pas de dégâts aux morts finalDisplay(); return; } @@ -27600,16 +27725,16 @@ var COFantasy = COFantasy || function() { dealDamage(perso, dmg, [], evt, false, options, explications, function(dmgDisplay, dmgFinal) { someDmgDone = true; addLineToFramedDisplay(display, - name + " re\xE7oit " + dmgDisplay + " DM"); + name + " reçoit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); finalDisplay(); }); }); //fin forEach - }); //fin du jet de d\xE9s + }); //fin du jet de dés } catch (rollError) { - error("Jet " + dmg.value + " mal form\xE9", dmg); + error("Jet " + dmg.value + " mal formé", dmg); } } @@ -27631,12 +27756,12 @@ var COFantasy = COFantasy || function() { if (valeur == 'false' || valeur == '0' || valeur == 'non' || valeur == 'no') valeur = false; if (valeur == 'true' || valeur == 'oui' || valeur == 'yes') valeur = true; if (!_.has(cof_states, etat)) { - error("Le premier argument de !cof-set-state n'est pas un \xE9tat valide", cmd); + error("Le premier argument de !cof-set-state n'est pas un état valide", cmd); return; } if (isCarac(cmd[2])) { if (cmd.length < 4) { - error("Il manque la difficult\xE9 du jet de sauvegarde.", cmd); + error("Il manque la difficulté du jet de sauvegarde.", cmd); return; } valeur = true; @@ -27649,7 +27774,7 @@ var COFantasy = COFantasy || function() { } else { options.saveActifParTour.difficulte = parseInt(cmd[3]); if (isNaN(options.saveActifParTour.difficulte)) { - error("Difficult\xE9 du jet de sauvegarde incorrecte", cmd); + error("Difficulté du jet de sauvegarde incorrecte", cmd); return; } } @@ -27657,12 +27782,12 @@ var COFantasy = COFantasy || function() { let cibles = []; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - error("Pas de cible pour le changement d'\xE9tat", msg); + error("Pas de cible pour le changement d'état", msg); return; } iterSelected(selected, function(perso) { if (options.seulementVivant && estNonVivant(perso)) { - sendPlayer(msg, "cet effet n'affecte que les cr\xE9atures vivantes", playerId); + sendPlayer(msg, "cet effet n'affecte que les créatures vivantes", playerId); return; } switch (etat) { @@ -27762,8 +27887,8 @@ var COFantasy = COFantasy || function() { }; if (options.save) { let saveOpts = { - msgPour: " pour r\xE9sister \xE0 l'effet " + stringOfEtat(etat), - msgRate: ", rat\xE9.", + msgPour: " pour résister à l'effet " + stringOfEtat(etat), + msgRate: ", raté.", rolls: options.rolls, chanceRollId: options.chanceRollId, type: options.type @@ -27786,7 +27911,7 @@ var COFantasy = COFantasy || function() { function textOfSaveState(etat, perso) { switch (etat) { case 'immobilise': - return "se lib\xE9rer"; + return "se libérer"; case 'aveugle': return "retrouver la vue"; case 'etourdi': @@ -27796,13 +27921,13 @@ var COFantasy = COFantasy || function() { case 'renverse': return "se relever"; case 'endormi': - return "se r\xE9veiller"; + return "se réveiller"; case 'apeure': return "retrouver du courage"; case 'enseveli': return "sortir de terre"; default: - return "ne plus \xEAtre " + stringOfEtat(etat, perso); + return "ne plus être " + stringOfEtat(etat, perso); } } @@ -27811,7 +27936,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 4 || !_.has(cof_states, cmd[1])) { - error("Param\xE8tres de !cof-save-state incorrects", cmd); + error("Paramètres de !cof-save-state incorrects", cmd); return; } let etat = cmd[1]; @@ -27822,17 +27947,17 @@ var COFantasy = COFantasy || function() { carac2 = carac.substring(3, 6); carac = carac.substring(0, 3); if (!isCarac(carac) || !isCarac(carac)) { - error("Param\xE8tres de !cof-save-state incorrects", cmd); + error("Paramètres de !cof-save-state incorrects", cmd); return; } } else { - error("Param\xE8tres de !cof-save-state incorrects", cmd); + error("Paramètres de !cof-save-state incorrects", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Pas de token s\xE9lectionn\xE9", msg.content); + error("Pas de token sélectionné", msg.content); return; } let pageId = options.pageId; @@ -27855,7 +27980,7 @@ var COFantasy = COFantasy || function() { } else { let seuil = parseInt(cmd[3]); if (isNaN(seuil)) { - error("La difficult\xE9 n'est pas un nombre", cmd); + error("La difficulté n'est pas un nombre", cmd); return; } iterSelected(selected, function(perso) { @@ -27904,7 +28029,7 @@ var COFantasy = COFantasy || function() { explications.forEach(function(e) { addLineToFramedDisplay(display, e); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); } else { let testId = 'saveState_' + carac + seuil; @@ -27933,13 +28058,13 @@ var COFantasy = COFantasy || function() { } //!cof-save-effet token_id attr_id - // o\xF9 attr_id est l'id de l'attribut de save + // où attr_id est l'id de l'attribut de save function parseSaveEffet(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 3) { - error("Param\xE8tres de !cof-save-effet incorrects", cmd); + error("Paramètres de !cof-save-effet incorrects", cmd); return; } let perso = persoOfId(cmd[1]); @@ -27957,7 +28082,7 @@ var COFantasy = COFantasy || function() { let effetC = attrName.substring(0, indexSave); let effetTemp = estEffetTemp(effetC); if (!effetTemp && !estEffetCombat(effetC)) { - error("Impossible de trouver l'effet correspondant \xE0 " + effetC, attrName); + error("Impossible de trouver l'effet correspondant à " + effetC, attrName); return; } attrName = effetC + attrName.substr(indexSave + 16); @@ -27967,19 +28092,19 @@ var COFantasy = COFantasy || function() { let msgPour = " pour "; if (met.msgSave) msgPour += met.msgSave; else { - msgPour += "ne plus \xEAtre sous l'effet de "; + msgPour += "ne plus être sous l'effet de "; if (effetC.startsWith('dotGen(')) msgPour += effetC.substring(7, effetC.indexOf(')')); else msgPour += effetC; } let carac = attr.get('current'); if (!isCarac(carac)) { - error("Save par tour " + attrName + " mal form\xE9", carac); + error("Save par tour " + attrName + " mal formé", carac); return; } let seuil = parseInt(attr.get('max')); if (isNaN(seuil)) { - error("Save par tour " + attrName + " mal form\xE9", seuil); + error("Save par tour " + attrName + " mal formé", seuil); return; } let attrEffet = findObjs({ @@ -28051,7 +28176,7 @@ var COFantasy = COFantasy || function() { explications.forEach(function(e) { addLineToFramedDisplay(display, e); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); if (reussite) { let eff = effetC; if (estEffetTemp(effetC)) eff = effetTempOfAttribute(attrEffet); @@ -28080,7 +28205,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("commande non form\xE9e", msg.content); + error("commande non formée", msg.content); return; } let armeLabel = ''; @@ -28093,7 +28218,7 @@ var COFantasy = COFantasy || function() { let personnages = []; getSelected(msg, function(selected) { if (selected === undefined || selected.length === 0) { - error("Qui doit d\xE9gainer ?", msg); + error("Qui doit dégainer ?", msg); return; } iterSelected(selected, function(perso) { @@ -28118,14 +28243,14 @@ var COFantasy = COFantasy || function() { persos.forEach(function(perso) { function afterSave() { let nomArme = degainerArme(perso, labelArme, evt, options); - if (nomArme) sendPerso(perso, "a d\xE9j\xE0 " + nomArme + " en main"); + if (nomArme) sendPerso(perso, "a déjà " + nomArme + " en main"); else if (options.montreActions && persos.length === 1) turnAction(perso); } if (options.save) { let saveOpts = { msgPour: " pour garder son arme en main", - msgRate: ", rat\xE9.", + msgRate: ", raté.", rolls: options.rolls, chanceRollId: options.chanceRollId }; @@ -28147,7 +28272,7 @@ var COFantasy = COFantasy || function() { function echangeInit(msg) { let combat = stateCOF.combat; if (!combat) { - error("\xC9change d'intiative en dehors du combat", msg); + error("Échange d'intiative en dehors du combat", msg); return; } let options = parseOptions(msg); @@ -28172,7 +28297,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3) { attackBonus = parseInt(cmd[3]); if (isNaN(attackBonus)) { - error("Le troisi\xE8me argument n'est pas un nombre", cmd[3]); + error("Le troisième argument n'est pas un nombre", cmd[3]); return; } } @@ -28187,23 +28312,23 @@ var COFantasy = COFantasy || function() { return (t.id == perso2.token.id); }); if (tourTok1 < 0) { - sendPerso(perso1, "a d\xE9j\xE0 agit, pas moyen d'\xE9changer son initiative"); + sendPerso(perso1, "a déjà agit, pas moyen d'échanger son initiative"); return; } if (tourTok2 < 0) { - sendPerso(perso2, "a d\xE9j\xE0 agit, pas moyen d'\xE9changer son initiative"); + sendPerso(perso2, "a déjà agit, pas moyen d'échanger son initiative"); return; } let pr1 = to.pasAgi[tourTok1].pr; let pr2 = to.pasAgi[tourTok2].pr; if (pr1 == pr2) { - sendPerso(perso1, "a la m\xEAme initiative que " + nomPerso(perso2)); + sendPerso(perso1, "a la même initiative que " + nomPerso(perso2)); return; } if (pr1 > pr2) { if (attackBonus) { setTokenAttr(perso1, 'actionConcertee', attackBonus, evt, { - msg: "gagne un bonus de " + attackBonus + " \xE0 ses attaques et en DEF pour ce tour" + msg: "gagne un bonus de " + attackBonus + " à ses attaques et en DEF pour ce tour" }); } setActiveToken(combat, perso2.token.id, evt); @@ -28242,7 +28367,7 @@ var COFantasy = COFantasy || function() { return arg == '--secret'; }); setTokenAttr(perso1, 'aCouvert', 1, evt, { - msg: "reste \xE0 couvert", + msg: "reste à couvert", maxVal: init, secret: secret }); @@ -28255,9 +28380,9 @@ var COFantasy = COFantasy || function() { } if (perso2.token.id == perso1.token.id) { if (secret) { - whisperChar(perso1.charId, "s'est cibl\xE9 " + onGenre(perso1, 'lui', 'elle') + "-m\xEAme, il est donc le seul \xE0 couvert"); + whisperChar(perso1.charId, "s'est ciblé " + onGenre(perso1, 'lui', 'elle') + "-même, il est donc le seul à couvert"); } else { - sendPerso(perso1, "s'est cibl\xE9 " + onGenre(perso1, 'lui', 'elle') + "-m\xEAme, il est donc le seul \xE0 couvert"); + sendPerso(perso1, "s'est ciblé " + onGenre(perso1, 'lui', 'elle') + "-même, il est donc le seul à couvert"); } addEvent(evt); return; @@ -28265,13 +28390,13 @@ var COFantasy = COFantasy || function() { let d = distanceCombat(perso1.token, perso2.token); if (d > 0) { if (secret) { - whisperChar(perso2.charId, "est trop \xE9loign\xE9 de " + nomPerso(perso1) + " pour rester \xE0 couvert avec lui"); + whisperChar(perso2.charId, "est trop éloigné de " + nomPerso(perso1) + " pour rester à couvert avec lui"); } else { - sendPerso(perso2, "est trop \xE9loign\xE9 de " + nomPerso(perso1) + " pour rester \xE0 couvert avec lui"); + sendPerso(perso2, "est trop éloigné de " + nomPerso(perso1) + " pour rester à couvert avec lui"); } } else { setTokenAttr(perso2, 'aCouvert', 1, evt, { - msg: "suit " + nomPerso(perso1) + " et reste \xE0 couvert", + msg: "suit " + nomPerso(perso1) + " et reste à couvert", maxVal: init, secret: secret }); @@ -28302,20 +28427,20 @@ var COFantasy = COFantasy || function() { effet += 'Temp'; } if (effet == 'forgeron' || effet == 'armeEnflammee' || effet == 'armeGlacee') { - //Compl\xE9ter description de l'effet + //Compléter description de l'effet if (!lanceur) { error("Pas de lanceur pour " + effet, msg.content); return; } let armeActuelle = tokenAttribute(lanceur, 'armeEnMain'); if (armeActuelle.length === 0) { - whisperChar(charId, "Pas d'arme en main, impossible de savoir \xE0 quoi appliquer " + effet); + whisperChar(charId, "Pas d'arme en main, impossible de savoir à quoi appliquer " + effet); return; } let labelArme = armeActuelle[0].get('current'); effet = effet + '(' + labelArme + ')'; } else if (!estEffetTemp(effet)) { - error(effet + " n'est pas un effet temporaire r\xE9pertori\xE9", msg.content); + error(effet + " n'est pas un effet temporaire répertorié", msg.content); return; } if (lanceur && options.mana !== undefined && attributeAsBool(lanceur, 'frappeDesArcanes')) { @@ -28336,7 +28461,7 @@ var COFantasy = COFantasy || function() { if (options.puissantDuree || options.tempeteDeManaDuree) duree = duree * 2; getSelected(msg, function(selected, playerId, aoe) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour l'effet", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour l'effet", playerId); return; } options.aoe = aoe; @@ -28355,7 +28480,7 @@ var COFantasy = COFantasy || function() { } if (lanceur && options.tempeteDeMana) { if (duree > 0 && options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, dm: mEffet.dm, @@ -28369,7 +28494,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPlayer(msg, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayer(msg, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } if (selected.length == 1 && options.tempeteDeMana.altruiste) { selected[0]._id = options.tempeteDeMana.altruiste.token.id; @@ -28389,7 +28514,7 @@ var COFantasy = COFantasy || function() { } if ((mEffet.seulementVivant || options.seulementVivant) && estNonVivant(perso)) { - sendPlayer(msg, "cet effet n'affecte que les cr\xE9atures vivantes", playerId); + sendPlayer(msg, "cet effet n'affecte que les créatures vivantes", playerId); return; } if (predicateAsBool(perso, 'liberteDAction') && @@ -28431,7 +28556,7 @@ var COFantasy = COFantasy || function() { }, options); } - //Si display est d\xE9fini, l'envoie dans le chat \xE0 la fin de l'appel + //Si display est défini, l'envoie dans le chat à la fin de l'appel function activerEffetTemporaire(lanceur, cibles, effet, mEffet, duree, options, evt, whisper, explications, display) { let ef = { effet: effet, @@ -28466,7 +28591,7 @@ var COFantasy = COFantasy || function() { explications.forEach(function(e) { addLineToFramedDisplay(display, e); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else { explications.forEach(function(e) { sendChat('', e); @@ -28487,7 +28612,7 @@ var COFantasy = COFantasy || function() { ressource = "limiteParJour_" + ressource; let utilisations = attributeAsInt(perso, ressource, options.limiteCibleParJour); if (utilisations === 0) { - expliquer("ne peut plus b\xE9n\xE9ficier de " + effet + " aujourd'hui"); + expliquer("ne peut plus bénéficier de " + effet + " aujourd'hui"); return; } setTokenAttr(perso, ressource, utilisations - 1, evt); @@ -28512,7 +28637,7 @@ var COFantasy = COFantasy || function() { height: diametre, layer: 'map', isDrawing: true, - name: 'Prison v\xE9g\xE9tale', + name: 'Prison végétale', gmnotes: 'terrainDifficile:disque ' + Math.floor(diametre) }); if (t) { @@ -28531,7 +28656,7 @@ var COFantasy = COFantasy || function() { setEffetTemporaire(perso, ef, d, evt, options); if (!renew) { if (effet.startsWith('forgeron(')) { - //Il faut d\xE9gainer l'arme si elle n'est pas en main, et ajouter une lumi\xE8re + //Il faut dégainer l'arme si elle n'est pas en main, et ajouter une lumière let labelArmeForgeron = effet.substring(9, effet.indexOf(')')); degainerArme(perso, labelArmeForgeron, evt); let feu = getIntValeurOfEffet(perso, effet, 1, 'voieDuMetal'); @@ -28590,14 +28715,14 @@ var COFantasy = COFantasy || function() { else sendPerso(perso, s); }; if (options.type && immuniseAuType(perso, options.type, lanceur)) { - expliquer("ne semble pas affect\xE9 par " + stringOfType(options.type)); + expliquer("ne semble pas affecté par " + stringOfType(options.type)); finalize(); return; } if (options.save) { let saveOpts = { - msgPour: options.save.msgPour || " pour r\xE9sister \xE0 l'effet " + effet, - msgRate: ", rat\xE9.", + msgPour: options.save.msgPour || " pour résister à l'effet " + effet, + msgRate: ", raté.", attaquant: lanceur, rolls: options.rolls, chanceRollId: options.chanceRollId, @@ -28614,7 +28739,7 @@ var COFantasy = COFantasy || function() { } if (reussite) { if (effet == 'reactionViolente' && predicateAsBool(perso, 'violenceCiblee')) { - expliquer("r\xE9siste \xE0 la provocation, mais emmagasine de la violence"); + expliquer("résiste à la provocation, mais emmagasine de la violence"); addToAttributeAsInt(perso, 'pointsDeViolence', 0, 1, evt); } finalize(); @@ -28636,7 +28761,7 @@ var COFantasy = COFantasy || function() { return (2 * magieEnArmure < defa + ma); } - //options doit \xEAtre d\xE9fini + //options doit être défini function effetTemporaire(playerId, cibles, effet, mEffet, duree, options) { const evt = { type: 'effetTemp', @@ -28683,15 +28808,15 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, line); activerEffetTemporaire(lanceur, cibles, effet, mEffet, duree, options, evt, whisper, explications, display); } else { - line += '< ' + difficulte + ", le sort est rat\xE9"; + line += '< ' + difficulte + ", le sort est raté"; addLineToFramedDisplay(display, line); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }); } else { activerEffetTemporaire(lanceur, cibles, effet, mEffet, duree, options, evt, whisper, explications); } - } else { //On met fin \xE0 l'effet + } else { //On met fin à l'effet explications.forEach(function(e) { sendChat('', e); }); @@ -28730,7 +28855,7 @@ var COFantasy = COFantasy || function() { case 'oui': case 'Oui': case 'true': - case 'd\xE9but': + case 'début': case 'debut': valeur = true; activer = true; @@ -28769,7 +28894,7 @@ var COFantasy = COFantasy || function() { } let effet = cmd[1]; if (!estEffetCombat(effet)) { - error(effet + " n'est pas un effet de combat r\xE9pertori\xE9", msg.content); + error(effet + " n'est pas un effet de combat répertorié", msg.content); return; } const evt = { @@ -28795,7 +28920,7 @@ var COFantasy = COFantasy || function() { } } if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour l'effet", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour l'effet", playerId); return; } if (lanceur === undefined) { @@ -28810,7 +28935,7 @@ var COFantasy = COFantasy || function() { } if (lanceur && options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, dm: messageEffetCombat[effet].dm, @@ -28823,7 +28948,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(lanceur, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort", options.secret); + sendPerso(lanceur, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort", options.secret); } if (selected.length == 1 && options.tempeteDeMana.altruiste) { selected[0]._id = options.tempeteDeMana.altruiste.token.id; @@ -28895,7 +29020,7 @@ var COFantasy = COFantasy || function() { setTokenAttr(perso, effet + 'TokenSide', oldSide, evt); } }); - } else { //on d\xE9sactive + } else { //on désactive iterSelected(selected, function(perso) { let actMsg = messageFin(perso, mEffet) + extraImg; removeTokenAttr(perso, effet, evt, { @@ -28977,7 +29102,7 @@ var COFantasy = COFantasy || function() { effetCombat(msg); return; } - error(effet + " n'est pas un effet r\xE9pertori\xE9", msg.content); + error(effet + " n'est pas un effet répertorié", msg.content); return; } let av = activeOuValeur(cmd, options); @@ -28991,7 +29116,7 @@ var COFantasy = COFantasy || function() { if (lanceur) charId = lanceur.charId; getSelected(msg, function(selected, playerId, aoe) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour l'effet", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour l'effet", playerId); return; } if (lanceur === undefined) { @@ -29009,7 +29134,7 @@ var COFantasy = COFantasy || function() { } if (lanceur && options.tempeteDeMana) { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPlayer(msg, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayer(msg, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } if (selected.length == 1 && options.tempeteDeMana.altruiste) { selected[0]._id = options.tempeteDeMana.altruiste.token.id; @@ -29038,12 +29163,12 @@ var COFantasy = COFantasy || function() { } if (activer === undefined) { if (cibles.length > 1) { - sendPlayer(msg, "On ne peut s\xE9lectionner qu'un token si on ne pr\xE9cise pas si il faut activer ou d\xE9sactiver l'effet"); + sendPlayer(msg, "On ne peut sélectionner qu'un token si on ne précise pas si il faut activer ou désactiver l'effet"); return; } let perso = persoOfId(selected[0]._id); if (!perso) { - error("Token s\xE9lectionn\xE9 non valide", selected); + error("Token sélectionné non valide", selected); return; } activer = !attributeAsBool(perso, effet); @@ -29067,7 +29192,7 @@ var COFantasy = COFantasy || function() { normalToken = JSON.parse(normalToken); let nw = normalToken.width; let nh = normalToken.height; - //Rien \xE0 faire si le token occupe d\xE9j\xE0 une case + //Rien à faire si le token occupe déjà une case if (nw >= PIX_PER_UNIT || nh >= PIX_PER_UNIT) return; setTokenAttr(perso, 'tailleDeTokenNormale', nw, evt, { maxVal: nh @@ -29101,7 +29226,7 @@ var COFantasy = COFantasy || function() { let nw = parseInt(attr.get('current')); let nh = parseInt(attr.get('max')); if (isNaN(nw) || isNaN(nh)) { - error("La taille de token sauvegard\xE9e n'est pas correcte", attr); + error("La taille de token sauvegardée n'est pas correcte", attr); attr.remove(); } let character = getObj('character', perso.charId); @@ -29246,11 +29371,11 @@ var COFantasy = COFantasy || function() { if (!msgPour) { msgPour = " pour "; if (mEffet.msgSave) msgPour += mEffet.msgSave; - else msgPour += "r\xE9sister \xE0 l'effet " + effet; + else msgPour += "résister à l'effet " + effet; } let saveOpts = { msgPour, - msgRate: ", rat\xE9.", + msgRate: ", raté.", silencieuxSiPasAffecte: options.silencieuxSiPasAffecte, attaquant: lanceur, rolls: options.rolls, @@ -29328,7 +29453,7 @@ var COFantasy = COFantasy || function() { let classeEffet = cmd[1]; getSelected(msg, function(selected) { if (selected === undefined || selected.length === 0) { - error("Pas de cible s\xE9lectionn\xE9e pour la fin d'une classe d'effets", msg); + error("Pas de cible sélectionnée pour la fin d'une classe d'effets", msg); return; } const evt = { @@ -29366,16 +29491,16 @@ var COFantasy = COFantasy || function() { predicateAsBool(target, 'sansEsprit') || attributeAsBool(target, 'enrage') || predicateAsBool(target, 'liberteDAction')) { - messages.push(targetName + " est insensible \xE0 la peur !"); + messages.push(targetName + " est insensible à la peur !"); callback(); return; } if (options.immuniseSiResiste && attributeAsBool(target, options.immuniseSiResiste)) { - messages.push(targetName + " a d\xE9j\xE0 r\xE9sist\xE9 \xE0 cet effet, " + onGenre(target, 'il', 'elle') + " n'y est plus sensible"); + messages.push(targetName + " a déjà résisté à cet effet, " + onGenre(target, 'il', 'elle') + " n'y est plus sensible"); callback(); return; } - let carac = 'SAG'; //carac pour r\xE9sister + let carac = 'SAG'; //carac pour résister if (options.resisteAvecForce) carac = meilleureCarac('SAG', 'FOR', target, difficulte); //chercher si un partenaire a sansPeur pour appliquer le bonus @@ -29387,7 +29512,7 @@ var COFantasy = COFantasy || function() { let allTokens; allies.forEach(function(cid) { if (charPredicateAsBool(cid, 'sansPeur')) { - //On cherche si l'alli\xE9 est pr\xE9sent sur la m\xEAme page + //On cherche si l'allié est présent sur la même page allTokens = allTokens || findObjs({ _type: "graphic", @@ -29406,7 +29531,7 @@ var COFantasy = COFantasy || function() { charId: cid, token: alliePresent }; - msgAllieSansPeur = nomPerso(allie) + " a donn\xE9 +" + bonusAllie + " au jet"; + msgAllieSansPeur = nomPerso(allie) + " a donné +" + bonusAllie + " au jet"; } } } @@ -29422,7 +29547,7 @@ var COFantasy = COFantasy || function() { let line = targetName + " fait " + tr.texte; let sujet = onGenre(target, 'il', 'elle'); if (tr.reussite) { - line += ", " + sujet + " r\xE9siste \xE0 la peur." + tr.modifiers; + line += ", " + sujet + " résiste à la peur." + tr.modifiers; if (options.immuniseSiResiste) setTokenAttr(target, options.immuniseSiResiste, true, evt); } else { @@ -29430,14 +29555,18 @@ var COFantasy = COFantasy || function() { let effet = 'apeureTemp'; let etat = 'apeure'; if (options.etourdi) { - line += "s'enfuit ou reste recroquevill\xE9" + eForFemale(target) + " sur place"; + line += "s'enfuit ou reste recroquevillé" + eForFemale(target) + " sur place"; effet = 'peurEtourdi'; } else if (options.ralenti) { line += "est ralenti" + eForFemale(target); effet = 'ralentiTemp'; etat = 'ralenti'; + } else if (options.paralyse) { + line += "est paralysé" + eForFemale(target); + effet = 'paralyseTemp'; + etat = 'paralyse'; } else if (options.secoue && !attributeAsBool(target, 'secoue')) { - line += "est secou\xE9" + eForFemale(target); + line += "est secoué" + eForFemale(target); effet = 'secoue'; etat = false; } else { @@ -29467,12 +29596,12 @@ var COFantasy = COFantasy || function() { let pageId = getPageId(playerId); let difficulte = parseInt(cmd[1]); if (isNaN(difficulte)) { - error("Le premier argument de !cof-peur, la difficult\xE9 du test de r\xE9sistance, n'est pas un nombre", cmd); + error("Le premier argument de !cof-peur, la difficulté du test de résistance, n'est pas un nombre", cmd); return; } - let duree = parseDice(cmd[2], "dur\xE9e de peur"); + let duree = parseDice(cmd[2], "durée de peur"); if (!dePositif(duree)) { - error("Le second argument de !cof-peur, la dur\xE9e, n'est pas un nombre positif", cmd); + error("Le second argument de !cof-peur, la durée, n'est pas un nombre positif", cmd); return; } let options = {}; @@ -29487,16 +29616,17 @@ var COFantasy = COFantasy || function() { case 'ralenti': case 'effroi': case 'secoue': + case 'paralyse': options[optCmd[0]] = true; return; case 'portee': if (optCmd.length < 2) { - error("Il manque l'argument de port\xE9e", optArgs); + error("Il manque l'argument de portée", optArgs); return; } options.portee = parseInt(optCmd[1]); if (isNaN(options.portee) || options.portee < 0) { - error("La port\xE9e n'est pas un nombre positif", optCmd); + error("La portée n'est pas un nombre positif", optCmd); delete options.portee; } return; @@ -29529,7 +29659,7 @@ var COFantasy = COFantasy || function() { let cibles = []; getSelected(msg, function(selected) { if (selected === undefined || selected.length === 0) { - error("Pas de cible s\xE9lectionn\xE9e pour la peur", msg); + error("Pas de cible sélectionnée pour la peur", msg); return; } iterSelected(selected, function(perso) { @@ -29546,7 +29676,7 @@ var COFantasy = COFantasy || function() { if (cibles.length > 0) { doPeur(cibles, difficulte, options); } else { - error("Aucune cible valable \xE0 port\xE9e de l'effet de Peur", msg); + error("Aucune cible valable à portée de l'effet de Peur", msg); } } @@ -29566,14 +29696,14 @@ var COFantasy = COFantasy || function() { if (options.titre) action += options.titre; else if (options.effroi) action += "est vraiment effrayant" + eForFemale(options.lanceur); - else action = "Capacit\xE9 : Sort de peur"; + else action = "Capacité : Effet de peur"; } else if (options.titre) action = options.titre; let messages = []; entrerEnCombat(options.lanceur, cibles, messages, evt); let display = startFramedDisplay(options.playerId, action, options.lanceur); let jet = " Jet de SAG "; if (options.resisteAvecForce) jet += "ou FOR "; - jet += "difficult\xE9 " + difficulte; + jet += "difficulté " + difficulte; addLineToFramedDisplay(display, jet, 80); let counter = cibles.length; let finalDisplay = function() { @@ -29587,7 +29717,7 @@ var COFantasy = COFantasy || function() { } } if (counter < 1) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }; cibles.forEach(function(perso) { @@ -29600,7 +29730,7 @@ var COFantasy = COFantasy || function() { if (options === undefined || options.cmd === undefined) return; let cmd = options.cmd; if (cmd.length < 3) { - error("Il faut au moins 2 arguments \xE0 !cof-attaque-magique", cmd); + error("Il faut au moins 2 arguments à !cof-attaque-magique", cmd); return; } let attaquant = persoOfId(cmd[1], cmd[1]); @@ -29634,13 +29764,13 @@ var COFantasy = COFantasy || function() { } } - // callback est seulement appel\xE9 si on fait le test - // evt est facultatif ; si absent, en cr\xE9e un nouveau g\xE9n\xE9rique et l'ajoute \xE0 l'historique + // callback est seulement appelé si on fait le test + // evt est facultatif ; si absent, en crée un nouveau générique et l'ajoute à l'historique function attaqueMagiqueOpposee(playerId, attaquant, cible, options, callback, evt) { if (options.attaqueMentale) { if (predicateAsBool(cible, 'sansEsprit') || predicateAsBool(cible, 'vegetatif')) { sendPerso(attaquant, " est sans esprit, " + onGenre(cible, 'il', 'elle') + - " est immunis\xE9" + onGenre(cible, '', 'e') + " aux attaques mentales."); + " est immunisé" + onGenre(cible, '', 'e') + " aux attaques mentales."); return; } else if (predicateAsBool(cible, 'liberteDAction')) { sendPerso(cible, "reste libre de ses actions !"); @@ -29720,7 +29850,7 @@ var COFantasy = COFantasy || function() { let attackRoll2 = d20roll2 + att2Skill; if (options.chanceRollId && options.chanceRollId.roll2) attackRoll2 += options.chanceRollId.roll2; - let action = "Attaque magique oppos\xE9e"; + let action = "Attaque magique opposée"; let reussi; if (d20roll1 == 1) { if (d20roll2 == 1) reussi = (attackRoll1 >= attackRoll2); @@ -29773,15 +29903,15 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, line); if (reussi) { diminueMalediction(cible, evt); - addLineToFramedDisplay(display, "Attaque r\xE9ussie !"); + addLineToFramedDisplay(display, "Attaque réussie !"); } else { diminueMalediction(attaquant, evt); - addLineToFramedDisplay(display, "L'attaque \xE9choue."); + addLineToFramedDisplay(display, "L'attaque échoue."); } explications.forEach(explication => addLineToFramedDisplay(display, explication, 80)); if (callback) callback(display, reussi); else { - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }); } @@ -29802,17 +29932,17 @@ var COFantasy = COFantasy || function() { function(display, reussi) { if (reussi) { if (attributeAsBool(cible, 'immunise24HA_injonction')) { - addLineToFramedDisplay(display, nomPerso(cible) + " a d\xE9j\xE0 r\xE9sist\xE9 \xE0 une injonction aujourd'hui, c'est sans effet"); + addLineToFramedDisplay(display, nomPerso(cible) + " a déjà résisté à une injonction aujourd'hui, c'est sans effet"); } else if (predicateAsBool(cible, 'liberteDAction')) { addLineToFramedDisplay(display, nomPerso(cible) + " reste libre de ses actions !"); } else { - addLineToFramedDisplay(display, nomPerso(cible) + " ob\xE9it \xE0 l'injonction"); + addLineToFramedDisplay(display, nomPerso(cible) + " obéit à l'injonction"); } - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } else { setTokenAttr(cible, 'immunise24HA_injonction', true, evt); - addLineToFramedDisplay(display, nomPerso(cible) + " n'ob\xE9it pas \xE0 l'injonction"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " n'obéit pas à l'injonction"); + sendFramedDisplay(display); } }, evt); } @@ -29832,13 +29962,13 @@ var COFantasy = COFantasy || function() { function(display, reussi) { if (reussi) { if (estNonVivant(cible)) { - addLineToFramedDisplay(display, nomPerso(cible) + " n'est pas une cr\xE9ature vivante, il ne peut croire \xE0 sa mort"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " n'est pas une créature vivante, il ne peut croire à sa mort"); + sendFramedDisplay(display); return; } if (attributeAsBool(cible, 'limiteParJour_tueurFantasmagorique')) { - addLineToFramedDisplay(display, nomPerso(cible) + " a d\xE9j\xE0 \xE9t\xE9 victime d'un tueur fantasmagorique aujourd'hui, c'est sans effet"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " a déjà été victime d'un tueur fantasmagorique aujourd'hui, c'est sans effet"); + sendFramedDisplay(display); return; } setTokenAttr(cible, 'limiteParJour_tueurFantasmagorique', true, evt); @@ -29856,7 +29986,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, message, 80); }; const saveOpts = { - msgPour: " pour r\xE9sister au tueur fantasmagorique", + msgPour: " pour résister au tueur fantasmagorique", attaquant: attaquant, rolls: options.rolls, chanceRollId: options.chanceRollId, @@ -29866,18 +29996,18 @@ var COFantasy = COFantasy || function() { save(s, cible, saveId, expliquer, saveOpts, evt, function(reussiteSave, texte) { if (reussiteSave) { - addLineToFramedDisplay(display, nomPerso(cible) + " perd l'\xE9quilibre et tombe par terre"); + addLineToFramedDisplay(display, nomPerso(cible) + " perd l'équilibre et tombe par terre"); setState(cible, 'renverse', true, evt); - } else { //save rat\xE9 - addLineToFramedDisplay(display, nomPerso(cible) + " succombe \xE0 ses pires terreurs"); + } else { //save raté + addLineToFramedDisplay(display, nomPerso(cible) + " succombe à ses pires terreurs"); updateCurrentBar(cible, 1, 0, evt); setState(cible, 'mort', true, evt); } - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); } else { setTokenAttr(cible, 'limiteParJour_tueurFantasmagorique', true, evt); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }, evt); } @@ -29897,8 +30027,8 @@ var COFantasy = COFantasy || function() { function(display, reussi) { if (reussi) { if (attributeAsBool(cible, 'limiteParJour_enkystementLointain')) { - addLineToFramedDisplay(display, nomPerso(cible) + " a d\xE9j\xE0 \xE9t\xE9 victime d'un enkystement lointain aujourd'hui, c'est sans effet"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " a déjà été victime d'un enkystement lointain aujourd'hui, c'est sans effet"); + sendFramedDisplay(display); return; } setTokenAttr(cible, 'limiteParJour_enkystementLointain', true, evt); @@ -29908,19 +30038,19 @@ var COFantasy = COFantasy || function() { val, roll } = rollDePlus(20); - let message = nomPerso(cible) + " est t\xE9l\xE9port\xE9" + eForFemale(cible) + " \xE0 une distance de "; + let message = nomPerso(cible) + " est téléporté" + eForFemale(cible) + " à une distance de "; if (niveauCible < niveauAttaquant / 2) { - message += (val * 100) + " kilom\xE8tres."; + message += (val * 100) + " kilomètres."; } else if (niveauCible < niveauAttaquant) { - message += roll + " kilom\xE8tre" + (val > 1) ? 's' : ''; + message += roll + " kilomètre" + (val > 1) ? 's' : ''; } else { - message += (val * 10) + " m\xE8tres."; + message += (val * 10) + " mètres."; } addLineToFramedDisplay(display, message); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } else { //Dans ce cas, pas victime, donc on permet d'autre tentatives - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }, evt); } @@ -29930,7 +30060,7 @@ var COFantasy = COFantasy || function() { if (options === undefined || options.cmd === undefined) return; const cmd = options.cmd; if (cmd.length < 3) { - error("Il faut au moins 2 arguments \xE0 !cof-injonction-mortelle", cmd); + error("Il faut au moins 2 arguments à !cof-injonction-mortelle", cmd); return; } let attaquant = persoOfId(cmd[1], cmd[1]); @@ -29949,7 +30079,7 @@ var COFantasy = COFantasy || function() { } function injonctionMortelle(playerId, attaquant, cible, options) { - var evt = { + const evt = { type: 'injonctionMortelle', action: { titre: "Injonction Mortelle", @@ -29967,19 +30097,19 @@ var COFantasy = COFantasy || function() { }); explications.forEach(msg => addLineToFramedDisplay(display, msg, 80)); if (attributeAsBool(cible, 'injonctionMortelle')) { - addLineToFramedDisplay(display, nomPerso(cible) + " a d\xE9j\xE0 \xE9t\xE9 victime d'une injonction mortelle ce combat, c'est sans effet"); - sendChat("", endFramedDisplay(display)); + addLineToFramedDisplay(display, nomPerso(cible) + " a déjà été victime d'une injonction mortelle ce combat, c'est sans effet"); + sendFramedDisplay(display); return; } if (predicateAsBool(cible, 'liberteDAction')) { addLineToFramedDisplay(display, nomPerso(cible) + " reste libre de ses actions !"); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); return; } setTokenAttr(cible, 'injonctionMortelle', true, evt); let saveOpts = { - msgPour: " pour r\xE9sister \xE0 l'injonction mortelle", - msgRate: ", rat\xE9.", + msgPour: " pour résister à l'injonction mortelle", + msgRate: ", raté.", attaquant: attaquant, rolls: options.rolls, chanceRollId: options.chanceRollId, @@ -30012,47 +30142,47 @@ var COFantasy = COFantasy || function() { cible.attaquant = attaquant; dealDamage(cible, dmg, [], evt, false, options, explicationsDmg, function(dmgDisplay, dmgFinal) { addLineToFramedDisplay(display, - name + " re\xE7oit " + dmgDisplay + " DM"); + name + " reçoit " + dmgDisplay + " DM"); explicationsDmg.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); }); } else { addLineToFramedDisplay(display, nomPerso(cible) + " meurt sous l'injonction mortelle !", 80); updateCurrentBar(cible, 1, 0, evt); setState(cible, 'mort', true, evt); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }); } function parseSommeil(msg) { //sort de sommeil - var options = parseOptions(msg); + const options = parseOptions(msg); if (options === undefined) return; - var args = options.cmd; + const args = options.cmd; if (args.length < 2) { error("La fonction !cof-sommeil a besoin du nom ou de l'id du lanceur de sort", args); return; } - var lanceur = persoOfId(args[1], args[1]); + const lanceur = persoOfId(args[1], args[1]); if (lanceur === undefined) { - error("Aucun personnage nomm\xE9 " + args[1], args); + error("Aucun personnage nommé " + args[1], args); return; } - var casterCharId = lanceur.charId; - var casterChar = getObj('character', casterCharId); + const casterCharId = lanceur.charId; + const casterChar = getObj('character', casterCharId); if (casterChar === undefined) { error("Fiche de personnage manquante"); return; } getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lectionn\xE9e pour le sort de sommeil", playerId); + sendPlayer(msg, "Pas de cible sélectionnée pour le sort de sommeil", playerId); return; } - var cibles = []; + let cibles = []; iterSelected(selected, function(perso) { cibles.push(perso); }); @@ -30063,14 +30193,14 @@ var COFantasy = COFantasy || function() { } function doSommeil(lanceur, cibles, options, ciblesSansSave, ciblesAvecSave) { - var evt = { + const evt = { type: 'sommeil', action: { - lanceur: lanceur, - cibles: cibles, - ciblesSansSave: ciblesSansSave, - ciblesAvecSave: ciblesAvecSave, - options: options + lanceur, + cibles, + ciblesSansSave, + ciblesAvecSave, + options } }; addEvent(evt); @@ -30089,14 +30219,14 @@ var COFantasy = COFantasy || function() { let rollD6 = evt.action.rolls[rollD6Id] || rolls.inlinerolls[d6RollNumber]; evt.action.rolls[rollD6Id] = rollD6; let nbTargetsMax = rollD6.results.total + cha; - let action = "Capacit\xE9 : Sort de sommeil (max " + nbTargetsMax + " cibles)"; + let action = "Capacité : Sort de sommeil (max " + nbTargetsMax + " cibles)"; let display = startFramedDisplay(options.playerId, action, lanceur); let attMag = rolls.inlinerolls[attMagRollNumber].results.total; let targetsWithSave = []; let targetsWithoutSave = []; cibles.forEach(function(perso) { - if (estNonVivant(perso) || predicateAsBool(perso, 'immunite_endormi')) { //le sort de sommeil n'affecte que les cr\xE9atures vivantes - addLineToFramedDisplay(display, nomPerso(perso) + " n'est pas affect\xE9 par le sommeil"); + if (estNonVivant(perso) || predicateAsBool(perso, 'immunite_endormi')) { //le sort de sommeil n'affecte que les créatures vivantes + addLineToFramedDisplay(display, nomPerso(perso) + " n'est pas affecté par le sommeil"); return; } if (predicateAsBool(perso, "liberteDAction")) { @@ -30105,7 +30235,7 @@ var COFantasy = COFantasy || function() { } let pv = perso.token.get('bar1_max'); if (pv > 2 * attMag) { - let line = nomPerso(perso) + " a trop de PV pour \xEAtre affect\xE9 par le sort"; + let line = nomPerso(perso) + " a trop de PV pour être affecté par le sort"; addLineToFramedDisplay(display, line); } else if (pv > attMag) { targetsWithSave.push(perso); @@ -30113,13 +30243,13 @@ var COFantasy = COFantasy || function() { targetsWithoutSave.push(perso); } }); - var ciblesSansSave; + let ciblesSansSave; if (evt.action.ciblesSansSave) { ciblesSansSave = evt.action.ciblesSansSave; nbTargetsMax -= ciblesSansSave.length; } else { ciblesSansSave = []; - var i, r; + let i, r; if (targetsWithoutSave.length > nbTargetsMax) { i = 0; //position to decide while (nbTargetsMax > 0) { @@ -30140,16 +30270,16 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, nomPerso(t) + " s'endort"); }); if (nbTargetsMax > 0 && targetsWithSave.length > 0) { - var ciblesAvecSave; + let ciblesAvecSave; if (evt.action.ciblesAvecSave) { ciblesAvecSave = evt.action.ciblesAvecSave; nbTargetsMax -= ciblesAvecSave.length; } else { ciblesAvecSave = []; if (targetsWithSave.length > nbTargetsMax) { - var j = 0; + let j = 0; while (nbTargetsMax > 0) { - var ra = randomInteger(nbTargetsMax) + j; + let ra = randomInteger(nbTargetsMax) + j; ciblesAvecSave.push(targetsWithSave[ra]); targetsWithSave[ra] = targetsWithSave[j]; j++; @@ -30160,21 +30290,21 @@ var COFantasy = COFantasy || function() { nbTargetsMax -= ciblesAvecSave.length; } } - var seuil = 10 + cha; - var tokensToProcess = ciblesAvecSave.length; - var finalize = function() { + let seuil = 10 + cha; + let tokensToProcess = ciblesAvecSave.length; + let finalize = function() { if (tokensToProcess == 1) { - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } tokensToProcess--; }; evt.action.ciblesAvecSave = ciblesAvecSave; ciblesAvecSave.forEach(function(perso) { - var testId = 'resisteSommeil_' + perso.token.id; + let testId = 'resisteSommeil_' + perso.token.id; testCaracteristique(perso, 'SAG', seuil, testId, options, evt, function(tr) { - var line = "Jet de r\xE9sistance de " + nomPerso(perso) + ": " + tr.texte; - var sujet = onGenre(perso, 'il', 'elle'); + let line = "Jet de résistance de " + nomPerso(perso) + ": " + tr.texte; + let sujet = onGenre(perso, 'il', 'elle'); if (tr.reussite) { line += ">=" + seuil + ", " + sujet + " ne s'endort pas." + tr.modifiers; } else { @@ -30186,22 +30316,23 @@ var COFantasy = COFantasy || function() { }); }); } else { // all targets are without save - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }); } //!cof-attaque-magique-contre-pv {selected|token_id} {target|token_id} + // deprecated function attaqueMagiqueContrePV(msg) { - var options = parseOptions(msg); + const options = parseOptions(msg); if (options === undefined || options.cmd === undefined) return; - var cmd = options.cmd; + let cmd = options.cmd; if (cmd.length < 3) { - error("Il faut au moins 2 arguments \xE0 !cof-attaque-magique-contre-pv", cmd); + error("Il faut au moins 2 arguments à !cof-attaque-magique-contre-pv", cmd); return; } - var attaquant = persoOfId(cmd[1], cmd[1]); - var cible = persoOfId(cmd[2], cmd[2]); + let attaquant = persoOfId(cmd[1], cmd[1]); + let cible = persoOfId(cmd[2], cmd[2]); if (attaquant === undefined || cible === undefined) { error("Arguments de !cof-attaque-magique-contre-pv incorrects", cmd); return; @@ -30224,7 +30355,7 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); if (limiteRessources(attaquant, options, 'attaque magique', "l'attaque magique", evt)) return; - var attaquantChar = getObj('character', attaquant.charId); + let attaquantChar = getObj('character', attaquant.charId); if (attaquantChar === undefined) { error("Fiche de l'attaquant introuvable"); return; @@ -30250,58 +30381,58 @@ var COFantasy = COFantasy || function() { effetAuD20(attaquant, d20roll); let attSkill = rolls.inlinerolls[attSkillNumber].results.total; if (estAffaibli(attaquant) && predicateAsBool(attaquant, 'insensibleAffaibli')) attSkill -= 2; - var attackRoll = d20roll + attSkill; + let attackRoll = d20roll + attSkill; let line = nomPerso(attaquant) + " fait " + buildinline(rolls.inlinerolls[attRollNumber]); if (attSkill > 0) line += "+" + attSkill + " = " + attackRoll; else if (attSkill < 0) line += attSkill + " = " + attackRoll; addLineToFramedDisplay(display, line); - var reussi; + let reussi; if (d20roll == 1) reussi = false; else if (d20roll == 20) reussi = true; else reussi = (attackRoll >= pvMax); if (reussi) { - addLineToFramedDisplay(display, "Attaque r\xE9ussie !"); + addLineToFramedDisplay(display, "Attaque réussi !"); } else { diminueMalediction(attaquant, evt); - addLineToFramedDisplay(display, "L'attaque \xE9choue."); + addLineToFramedDisplay(display, "L'attaque échoue."); } - sendChat("", endFramedDisplay(display)); - }); //Fin du jet de d\xE9s pour l'attaque + sendFramedDisplay(display); + }); //Fin du jet de dés pour l'attaque } function transeGuerison(msg) { if (stateCOF.combat) { - sendPlayer(msg, "Pas possible de m\xE9diter en combat"); + sendPlayer(msg, "Pas possible de méditer en combat"); return; } - var options = parseOptions(msg); + const options = parseOptions(msg); if (options === undefined) return; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lectionn\xE9e pour la transe de gu\xE9rison", playerId); + sendPlayer(msg, "Pas de cible sélectionnée pour la transe de guérison", playerId); return; } - var evt = { - type: "Transe de gu\xE9rison", + const evt = { + type: "Transe de guérison", }; iterSelected(selected, function(perso) { - var token = perso.token; - if (attributeAsBool(perso, 'transeDeGu\xE9rison')) { - sendPerso(perso, "a d\xE9j\xE0 m\xE9dit\xE9 depuis le dernier combat"); + let token = perso.token; + if (attributeAsBool(perso, 'transeDeGuérison')) { + sendPerso(perso, "a déjà médité depuis le dernier combat"); return; } - var bar1 = parseInt(token.get("bar1_value")); - var pvmax = parseInt(token.get("bar1_max")); + let bar1 = parseInt(token.get("bar1_value")); + let pvmax = parseInt(token.get("bar1_max")); if (isNaN(bar1) || isNaN(pvmax)) return; if (bar1 >= pvmax) { - sendPerso(perso, "n'a pas besoin de m\xE9diter"); + sendPerso(perso, "n'a pas besoin de méditer"); return; } - var sagMod = modCarac(perso, 'sagesse'); - var niveau = ficheAttributeAsInt(perso, 'niveau', 1); - var soin = niveau + sagMod; + let sagMod = modCarac(perso, 'sagesse'); + let niveau = ficheAttributeAsInt(perso, 'niveau', 1); + let soin = niveau + sagMod; if (soin < 0) soin = 0; if (bar1 === 0) { if (attributeAsBool(perso, 'etatExsangue')) { @@ -30316,8 +30447,8 @@ var COFantasy = COFantasy || function() { bar1 = pvmax; } updateCurrentBar(perso, 1, bar1, evt); - setTokenAttr(perso, 'transeDeGu\xE9rison', true, evt); - sendPerso(perso, "entre en m\xE9ditation pendant 10 minutes et r\xE9cup\xE8re " + soin + " points de vie."); + setTokenAttr(perso, 'transeDeGuérison', true, evt); + sendPerso(perso, "entre en méditation pendant 10 minutes et récupère " + soin + " points de vie."); }); addEvent(evt); }); @@ -30332,7 +30463,7 @@ var COFantasy = COFantasy || function() { } function estFee(perso) { - if (predicateAsBool(perso, 'f\xE9e')) return true; + if (predicateAsBool(perso, 'fée')) return true; if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); perso.race = perso.race.toLowerCase(); @@ -30342,7 +30473,7 @@ var COFantasy = COFantasy || function() { case 'licorne': case 'farfadet': case 'fee': - case 'f\xE9e': + case 'fée': case 'pixie': case 'lutin': return true; @@ -30352,14 +30483,14 @@ var COFantasy = COFantasy || function() { } function estDemon(perso) { - if (predicateAsBool(perso, 'd\xE9mon')) return true; + if (predicateAsBool(perso, 'démon')) return true; if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); perso.race = perso.race.toLowerCase(); } if (perso.race === '') return false; switch (perso.race) { - case 'd\xE9mon': + case 'démon': case 'demon': case 'balor': case 'marilith': @@ -30411,14 +30542,14 @@ var COFantasy = COFantasy || function() { } function estGeant(perso) { - if (predicateAsBool(perso, 'g\xE9ant')) return true; + if (predicateAsBool(perso, 'géant')) return true; if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); perso.race = perso.race.toLowerCase(); } if (perso.race === '') return false; switch (perso.race) { - case 'g\xE9ant': + case 'géant': case 'geant': case 'ogre': case 'troll': @@ -30484,7 +30615,7 @@ var COFantasy = COFantasy || function() { return false; } - //Vrai pour les insectes et araign\xE9es + //Vrai pour les insectes et araignées function estInsecte(perso) { if (predicateAsBool(perso, 'insecte')) return true; if (perso.profil === undefined) { @@ -30492,7 +30623,7 @@ var COFantasy = COFantasy || function() { perso.profil = perso.profil.toLowerCase(); } if (perso.profil == 'insecte') return true; - if (perso.profil == 'araign\xE9e') return true; + if (perso.profil == 'araignée') return true; if (perso.race === undefined) { perso.race = ficheAttribute(perso, 'race', ''); perso.race = perso.race.toLowerCase(); @@ -30501,7 +30632,7 @@ var COFantasy = COFantasy || function() { if (perso.race.includes('elf') && perso.race.includes('noir')) return true; switch (perso.race) { case 'ankheg': - case 'araign\xE9e': + case 'araignée': case 'araignee': case 'insecte': return true; @@ -30526,18 +30657,18 @@ var COFantasy = COFantasy || function() { case 'drow': case 'haut elfe': case 'halfelin': - case 'g\xE9ant': + case 'géant': case 'geant': case 'ange': case 'barghest': - case 'd\xE9mon': + case 'démon': case 'doppleganger': case 'dryade': case 'gnoll': case 'gobelin': case 'gobelours': case 'hobegobelin': - case 'homme-l\xE9zard': + case 'homme-lézard': case 'kobold': case 'nymphe': case 'ogre': @@ -30559,25 +30690,25 @@ var COFantasy = COFantasy || function() { if (perso.race === '') return false; switch (perso.race) { case 'ankheg': - case 'araign\xE9e': + case 'araignée': case 'araignee': case 'basilic': - case 'b\xE9hir': + case 'béhir': case 'behir': case 'bulette': case 'bison': case 'centaure': case 'cheval': case 'chien': - case 'chim\xE8re': + case 'chimère': case 'chimere': case 'cockatrice': case 'crocodile': case 'dragon': case 'drider': - case 'el\xE9phant': + case 'eléphant': case 'elephant': - case '\xE9l\xE9phant': + case 'éléphant': case 'mammouth': case 'griffon': case 'hipogriffe': @@ -30590,13 +30721,13 @@ var COFantasy = COFantasy || function() { case 'manticore': case 'ours': case 'panthere': - case 'panth\xE8re': + case 'panthère': case 'pegase': - case 'p\xE9gase': + case 'pégase': case 'pieuvre': case 'rat': case 'rhinoceros': - case 'rhinoc\xE9ros': + case 'rhinocéros': case 'sanglier': case 'taureau': case 'tigre': @@ -30628,7 +30759,7 @@ var COFantasy = COFantasy || function() { case 'animal': case 'aigle': case 'araignee': - case 'araign\xE9e': + case 'araignée': case 'basilic': case 'bulette': case 'bison': @@ -30638,8 +30769,8 @@ var COFantasy = COFantasy || function() { case 'chien': case 'crocodile': case 'dinosaure': - case '\xE9l\xE9phant': - case 'el\xE9phant': + case 'éléphant': + case 'eléphant': case 'elephant': case 'gorille': case 'griffon': @@ -30652,11 +30783,11 @@ var COFantasy = COFantasy || function() { case 'manticore': case 'ours': case 'ours-hibou': - case 'panth\xE8re': + case 'panthère': case 'pegase': - case 'p\xE9gase': + case 'pégase': case 'pieuvre': - case 'rhinoc\xE9ros': + case 'rhinocéros': case 'roc': case 'sanglier': case 'serpent': @@ -30676,7 +30807,7 @@ var COFantasy = COFantasy || function() { switch (perso.race) { case 'squelette': case 'zombie': - case '\xE9l\xE9mentaire': + case 'élémentaire': case 'momie': return true; default: @@ -30697,7 +30828,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd.length < 2) { - error("Il faut au moins un argument \xE0 !cof-soin", cmd); + error("Il faut au moins un argument à !cof-soin", cmd); return; } let soigneur = options.lanceur; @@ -30705,7 +30836,7 @@ var COFantasy = COFantasy || function() { let cible; let argSoin; if (cmd.length > 4) { - error("Trop d'arguments \xE0 !cof-soin", cmd); + error("Trop d'arguments à !cof-soin", cmd); } if (cmd.length > 2) { //cof-soin lanceur [cible] montant if (soigneur === undefined) { @@ -30719,7 +30850,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3) { // on a la cible en argument cible = persoOfId(cmd[2], cmd[2], pageId); if (cible === undefined) { - error("Le deuxi\xE8me argument n'est pas un token valide: " + msg.content, cmd[2]); + error("Le deuxième argument n'est pas un token valide: " + msg.content, cmd[2]); return; } argSoin = cmd[3]; @@ -30730,7 +30861,7 @@ var COFantasy = COFantasy || function() { argSoin = cmd[1]; } if (soigneur === undefined && (options.mana || (options.portee !== undefined) || options.limiteParJour || options.limiteParCombat || options.dose || options.limiteSoinsParJour)) { - error("Il faut pr\xE9ciser un soigneur pour ces options d'effet", options); + error("Il faut préciser un soigneur pour ces options d'effet", options); return; } let charId; @@ -30748,11 +30879,11 @@ var COFantasy = COFantasy || function() { if (options.tempeteDeManaIntense) nbDes += options.tempeteDeManaIntense; switch (argSoin) { case 'leger': - effet += ' l\xE9gers'; + effet += ' légers'; if (options.dose === undefined && options.limiteParJour === undefined) options.limiteAttribut = { nom: 'soinsLegers', - message: "ne peut plus lancer de sort de soins l\xE9gers aujourd'hui", + message: "ne peut plus lancer de sort de soins légers aujourd'hui", limite: rangSoin }; let bonusLeger = niveau + predicateAsInt(soigneur, 'voieDuGuerisseur', 0); @@ -30764,11 +30895,11 @@ var COFantasy = COFantasy || function() { if (options.portee === undefined) options.portee = 0; break; case 'modere': - effet += ' mod\xE9r\xE9s'; + effet += ' modérés'; if (options.dose === undefined && options.limiteParJour === undefined) options.limiteAttribut = { nom: 'soinsModeres', - message: "ne peut plus lancer de sort de soins mod\xE9r\xE9ss aujourd'hui", + message: "ne peut plus lancer de sort de soins modéréss aujourd'hui", limite: rangSoin }; if (options.portee === undefined) options.portee = 0; @@ -30822,7 +30953,7 @@ var COFantasy = COFantasy || function() { if (options.dose === undefined && options.limiteParJour === undefined) options.limiteAttribut = { nom: 'attributDeCombat_soinsDeGroupe', - message: " a d\xE9j\xE0 fait un soin de groupe durant ce combat", + message: " a déjà fait un soin de groupe durant ce combat", limite: 1 }; if (options.puissant) soins = "[[1d10"; @@ -30841,14 +30972,14 @@ var COFantasy = COFantasy || function() { case 'secondSouffle': { if (!stateCOF.combat) { - whisperChar(charId, " ne peut pas utiliser la capacit\xE9 second souffle en dehors des combats"); + whisperChar(charId, " ne peut pas utiliser la capacité second souffle en dehors des combats"); return; } effet = "second souffle"; if (options.dose === undefined && options.limiteParJour === undefined) options.limiteAttribut = { nom: 'secondSouffleUtilise', - message: " a d\xE9j\xE0 repris son souffle durant ce combat", + message: " a déjà repris son souffle durant ce combat", limite: 1 }; soins = "[[1d10+"; @@ -30858,8 +30989,8 @@ var COFantasy = COFantasy || function() { soins += "]]"; cible = soigneur; options.recuperation = true; - if (bonus == -1 || bonus > 0) { //Il y a un pr\xE9dicat second souffle - //On limite les soins \xE0 ce qui a \xE9t\xE9 perdu dans ce combat + if (bonus == -1 || bonus > 0) { //Il y a un prédicat second souffle + //On limite les soins à ce qui a été perdu dans ce combat const pvDebut = attributeAsInt(soigneur, 'PVsDebutCombat', 0); let pv = parseInt(soigneur.token.get('bar1_value')); if (isNaN(pv)) return; @@ -30908,7 +31039,7 @@ var COFantasy = COFantasy || function() { const playerId = getPlayerIdFromMsg(msg); if (options.tempeteDeMana && soigneur) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options const optMana = { mana: options.mana, rang: options.rang, @@ -30920,7 +31051,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(soigneur, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPerso(soigneur, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -30929,7 +31060,7 @@ var COFantasy = COFantasy || function() { soins = res[0].inlinerolls[0].results.total; let soinTxt = buildinline(res[0].inlinerolls[0], 'normal', true); if (soins <= 0) { - sendChar(charId, "ne r\xE9ussit pas \xE0 soigner (total de soins " + soinTxt + ")", true); + sendChar(charId, "ne réussit pas à soigner (total de soins " + soinTxt + ")", true); return; } const evt = { @@ -30962,7 +31093,7 @@ var COFantasy = COFantasy || function() { if (nbCibles > 1) { display = startFramedDisplay(playerId, effet, soigneur); } else if (nbCibles === 0) { - sendChar(charId, "personne \xE0 soigner", true); + sendChar(charId, "personne à soigner", true); return; } iterSelected(selected, callback); @@ -30979,7 +31110,7 @@ var COFantasy = COFantasy || function() { else sendChar(charId, message, true); }); } - if (display) sendChat("", endFramedDisplay(display)); + if (display) sendFramedDisplay(display); if (ressourceLimiteSoinsParJour) { whisperChar(charId, "peut encore soigner de " + attributeAsInt(soigneur, ressourceLimiteSoinsParJour, options.limiteSoinsParJour) + " PV aujourd'hui."); } @@ -31008,7 +31139,7 @@ var COFantasy = COFantasy || function() { let utilisations = attributeAsInt(cible, ressourceLimiteCibleParJour, options.limiteCibleParJour); if (utilisations === 0) { - sendPerso(cible, "ne peut plus b\xE9n\xE9ficier de " + effet + " aujourd'hui"); + sendPerso(cible, "ne peut plus bénéficier de " + effet + " aujourd'hui"); finSoin(); return; } @@ -31044,11 +31175,11 @@ var COFantasy = COFantasy || function() { return; } if (display) { - addLineToFramedDisplay(display, "R\xE9sultat des d\xE9s : " + soinTxt); + addLineToFramedDisplay(display, "Résultat des dés : " + soinTxt); } if (msg.content.includes(' --sacrifierPV')) { //paie autant de PV que soins if (soigneur === undefined) { - error("Il faut pr\xE9ciser qui est le soigneur pour utiliser l'option --sacrifierPV", msg.content); + error("Il faut préciser qui est le soigneur pour utiliser l'option --sacrifierPV", msg.content); soinImpossible = true; display = undefined; finSoin(); @@ -31083,7 +31214,7 @@ var COFantasy = COFantasy || function() { let pv = parseInt(cible.token.get('bar1_value')); if (isNaN(pv) || pv > 0) { let sort = (souffleDeVie > 0) ? "souffle de vie" : "premiers soins"; - let m = nomPerso(cible) + " n'est pas \xE0 0 PV, impossible d'utiliser " + sort + " pour " + onGenre(cible, 'lui', 'elle'); + let m = nomPerso(cible) + " n'est pas à 0 PV, impossible d'utiliser " + sort + " pour " + onGenre(cible, 'lui', 'elle'); if (display) addLineToFramedDisplay(display, m); else sendChar(charId, m, true); finSoin(); @@ -31103,7 +31234,7 @@ var COFantasy = COFantasy || function() { } } if (tropTard) { - let m = nomPerso(cible) + " est \xE0 0 PV depuis plus de 2 tours, impossible d'utiliser le souffle de vie pour " + onGenre(cible, 'lui', 'elle'); + let m = nomPerso(cible) + " est à 0 PV depuis plus de 2 tours, impossible d'utiliser le souffle de vie pour " + onGenre(cible, 'lui', 'elle'); if (display) addLineToFramedDisplay(display, m); else sendChar(charId, m, true); finSoin(); @@ -31127,7 +31258,7 @@ var COFantasy = COFantasy || function() { if (display) { addLineToFramedDisplay(display, "" + nomCible + " : pas besoin de soins."); } else { - var maxMsg = "n'a pas besoin de "; + let maxMsg = "n'a pas besoin de "; if (options.recuperation) { maxMsg = "se reposer"; charId = soigneur.charId; @@ -31137,7 +31268,7 @@ var COFantasy = COFantasy || function() { } else { maxMsg += "soigner " + nomCible; } - sendChar(charId, maxMsg + ". " + Sujet + " est d\xE9j\xE0 au maximum de PV", true); + sendChar(charId, maxMsg + ". " + Sujet + " est déjà au maximum de PV", true); } }; let extraImg = afficheOptionImage(options); @@ -31157,9 +31288,9 @@ var COFantasy = COFantasy || function() { msgSoin = 'soigne ' + nomCible; } msgSoin += " de "; - if (options.recuperation) msgSoin = "r\xE9cup\xE8re "; + if (options.recuperation) msgSoin = "récupère "; if (limiteSoinsAtteinte || s != soins) - msgSoin += s + " PV. (Le r\xE9sultat du jet \xE9tait " + soinTxt + ")"; + msgSoin += s + " PV. (Le résultat du jet était " + soinTxt + ")"; else msgSoin += soinTxt + " PV."; msgSoin += extraImg; sendChar(charId, msgSoin, true); @@ -31168,7 +31299,7 @@ var COFantasy = COFantasy || function() { let callTrueFinal = printTrue; if (msg.content.includes(' --transfer')) { //paie avec ses PV if (soigneur === undefined) { - error("Il faut pr\xE9ciser qui est le soigneur pour utiliser l'option --transfer", msg.content); + error("Il faut préciser qui est le soigneur pour utiliser l'option --transfer", msg.content); soinImpossible = true; finSoin(); return; @@ -31194,11 +31325,11 @@ var COFantasy = COFantasy || function() { }; } if (options.fx) { - var p1e = { + let p1e = { x: soigneur.token.get('left'), y: soigneur.token.get('top'), }; - var p2e = { + let p2e = { x: cible.token.get('left'), y: cible.token.get('top'), }; @@ -31211,15 +31342,15 @@ var COFantasy = COFantasy || function() { soigneToken(cible, soins, evt, callTrueFinal, callMax, options); finSoin(); }); //fin de iterCibles - }); //fin du sendChat du jet de d\xE9s + }); //fin du sendChat du jet de dés } catch (e) { if (soins) { log(msg.content); - log("L'expression des soins \xE9tait " + soins + ", et il y a eu une erreur durant son \xE9valuation"); + log("L'expression des soins était " + soins + ", et il y a eu une erreur durant son évaluation"); if (argSoin) { - error("L'expression des soins (" + argSoin + ") n'est pas bien form\xE9e", msg.content); + error("L'expression des soins (" + argSoin + ") n'est pas bien formée", msg.content); } else { - error("Erreur pendant l'\xE9valuation de l'expression des soins. Plus d'informations dans le log", msg); + error("Erreur pendant l'évaluation de l'expression des soins. Plus d'informations dans le log", msg); } } else { error("Erreur pendant les soins ", msg.content); @@ -31263,7 +31394,7 @@ var COFantasy = COFantasy || function() { } function ajouterConsommable(perso, nom, nb, action, evt) { - if (perso.token.get('bar1_link') === '') { //Perso non li\xE9, on utilise un attribut + if (perso.token.get('bar1_link') === '') { //Perso non lié, on utilise un attribut let attrName = 'dose_' + nom; let attr = tokenAttribute(perso, attrName); if (attr.length > 0) { @@ -31285,7 +31416,7 @@ var COFantasy = COFantasy || function() { maxVal: action }); } - } else { //On va mettre les consommables dans l'\xE9quipement + } else { //On va mettre les consommables dans l'équipement let attributes = findObjs({ _type: 'attribute', _characterid: perso.charId @@ -31335,7 +31466,7 @@ var COFantasy = COFantasy || function() { }); return true; }); - // si le consommable n'a pas \xE9t\xE9 trouv\xE9, on le cr\xE9e avec une valeur de nb + // si le consommable n'a pas été trouvé, on le crée avec une valeur de nb if (!found) { let pref = 'repeating_equipement_' + generateRowID() + '_'; let attre = createObj("attribute", { @@ -31370,12 +31501,12 @@ var COFantasy = COFantasy || function() { } function parseNatureNourriciere(msg) { - var options = parseOptions(msg); + const options = parseOptions(msg); getSelected(msg, function(selected) { iterSelected(selected, function(lanceur) { - var voieDeLaSurvie = predicateAsInt(lanceur, 'voieDeLaSurvie', 0); + let voieDeLaSurvie = predicateAsInt(lanceur, 'voieDeLaSurvie', 0); if (voieDeLaSurvie < 1) { - sendPerso(lanceur, " ne conna\xEEt pas la Voie de la Survie ?"); + sendPerso(lanceur, " ne connaît pas la Voie de la Survie ?"); } doNatureNourriciere(lanceur, options); }); @@ -31392,34 +31523,34 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - var voieDeLaSurvie = predicateAsInt(perso, 'voieDeLaSurvie', 0); - var trouveBaies = predicateAsBool(perso, 'natureNourriciereBaies'); + let voieDeLaSurvie = predicateAsInt(perso, 'voieDeLaSurvie', 0); + let trouveBaies = predicateAsBool(perso, 'natureNourriciereBaies'); if (options.rolls && options.rolls.duree) { evt.action.rolls.duree = options.rolls.duree; } else { evt.action.rolls.duree = rollDePlus(6); } - var output = "cherche des herbes. "; + let output = "cherche des herbes. "; if (trouveBaies) output = "cherche des baies. "; - output += "Apr\xE8s " + evt.action.rolls.duree.roll + " heure"; + output += "Après " + evt.action.rolls.duree.roll + " heure"; if (evt.action.rolls.duree.val > 1) output += "s"; output += ", " + onGenre(perso, "il", "elle"); - var testId = 'natureNourriciere'; + const testId = 'natureNourriciere'; testCaracteristique(perso, 'SAG', 10, testId, options, evt, function(tr) { - var post = ""; + let post = ""; if ((tr.reussite && !trouveBaies) || (trouveBaies && !tr.reussite && tr.valeur > 7)) { if (voieDeLaSurvie > 0) { - output += " revient avec " + voieDeLaSurvie + " plantes m\xE9dicinales." + tr.modifiers; - var actionHerbes = "!cof-soin @{selected|token_id} @{selected|token_id} 1d6"; - ajouterConsommable(perso, 'Plante m\xE9dicinale', voieDeLaSurvie, actionHerbes, evt); + output += " revient avec " + voieDeLaSurvie + " plantes médicinales." + tr.modifiers; + let actionHerbes = "!cof-soin @{selected|token_id} @{selected|token_id} 1d6"; + ajouterConsommable(perso, 'Plante médicinale', voieDeLaSurvie, actionHerbes, evt); } else { - output += " revient avec de quoi soigner les bless\xE9s." + tr.modifiers; + output += " revient avec de quoi soigner les blessés." + tr.modifiers; } } else if (tr.reussite && trouveBaies) { - var niveau = ficheAttributeAsInt(perso, 'niveau', 1); - var actionBaies = "!cof-consommer-baie " + niveau + " --limiteParJour 1 baieMagique"; - var nbBaies = voieDeLaSurvie + Math.floor((tr.valeur - 10) / 2); + let niveau = ficheAttributeAsInt(perso, 'niveau', 1); + let actionBaies = "!cof-consommer-baie " + niveau + " --limiteParJour 1 baieMagique"; + let nbBaies = voieDeLaSurvie + Math.floor((tr.valeur - 10) / 2); if (nbBaies === 0) nbBaies = 1; output += " revient avec " + nbBaies + " baies magiques." + tr.modifiers; ajouterConsommable(perso, 'Baie magique', nbBaies, actionBaies, evt); @@ -31437,10 +31568,10 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; let evtARefaire = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[1]); if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } @@ -31448,11 +31579,11 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(chevalier) { let token = chevalier.token; if (attributeAsInt(chevalier, 'douleurIgnoree', 0) > 0) { - sendPerso(chevalier, "a d\xE9j\xE0 ignor\xE9 la doubleur une fois pendant ce combat"); + sendPerso(chevalier, "a déjà ignoré la doubleur une fois pendant ce combat"); return; } if (evtARefaire === undefined || evtARefaire.type === undefined || !evtARefaire.type.startsWith('Attaque')) { - sendPerso(chevalier, "s'y prend trop tard pour ignorer la douleur : la derni\xE8re action n'\xE9tait pas une attaque"); + sendPerso(chevalier, "s'y prend trop tard pour ignorer la douleur : la dernière action n'était pas une attaque"); return; } let aIgnore; @@ -31460,18 +31591,18 @@ var COFantasy = COFantasy || function() { type: 'ignorer la douleur' }; let PVid = token.get('bar1_link'); - if (PVid === '') { //token non li\xE9, effets seulement sur le token. + if (PVid === '') { //token non lié, effets seulement sur le token. if (evtARefaire.affecte) { let affecte = evtARefaire.affectes[token.id]; if (affecte && affecte.prev) { let lastBar1 = affecte.prev.bar1_value; let bar1 = parseInt(token.get('bar1_value')); if (isNaN(lastBar1) || isNaN(bar1) || lastBar1 <= bar1) { - //On regarde la barre 2, peut-\xEAtre qu'il s'agit de DM temporaires + //On regarde la barre 2, peut-être qu'il s'agit de DM temporaires let lastBar2 = affecte.prev.bar2_value; let bar2 = parseInt(token.get('bar2_value')); if (isNaN(lastBar2) || isNaN(bar2) || bar2 <= lastBar2) { - sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la derni\xE8re attaque ne lui ait pas enlev\xE9 de PV"); + sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la dernière attaque ne lui ait pas enlevé de PV"); return; } updateCurrentBar(chevalier, 2, lastBar2, evt); @@ -31484,7 +31615,7 @@ var COFantasy = COFantasy || function() { } } } - } else { // token li\xE9, il faut regarder l'attribut + } else { // token lié, il faut regarder l'attribut let attrPV = evtARefaire.attributes.find(function(attr) { return (attr.attribute.id == PVid); }); @@ -31492,13 +31623,13 @@ var COFantasy = COFantasy || function() { let lastPV = attrPV.current; let newPV = attrPV.attribute.get('current'); if (isNaN(lastPV) || isNaN(newPV) || lastPV <= newPV) { - sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la derni\xE8re attaque ne lui ait pas enlev\xE9 de PV"); + sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la dernière attaque ne lui ait pas enlevé de PV"); return; } updateCurrentBar(chevalier, 1, lastPV, evt); setTokenAttr(chevalier, 'douleurIgnoree', lastPV - newPV, evt); aIgnore = true; - } else { //peut-\xEAtre qu'il s'agit de DM temporaires + } else { //peut-être qu'il s'agit de DM temporaires PVid = token.get('bar2_link'); attrPV = evtARefaire.attributes.find(function(attr) { return (attr.attribute.id == PVid); @@ -31507,7 +31638,7 @@ var COFantasy = COFantasy || function() { let lastDmTemp = attrPV.current; let newDmTemp = attrPV.attribute.get('current'); if (isNaN(lastDmTemp) || isNaN(newDmTemp) || newDmTemp <= lastDmTemp) { - sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la derni\xE8re attaque ne lui ait pas augment\xE9 les DM temporaires"); + sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la dernière attaque ne lui ait pas augmenté les DM temporaires"); return; } updateCurrentBar(chevalier, 2, lastDmTemp, evt); @@ -31517,10 +31648,10 @@ var COFantasy = COFantasy || function() { } } if (aIgnore) { - sendPerso(chevalier, " ignore la douleur de la derni\xE8re attaque"); + sendPerso(chevalier, " ignore la douleur de la dernière attaque"); addEvent(evt); } else { - sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la derni\xE8re attaque ne l'ait pas affect\xE9"); + sendPerso(chevalier, "ne peut ignorer la douleur : il semble que la dernière attaque ne l'ait pas affecté"); } }); }); @@ -31531,7 +31662,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("La fonction !cof-fortifiant attend en argument le rang dans la Voie des \xE9lixirs du cr\xE9ateur", cmd); + error("La fonction !cof-fortifiant attend en argument le rang dans la Voie des élixirs du créateur", cmd); return; } const rang = parseInt(cmd[1]); @@ -31552,9 +31683,9 @@ var COFantasy = COFantasy || function() { }); sendPerso(beneficiaire, " boit un fortifiant"); soigneToken(beneficiaire, soins.val, evt, function(soinsEffectifs) { - let msgSoins = "et est soign\xE9 de "; + let msgSoins = "et est soigné de "; if (soinsEffectifs == soins.val) msgSoins += soins.roll + " PV"; - else msgSoins += soinsEffectifs + " PV (le jet \xE9tait " + soins.roll + ")"; + else msgSoins += soinsEffectifs + " PV (le jet était " + soins.roll + ")"; sendPerso(beneficiaire, msgSoins); }); // Finalement on met l'effet fortifie @@ -31564,7 +31695,7 @@ var COFantasy = COFantasy || function() { } //Appliquer une huile instable sur l'arme de la cible - // Par d\xE9faut, c'est l'arme en main de la cible + // Par défaut, c'est l'arme en main de la cible // TODO: le faire pour les projectiles // !cof-huile-instable @{target|token_id} function huileInstable(msg) { @@ -31613,7 +31744,7 @@ var COFantasy = COFantasy || function() { _id: options.lanceur.token.id }]; } else { - error("Pas de token s\xE9lection\xE9e pour !cof-lancer-sort", cmd); + error("Pas de token sélectionée pour !cof-lancer-sort", cmd); return; } } @@ -31625,7 +31756,7 @@ var COFantasy = COFantasy || function() { let lanceur = options.lanceur; if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, dm: false, @@ -31638,7 +31769,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(lanceur, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPerso(lanceur, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -31651,7 +31782,7 @@ var COFantasy = COFantasy || function() { if (!options.lanceur) { if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options const optMana = { mana: options.mana, dm: false, @@ -31664,7 +31795,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(cible, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPerso(cible, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -31714,11 +31845,11 @@ var COFantasy = COFantasy || function() { sendChat(nomPerso, cmd.join(' ')); } - // Renvoie la dur\xE9e mise \xE0 jour ou undefined si l'action n'est pas possible + // Renvoie la durée mise à jour ou undefined si l'action n'est pas possible function lancerMurDeForce(lanceur, playerId, duree, msg, typeMur, evt, options) { if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, dm: false, @@ -31731,7 +31862,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPerso(lanceur, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPerso(lanceur, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -31754,7 +31885,7 @@ var COFantasy = COFantasy || function() { } //!cof-mur-de-force [opt] [duree] - // opt peut \xEAtre mur, noImage ou vent + // opt peut être mur, noImage ou vent // On peut changer la taille du mur avec l'option --portee. function murDeForce(msg) { let options = parseOptions(msg); @@ -31784,13 +31915,13 @@ var COFantasy = COFantasy || function() { if (cmd.length > 2) { duree = parseInt(cmd[2]); if (isNaN(duree) || duree < 1) { - error("Le deuxi\xE8me argument de !cof-mur-de-force doit \xEAtre une dur\xE9e", cmd); + error("Le deuxième argument de !cof-mur-de-force doit être une durée", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Aucun personnage s\xE9lectionn\xE9 pour lancer le mur de " + typeMur, playerId); + sendPlayer(msg, "Aucun personnage sélectionné pour lancer le mur de " + typeMur, playerId); return; } const evt = { @@ -31843,7 +31974,7 @@ var COFantasy = COFantasy || function() { if (options.puissantDuree || options.tempeteDeManaDuree) duree += duree; setAttrDuree(cible, 'murDeForce', duree, evt); } else { - error("Impossible de cr\xE9er l'image " + options.image, imageFields); + error("Impossible de créer l'image " + options.image, imageFields); } } else { sendPlayerAndGM(msg, playerId, "placer l'image du mur sur la carte"); @@ -31890,7 +32021,7 @@ var COFantasy = COFantasy || function() { } else { capitaine = persoOfId(cmd[1], cmd[1]); if (capitaine === undefined) { - error("Le premier argument de !cof-capitaine doit \xEAtre un token", cmd[1]); + error("Le premier argument de !cof-capitaine doit être un token", cmd[1]); return; } setState(capitaine, 'chef', true, evt); @@ -31898,7 +32029,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 2 && !cmd[2].startsWith('--')) { bonus = parseInt(cmd[2]); if (isNaN(bonus) || bonus < 0) { - error("Le bonus de capitaine (second argument) doit \xEAtre un nombre positif", cmd); + error("Le bonus de capitaine (second argument) doit être un nombre positif", cmd); return; } if (bonus === 0) remove = true; @@ -31907,7 +32038,7 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected) { if (selected.length === 0) { - error("Pas de token s\xE9lectionn\xE9 pour !cof-capitaine"); + error("Pas de token sélectionné pour !cof-capitaine"); return; } iterSelected(selected, function(perso) { @@ -31932,12 +32063,12 @@ var COFantasy = COFantasy || function() { function distribuerBaies(msg) { if (msg.selected === undefined || msg.selected.length != 1) { - error("Pour utiliser !cof-distribuer-baies, il faut s\xE9lectionner un token", msg); + error("Pour utiliser !cof-distribuer-baies, il faut sélectionner un token", msg); return; } let druide = persoOfId(msg.selected[0]._id); if (druide === undefined) { - error("Erreur de s\xE9lection dans !cof-distribuer-baies", msg.selected); + error("Erreur de sélection dans !cof-distribuer-baies", msg.selected); return; } let niveau = ficheAttributeAsInt(druide, 'niveau', 1); @@ -31951,13 +32082,13 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(perso) { let nom = nomPerso(perso); ajouterConsommable(perso, 'Baie magique', 1, mangerBaie, evt); - let line = nom + " re\xE7oit une baie"; + let line = nom + " reçoit une baie"; if (perso.token.id == druide.token.id) line = nom + " en garde une pour " + onGenre(druide, "lui", "elle"); addLineToFramedDisplay(display, line); }); addEvent(evt); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }, { lanceur: druide }); //fin du getSelected @@ -31969,17 +32100,17 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd.length < 2) { - error("Il faut un argument \xE0 !cof-consommer-baie", cmd); + error("Il faut un argument à !cof-consommer-baie", cmd); return; } let baie = parseInt(cmd[1]); if (isNaN(baie) || baie < 0) { - error("L'argument de !cof-consommer-baie doit \xEAtre un nombre positif", cmd); + error("L'argument de !cof-consommer-baie doit être un nombre positif", cmd); return; } getSelected(msg, function(selected, playerId) { if (selected === undefined) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof-consommer-baie", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof-consommer-baie", playerId); return; } const evt = { @@ -31987,21 +32118,21 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); iterSelected(selected, function(perso) { - if (limiteRessources(perso, options, 'baieMagique', "a d\xE9j\xE0 mang\xE9 une baie aujourd'hui. Pas d'effet.", evt)) return; + if (limiteRessources(perso, options, 'baieMagique', "a déjà mangé une baie aujourd'hui. Pas d'effet.", evt)) return; let soins = rollDePlus(6, { bonus: baie }); soigneToken(perso, soins.val, evt, function(soinsEffectifs) { let msgSoins = "mange une baie magique. " + - onGenre(perso, "Il est rassasi\xE9", "Elle est rassasi\xE9e") + - " et r\xE9cup\xE8re "; + onGenre(perso, "Il est rassasié", "Elle est rassasiée") + + " et récupère "; if (soinsEffectifs == soins.val) msgSoins += soins.roll + " points de vie"; - else msgSoins += soinsEffectifs + " PV (le jet \xE9tait " + soins.roll + ")"; + else msgSoins += soinsEffectifs + " PV (le jet était " + soins.roll + ")"; sendPerso(perso, msgSoins); }, function() { - sendPerso(perso, "mange une baie magique. " + onGenre(perso, "Il", "Elle") + " se sent rassasi\xE9" + onGenre(perso, '', 'e') + '.'); + sendPerso(perso, "mange une baie magique. " + onGenre(perso, "Il", "Elle") + " se sent rassasié" + onGenre(perso, '', 'e') + '.'); }); }); }); //fin de getSelected @@ -32021,9 +32152,9 @@ var COFantasy = COFantasy || function() { } } - /* Quand on prot\xE8ge un alli\xE9, on stocke l'idName dans un attribut 'protegerUnAllie', et pour ce token, on met un - * attribut 'protegePar_nom' o\xF9 nom est le nom du token protecteur, et qui contient l'idName du protecteur - * Ces attributs disparaissent \xE0 la fin des combats */ + /* Quand on protège un allié, on stocke l'idName dans un attribut 'protegerUnAllie', et pour ce token, on met un + * attribut 'protegePar_nom' où nom est le nom du token protecteur, et qui contient l'idName du protecteur + * Ces attributs disparaissent à la fin des combats */ function protegerUnAllie(msg) { let args = msg.content.split(' '); if (args.length < 3) { @@ -32040,27 +32171,27 @@ var COFantasy = COFantasy || function() { let pageId = tokenProtecteur.get('pageid'); let target = persoOfId(args[2], args[2], pageId); if (target === undefined) { - error("Le deuxi\xE8me argument n'est pas un token valide: " + msg.content, args[2]); + error("Le deuxième argument n'est pas un token valide: " + msg.content, args[2]); return; } let tokenTarget = target.token; if (tokenTarget.id == tokenProtecteur.id) { - sendPerso(protecteur, "ne peut pas se prot\xE9ger i" + onGenre(protecteur, 'lui', 'elle') + "-m\xEAme"); + sendPerso(protecteur, "ne peut pas se protéger i" + onGenre(protecteur, 'lui', 'elle') + "-même"); return; } const nameTarget = nomPerso(target); const evt = { - type: "Prot\xE9ger un alli\xE9" + type: "Protéger un allié" }; let attrsProtecteur = tokenAttribute(protecteur, 'protegerUnAllie'); let protegePar = 'protegePar_' + nameProtecteur; let other; - if (attrsProtecteur.length > 0) { //On prot\xE8ge d\xE9j\xE0 quelqu'un + if (attrsProtecteur.length > 0) { //On protège déjà quelqu'un let previousTarget = persoOfIdName(attrsProtecteur[0].get('current'), pageId); if (previousTarget) { if (previousTarget.token.id == tokenTarget.id) { - sendPerso(protecteur, "prot\xE8ge d\xE9j\xE0 " + nameTarget); + sendPerso(protecteur, "protège déjà " + nameTarget); return; } if (predicateAsBool(protecteur, 'protegerUnAllieAvance')) { @@ -32068,25 +32199,25 @@ var COFantasy = COFantasy || function() { persoOfIdName(attrsProtecteur[0].get('max'), pageId); if (previousTarget2) { if (previousTarget2.token.id == tokenTarget.id) { - sendPerso(protecteur, "prot\xE8ge d\xE9j\xE0 " + nameTarget); + sendPerso(protecteur, "protège déjà " + nameTarget); return; } removeTokenAttr(previousTarget2, protegePar, evt, { - msg: "n'est plus prot\xE9g\xE9 par " + nameProtecteur + msg: "n'est plus protégé par " + nameProtecteur }); } else { other = attrsProtecteur[0].get('current'); } } removeTokenAttr(previousTarget, protegePar, evt, { - msg: "n'est plus prot\xE9g\xE9 par " + nameProtecteur + msg: "n'est plus protégé par " + nameProtecteur }); } } let distTargetProtecteur = distanceCombat(target.token, protecteur.token, pageId); if (distTargetProtecteur > 0) { sendPerso(protecteur, "est trop loin de " + - nameTarget + " pour le prot\xE9ger"); + nameTarget + " pour le protéger"); return; } if (ficheAttributeAsInt(protecteur, 'defbouclieron', 0) === 0) { @@ -32105,24 +32236,24 @@ var COFantasy = COFantasy || function() { setTokenAttr(protecteur, 'protegerUnAllie', other, evt, opt); } setTokenAttr(target, protegePar, idName(protecteur), evt); - sendPerso(protecteur, "prot\xE8ge " + nameTarget); + sendPerso(protecteur, "protège " + nameTarget); addEvent(evt); } function actionDefensive(msg) { let combat = stateCOF.combat; if (!combat) { - sendPlayer(msg, "Il faut entrer en combat pour se d\xE9fendre"); + sendPlayer(msg, "Il faut entrer en combat pour se défendre"); return; } let cmd = msg.content.split(' '); - let def = 2; //pour une d\xE9fense simple - let defMsg = "pr\xE9f\xE8re se d\xE9fendre pendant ce tour"; + let def = 2; //pour une défense simple + let defMsg = "préfère se défendre pendant ce tour"; if (cmd.length > 1) { switch (cmd[1]) { case 'totale': def = 4; - defMsg = "se consacre enti\xE8rement \xE0 sa d\xE9fense pendant ce tour"; + defMsg = "se consacre entièrement à sa défense pendant ce tour"; break; case 'simple': def = 2; @@ -32132,7 +32263,7 @@ var COFantasy = COFantasy || function() { } } const evt = { - type: "action d\xE9fensive" + type: "action défensive" }; getSelected(msg, function(selected) { initiative(selected, evt); @@ -32160,7 +32291,7 @@ var COFantasy = COFantasy || function() { var pageId = necromancien.token.get('pageid'); var target = persoOfId(args[2], args[2], pageId); if (target === undefined) { - error("Le deuxi\xE8me argument n'est pas un token valide: " + msg.content, args[2]); + error("Le deuxième argument n'est pas un token valide: " + msg.content, args[2]); return; } let name2 = nomPerso(target); @@ -32176,7 +32307,7 @@ var COFantasy = COFantasy || function() { if (dureeStrang.length > 0) { nouvelleDuree = parseInt(dureeStrang[0].get('current')); if (isNaN(nouvelleDuree)) { - log("Dur\xE9e de strangulation n'est pas un nombre"); + log("Durée de strangulation n'est pas un nombre"); log(dureeStrang); nouvelleDuree = 1; } else nouvelleDuree++; @@ -32229,7 +32360,7 @@ var COFantasy = COFantasy || function() { } let duree = parseInt(cmd[3]); if (isNaN(duree) || duree <= 0) { - error("La dur\xE9e doit \xEAtre un nombre positif", cmd); + error("La durée doit être un nombre positif", cmd); return; } let image = options.image || stateCOF.options.images.val.image_ombre.val; @@ -32247,13 +32378,13 @@ var COFantasy = COFantasy || function() { let msgRes = "invoquer une ombre mortelle"; if (limiteRessources(lanceur, options, "Ombre_mortelle", msgRes, evt)) return; copieToken(cible, image, stateCOF.options.images.val.image_ombre.val, "Ombre de " + nomPerso(cible), 'ombreMortelle', duree, pageId, evt); - let msgOmbre = "anime l'ombre de " + cible.tokName + ". Celle-ci commence \xE0 attaquer " + cible.tokName + " !"; + let msgOmbre = "anime l'ombre de " + cible.tokName + ". Celle-ci commence à attaquer " + cible.tokName + " !"; if (options.secret) whisperChar(lanceur.charId, msgOmbre); else sendPerso(lanceur, msgOmbre); addEvent(evt); } - //renvoie l'attribut de l'effet temporaire cr\xE9\xE9 + //renvoie l'attribut de l'effet temporaire créé function copieToken(cible, image1, image2, nom, effet, duree, pageId, evt) { let pv = parseInt(cible.token.get('bar1_value')); if (isNaN(pv)) { @@ -32300,7 +32431,7 @@ var COFantasy = COFantasy || function() { newToken = createObj('graphic', tokenFields); } if (newToken === undefined) { - error("L'image du token s\xE9lectionn\xE9 n'a pas \xE9t\xE9 upload\xE9, et l'image par d\xE9faut n'est pas correcte. Impossible de cr\xE9er un token.", tokenFields); + error("L'image du token sélectionné n'a pas été uploadé, et l'image par défaut n'est pas correcte. Impossible de créer un token.", tokenFields); return; } } @@ -32316,7 +32447,7 @@ var COFantasy = COFantasy || function() { return attr; } - //retourne true si le joueur est effectivement d\xE9plac\xE9 + //retourne true si le joueur est effectivement déplacé function movePlayerToPage(pid, oldPageId, newPageId) { if (getObj('player', pid) === undefined) return; var c = Campaign(); @@ -32374,8 +32505,8 @@ var COFantasy = COFantasy || function() { function escalier(msg) { getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de s\xE9lection de token pour !cof-escalier", playerId); - log("!cof-escalier requiert de s\xE9lectionner des tokens"); + sendPlayer(msg, "Pas de sélection de token pour !cof-escalier", playerId); + log("!cof-escalier requiert de sélectionner des tokens"); return; } let pageId = getObj('graphic', selected[0]._id).get('pageid'); @@ -32459,7 +32590,7 @@ var COFantasy = COFantasy || function() { let left = sortieEscalier.get('left'); let top = sortieEscalier.get('top'); let newPageId = sortieEscalier.get('pageid'); - //D\xE9placement du token + //Déplacement du token if (newPageId == pageId) { token.set('left', left); token.set('top', top); @@ -32467,7 +32598,7 @@ var COFantasy = COFantasy || function() { //On change de carte, il faut donc copier le token var tokenObj = JSON.parse(JSON.stringify(token)); tokenObj._pageid = newPageId; - //On met la taille du token \xE0 jour en fonction des \xE9chelles des cartes. + //On met la taille du token à jour en fonction des échelles des cartes. var ratio = computeScale(pageId) / computeScale(newPageId); if (ratio < 0.9 || ratio > 1.1) { if (ratio < 0.25) ratio = 0.25; @@ -32484,12 +32615,12 @@ var COFantasy = COFantasy || function() { return; } } - //On d\xE9place ensuite le joueur. + //On déplace ensuite le joueur. let character = getObj('character', perso.charId); if (character === undefined) return; let charControlledby = character.get('controlledby'); if (charControlledby === '') { - //Seul le MJ contr\xF4le le personnage + //Seul le MJ contrôle le personnage let players = findObjs({ _type: 'player', online: true @@ -32507,7 +32638,7 @@ var COFantasy = COFantasy || function() { sendPing(left, top, newPageId, pid, true, pid); }); } - //Enfin, on efface le token de d\xE9part si on a chang\xE9 de page + //Enfin, on efface le token de départ si on a changé de page if (newPageId != pageId) token.remove(); return; } @@ -32539,10 +32670,10 @@ var COFantasy = COFantasy || function() { return; } var evt = { - type: "D\xE9faut dans la cuirasse" + type: "Défaut dans la cuirasse" }; setTokenAttr(cible, 'defautDansLaCuirasse_' + nomPerso(tireur), 2, evt); - sendPerso(tireur, "passe le tour \xE0 analyser les points faibles de " + nomPerso(cible)); + sendPerso(tireur, "passe le tour à analyser les points faibles de " + nomPerso(cible)); addEvent(evt); } @@ -32555,12 +32686,12 @@ var COFantasy = COFantasy || function() { var bonus = parseInt(args[1]); var attrDebuf = args[2]; if (attrDebuf != 'DEF' && attrDebuf != 'ATT' && attrDebuf != 'DM') { - error("L'attribut \xE0 d\xE9buffer pour la posture de combat est incorrect", args); + error("L'attribut à débuffer pour la posture de combat est incorrect", args); return; } var attrBuf = args[3]; if (attrBuf != 'DEF' && attrBuf != 'ATT' && attrBuf != 'DM') { - error("L'attribut \xE0 augmenter pour la posture de combat est incorrect", args); + error("L'attribut à augmenter pour la posture de combat est incorrect", args); return; } getSelected(msg, function(selected, playerId) { @@ -32571,7 +32702,7 @@ var COFantasy = COFantasy || function() { } var rang = predicateAsInt(guerrier, "voieDuSoldat", 0); if (rang > 0 && rang < bonus) { - sendPerso(guerrier, "ne peut choisir qu'un bonus inf\xE9rieur \xE0 " + rang + " pour sa posture de combat"); + sendPerso(guerrier, "ne peut choisir qu'un bonus inférieur à " + rang + " pour sa posture de combat"); return; } var evt = { @@ -32586,7 +32717,7 @@ var COFantasy = COFantasy || function() { msg = "prend une posture "; switch (attrBuf) { case 'DEF': - msg += "d\xE9fensive"; + msg += "défensive"; break; case 'ATT': msg += "offensive"; @@ -32599,10 +32730,10 @@ var COFantasy = COFantasy || function() { msg += " mais "; switch (attrDebuf) { case 'DEF': - msg += "risqu\xE9e"; + msg += "risquée"; break; case 'ATT': - msg += "moins pr\xE9cise"; + msg += "moins précise"; break; case 'DM': msg += "moins puissante"; @@ -32626,21 +32757,21 @@ var COFantasy = COFantasy || function() { } let bonus = parseInt(args[1]); if (bonus != 0 && bonus != 2 && bonus != 5) { - error("Le malus de DEF ne peut \xEAtre que 0, 2 ou 5", args); + error("Le malus de DEF ne peut être que 0, 2 ou 5", args); return; } getSelected(msg, function(selected) { iterSelected(selected, function(guerrier) { const evt = { - type: "Attaque \xE0 outrance" + type: "Attaque à outrance" }; if (bonus === 0) { - sendPerso(guerrier, "n'attaque plus \xE0 outrance"); + sendPerso(guerrier, "n'attaque plus à outrance"); removeTokenAttr(guerrier, 'attaqueAOutrance', evt); addEvent(evt); return; } - msg = "attaque \xE0 outrance "; + msg = "attaque à outrance "; switch (bonus) { case 2: msg += "(-2 DEF, +1D6 DM)"; @@ -32662,14 +32793,14 @@ var COFantasy = COFantasy || function() { var options = parseOptions(msg); var cmd = options.cmd; if (cmd < 2) { - error("Il manque un argument \xE0 !cof-tour-de-force", cmd); + error("Il manque un argument à !cof-tour-de-force", cmd); return; } var seuil = parseInt(cmd[1]); getSelected(msg, function(selected, playerId) { iterSelected(selected, function(barbare) { if (isNaN(seuil)) { - sendPlayer(msg, "le seuil de difficult\xE9 du tour de force doit \xEAtre un nombre", playerId); + sendPlayer(msg, "le seuil de difficulté du tour de force doit être un nombre", playerId); return; } doTourDeForce(barbare, seuil, options); @@ -32687,18 +32818,18 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - let action = "Capacit\xE9 : Tour de force"; + let action = "Capacité : Tour de force"; let display = startFramedDisplay(options.playerId, action, perso); let testId = 'tourDeForce'; options.bonus = 10; testCaracteristique(perso, 'FOR', seuil, testId, options, evt, function(tr) { - addLineToFramedDisplay(display, " Jet de force difficult\xE9 " + seuil); + addLineToFramedDisplay(display, " Jet de force difficulté " + seuil); let smsg = nomPerso(perso) + " fait " + tr.texte; if (tr.reussite) { - smsg += " => r\xE9ussite"; + smsg += " => réussite"; } else { - smsg += " => \xE9chec" + tr.rerolls; + smsg += " => échec" + tr.rerolls; } addLineToFramedDisplay(display, smsg); let d4 = options.rolls.tourDeForceDmg || rollDePlus(4); @@ -32712,12 +32843,12 @@ var COFantasy = COFantasy || function() { perso.ignoreTouteRD = true; dealDamage(perso, r, [], evt, false, {}, explications, function(dmgDisplay, dmg) { - let dmgMsg = "mais cela lui co\xFBte " + dmgDisplay + " PV"; + let dmgMsg = "mais cela lui coûte " + dmgDisplay + " PV"; addLineToFramedDisplay(display, dmgMsg); explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); } @@ -32736,41 +32867,41 @@ var COFantasy = COFantasy || function() { } } - //!cof-encaisser-un-coup, avec la personne qui encaisse s\xE9lectionn\xE9e + //!cof-encaisser-un-coup, avec la personne qui encaisse sélectionnée function doEncaisserUnCoup(msg) { var optionsEncaisser = parseOptions(msg); if (optionsEncaisser === undefined) return; var cmd = optionsEncaisser.cmd; var evt = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Personne n'est s\xE9lectionn\xE9 pour encaisser un coup", msg); + error("Personne n'est sélectionné pour encaisser un coup", msg); return; } if (evt === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour encaisser un coup"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour encaisser un coup"); return; } if (evt.type != 'Attaque' || evt.succes === false) { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour encaisser le coup d'une action pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour encaisser le coup d'une action précédente"); return; } var action = evt.action; if (action.options.distance) { - sendChat('', "Impossible d'encaisser le dernier coup, ce n'\xE9tait pas une attaque au contact"); + sendChat('', "Impossible d'encaisser le dernier coup, ce n'était pas une attaque au contact"); return; } var toProceed; iterSelected(selected, function(chevalier) { if (!attributeAsBool(chevalier, 'encaisserUnCoup')) { - sendPerso(chevalier, "n'est pas plac\xE9 pour encaisser un coup"); + sendPerso(chevalier, "n'est pas placé pour encaisser un coup"); return; } if (!peutController(msg, chevalier)) { @@ -32781,7 +32912,7 @@ var COFantasy = COFantasy || function() { return (target.token.id === chevalier.token.id); }); if (cible === undefined) { - sendPerso(chevalier, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(chevalier, "n'est pas la cible de la dernière attaque"); return; } action.choices = action.choices || {}; @@ -32804,40 +32935,40 @@ var COFantasy = COFantasy || function() { removePreDmg(options, cible, "encaisserUnCoup"); } - //!cof-devier-les-coups, avec la personne qui encaisse s\xE9lectionn\xE9e + //!cof-devier-les-coups, avec la personne qui encaisse sélectionnée function doDevierLesCoups(msg) { let optionsDevier = parseOptions(msg); if (optionsDevier === undefined) return; let cmd = optionsDevier.cmd; let evt = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Personne n'est s\xE9lectionn\xE9 pour d\xE9vier les coups", msg); + error("Personne n'est sélectionné pour dévier les coups", msg); return; } if (evt === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour d\xE9vier les coups"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour dévier les coups"); return; } if (evt.type != 'Attaque' || evt.succes === false) { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour d\xE9vier les coups d'une action pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour dévier les coups d'une action précédente"); return; } var action = evt.action; if (action.options.distance) { - sendChat('', "Impossible d'encaisser le dernier coup, ce n'\xE9tait pas une attaque au contact"); + sendChat('', "Impossible d'encaisser le dernier coup, ce n'était pas une attaque au contact"); return; } let toProceed; iterSelected(selected, function(perso) { - let testDevierCoups = testLimiteUtilisationsCapa(perso, 'devierLesCoups', 'tour', "ne peut plus d\xE9vier les coups \xE0 ce tour-ci"); + let testDevierCoups = testLimiteUtilisationsCapa(perso, 'devierLesCoups', 'tour', "ne peut plus dévier les coups à ce tour-ci"); if (testDevierCoups === undefined) return; if (!peutController(msg, perso)) { sendPlayer(msg, "pas le droit d'utiliser ce bouton", playerId); @@ -32847,7 +32978,7 @@ var COFantasy = COFantasy || function() { return (target.token.id === perso.token.id); }); if (cible === undefined) { - sendPerso(perso, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(perso, "n'est pas la cible de la dernière attaque"); return; } action.choices = action.choices || {}; @@ -32866,9 +32997,7 @@ var COFantasy = COFantasy || function() { function appliquerDevierLesCoups(cible, test, options, evt) { utiliseCapacite(cible, test, evt); - cible.extraRDBouclier = - ficheAttributeAsInt(cible, 'defbouclier', 0) * - ficheAttributeAsInt(cible, 'defbouclieron', 0); + cible.extraRDBouclier = defenseBouclier(cible); removePreDmg(options, cible, 'devierLesCoups'); } @@ -32878,33 +33007,33 @@ var COFantasy = COFantasy || function() { if (optionsParade === undefined) return; var cmd = optionsParade.cmd; var evt = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Personne n'est s\xE9lectionn\xE9 pour parer le projectile", msg); + error("Personne n'est sélectionné pour parer le projectile", msg); return; } if (evt === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour parer le projectile"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour parer le projectile"); return; } if (evt.type != 'Attaque' || evt.succes === false) { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour parer le projectile d'une action pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour parer le projectile d'une action précédente"); return; } var action = evt.action; if (!action.options.distance) { - sendChat('', "Impossible de parer le projectile, ce n'\xE9tait pas une attaque \xE0 distance"); + sendChat('', "Impossible de parer le projectile, ce n'était pas une attaque à distance"); return; } if (action.options.poudre) { - sendChat('', "Impossible de parer le projectile, il s'agit d'une arme \xE0 poudre"); + sendChat('', "Impossible de parer le projectile, il s'agit d'une arme à poudre"); return; } if (action.cibles.length > 1) { @@ -32925,7 +33054,7 @@ var COFantasy = COFantasy || function() { return (target.token.id === moine.token.id); }); if (cible === undefined) { - sendPerso(moine, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(moine, "n'est pas la cible de la dernière attaque"); return; } action.choices = action.choices || {}; @@ -32950,8 +33079,8 @@ var COFantasy = COFantasy || function() { // asynchrone : on fait les jets du personnage en opposition // options : - // predicat : on utilise un pr\xE9dicat et non un attribut. Peut \xEAtre 'tour' ou 'combat' - // protecteur: c'est un protecteur qui prot\xE8ge la cible (pas compatible avec predicate + // predicat : on utilise un prédicat et non un attribut. Peut être 'tour' ou 'combat' + // protecteur: c'est un protecteur qui protège la cible (pas compatible avec predicate function evitementGenerique(msg, verbe, attributeName, actionName, tente, msgDejaFait, carac, typeAttaque, msgReussite, opt) { let options = parseOptions(msg); if (options === undefined) return; @@ -32966,10 +33095,10 @@ var COFantasy = COFantasy || function() { } let evt; let chance; - if (cmd.length > 2) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 2) { //On relance pour un événement particulier evt = findEvent(cmd[2]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } chance = cmd.length > 3 && cmd[3] == 'chance'; @@ -32977,11 +33106,11 @@ var COFantasy = COFantasy || function() { evt = lastEvent(); } if (evt === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour esquiver"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour esquiver"); return; } if (evt.type != 'Attaque') { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour " + verbe + " l'attaque pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour " + verbe + " l'attaque précédente"); return; } const perso = persoOfId(cmd[1]); @@ -32996,12 +33125,12 @@ var COFantasy = COFantasy || function() { return (target.token.id === perso.token.id); }); if (cible === undefined) { - sendPerso(perso, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(perso, "n'est pas la cible de la dernière attaque"); return; } let attributAVerifier = attributeName; let persoAttribut = perso; - if (opt.protecteur) { // c'est un personnage tiers qui prot\xE8ge la cible + if (opt.protecteur) { // c'est un personnage tiers qui protège la cible let protecteurAttrs = tokenAttribute(perso, attributeName + 'Valeur'); if (protecteurAttrs.length < 1) { error("Erreur interne dans le bouton de protection, protecteur introuvable", cmd); @@ -33048,7 +33177,7 @@ var COFantasy = COFantasy || function() { } else { let curAttribut = parseInt(attribut.get('current')); if (isNaN(curAttribut)) { - error("Resource pour " + actionName + " mal form\xE9e", attribut); + error("Resource pour " + actionName + " mal formée", attribut); return; } if (curAttribut < 1) { @@ -33111,8 +33240,8 @@ var COFantasy = COFantasy || function() { } } else if (testPredicat) { utiliseCapacite(testPredicat.perso, testPredicat, evt); - } else if (attributeName !== undefined) { //ni attribut ni pr\xE9dicat - error("On n'a ni attribut ni pr\xE9dicat pour un \xE9vitement g\xE9n\xE9rique", evitementGen); + } else if (attributeName !== undefined) { //ni attribut ni prédicat + error("On n'a ni attribut ni prédicat pour un évitement générique", evitementGen); return; } let optDice; @@ -33194,17 +33323,17 @@ var COFantasy = COFantasy || function() { onGenre(lanceur, "Il", "elle") + " fait " + msg; var generalMsg = ''; if (totalEvitement < jetAdversaire) { - msg += " => Rat\xE9"; + msg += " => Raté"; var pc = pointsDeChance(lanceur); if (attackRoll.results.total != 1 && pc > 0) { generalMsg += '
    ' + boutonSimple("!cof-bouton-chance " + evt.id + " " + testId, "Chance") + " (reste " + pc + " PC)"; } - if (stateCOF.combat && attributeAsBool(lanceur, 'runeForgesort_\xE9nergie') && - attributeAsInt(lanceur, 'limiteParCombat_runeForgesort_\xE9nergie', 1) > 0 && + if (stateCOF.combat && attributeAsBool(lanceur, 'runeForgesort_énergie') && + attributeAsInt(lanceur, 'limiteParCombat_runeForgesort_énergie', 1) > 0 && (carac == 'force' || carac == 'constitution' || carac == 'dexterite')) { - generalMsg += '
    ' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'\xE9nergie"); + generalMsg += '
    ' + boutonSimple("!cof-bouton-rune-energie " + evt.id + " " + testId, "Rune d'énergie"); } if (stateCOF.combat && capaciteDisponible(lanceur, 'petitVeinard', 'combat')) { generalMsg += '
    ' + boutonSimple("!cof-bouton-petit-veinard " + evt.id + " " + testId, "Petit veinard"); @@ -33214,23 +33343,23 @@ var COFantasy = COFantasy || function() { } else { //Sinon cacher le bouton mais laisser l'option reroll removePreDmg(options, cible, attributeName, 'reroll'); } - } else { //\xC9vitement r\xE9ussi + } else { //Évitement réussi if (opt && cible.critique && (opt.critiqueDevientNormal || (opt.critiqueAnnuleCritique && d20roll != 20))) { cible.critique = false; - msg += " => R\xE9ussi, l'attaque fait des d\xE9g\xE2ts normaux"; + msg += " => Réussi, l'attaque fait des dégâts normaux"; removePreDmg(options, cible, attributeName); } else { cible.touche = false; if (opt.annule) { delete options.preDmg; options.preDmgAnnule = true; - generalMsg += " => R\xE9ussi, " + msgReussite; + generalMsg += " => Réussi, " + msgReussite; } else { action.ciblesTouchees = action.ciblesTouchees.filter(function(c) { return c.token.id != cible.token.id; }); removePreDmg(options, cible); - msg += " => R\xE9ussi, " + msgReussite; + msg += " => Réussi, " + msgReussite; } } } @@ -33249,7 +33378,7 @@ var COFantasy = COFantasy || function() { }; evitementGenerique(msg, "absorber un coup au bouclier", 'absorberUnCoup', "d'absorption de coup au bouclier", "d'absorber un coup au bouclier", - " a d\xE9j\xE0 essay\xE9 d'absorber un coup au bouclier ce tour", 'force', 'contact', "le coup est absorb\xE9 !", { + " a déjà essayé d'absorber un coup au bouclier ce tour", 'force', 'contact', "le coup est absorbé !", { attrAsBool: true, condition, }); @@ -33266,7 +33395,7 @@ var COFantasy = COFantasy || function() { }; evitementGenerique(msg, "absorber un sort au bouclier", 'absorberUnSort', "d'absorption de sort au bouclier", "d'absorber un sort au bouclier", - " a d\xE9j\xE0 essay\xE9 d'absorber un sort au bouclier ce tour", 'sagesse', 'magique', "le sort est absorb\xE9 !", { + " a déjà essayé d'absorber un sort au bouclier ce tour", 'sagesse', 'magique', "le sort est absorbé !", { attrAsBool: true, condition: condition }); @@ -33275,10 +33404,10 @@ var COFantasy = COFantasy || function() { // asynchrone : on fait les jets du barbare en opposition //!cof-resister-a-la-magie id [evtid] [chance] function resisterALaMagie(msg) { - evitementGenerique(msg, 'r\xE9sister \xE0 la magie', 'resistanceALaMagieBarbare', - 'r\xE9sistance \xE0 la magie', "de r\xE9sister \xE0 la magie", - " a d\xE9j\xE0 essay\xE9 de r\xE9sister \xE0 la magie ce tour", - 'sagesse', 'magique', "il r\xE9siste \xE0 la magie !", { + evitementGenerique(msg, 'résister à la magie', 'resistanceALaMagieBarbare', + 'résistance à la magie', "de résister à la magie", + " a déjà essayé de résister à la magie ce tour", + 'sagesse', 'magique', "il résiste à la magie !", { predicat: 'tour' }); } @@ -33288,8 +33417,8 @@ var COFantasy = COFantasy || function() { function cercleDeProtection(msg) { evitementGenerique(msg, 'activer le cercle de protection', 'cercleDeProtection', 'activation du cercle de protection', "de bloquer le sort avec le Cercle de Protection", - " a d\xE9j\xE0 active le Cercle de Protection ce tour", - 'intelligence', 'magique', "le sort est annul\xE9 !", { + " a déjà active le Cercle de Protection ce tour", + 'intelligence', 'magique', "le sort est annulé !", { protecteur: true, annule: true }); @@ -33299,7 +33428,7 @@ var COFantasy = COFantasy || function() { //!cof-esquive-acrobatique id [evtid] [chance] function doEsquiveAcrobatique(msg) { evitementGenerique(msg, 'esquiver', 'esquiveAcrobatique', - 'esquive acrobatique', "une esquive acrobatique", " a d\xE9j\xE0 fait une esquive acrobatique ce tour", 'dexterite', 'distance', "l'attaque est esquiv\xE9e !", { + 'esquive acrobatique', "une esquive acrobatique", " a déjà fait une esquive acrobatique ce tour", 'dexterite', 'distance', "l'attaque est esquivée !", { critiqueDevientNormal: true, predicat: 'tour' }); @@ -33307,12 +33436,12 @@ var COFantasy = COFantasy || function() { function doEsquiveDeLaMagie(msg) { evitementGenerique(msg, 'esquiver', undefined, - "esquive de la magie", "d'esquiver la magie", " a d\xE9j\xE0 fait esquiv\xE9 la magie", 'dexterite', 'esquive', "l'attaque est esquiv\xE9e !", {}); + "esquive de la magie", "d'esquiver la magie", " a déjà fait esquivé la magie", 'dexterite', 'esquive', "l'attaque est esquivée !", {}); } function doEsquiveMagistrale(msg) { evitementGenerique(msg, 'esquiver', 'paradeMagistrale', - 'esquive acrobatique', "une esquive acrobatique", " a d\xE9j\xE0 fait une parade magistrale ce tour", 'dexterite', 'distance', "l'attaque est esquiv\xE9e !", { + 'esquive acrobatique', "une esquive acrobatique", " a déjà fait une parade magistrale ce tour", 'dexterite', 'distance', "l'attaque est esquivée !", { bonusAttaque: -5, critiqueDevientNormal: true, predicat: 'tour' @@ -33321,7 +33450,7 @@ var COFantasy = COFantasy || function() { function doParadeMagistrale(msg) { evitementGenerique(msg, 'parer', 'paradeMagistrale', - 'parade magistrale', "une parade magistrale", " a d\xE9j\xE0 fait une parade magistrale ce tour", 'dexterite', 'distance', "l'attaque est par\xE9e !", { + 'parade magistrale', "une parade magistrale", " a déjà fait une parade magistrale ce tour", 'dexterite', 'distance', "l'attaque est parée !", { arme: true, critiqueDevientNormal: true, predicat: 'tour' @@ -33331,7 +33460,7 @@ var COFantasy = COFantasy || function() { //!cof-parade-au-bouclier function doParadeAuBouclier(msg) { evitementGenerique(msg, 'parer', 'paradeAuBouclier', - 'parade au bouclier', "une parade au bouclier", " a d\xE9j\xE0 fait une parade au bouclier ce tour", 'force', 'contact', "l'attaque est par\xE9e !", { + 'parade au bouclier', "une parade au bouclier", " a déjà fait une parade au bouclier ce tour", 'force', 'contact', "l'attaque est parée !", { armeGauche: true, critiqueAnnuleCritique: true, predicat: 'tour' @@ -33339,7 +33468,7 @@ var COFantasy = COFantasy || function() { } //!cof-chair-a-canon id1 id2 [evt_id] - // id1 est l'id du pnj r\xE9current + // id1 est l'id du pnj récurrent // id2 est l'id du token qui se met devant l'attaque function doChairACanon(msg) { let options = parseOptions(msg); @@ -33350,13 +33479,13 @@ var COFantasy = COFantasy || function() { return; } let evtARefaire; - if (cmd.length > 3) { //On relance pour un \xE9v\xE9nement particulier + if (cmd.length > 3) { //On relance pour un événement particulier evtARefaire = findEvent(cmd[3]); } else { evtARefaire = lastEvent(); } if (evtARefaire === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } let pnjRec = persoOfId(cmd[1]); @@ -33368,7 +33497,7 @@ var COFantasy = COFantasy || function() { sendPlayer(msg, "pas le droit d'utiliser ce bouton"); return; } - let testChairACanon = testLimiteUtilisationsCapa(pnjRec, 'chairACanon', 'tour', "a d\xE9j\xE0 utilis\xE9 un sous-fifre ce tour", "ne sait pas utiliser ses sous-fifres pour se d\xE9fendre"); + let testChairACanon = testLimiteUtilisationsCapa(pnjRec, 'chairACanon', 'tour', "a déjà utilisé un sous-fifre ce tour", "ne sait pas utiliser ses sous-fifres pour se défendre"); if (testChairACanon === undefined) { return; } @@ -33378,11 +33507,11 @@ var COFantasy = COFantasy || function() { return; } if (evtARefaire === undefined) { - sendChat('', "Historique d'actions vide, pas d'action trouv\xE9e pour la chair \xE0 canon"); + sendChat('', "Historique d'actions vide, pas d'action trouvée pour la chair à canon"); return; } if (evtARefaire.type != 'Attaque') { - sendChat('', "la derni\xE8re action n'est pas une attaque"); + sendChat('', "la dernière action n'est pas une attaque"); return; } let attaque = evtARefaire.action; @@ -33407,7 +33536,7 @@ var COFantasy = COFantasy || function() { let optionsRedo = attaque.options; optionsRedo.rolls = attaque.rolls; let evt = { - type: "chair \xE0 canon" + type: "chair à canon" }; utiliseCapacite(pnjRec, testChairACanon, evt); undoEvent(evtARefaire); @@ -33416,7 +33545,7 @@ var COFantasy = COFantasy || function() { redoEvent(evtARefaire, attaque); } - // modifie res et le retourne (au cas o\xF9 il ne serait pas donn\xE9) + // modifie res et le retourne (au cas où il ne serait pas donné) function listRollResults(roll, res) { res = res || []; switch (roll.type) { @@ -33431,7 +33560,7 @@ var COFantasy = COFantasy || function() { roll.results.forEach(function(r) { if (r.v) res.push(r.v); else if (r.d) res.push(r.d); - else log("Type de r\xE9sultat de d\xE9 inconnu " + r); + else log("Type de résultat de dé inconnu " + r); }); return res; case 'M': @@ -33452,9 +33581,9 @@ var COFantasy = COFantasy || function() { return res; } - //category est un tableau de string, le premier \xE9l\xE9ment \xE9tant la cat\xE9gorie - //principale, le suivant la sous-cat\xE9gorie, etc - //value peut \xEAtre un nombre, un tableau de nombres, ou un inline roll + //category est un tableau de string, le premier élément étant la catégorie + //principale, le suivant la sous-catégorie, etc + //value peut être un nombre, un tableau de nombres, ou un inline roll function addStatistics(playerId, category, value) { if (stateCOF.statistiques === undefined) return; var stat = stateCOF.statistiques; @@ -33495,7 +33624,7 @@ var COFantasy = COFantasy || function() { nombre: 0, total: 0, }; - if (stats.nombre) { //on peut afficher des r\xE9sultats + if (stats.nombre) { //on peut afficher des résultats res.nombre = stats.nombre; res.total = stats.total; } @@ -33507,7 +33636,7 @@ var COFantasy = COFantasy || function() { res.nombre += catRes.nombre; res.total += catRes.total; } - var msg = "aucun jet cellect\xE9"; + var msg = "aucun jet cellecté"; if (res.nombre > 0) { var moyenne = res.total / res.nombre; msg = res.nombre + " jet" + ((res.nombre > 1) ? "s" : "") + ", moyenne " + moyenne; @@ -33529,8 +33658,8 @@ var COFantasy = COFantasy || function() { if (stats) addLineToFramedDisplay(display, "Statistiques en pause"); else { - addLineToFramedDisplay(display, "Aucune statistique collect\xE9e"); - sendChat("COF", endFramedDisplay(display)); + addLineToFramedDisplay(display, "Aucune statistique collectée"); + sendFramedDisplay(display); return; } } @@ -33563,7 +33692,7 @@ var COFantasy = COFantasy || function() { tot.nombre += catRes.nombre; } addLineToFramedDisplay(display, tot.nombre + " jets au total, dont la somme fait " + tot.total); - sendChat("COF", endFramedDisplay(display)); + sendFramedDisplay(display); } function parseDestructionDesMortsVivants(msg) { @@ -33571,7 +33700,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let args = options.cmd; if (args === undefined || args.length < 2) { - error("Il faut au moins un argument \xE0 !cof-destruction-des-morts-vivants", args); + error("Il faut au moins un argument à !cof-destruction-des-morts-vivants", args); return; } args.shift(); @@ -33584,11 +33713,11 @@ var COFantasy = COFantasy || function() { dm = dm.replace(/\]/g, ']'); getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Il faut s\xE9lectionner le lanceur de la destruction des morts-vivants", playerId); + sendPlayer(msg, "Il faut sélectionner le lanceur de la destruction des morts-vivants", playerId); return; } if (selected.length > 1) { - sendPlayer(msg, "Ne s\xE9lectionner qu'un token \xE0 la fois pour lancer la destruction des mort-vivants.", playerId); + sendPlayer(msg, "Ne sélectionner qu'un token à la fois pour lancer la destruction des mort-vivants.", playerId); return; } let playerName = msg.who; @@ -33596,7 +33725,7 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(lanceur) { if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options var optMana = { mana: options.mana, dm: true, @@ -33608,7 +33737,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.rang && options.tempeteDeMana.cout > options.rang) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -33618,7 +33747,7 @@ var COFantasy = COFantasy || function() { let nbDes = parseInt(findNbDes[1]); dm = dm.replace(findNbDes[0], (nbDes + options.tempeteDeManaIntense) + 'd'); } else { - log("Pas r\xE9ussi \xE0 trouver le nombre de d\xE9s dans " + dm); + log("Pas réussi à trouver le nombre de dés dans " + dm); } } else if (options.puissant) { let findValDes = dm.match(/^([0-9]+d)([0-9]+)/); @@ -33626,7 +33755,7 @@ var COFantasy = COFantasy || function() { let valDes = parseInt(findValDes[2]) + 2; dm = dm.replace(findValDes[0], findValDes[1] + valDes); } else { - log("Pas r\xE9ussi \xE0 trouver le nombre de faces des d\xE9s dans " + dm); + log("Pas réussi à trouver le nombre de faces des dés dans " + dm); } } doDestructionDesMortsVivants(lanceur, playerName, dm, options); @@ -33698,7 +33827,7 @@ var COFantasy = COFantasy || function() { if (!estMortVivant(cible)) return; if (getState(cible, 'mort')) return; if (predicateAsBool(cible, 'immunite_destruction')) { - addLineToFramedDisplay(display, nomPerso(cible) + " ne semble pas affect\xE9 par la destruction des morts-vivants"); + addLineToFramedDisplay(display, nomPerso(cible) + " ne semble pas affecté par la destruction des morts-vivants"); return; } cibles.push(cible); @@ -33706,7 +33835,7 @@ var COFantasy = COFantasy || function() { let nbCibles = cibles.length; if (nbCibles === 0) { addLineToFramedDisplay(display, "Aucun mort-vivant en vue"); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); return; } let expl = []; @@ -33725,7 +33854,7 @@ var COFantasy = COFantasy || function() { let finalDisplay = function() { nbCibles--; if (nbCibles < 1) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }; cibles.forEach(function(perso) { @@ -33745,23 +33874,23 @@ var COFantasy = COFantasy || function() { dmg.display = buildinline(dmg.roll.inlinerolls[dmgRollNumber], dmg.type, optionsDM.magique); dealDamage(perso, dmg, [], evt, false, optionsDM, explications, function(dmgDisplay, dmgFinal) { addLineToFramedDisplay(display, - name + " re\xE7oit " + dmgDisplay + " DM"); + name + " reçoit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); finalDisplay(); }); - }); //fin du jet de d\xE9s + }); //fin du jet de dés } catch (rollError) { - error("Jet " + dm + " mal form\xE9", dm); + error("Jet " + dm + " mal formé", dm); } }); //fin forEach } else { addLineToFramedDisplay(display, msgJet + " < " + difficulte); - let msgRate = nomPerso(lanceur) + " ne r\xE9ussit pas \xE0 invoquer son dieu." + testRes.rerolls + testRes.modifiers; + let msgRate = nomPerso(lanceur) + " ne réussit pas à invoquer son dieu." + testRes.rerolls + testRes.modifiers; addLineToFramedDisplay(display, msgRate); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }); } @@ -33780,7 +33909,7 @@ var COFantasy = COFantasy || function() { let label = cmd[1]; let typePoison = cmd[2]; if (typePoison != 'rapide' && typePoison != 'affaiblissant') { - error("Les seuls type de poison g\xE9r\xE9s sont rapide et affaiblissant, mais pas encore " + typePoison, cmd); + error("Les seuls type de poison gérés sont rapide et affaiblissant, mais pas encore " + typePoison, cmd); } let nomMunition; let estMunition = label.startsWith('munition_'); @@ -33788,7 +33917,7 @@ var COFantasy = COFantasy || function() { let forcePoison = cmd[3]; let savePoison = parseInt(cmd[4]); if (isNaN(savePoison)) { - error("Le dernier argument non optionnel doit \xEAtre la difficult\xE9 du test de CON", cmd); + error("Le dernier argument non optionnel doit être la difficulté du test de CON", cmd); return; } let testINT = 14; @@ -33797,7 +33926,7 @@ var COFantasy = COFantasy || function() { switch (cmd[0]) { case 'testINT': if (cmd.length < 2) { - error("Il faut un argument \xE0 --testINT", cmd); + error("Il faut un argument à --testINT", cmd); return; } testINT = parseInt(cmd[1]); @@ -33845,11 +33974,11 @@ var COFantasy = COFantasy || function() { return; } if (arme.sortilege) { - sendPerso(perso, "imossible d'enduire un sortil\xE8ge de poison", true); + sendPerso(perso, "imossible d'enduire un sortilège de poison", true); return; } if (arme.typeDegats == 'contondant') { - sendPerso(perso, arme.name + " fait des d\xE9g\xE2ts contondants. Est-il vraiment possible de l'empoisonner ?", true); + sendPerso(perso, arme.name + " fait des dégâts contondants. Est-il vraiment possible de l'empoisonner ?", true); } if (arme.armeDeJet) estMunition = true; } @@ -33864,22 +33993,22 @@ var COFantasy = COFantasy || function() { let munitions = listAllMunitions(perso); let m = munitions[nomMunition]; if (m) { - let typeMunition = fieldAsString(m, 'typemunition', 'Fl\xE8che'); + let typeMunition = fieldAsString(m, 'typemunition', 'Flèche'); armeEnduite = fieldAsString(m, 'nommunition', typeMunition); munitionsCourantes = fieldAsInt(m, 'qtemunition', 1); maxMunitions = fieldAsInt(m, 'qtemunition_max', 1); - } else { //ancienne variante, obsol\xE8te depuis mars 2023 + } else { //ancienne variante, obsolète depuis mars 2023 armeEnduite = nomMunition.replace(/_/g, ' '); let attrQte = tokenAttribute(perso, labelArme); if (attrQte.length === 0) { - sendPerso(perso, "n'a pas de munition nomm\xE9e " + nomMunition); + sendPerso(perso, "n'a pas de munition nommée " + nomMunition); return; } attrQte = attrQte[0]; munitionsCourantes = parseInt(attrQte.get('current')); maxMunitions = parseInt(attrQte.get('max')); if (isNaN(munitionsCourantes) || isNaN(maxMunitions)) { - error("Attribut de munitions mal form\xE9", attrQte); + error("Attribut de munitions mal formé", attrQte); return; } } @@ -33893,7 +34022,7 @@ var COFantasy = COFantasy || function() { let infos = attr[0].get('max'); let indexInfos = infos.indexOf(' '); if (indexInfos < 1) { - error("Attribut de poison rapide de munition mal form\xE9 (il faudrait la difficult\xE9 du save + le nombre de munitions empoisonn\xE9es)", infos); + error("Attribut de poison rapide de munition mal formé (il faudrait la difficulté du save + le nombre de munitions empoisonnées)", infos); return; } let oldSave = parseInt(infos.substring(0, indexInfos)); @@ -33902,23 +34031,23 @@ var COFantasy = COFantasy || function() { if (dejaEnduits > 0 && (attr[0].get('current') != typePoison + ' ' + forcePoison || oldSave != savePoison)) { - sendPlayer(msg, "Il y a d\xE9j\xE0 du poison de type " + attr[0].get('current') + "et de save " + oldSave + " sur les munitions " + armeEnduite + ". Le script ne sait pas g\xE9rer diff\xE9rents poisons sur les m\xEAmes munitions.", playerId); + sendPlayer(msg, "Il y a déjà du poison de type " + attr[0].get('current') + "et de save " + oldSave + " sur les munitions " + armeEnduite + ". Le script ne sait pas gérer différents poisons sur les mêmes munitions.", playerId); return; } } infosAdditionelles = savePoison + ' ' + (dejaEnduits + 1); if (dejaEnduits >= maxMunitions) { - sendPlayer(msg, "Toutes les munitions " + armeEnduite + " sont d\xE9j\xE0 enduites de poison", playerId); + sendPlayer(msg, "Toutes les munitions " + armeEnduite + " sont déjà enduites de poison", playerId); return; } } else { armeEnduite = getAttackName(labelArme, perso); if (armeEnduite === undefined) { - error(perso.tokNname + " n'a pas d'arme associ\xE9e au label " + labelArme, cmd); + error(perso.tokNname + " n'a pas d'arme associée au label " + labelArme, cmd); return; } if (attributeAsBool(perso, attribut)) { - sendPlayer(msg, armeEnduite + " est d\xE9j\xE0 enduit de poison.", playerId); + sendPlayer(msg, armeEnduite + " est déjà enduit de poison.", playerId); return; } } @@ -33958,13 +34087,13 @@ var COFantasy = COFantasy || function() { addEvent(evt); if (limiteRessources(perso, options, 'enduirePoison', 'enduire de poison', evt)) return; const display = startFramedDisplay(options.playerId, "Essaie d'enduire " + armeEnduite + " de poison", perso); - //Test d'INT pour savoir si l'action r\xE9ussit. + //Test d'INT pour savoir si l'action réussit. let testId = 'enduireDePoison'; testCaracteristique(perso, 'INT', testINT, testId, options, evt, function(tr) { let jet = "Jet d'INT : " + tr.texte; - if (tr.echecCritique) { //\xE9chec critique - jet += " \xC9chec critique !" + tr.rerolls + tr.modifiers; + if (tr.echecCritique) { //échec critique + jet += " Échec critique !" + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, jet); addLineToFramedDisplay(display, nomPerso(perso) + " s'empoisonne."); sendChat('', "[[" + forcePoison + "]]", function(res) { @@ -33992,8 +34121,8 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, e); }); addLineToFramedDisplay(display, nomPerso(perso) + " subit " + dmgDisplay + " DM"); - sendChat('', endFramedDisplay(display)); - }); //fin de dmg dus \xE0 l'\xE9chec critique + sendFramedDisplay(display); + }); //fin de dmg dus à l'échec critique } }); //fin du jet de dmg } else if (tr.reussite) { @@ -34003,82 +34132,82 @@ var COFantasy = COFantasy || function() { maxVal: infosAdditionelles }); addLineToFramedDisplay(display, armeEnduite + " est maintenant enduit de poison"); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } else { //echec normal au jet d'INT - jet += " < " + testINT + " : \xE9chec" + tr.rerolls + tr.modifiers; + jet += " < " + testINT + " : échec" + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, jet); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); } }); //fin du test de carac } const listeElixirs = [{ - nom: '\xC9lixir fortifiant', + nom: 'Élixir fortifiant', attrName: 'fortifiant', action: "!cof-fortifiant $rang", rang: 1 }, { - nom: '\xC9lixir de feu gr\xE9geois', - attrName: 'feu_gr\xE9geois', - action: "!cof-attack @{selected|token_id} @{target|token_id} Feu Gr\xE9geois --auto --dm $rangd6 --feu --psave DEX [[$base_save+@{selected|INT}]] --disque 3 --portee 10 --targetFx burst-fire", + nom: 'Élixir de feu grégeois', + attrName: 'feu_grégeois', + action: "!cof-attack @{selected|token_id} @{target|token_id} Feu Grégeois --auto --dm $rangd6 --feu --psave DEX [[$base_save+@{selected|INT}]] --disque 3 --portee 10 --targetFx burst-fire", rang: 2 }, { - nom: '\xC9lixir de gu\xE9rison', - attrName: '\xE9lixir_de_gu\xE9rison', + nom: 'Élixir de guérison', + attrName: 'élixir_de_guérison', action: "!cof-soin 3d6+$INT", rang: 3 }, { - nom: "\xC9lixir d'agrandissement", + nom: "Élixir d'agrandissement", attrName: "potion_d_agrandissement", action: "!cof-effet-temp agrandissement [[5+$INT]]", rang: 4 }, { - nom: "\xC9lixir de forme gazeuse", + nom: "Élixir de forme gazeuse", attrName: "potion_de_forme_gazeuse", action: "!cof-effet-temp formeGazeuse [[1d4+$INT]]", rang: 4 }, { - nom: "\xC9lixir de protection contre les \xE9l\xE9ments", - attrName: "potion_de_protection_contre_les_\xE9l\xE9ments", + nom: "Élixir de protection contre les éléments", + attrName: "potion_de_protection_contre_les_éléments", action: "!cof-effet-temp protectionContreLesElements [[5+$INT]] --valeur $rang", rang: 4 }, { - nom: "\xC9lixir d'armure de mage", + nom: "Élixir d'armure de mage", attrName: "potion_d_armure_de_mage", action: "!cof-effet-combat armureDuMage", rang: 4 }, { - nom: "\xC9lixir de chute ralentie", + nom: "Élixir de chute ralentie", attrName: "potion_de_chute_ralentie", - action: "est l\xE9ger comme une plume.", + action: "est léger comme une plume.", rang: 4 }, { - nom: "\xC9lixir d'invisibilit\xE9", - attrName: "potion_d_invisibilit\xE9", + nom: "Élixir d'invisibilité", + attrName: "potion_d_invisibilité", action: "!cof-set-state invisible true --message se rend invisible ([[1d6+$INT]] minutes)", rang: 5 }, { - nom: "\xC9lixir de vol", + nom: "Élixir de vol", attrName: "potion_de_vol", - action: "se met \xE0 voler", + action: "se met à voler", rang: 5 }, { - nom: "\xC9lixir de respiration aquatique", + nom: "Élixir de respiration aquatique", attrName: "potion_de_respiration_aquatique", action: "peut respirer sous l'eau", rang: 5 }, { - nom: "\xC9lixir de flou", + nom: "Élixir de flou", attrName: "potion_de_flou", action: "!cof-effet-temp flou [[1d4+$INT]]", rang: 5 }, { - nom: "\xC9lixir de h\xE2te", - attrName: "potion_de_h\xE2te", + nom: "Élixir de hâte", + attrName: "potion_de_hâte", action: "!cof-effet-temp hate [[1d6+$INT]]", rang: 5 }, - //Le \xE9lixirs pour les terres d'Arran + //Le élixirs pour les terres d'Arran { nom: 'Huile instable', attrName: 'huileInstable', @@ -34086,25 +34215,25 @@ var COFantasy = COFantasy || function() { rang: 3, arran: true }, { - nom: '\xC9lixir de gu\xE9rison', - attrName: '\xE9lixirGu\xE9rison', + nom: 'Élixir de guérison', + attrName: 'élixirGuérison', action: "!cof-soin 3d6+$INT", rang: 4, arran: true }, { - nom: "\xC9lixir de peau d'\xE9corce", + nom: "Élixir de peau d'écorce", attrName: 'peauEcorce', action: "!cof-effet-temp peauDEcorce [[5+$SAG]] --valeur 4", rang: 5, arran: true }, { - nom: "\xC9lixir d'image d\xE9cal\xE9e", + nom: "Élixir d'image décalée", attrName: 'imageDecalee', action: "!cof-effet-temp imageDecalee [[5+$SAG]]", rang: 5, arran: true }, { - nom: "\xC9lixir de protection contre les \xE9l\xE9ments", + nom: "Élixir de protection contre les éléments", attrName: 'protectionContreElements', action: "!cof-effet-temp protectionContreLesElements [[5+$SAG]] --valeur 5", rang: 5, @@ -34128,7 +34257,7 @@ var COFantasy = COFantasy || function() { getSelected(msg, function(selected, playerId) { iterSelected(selected, function(perso) { if (perso.token.get('bar1_link') === '') { - error("La liste de consommables n'est pas au point pour les tokens non li\xE9s", perso); + error("La liste de consommables n'est pas au point pour les tokens non liés", perso); return; } let display = startFramedDisplay(playerId, 'Liste de vos consommables :', perso, { @@ -34194,7 +34323,7 @@ var COFantasy = COFantasy || function() { var aConsommable; _.each(consommables, function(c, prefix) { if (c.effet === undefined || c.effet === '' || c.nom === undefined || c.nom === '') return; - //La quantit\xE9 est de 1 par d\xE9faut sur la fiche + //La quantité est de 1 par défaut sur la fiche if (c.quantite === undefined) { c.quantite = 1; c.attr = createObj('attribute', { @@ -34211,15 +34340,15 @@ var COFantasy = COFantasy || function() { ressource: c.attr }); // Pictos : https://wiki.roll20.net/CSS_Wizardry#Pictos - var overlay = ' title="Cliquez pour \xE9changer"'; + var overlay = ' title="Cliquez pour échanger"'; ligne += boutonSimple('!cof-echange-consommable ' + perso.token.id + ' @{target|token_id} ' + c.attr.id, 'r', overlay); addLineToFramedDisplay(display, ligne); }); //fin de la boucle sur les onsommables if (aConsommable) - addLineToFramedDisplay(display, 'Cliquez sur le consommable pour l\'utiliser ou sur r pour l\'\xE9changer avec un autre personnage.'); + addLineToFramedDisplay(display, 'Cliquez sur le consommable pour l\'utiliser ou sur r pour l\'échanger avec un autre personnage.'); else addLineToFramedDisplay(display, "Vous n'avez aucun consommable"); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); //fin du getSelected } @@ -34235,15 +34364,15 @@ var COFantasy = COFantasy || function() { cmd.shift(); var perso = persoOfId(cmd[0]); if (perso === undefined) { - log("Propri\xE9taire perdu"); - sendChat('COF', "Plus possible d'utiliser cette action. R\xE9afficher les consommables."); + log("Propriétaire perdu"); + sendChat('COF', "Plus possible d'utiliser cette action. Réafficher les consommables."); return; } - // V\xE9rifie les droits d'utiliser le consommable + // Vérifie les droits d'utiliser le consommable if (msg.selected && msg.selected.length == 1) { var utilisateur = persoOfId(msg.selected[0]._id); if (utilisateur === undefined) { - sendChat('COF', "Le token s\xE9lectionn\xE9 n'est pas valide"); + sendChat('COF', "Le token sélectionné n'est pas valide"); return; } var d = distanceCombat(perso.token, utilisateur.token); @@ -34253,19 +34382,19 @@ var COFantasy = COFantasy || function() { } perso = utilisateur; } else { - //On regarde si le joueur contr\xF4le le token + //On regarde si le joueur contrôle le token if (!peutController(msg, perso)) { - sendPlayer(msg, "Pas les droits pour \xE7a"); + sendPlayer(msg, "Pas les droits pour ça"); return; } } - //on r\xE9cup\xE8re l'attribut \xE0 utiliser + //on récupère l'attribut à utiliser cmd.shift(); var attr = getObj('attribute', cmd[0]); if (attr === undefined) { - log("Attribut a chang\xE9/perdu"); + log("Attribut a changé/perdu"); log(msg.content); - sendChat('COF', "Plus possible d'utiliser cette action. Veuillez r\xE9afficher les consommables."); + sendChat('COF', "Plus possible d'utiliser cette action. Veuillez réafficher les consommables."); return; } //Nom du consommable (pour affichage) @@ -34314,40 +34443,40 @@ var COFantasy = COFantasy || function() { return; } if (cmd[1] == cmd[2]) { - sendChat('COF', "\xC9change avec soi-m\xEAme, sans effet"); + sendChat('COF', "Échange avec soi-même, sans effet"); return; } - //perso1 = token avec qui va \xE9changer le consommable + //perso1 = token avec qui va échanger le consommable var perso1 = persoOfId(cmd[1]); if (perso1 === undefined) { - log("Propri\xE9taire perdu"); - sendChat('COF', "Plus possible d'utiliser cette action. R\xE9afficher les consommables."); + log("Propriétaire perdu"); + sendChat('COF', "Plus possible d'utiliser cette action. Réafficher les consommables."); return; } - //perso2 = token avec lequel on va faire l'\xE9change + //perso2 = token avec lequel on va faire l'échange let perso2 = persoOfId(cmd[2]); if (perso2 === undefined) { log("Destinataire perdu"); - sendChat('COF', "Erreur concernant le destinataire. Veuillez r\xE9essayer."); + sendChat('COF', "Erreur concernant le destinataire. Veuillez réessayer."); return; } - //On regarde si le joueur contr\xF4le le token + //On regarde si le joueur contrôle le token if (!peutController(msg, perso1)) { - sendPlayer(msg, "Pas les droits pour \xE7a"); + sendPlayer(msg, "Pas les droits pour ça"); return; } - //on r\xE9cup\xE8re l'attribut \xE0 \xE9changer de perso1 + //on récupère l'attribut à échanger de perso1 var attr1 = getObj('attribute', cmd[3]); if (attr1 === undefined) { - log("Attribut a chang\xE9/perdu"); + log("Attribut a changé/perdu"); log(cmd); - sendChat('COF', "Plus possible d'utiliser cette action. Veuillez r\xE9afficher les consommables."); + sendChat('COF', "Plus possible d'utiliser cette action. Veuillez réafficher les consommables."); return; } var consName; var quantite1 = parseInt(attr1.get('current')); var evt = { - type: "\xC9change de consommable", + type: "Échange de consommable", attributes: [{ attribute: attr1, current: quantite1, @@ -34377,7 +34506,7 @@ var COFantasy = COFantasy || function() { whisperChar(perso1.charId, "Vous ne disposez plus de " + consName); return; } - // on baisse la valeur de 1 du consommable qu'on s'appr\xEAte \xE0 \xE9changer + // on baisse la valeur de 1 du consommable qu'on s'apprête à échanger quantite1--; attr1.set('current', quantite1); // ajout du consommable dans perso2 : @@ -34404,7 +34533,7 @@ var COFantasy = COFantasy || function() { attribute: attrEffet2, }); } else if (attrEffet2[0].get('current').trim() != effet) { - error("\xC9change dangereux : pas le m\xEAme effet pour le consommable selon le personnage \n" + + error("Échange dangereux : pas le même effet pour le consommable selon le personnage \n" + "Effet chez " + nomPerso(perso1) + " : " + effet + "\n" + "Effet chez " + nomPerso(perso2) + " : " + attrEffet2[0].get('current'), attr2.get('name')); return false; @@ -34433,7 +34562,7 @@ var COFantasy = COFantasy || function() { return true; } else if (!m1 && attrName == attrName2.trim()) { if (attr2.get('max').trim() != effet) { - error("\xC9change dangereux : pas le m\xEAme effet pour le consommable selon le personnage \n" + + error("Échange dangereux : pas le même effet pour le consommable selon le personnage \n" + "Effet chez " + nomPerso(perso1) + " : " + effet + "\n" + "Effet chez " + nomPerso(perso2) + " : " + attr2.get('max'), attr2); return false; @@ -34450,7 +34579,7 @@ var COFantasy = COFantasy || function() { } return false; }); - // si le consommable n'a pas \xE9t\xE9 trouv\xE9, on le cr\xE9e avec une valeur de 1. + // si le consommable n'a pas été trouvé, on le crée avec une valeur de 1. if (!found) { if (m1) { var pref = 'repeating_equipement_' + generateRowID() + '_'; @@ -34483,12 +34612,12 @@ var COFantasy = COFantasy || function() { } } quantite2++; - // on envoie un petit message pr\xE9cisant la r\xE9sultante de l'action. - sendChat('COF', "Echange entre " + nomPerso(perso1) + " et " + nomPerso(perso2) + " termin\xE9e."); + // on envoie un petit message précisant la résultante de l'action. + sendChat('COF', "Echange entre " + nomPerso(perso1) + " et " + nomPerso(perso2) + " terminée."); whisperChar(perso1.charId, " Il vous reste " + quantite1 + " " + consName + "."); - whisperChar(perso2.charId, " Vous poss\xE9dez d\xE9sormais " + quantite2 + " " + consName + "."); - // le MJ est notifi\xE9 : - sendChat('COF', "/w GM " + nomPerso(perso1) + " vient de donner 1 " + consName + " \xE0 " + nomPerso(perso2) + "."); + whisperChar(perso2.charId, " Vous possédez désormais " + quantite2 + " " + consName + "."); + // le MJ est notifié : + sendChat('COF', "/w GM " + nomPerso(perso1) + " vient de donner 1 " + consName + " à " + nomPerso(perso2) + "."); addEvent(evt); } @@ -34497,7 +34626,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -34511,7 +34640,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-provocation n'est pas un token valide"); + error("Le deuxième argument de !cof-provocation n'est pas un token valide"); return; } if (cmd.length > 3 && cmd[3] == 'raillerie') { @@ -34560,16 +34689,16 @@ var COFantasy = COFantasy || function() { }); let reussite; switch (res) { - case 0: //en cas d'\xE9galit\xE9, on consid\xE8re que la provocation est r\xE9ussie + case 0: //en cas d'égalité, on considère que la provocation est réussie diminueMalediction(cible, evt); switch (crit) { case -1: - reussite = "Sur un malentendu, la " + action + " r\xE9ussit..."; + reussite = "Sur un malentendu, la " + action + " réussit..."; if (options.raillerie) setAttrDuree(cible, 'enerve', 1, evt); break; case 0: case 1: - reussite = "La " + action + " r\xE9ussit tout juste."; + reussite = "La " + action + " réussit tout juste."; if (options.raillerie) { setAttrDuree(cible, 'enerve', 1, evt); setTokenAttr(cible, 'resistanceRaillerie', @@ -34580,7 +34709,7 @@ var COFantasy = COFantasy || function() { case 1: switch (crit) { case -1: - reussite = nomCible + " marche compl\xE8tement, il attaque " + nomVoleur; + reussite = nomCible + " marche complètement, il attaque " + nomVoleur; if (options.raillerie) { setAttrDuree(cible, 'enerve', 1, evt); removeTokenAttr(cible, 'resistanceRaillerie', evt); @@ -34589,13 +34718,13 @@ var COFantasy = COFantasy || function() { case 0: if (options.raillerie) { setAttrDuree(cible, 'enerve', 1, evt); - reussite = nomVoleur + " a r\xE9ussi \xE0 bien \xE9nerver " + nomCible; + reussite = nomVoleur + " a réussi à bien énerver " + nomCible; setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) + 1, evt); - } else reussite = "La provocation r\xE9ussit."; + } else reussite = "La provocation réussit."; break; case 1: - reussite = "La provocation est une r\xE9ussite critique !"; + reussite = "La provocation est une réussite critique !"; setAttrDuree(cible, 'enerve', 1, evt); setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) - 1, evt); @@ -34604,7 +34733,7 @@ var COFantasy = COFantasy || function() { case 2: switch (crit) { case -1: - reussite = "\xC9chec critique de la " + action + " !"; + reussite = "Échec critique de la " + action + " !"; if (options.raillerie) { setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) + 5, evt); @@ -34615,19 +34744,19 @@ var COFantasy = COFantasy || function() { setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) + 1, evt); } - reussite = "La provocation \xE9choue"; + reussite = "La provocation échoue"; break; case 1: if (options.raillerie) { setTokenAttr(cible, 'resistanceRaillerie', attributeAsInt(cible, 'resistanceRaillerie', 0) + 10, evt); } - reussite = nomCible + " voit clair dans le jeu de " + nomVoleur + ". La provocation \xE9choue."; + reussite = nomCible + " voit clair dans le jeu de " + nomVoleur + ". La provocation échoue."; } } addLineToFramedDisplay(display, reussite); - sendChat('', endFramedDisplay(display)); - }); //Fin du test oppos\xE9 + sendFramedDisplay(display); + }); //Fin du test opposé } function enSelle(msg) { @@ -34671,14 +34800,14 @@ var COFantasy = COFantasy || function() { let nomMonture = cmd.join(' '); let monture = persoOfId(nomMonture, nomMonture, pageId); if (monture === undefined || !predicateAsBool(monture, 'monture')) { - sendPerso(cavalier, "ne peut pas monter l\xE0-dessus"); + sendPerso(cavalier, "ne peut pas monter là-dessus"); log(nomMonture); return; } const tokenM = monture.token; nomMonture = tokenM.get('name'); if (attributeAsBool(monture, 'estMontePar')) { - //V\xE9rifie si le cavalier existe bien sur cette page. + //Vérifie si le cavalier existe bien sur cette page. let cavalierBis; let estMontePar = tokenAttribute(monture, 'estMontePar'); estMontePar.forEach(function(emp) { @@ -34687,7 +34816,7 @@ var COFantasy = COFantasy || function() { if (cavalierBis === undefined) emp.remove(); }); if (cavalierBis) { - sendPerso(cavalier, "ne peut monter sur " + nomMonture + " car " + onGenre(monture, 'il', 'elle') + " a d\xE9j\xE0 un cavalier, " + nomPerso(cavalierBis)); + sendPerso(cavalier, "ne peut monter sur " + nomMonture + " car " + onGenre(monture, 'il', 'elle') + " a déjà un cavalier, " + nomPerso(cavalierBis)); return; } } @@ -34721,9 +34850,9 @@ var COFantasy = COFantasy || function() { } else voieDesElixirs = predicateAsInt(perso, 'voieDesElixirs', 0); if (voieDesElixirs < 1 && !noMsg) { if (arran) - sendPerso(perso, "ne conna\xEEt pas la Voie de l'Alchimie"); + sendPerso(perso, "ne connaît pas la Voie de l'Alchimie"); else - sendPerso(perso, "ne conna\xEEt pas la Voie des \xC9lixirs"); + sendPerso(perso, "ne connaît pas la Voie des Élixirs"); return; } return voieDesElixirs; @@ -34747,7 +34876,7 @@ var COFantasy = COFantasy || function() { if (forgesort === undefined) { let c = getObj('character', cmd[1]); if (c === undefined) { - error("Impossible de savoir qui cr\xE9e l'\xE9lixir", cmd); + error("Impossible de savoir qui crée l'élixir", cmd); return; } forgesort = { @@ -34761,7 +34890,7 @@ var COFantasy = COFantasy || function() { if (exilirInconnu(i, forgesort, voieDesElixirs)) return false; return i.attrName == cmd[2]; }); - if (elixir === undefined) { //Version perso des \xE9lixirs + if (elixir === undefined) { //Version perso des élixirs let altElixirs = findObjs({ _type: 'attribute', _characterid: forgesort.charId @@ -34782,16 +34911,16 @@ var COFantasy = COFantasy || function() { return true; }); if (elixir === undefined) { - error(nomPerso(forgesort) + " est incapable de cr\xE9er " + cmd[2], cmd); + error(nomPerso(forgesort) + " est incapable de créer " + cmd[2], cmd); return; } } const evt = { - type: "Cr\xE9ation d'\xE9lixir" + type: "Création d'élixir" }; addEvent(evt); let arran = persoArran(forgesort); - //D\xE9pense de mana + //Dépense de mana if (!arran && reglesOptionelles.mana.val.elixirs_sorts.val && ficheAttributeAsBool(forgesort, 'option_pm', true)) { if (reglesOptionelles.mana.val.mana_totale.val) { switch (elixir.rang) { @@ -34817,14 +34946,14 @@ var COFantasy = COFantasy || function() { } let elixirsACreer = tokenAttribute(forgesort, 'elixirsACreer'); if (elixirsACreer.length === 0) { - error(nomPerso(forgesort) + " ne peut cr\xE9er d'\xE9lixirs " + cmd[2], cmd); + error(nomPerso(forgesort) + " ne peut créer d'élixirs " + cmd[2], cmd); return; } elixirsACreer = elixirsACreer[0]; let extraFortifiants = toInt(elixirsACreer.get('max'), 0); let extra = extraFortifiants > 0 && elixir.rang == 1; if (!extra) options.decrAttribute = elixirsACreer.id; - if (limiteRessources(forgesort, options, 'elixirsACreer', '\xE9lixirs \xE0 cr\xE9er', evt)) return; + if (limiteRessources(forgesort, options, 'elixirsACreer', 'élixirs à créer', evt)) return; if (extra) { evt.attributes = evt.attributes || []; evt.attributes.push({ @@ -34835,7 +34964,7 @@ var COFantasy = COFantasy || function() { elixirsACreer.set('max', extraFortifiants - 1); } let attrName = 'elixir_' + elixir.attrName; - let message = "cr\xE9e un " + elixir.nom; + let message = "crée un " + elixir.nom; let attr = tokenAttribute(forgesort, attrName); if (attr.length === 0) { let rang = voieDesElixirs; @@ -34886,20 +35015,20 @@ var COFantasy = COFantasy || function() { let titre; if (elixirsACreer < 1) { if (fortifiantExtra < 1) - titre = "Impossible de cr\xE9er un autre \xE9lixir aujourd'hui"; + titre = "Impossible de créer un autre élixir aujourd'hui"; else { titre = "Encore " + fortifiantExtra + " fortifiant"; if (fortifiantExtra > 1) titre += 's'; - titre += "\xE0 cr\xE9er"; + titre += "à créer"; } } else { - titre = "Encore " + elixirsACreer + " \xE9lixir"; + titre = "Encore " + elixirsACreer + " élixir"; if (elixirsACreer > 1) titre += 's'; if (fortifiantExtra > 0) { titre += " et " + fortifiantExtra + " fortifiant"; if (fortifiantExtra > 1) titre += 's'; } - titre += " \xE0 cr\xE9er"; + titre += " à créer"; } let display = startFramedDisplay(playerId, titre, forgesort, { chuchote: true @@ -34907,7 +35036,7 @@ var COFantasy = COFantasy || function() { listeElixirs.forEach(function(elixir) { if (exilirInconnu(elixir, forgesort, voieDesElixirs)) return; if (elixir.rang < 4) { - //Il est possible de changer l'\xE9lixir par d\xE9faut + //Il est possible de changer l'élixir par défaut let altElixir = charAttribute(forgesort.charId, 'Elixir ' + elixir.rang); if (altElixir.length > 0) { elixir.nom = altElixir[0].get('current'); @@ -34955,7 +35084,7 @@ var COFantasy = COFantasy || function() { } addLineToFramedDisplay(display, options); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); //Fin du getSelected } @@ -34999,17 +35128,17 @@ var COFantasy = COFantasy || function() { function proposerRenouveauElixirs(evt, attrs, options) { let attrsNamed = allAttributesNamed(attrs, 'elixir'); if (attrsNamed.length === 0) return attrs; - // Trouver les forgesorts avec des \xE9lixirs sur eux + // Trouver les forgesorts avec des élixirs sur eux let forgesorts = {}; attrsNamed.forEach(function(attr) { - // Check de l'existence d'un cr\xE9ateur + // Check de l'existence d'un créateur let charId = attr.get('characterid'); - let personnage = persoOfCharId(charId, options.pageId, "avec un \xE9lixir"); + let personnage = persoOfCharId(charId, options.pageId, "avec un élixir"); if (personnage === undefined) personnage = { charId }; let voieDesElixirs = rangVoieDesElixirs(personnage, true); - //TODO: r\xE9fl\xE9chir \xE0 une solution pour le renouveau des \xE9lixirs \xE9chang\xE9s + //TODO: réfléchir à une solution pour le renouveau des élixirs échangés if (voieDesElixirs > 0) { let elixirsDuForgesort = forgesorts[charId]; if (elixirsDuForgesort === undefined) { @@ -35019,24 +35148,24 @@ var COFantasy = COFantasy || function() { elixirsParRang: {} }; } - // Check de l'\xE9lixir \xE0 renouveler + // Check de l'élixir à renouveler let nomElixir = attr.get('name'); let typeElixir = listeElixirs.find(function(i) { if (i.rang > voieDesElixirs) return false; return "elixir_" + i.attrName == nomElixir; }); if (typeElixir === undefined) { - error("Impossible de trouver l'\xE9lixir \xE0 renouveler"); + error("Impossible de trouver l'élixir à renouveler"); return; } // Check des doses let doses = attr.get("current"); if (isNaN(doses)) { - error("Erreur interne : \xE9lixir mal form\xE9"); + error("Erreur interne : élixir mal formé"); return; } if (doses > 0) { - // Tout est ok, cr\xE9ation de l'item + // Tout est ok, création de l'item let elixirArenouveler = { typeElixir: typeElixir, doses: doses @@ -35070,7 +35199,7 @@ var COFantasy = COFantasy || function() { opt.maxVal = 2; } setTokenAttr(forgesort, 'elixirsACreer', elixirsDuForgesort.voieDesElixirs * 2, evt, opt); - let display = startFramedDisplay(allPlayers[0], "Renouveler les \xE9lixirs", forgesort, displayOpt); + let display = startFramedDisplay(allPlayers[0], "Renouveler les élixirs", forgesort, displayOpt); let actionToutRenouveler = ""; // Boucle par rang de rune for (const rang in elixirsDuForgesort.elixirsParRang) { @@ -35079,7 +35208,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, "Elixirs de rang " + rang, undefined, true); let actionTout = ''; let ligneBoutons = ''; - // Boucle par \xE9lixir de ce rang \xE0 renouveler + // Boucle par élixir de ce rang à renouveler for (const i in elixirsDeRang) { let elixir = elixirsDeRang[i]; // Boucle par dose @@ -35104,7 +35233,7 @@ var COFantasy = COFantasy || function() { buttonStyle: "background-color: green;" }); addLineToFramedDisplay(display, boutonToutRenouveler, undefined, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } return removeAllAttributes("elixir", evt, attrs); } @@ -35113,9 +35242,9 @@ var COFantasy = COFantasy || function() { var liste = []; if (rang < 2) return liste; liste.push({ - nom: "Rune d'\xE9nergie", + nom: "Rune d'énergie", action: "!cof-rune-energie", - attrName: "runeForgesort_\xE9nergie", + attrName: "runeForgesort_énergie", rang: 2 }); if (rang < 3) return liste; @@ -35145,23 +35274,23 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(forgesort) { let voieDesRunes = predicateAsInt(forgesort, 'voieDesRunes', 0); if (voieDesRunes < 1) { - sendPerso(forgesort, "ne conna\xEEt pas la Voie des Runes."); + sendPerso(forgesort, "ne connaît pas la Voie des Runes."); return; } else if (voieDesRunes < 2) { - sendPerso(forgesort, "ne peut \xE9crire que des Runes de d\xE9fense."); + sendPerso(forgesort, "ne peut écrire que des Runes de défense."); return; } - let titre = "Cr\xE9ation de runes"; + let titre = "Création de runes"; let display = startFramedDisplay(playerId, titre, forgesort, { chuchote: true }); listeRunes(voieDesRunes).forEach(function(rune) { var action = "!cof-creer-rune " + forgesort.token.id + " @{target|token_id} " + rune.rang; - if (rune.rang === 4) action += " ?{Num\xE9ro de l'arme de la cible?}"; + if (rune.rang === 4) action += " ?{Numéro de l'arme de la cible?}"; var options = bouton(action, rune.nom, forgesort); addLineToFramedDisplay(display, options); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); //Fin du getSelected } @@ -35181,40 +35310,40 @@ var COFantasy = COFantasy || function() { forgesort = persoOfId(msg.selected[0]._id); } if (forgesort === undefined) { - error("Impossible de savoir qui cr\xE9e la rune", cmd); + error("Impossible de savoir qui crée la rune", cmd); return; } } var target = persoOfId(cmd[2], cmd[2], options.pageId); if (target === undefined) { - error("Impossible de savoir \xE0 qui octroyer la rune", cmd); + error("Impossible de savoir à qui octroyer la rune", cmd); return; } var voieDesRunes = predicateAsInt(forgesort, 'voieDesRunes', 0); if (voieDesRunes < 1) { - sendPerso(forgesort, "ne conna\xEEt pas la Voie des Runes"); + sendPerso(forgesort, "ne connaît pas la Voie des Runes"); return; } else if (voieDesRunes < 2) { - sendPerso(forgesort, "ne peut \xE9crire que des Runes de d\xE9fense."); + sendPerso(forgesort, "ne peut écrire que des Runes de défense."); return; } var rune = listeRunes(voieDesRunes).find(function(i) { return i.rang == cmd[3]; }); if (rune === undefined) { - error(nomPerso(forgesort) + " est incapable de cr\xE9er " + cmd[3], cmd); + error(nomPerso(forgesort) + " est incapable de créer " + cmd[3], cmd); return; } var labelArme; if (rune.rang == 4) { if (cmd.length < 5) { - error("La rune de puissance n\xE9cessite de choisir un label d'arme."); + error("La rune de puissance nécessite de choisir un label d'arme."); return; } labelArme = parseInt(cmd[4]); } var evt = { - type: "Cr\xE9ation de rune" + type: "Création de rune" }; addEvent(evt); if (ficheAttributeAsBool(forgesort, 'option_pm', true)) { @@ -35235,11 +35364,11 @@ var COFantasy = COFantasy || function() { } } let attrName = rune.attrName; - let message = "re\xE7oit "; + let message = "reçoit "; let typeRune; switch (rune.rang) { case 2: - typeRune = "une rune d'\xE9nergie"; + typeRune = "une rune d'énergie"; break; case 3: typeRune = "une rune de protection"; @@ -35254,10 +35383,10 @@ var COFantasy = COFantasy || function() { } message += typeRune; if (attributeAsInt(target, attrName, 0) > 0) { - error("La cible poss\xE8de d\xE9j\xE0 une rune " + typeRune, cmd); + error("La cible possède déjà une rune " + typeRune, cmd); return; } - if (options.mana !== undefined && limiteRessources(forgesort, options, undefined, "cr\xE9er " + typeRune, evt)) return; + if (options.mana !== undefined && limiteRessources(forgesort, options, undefined, "créer " + typeRune, evt)) return; setTokenAttr(target, attrName, 1, evt, { msg: message, maxVal: forgesort.charId @@ -35273,19 +35402,19 @@ var COFantasy = COFantasy || function() { function proposerRenouveauRunes(evt, attrs, options) { let attrsNamed = allAttributesNamed(attrs, 'runeForgesort'); if (attrsNamed.length === 0) return attrs; - // Filtrer par Forgesort, dans l'\xE9ventualit\xE9 qu'il y en ait plusieurs actifs + // Filtrer par Forgesort, dans l'éventualité qu'il y en ait plusieurs actifs let forgesorts = {}; attrsNamed.forEach(function(attr) { - // Check de l'existence d'un cr\xE9ateur + // Check de l'existence d'un créateur let forgesortId = attr.get('max'); if (forgesortId === undefined) { - error("Impossible de retrouver le cr\xE9ateur de la rune : " + attr); + error("Impossible de retrouver le créateur de la rune : " + attr); return; } let runesDuForgesort = forgesorts[forgesortId]; if (runesDuForgesort === undefined) { - // Check de l'existence d'un token pr\xE9sent pour le cr\xE9ateur - let forgesort = persoOfCharId(forgesortId, options.pageId, "ayant cr\xE9\xE9 une rune"); + // Check de l'existence d'un token présent pour le créateur + let forgesort = persoOfCharId(forgesortId, options.pageId, "ayant créé une rune"); if (forgesort === undefined) { attr.remove(); return; @@ -35293,10 +35422,10 @@ var COFantasy = COFantasy || function() { // Check du perso voie des Runes let voieDesRunes = predicateAsInt(forgesort, 'voieDesRunes', 0); if (voieDesRunes < 1) { - sendPerso(forgesort, "ne conna\xEEt pas la Voie des Runes"); + sendPerso(forgesort, "ne connaît pas la Voie des Runes"); return; } else if (voieDesRunes < 2) { - sendPerso(forgesort, "ne peut \xE9crire que des Runes de d\xE9fense."); + sendPerso(forgesort, "ne peut écrire que des Runes de défense."); return; } runesDuForgesort = { @@ -35305,21 +35434,21 @@ var COFantasy = COFantasy || function() { runesParRang: {} }; } - // Check de la pr\xE9sence d'un token pour la cible + // Check de la présence d'un token pour la cible let targetCharId = attr.get('characterid'); let target = persoOfCharId(targetCharId, options.pageId, "ayant une rune"); if (target === undefined) return; - // Check de la rune \xE0 renouveler + // Check de la rune à renouveler let runeName = attr.get('name'); let typeRune = listeRunes(runesDuForgesort.voieDesRunes).find(function(i) { return i.attrName == runeName.split("(")[0]; }); if (typeRune === undefined) { - error("Impossible de trouver la rune \xE0 renouveler"); + error("Impossible de trouver la rune à renouveler"); return; } - // Tout est ok, cr\xE9ation de l'item + // Tout est ok, création de l'item let runeARenouveler = { target: target, typeRune: typeRune, @@ -35356,7 +35485,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, runesDeRang[0].typeRune.nom, undefined, true); let actionTout = ""; let ligneBoutons = ""; - // Boucle par rune de ce rang \xE0 renouveler + // Boucle par rune de ce rang à renouveler for (const i in runesDeRang) { let rune = runesDeRang[i]; let action = @@ -35379,7 +35508,7 @@ var COFantasy = COFantasy || function() { buttonStyle: "background-color: green;" }); addLineToFramedDisplay(display, boutonToutRenouveler, undefined, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } return removeAllAttributes("runeForgesort", evt, attrs); } @@ -35389,7 +35518,7 @@ var COFantasy = COFantasy || function() { if (msg.content.includes(' --furie')) typeRage = 'furie'; getSelected(msg, function(selection, playerId) { if (selection.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour la rage", playerId); + sendPlayer(msg, "Pas de token sélectionné pour la rage", playerId); return; } const options = parseOptions(msg); @@ -35420,20 +35549,20 @@ var COFantasy = COFantasy || function() { typeRage = attrRage.get('current'); let difficulte = 13; if (typeRage == 'furie') difficulte = 16; - //Jet de sagesse difficult\xE9 13 pou 16 pour sortir de cet \xE9tat + //Jet de sagesse difficulté 13 pou 16 pour sortir de cet état let display = startFramedDisplay(options.playerId, "Essaie de calmer sa " + typeRage, perso); let testId = 'rageDuBerserk_' + perso.token.id; testCaracteristique(perso, 'SAG', difficulte, testId, options, evt, function(tr) { - addLineToFramedDisplay(display, "R\xE9sultat du jet de SAG : " + tr.texte); + addLineToFramedDisplay(display, "Résultat du jet de SAG : " + tr.texte); if (tr.reussite) { - addLineToFramedDisplay(display, "C'est r\xE9ussi, " + nomPerso(perso) + " se calme." + tr.modifiers); + addLineToFramedDisplay(display, "C'est réussi, " + nomPerso(perso) + " se calme." + tr.modifiers); removeTokenAttr(perso, 'rageDuBerserk', evt); } else { - let msgRate = "C'est rat\xE9, " + nomPerso(perso) + " reste enrag\xE9" + tr.rerolls + tr.modifiers; + let msgRate = "C'est raté, " + nomPerso(perso) + " reste enragé" + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, msgRate); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); } else { //Le barbare passe en rage @@ -35457,17 +35586,17 @@ var COFantasy = COFantasy || function() { var options = parseOptions(msg); var cmd = msg.content.split(' '); if (cmd.length < 3) { - error("Il faut deux arguments \xE0 !cof-arme-secrete", cmd); + error("Il faut deux arguments à !cof-arme-secrete", cmd); return; } var barde = persoOfId(cmd[1]); var cible = persoOfId(cmd[2]); if (barde === undefined || cible === undefined) { - error("Token non valide pour l'arme secr\xE8te", cmd); + error("Token non valide pour l'arme secrète", cmd); return; } if (attributeAsInt(barde, 'armeSecreteBardeUtilisee')) { - sendPerso(barde, "a d\xE9j\xE0 utilis\xE9 son arme secr\xE8te durant ce combat"); + sendPerso(barde, "a déjà utilisé son arme secrète durant ce combat"); return; } doArmeSecrete(barde, cible, options); @@ -35495,21 +35624,21 @@ var COFantasy = COFantasy || function() { var testId = 'armeSecreteBarde'; testCaracteristique(perso, 'CHA', intCible, testId, options, evt, function(tr) { var display = startFramedDisplay(options.playerId, - "Arme secr\xE8te", perso, { + "Arme secrète", perso, { perso2: cible }); var line = "Jet de CHA : " + tr.texte; if (tr.reussite) { line += " ≥ " + intCible + tr.modifiers; addLineToFramedDisplay(display, line); - addLineToFramedDisplay(display, nomPerso(cible) + " est compl\xE8tement d\xE9stabilis\xE9"); + addLineToFramedDisplay(display, nomPerso(cible) + " est complètement déstabilisé"); setAttrDuree(cible, 'armeSecreteBarde', 1, evt); } else { line += " < " + intCible + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, line); addLineToFramedDisplay(display, nomPerso(cible) + " reste insensible au charme de " + nomPerso(perso)); } - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); //fin testCarac } @@ -35531,15 +35660,15 @@ var COFantasy = COFantasy || function() { } } - //Cr\xE9e un nouveau personnage (de type PNJ par d\xE9faut) - //spec contient les charact\xE9ristiques, attributs et abilities - // - attributesFiche contient les attributs d\xE9finis dans la fiche + //Crée un nouveau personnage (de type PNJ par défaut) + //spec contient les charactéristiques, attributs et abilities + // - attributesFiche contient les attributs définis dans la fiche // nom_attribut: valeur - // - pv (permet d'\xEAtre ind\xE9pendant de PJ ou PNJ) + // - pv (permet d'être indépendant de PJ ou PNJ) // - attaques, liste d'attaques, chacune avec (nom, atk, dmnbde, dmde, dm,...) // - attributes autres attributs (name, current, max) - // - abilities (name, action), toujours rajout\xE9es \xE0 la liste d'actions - // - actions (titre, code), ajout\xE9es aux listes d'actions + // - abilities (name, action), toujours rajoutées à la liste d'actions + // - actions (titre, code), ajoutées aux listes d'actions function createCharacter(nom, playerId, avatar, token, spec, evt, createur) { let res = createObj('character', { name: nom, @@ -35756,7 +35885,7 @@ var COFantasy = COFantasy || function() { } let tokenArbre = getObj('graphic', cmd[2]); if (tokenArbre === undefined) { - error("Le deuxi\xE8me argument de !cof-animer-arbre n'est pas un token", cmd); + error("Le deuxième argument de !cof-animer-arbre n'est pas un token", cmd); return; } if (tokenArbre.get('represents') !== '') { @@ -35771,10 +35900,10 @@ var COFantasy = COFantasy || function() { } } let rang = predicateAsInt(druide, 'voieDesVegetaux', 3); - if (cmd.length > 3) { //Le rang est sp\xE9cifi\xE9 en argument optionnel + if (cmd.length > 3) { //Le rang est spécifié en argument optionnel let cmd3 = parseInt(cmd[3]); if (isNaN(cmd3) || cmd3 < 1) { - error("Le rang n'est pas un nombre valie. On utilise " + rang + " \xE0 la place", cmd); + error("Le rang n'est pas un nombre valie. On utilise " + rang + " à la place", cmd); } else rang = cmd3; } const evt = { @@ -35786,7 +35915,7 @@ var COFantasy = COFantasy || function() { initPerso(druide, evt); } let niveau = ficheAttributeAsInt(druide, 'niveau', 1); - let nomArbre = nouveauNomDePerso('Arbre anim\xE9'); + let nomArbre = nouveauNomDePerso('Arbre animé'); let avatar = "https://s3.amazonaws.com/files.d20.io/images/42323556/6qxlm965aFhBXGoYFy5fqg/thumb.png?1510582137"; let specArbre = { pv: rang * 10, @@ -35829,11 +35958,11 @@ var COFantasy = COFantasy || function() { }; let charArbre = createCharacter(nomArbre, options.playerId, avatar, tokenArbre, specArbre, evt, druide); evt.characters = [charArbre]; - sendChar(charArbre.id, "commence \xE0 s'animer", true); + sendChar(charArbre.id, "commence à s'animer", true); initiative([{ _id: tokenArbre.id }], evt); - // Ajout de l'arbre anim\xE9 aux alli\xE9s du Druide + // Ajout de l'arbre animé aux alliés du Druide let alliesDruide = alliesParPerso[druide.charId] || new Set(); alliesDruide.add(charArbre.id); alliesParPerso[druide.charId] = alliesDruide; @@ -35849,20 +35978,20 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; var cmd = options.cmd; var evt = lastEvent(); - if (cmd !== undefined && cmd.length > 1) { //On relance pour un \xE9v\xE9nement particulier + if (cmd !== undefined && cmd.length > 1) { //On relance pour un événement particulier evt = findEvent(cmd[1]); if (evt === undefined) { - error("L'action est trop ancienne ou a \xE9t\xE9 annul\xE9e", cmd); + error("L'action est trop ancienne ou a été annulée", cmd); return; } } if (evt.type != 'Attaque') { - sendChat('', "la derni\xE8re action n'est pas une attaque r\xE9ussie, trop tard pour absorber l'attaque pr\xE9c\xE9dente"); + sendChat('', "la dernière action n'est pas une attaque réussie, trop tard pour absorber l'attaque précédente"); return; } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Personne n'est s\xE9lectionn\xE9 pour utiliser une rune", msg); + error("Personne n'est sélectionné pour utiliser une rune", msg); return; } var action = evt.action; @@ -35875,7 +36004,7 @@ var COFantasy = COFantasy || function() { return (target.token.id === perso.token.id); }); if (cible === undefined) { - sendPerso(perso, "n'est pas la cible de la derni\xE8re attaque"); + sendPerso(perso, "n'est pas la cible de la dernière attaque"); return; } if (!attributeAsBool(perso, 'runeForgesort_protection')) { @@ -35883,7 +36012,7 @@ var COFantasy = COFantasy || function() { return; } if (attributeAsInt(perso, 'limiteParCombat_runeForgesort_protection', 1) < 1) { - sendPerso(perso, "a d\xE9j\xE0 utilis\xE9 sa rune de protection durant ce combat"); + sendPerso(perso, "a déjà utilisé sa rune de protection durant ce combat"); return; } action.choices = action.choices || {}; @@ -35922,7 +36051,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2], options.pageId); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-delivrance n'est pas un token valide", msg.content); + error("Le deuxième argument de !cof-delivrance n'est pas un token valide", msg.content); return; } if (options.portee !== undefined) { @@ -35933,12 +36062,12 @@ var COFantasy = COFantasy || function() { } } const evt = { - type: "D\xE9livrance", + type: "Délivrance", deletedAttributes: [] }; addEvent(evt); - if (limiteRessources(pretre, options, 'd\xE9livrance', 'd\xE9livrance', evt)) return; - let display = startFramedDisplay(getPlayerIdFromMsg(msg), 'D\xE9livrance', pretre, { + if (limiteRessources(pretre, options, 'délivrance', 'délivrance', evt)) return; + let display = startFramedDisplay(getPlayerIdFromMsg(msg), 'Délivrance', pretre, { perso2: cible }); let printEffet = function(message) { @@ -35950,7 +36079,7 @@ var COFantasy = COFantasy || function() { }; _.each(messageEffetTemp, function(effet, nomEffet) { if (effet.prejudiciable) { - //Attention, ne fonctionne pas avec les effets g\xE9n\xE9riques + //Attention, ne fonctionne pas avec les effets génériques let attr = tokenAttribute(cible, nomEffet); if (attr.length > 0) finDEffet(attr[0], nomEffet, attr[0].get('name'), cible.charId, evt, optFin); @@ -35984,7 +36113,7 @@ var COFantasy = COFantasy || function() { printEffet("n'a plus de point de sang."); removeTokenAttr(cible, 'pointsDeSang', evt); } - //On enl\xE8ve les \xE9tats pr\xE9judiciables + //On enlève les états préjudiciables if (getState(cible, 'aveugle')) { printEffet("retrouve la vue"); setState(cible, 'aveugle', false, evt); @@ -35998,7 +36127,7 @@ var COFantasy = COFantasy || function() { setState(cible, 'etourdi', false, evt); } if (getState(cible, 'paralyse')) { - printEffet("peut \xE0 nouveau bouger"); + printEffet("peut à nouveau bouger"); setState(cible, 'paralyse', false, evt); } if (getState(cible, 'ralenti')) { @@ -36006,41 +36135,41 @@ var COFantasy = COFantasy || function() { setState(cible, 'ralenti', false, evt); } if (getState(cible, 'endormi')) { - printEffet("se r\xE9veille"); + printEffet("se réveille"); setState(cible, 'endormi', false, evt); } if (getState(cible, 'apeure')) { printEffet("reprend courage"); setState(cible, 'apeure', false, evt); } - //R\xE9g\xE9n\xE9ration d'une carac affaiblie de 1d4, si il y en a. + //Régénération d'une carac affaiblie de 1d4, si il y en a. if (attributeAsInt(cible, 'affaiblissementdesagesse', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'sagesse', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de sagesse"); + printEffet("récupère " + d4.roll + " points de sagesse"); } else if (attributeAsInt(cible, 'affaiblissementdecharisme', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'charisme', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de charisme"); + printEffet("récupère " + d4.roll + " points de charisme"); } else if (attributeAsInt(cible, 'affaiblissementdeintelligence', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'intelligence', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points d'intelligence"); + printEffet("récupère " + d4.roll + " points d'intelligence"); } if (attributeAsInt(cible, 'affaiblissementdeconstitution', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'constitution', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de constitution"); + printEffet("récupère " + d4.roll + " points de constitution"); } else if (attributeAsInt(cible, 'affaiblissementdeforce', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'force', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de force"); + printEffet("récupère " + d4.roll + " points de force"); } else if (attributeAsInt(cible, 'affaiblissementdedexterite', 0) > 0) { let d4 = rollDePlus(4); diminueAffaiblissement(cible, 'dexterite', d4.val, evt); - printEffet("r\xE9cup\xE8re " + d4.roll + " points de dext\xE9rit\xE9"); + printEffet("récupère " + d4.roll + " points de dextérité"); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } function guerisonPerso(perso, evt, lanceur) { @@ -36052,32 +36181,36 @@ var COFantasy = COFantasy || function() { msgSoin = 'soigne ' + nomPerso(perso); } } else { - msgSoin = 'r\xE9cup\xE8re'; + msgSoin = 'récupère'; } msgSoin += ' de toutes les blessures subies'; if (lanceur) sendPerso(lanceur, msgSoin); else sendPerso(perso, msgSoin); if (getState(perso, 'blesse')) { setState(perso, 'blesse', false, evt); - } else { //On peut bien faire r\xE9cup\xE9rer un PR + } else { //On peut bien faire récupérer un PR let d = rajouterPointDeRecuperation(perso, evt); - if (d) sendPerso(perso, "r\xE9cup\xE8re un point de r\xE9cup\xE9ration"); + if (d) sendPerso(perso, "récupère un point de récupération"); } let soins = perso.token.get('bar1_max') - perso.token.get('bar1_value'); if (isNaN(soins)) { updateCurrentBar(perso, 1, perso.token.get('bar1_max'), evt); return; } - //Les affaiblissements de caract\xE9ristiques + //Les affaiblissements de caractéristiques allCaracs.forEach(function(carac) { let malus = attributeAsInt(perso, 'affaiblissementde' + carac, 0); if (malus > 0) { diminueAffaiblissement(perso, carac, malus, evt, malus); - sendPerso(perso, "r\xE9cup\xE8re " + malus + " points " + deCarac(carac)); + sendPerso(perso, "récupère " + malus + " points " + deCarac(carac)); } }); + //La putréfaction des momies + if (attributeAsBool(perso, 'putrefaction')) { + finDEffetDeNom(perso, 'putrefaction', evt); + } if (soins <= 0) { - //Rien d'autre \xE0 faire (le script ne g\xE8re pas encore le reste) + //Rien d'autre à faire (le script ne gère pas encore le reste) return; } soigneToken(perso, soins, evt); @@ -36099,7 +36232,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2], options.pageId); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-guerison n'est pas un token valide", msg.content); + error("Le deuxième argument de !cof-guerison n'est pas un token valide", msg.content); return; } if (options.dose === undefined && options.decrAttribute === undefined) { @@ -36113,10 +36246,10 @@ var COFantasy = COFantasy || function() { } } const evt = { - type: "Gu\xE9rison", + type: "Guérison", }; addEvent(evt); - if (limiteRessources(lanceur, options, 'gu\xE9rison', 'gu\xE9rison', evt)) return; + if (limiteRessources(lanceur, options, 'guérison', 'guérison', evt)) return; guerisonPerso(cible, evt, lanceur); if (options.messages) { options.messages.forEach(function(m) { @@ -36130,16 +36263,16 @@ var COFantasy = COFantasy || function() { arme = armesEnMain(perso); if (arme === undefined && labelArmeDefaut) arme = getWeaponStats(perso, labelArmeDefaut); - //L'arme doit \xEAtre une arme de contact ? + //L'arme doit être une arme de contact ? if (armeContact && arme && arme.portee) { - sendPerso(perso, armeContact + " " + arme.name + " est une arme \xE0 distance."); + sendPerso(perso, armeContact + " " + arme.name + " est une arme à distance."); return; } if (arme) { return arme; } arme = { - name: 'Attaque par d\xE9faut', + name: 'Attaque par défaut', attSkillDiv: 0, attSkill: "@{ATKCAC}", crit: 20, @@ -36155,12 +36288,12 @@ var COFantasy = COFantasy || function() { }; options.contact = true; entrerEnCombat(attaquant, [defenseur], explications, evt); - //Recherche des armes utilis\xE9es + //Recherche des armes utilisées let armeAttaquant = armeDeContact(attaquant, options.armeAttaquant, options.labelArmeAttaquant, options.armeAttaquantContact); let armeDefenseur = armeDeContact(defenseur, options.armeDefenseur, options.labelArmeDefenseur, options.armeDefenseurContact); - let action = options.action || "Attaque oppos\xE9e"; + let action = options.action || "Attaque opposée"; if (!armeAttaquant.parDefaut) { action += " (" + armeAttaquant.name + ")"; } @@ -36180,7 +36313,7 @@ var COFantasy = COFantasy || function() { } } else if (getState(attaquant, 'immobilise')) { dice = 12; - explications.push("Attaquant immobilis\xE9 => D12 au lieu de D20 en Attaque"); + explications.push("Attaquant immobilisé => D12 au lieu de D20 en Attaque"); } let toEvaluateAttack = attackExpression(attaquant, 1, dice, critAttaquant, true, armeAttaquant); @@ -36213,20 +36346,20 @@ var COFantasy = COFantasy || function() { }); } addLineToFramedDisplay(display, "Jet de " + nomPerso(attaquant) + " : " + attRollValue); - var critDefenseur = critEnAttaque(defenseur, armeDefenseur, options); + let critDefenseur = critEnAttaque(defenseur, armeDefenseur, options); dice = 20; malusAttaque = 0; if (estAffaibli(defenseur)) { if (predicateAsBool(defenseur, 'insensibleAffaibli')) { malusAttaque = -2; - explications.push("D\xE9fenseur affaibli, mais insensible => -2 en Attaque"); + explications.push("Défenseur affaibli, mais insensible => -2 en Attaque"); } else { dice = 12; - explications.push("D\xE9fenseur affaibli => D12 au lieu de D20 en Attaque"); + explications.push("Défenseur affaibli => D12 au lieu de D20 en Attaque"); } } else if (getState(defenseur, 'immobilise')) { dice = 12; - explications.push("D\xE9fenseur immobilis\xE9 => D12 au lieu de D20 en Attaque"); + explications.push("Défenseur immobilisé => D12 au lieu de D20 en Attaque"); } toEvaluateAttack = attackExpression(defenseur, 1, dice, critDefenseur, true, armeDefenseur); sendChat('', toEvaluateAttack, function(resAttack) { @@ -36256,10 +36389,10 @@ var COFantasy = COFantasy || function() { }); } addLineToFramedDisplay(display, "Jet de " + nomPerso(defenseur) + " : " + attRollValue); - var resultat = { + let resultat = { rollAttaquant: attackRollAttaquant, rollDefenseur: attackRollDefenseur, - armeAttaquant: armeAttaquant + armeAttaquant }; if (d20rollAttaquant == 1 && d20rollDefenseur > 1) { resultat.echec = true; @@ -36284,11 +36417,11 @@ var COFantasy = COFantasy || function() { resultat.succes = true; diminueMalediction(defenseur, evt); } - callback(resultat, display, explications); //evt est mis \xE0 jour - }); //fin du sendchat pour jet du d\xE9fenseur + callback(resultat, display, explications); //evt est mis à jour + }); //fin du sendchat pour jet du défenseur }); //Fin du sendChat pour jet de l'attaquant } catch (rollError) { - error("Erreur pendant le jet " + toEvaluateAttack + " dans attaqueContactOppos\xE9", options); + error("Erreur pendant le jet " + toEvaluateAttack + " dans attaqueContactOpposé", options); } } @@ -36301,15 +36434,15 @@ var COFantasy = COFantasy || function() { const attaquant = persoOfId(cmd[1], cmd[1]); const defenseur = persoOfId(cmd[2], cmd[2]); if (attaquant === undefined) { - error("Le premier argument de !cof-test-attaque-opposee doit \xEAtre un token valide", cmd[1]); + error("Le premier argument de !cof-test-attaque-opposee doit être un token valide", cmd[1]); return; } if (defenseur === undefined) { - error("Le deuxi\xE8me argument de !cof-test-attaque-opposee doit \xEAtre un token valide", cmd[2]); + error("Le deuxième argument de !cof-test-attaque-opposee doit être un token valide", cmd[2]); return; } const evt = { - type: "Test d'attaque oppos\xE9e" + type: "Test d'attaque opposée" }; const options = { pasDeDmg: true @@ -36325,7 +36458,7 @@ var COFantasy = COFantasy || function() { explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addEvent(evt); }); } @@ -36334,7 +36467,7 @@ var COFantasy = COFantasy || function() { function desarmer(msg) { let cmd = msg.content.split(' '); if (cmd.length < 3) { - error("Il manque des arguments \xE0 !cof-desarmer", msg.content); + error("Il manque des arguments à !cof-desarmer", msg.content); return; } const guerrier = persoOfId(cmd[1], cmd[1]); @@ -36344,21 +36477,21 @@ var COFantasy = COFantasy || function() { } const cible = persoOfId(cmd[2], cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-desarmer n'est pas un token valide", cmd); + error("Le deuxième argument de !cof-desarmer n'est pas un token valide", cmd); return; } let pageId = guerrier.token.get('pageid'); if (distanceCombat(guerrier.token, cible.token, pageId)) { - sendPerso(guerrier, "est trop loin de " + nomPerso(cible) + " pour le d\xE9sarmer."); + sendPerso(guerrier, "est trop loin de " + nomPerso(cible) + " pour le désarmer."); return; } var options = { - action: "D\xE9sarmement", - armeContact: "doit porter une arme de contact pour d\xE9sarmer son adversaire.", + action: "Désarmement", + armeContact: "doit porter une arme de contact pour désarmer son adversaire.", pasDeDmg: true, pageId: pageId, }; - //On cherche l'arme de la cible. On en aura besoin pour d\xE9sarmer + //On cherche l'arme de la cible. On en aura besoin pour désarmer let armeCible = armesEnMain(cible); let attrArmeCible = cible.attrArmeEnMain; if (armeCible) { @@ -36366,7 +36499,7 @@ var COFantasy = COFantasy || function() { if (armeCible.deuxMains) { options.bonusAttaqueDefenseur = [{ val: 5, - explication: nomPerso(cible) + " porte une arme \xE0 2 mains => +5 \xE0 son jet" + explication: nomPerso(cible) + " porte une arme à 2 mains => +5 à son jet" }]; } } @@ -36379,7 +36512,7 @@ var COFantasy = COFantasy || function() { } }; const evt = { - type: 'D\xE9sarmer' + type: 'Désarmer' }; if (cmd.length > 3) options.labelArmeAttaquant = cmd[3]; const playerId = getPlayerIdFromMsg(msg); @@ -36387,37 +36520,37 @@ var COFantasy = COFantasy || function() { function(res, display, explications) { let resultat; if (res.echecCritique) { - resultat = "\xE9chec critique"; + resultat = "échec critique"; } else if (res.echecCritiqueDefenseur) { - resultat = "succ\xE8s, " + nomPerso(cible) + " laisse tomber son arme, difficile de la r\xE9cup\xE9rer..."; + resultat = "succès, " + nomPerso(cible) + " laisse tomber son arme, difficile de la récupérer..."; enleverArmeCible(); } else if (res.critique) { - resultat = "r\xE9ussite critique : " + nomPerso(cible) + " est d\xE9sarm\xE9, et " + nomPerso(guerrier) + " emp\xEAche de reprendre l'arme"; + resultat = "réussite critique : " + nomPerso(cible) + " est désarmé, et " + nomPerso(guerrier) + " empêche de reprendre l'arme"; enleverArmeCible(); } else if (res.critiqueDefenseur) { - resultat = "\xE9chec, " + nomPerso(cible) + " garde son arme bien en main"; + resultat = "échec, " + nomPerso(cible) + " garde son arme bien en main"; } else if (res.echec) { - resultat = "\xE9chec, " + nomPerso(guerrier) + " n'a pas r\xE9ussi \xE0 d\xE9sarmer son adversaire"; - } else { //succ\xE8s + resultat = "échec, " + nomPerso(guerrier) + " n'a pas réussi à désarmer son adversaire"; + } else { //succès enleverArmeCible(); if (res.rollAttaquant > res.rollDefenseur + 9) { - resultat = "succ\xE8s, " + nomPerso(guerrier) + " d\xE9sarme son adversaire et l'emp\xEAche de r\xE9cup\xE9rer son arme"; + resultat = "succès, " + nomPerso(guerrier) + " désarme son adversaire et l'empêche de récupérer son arme"; } else { - resultat = "succ\xE8s, " + nomPerso(guerrier) + " d\xE9sarme son adversaire."; + resultat = "succès, " + nomPerso(guerrier) + " désarme son adversaire."; } } addLineToFramedDisplay(display, resultat); explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addEvent(evt); }); } function appliquerBloquer(attaquant, cible, critique, evt, envoyerMessage) { let msg; - if (envoyerMessage) msg = "est bloqu\xE9 par son adversaire"; + if (envoyerMessage) msg = "est bloqué par son adversaire"; setAttrDuree(cible, 'bloqueManoeuvre', 1, evt, msg); if (critique) appliquerTenirADistance(attaquant, cible, false, evt, envoyerMessage); @@ -36425,7 +36558,7 @@ var COFantasy = COFantasy || function() { function appliquerTenirADistance(attaquant, cible, critique, evt, envoyerMessage) { let msg; - if (envoyerMessage) msg = "est tenu \xE0 distance par son adversaire"; + if (envoyerMessage) msg = "est tenu à distance par son adversaire"; setAttrDuree( cible, 'tenuADistanceManoeuvre(' + attaquant.token.id + ')', 1, evt, msg); if (critique) appliquerBloquer(attaquant, cible, false, evt, envoyerMessage); @@ -36437,7 +36570,7 @@ var COFantasy = COFantasy || function() { let duree = 1; if (critique) duree = randomInteger(6); let msg; - if (envoyerMessage) msg = "est aveugl\xE9 par son adversaire"; + if (envoyerMessage) msg = "est aveuglé par son adversaire"; setAttrDuree( cible, 'aveugleManoeuvre', duree, evt, msg); return critique; //Pour les DMs en plus @@ -36461,19 +36594,19 @@ var COFantasy = COFantasy || function() { attrArmeCible.remove(); } if (envoyerMessage) { - let msgDesarme = "est d\xE9sarm\xE9" + onGenre(cible, '', 'e'); + let msgDesarme = "est désarmé" + onGenre(cible, '', 'e'); if (critique) msgDesarme += ", son adversaire lui a pris son arme."; else msgDesarme += "."; sendPerso(cible, msgDesarme); } }, - verbe: 'd\xE9sarmer', + verbe: 'désarmer', duelliste: true }, faireDiversion: { appliquer: function(attaquant, cible, critique, evt, envoyerMessage) { var msg; - if (envoyerMessage) msg = "a son attention attir\xE9e ailleurs"; + if (envoyerMessage) msg = "a son attention attirée ailleurs"; var malus = -5; if (critique) malus = -10; setAttrDuree(cible, 'diversionManoeuvre', 1, evt, msg); @@ -36509,7 +36642,7 @@ var COFantasy = COFantasy || function() { var distance = rollDePlus(6); if (critique && distance < 3) distance = 3; if (envoyerMessage) - sendPerso(cible, "est repouss\xE9" + onGenre(cible, '', 'e') + " et doit reculer de " + distance.roll + "m."); + sendPerso(cible, "est repoussé" + onGenre(cible, '', 'e') + " et doit reculer de " + distance.roll + "m."); if (critique) setState(cible, 'renverse', true, evt); }, penalitePlusPetit: true, @@ -36518,13 +36651,13 @@ var COFantasy = COFantasy || function() { }, tenirADistance: { appliquer: appliquerTenirADistance, - verbe: 'tenir \xE0 distance', + verbe: 'tenir à distance', duelliste: true } }; //!cof-appliquer-manoeuvre id1 id2 effet attrId - //attrId est utilis\xE9 pour limiter le nombre d'utilisations + //attrId est utilisé pour limiter le nombre d'utilisations function appliquerManoeuvre(msg) { var cmd = msg.content.split(' '); if (cmd.length < 5) { @@ -36537,7 +36670,7 @@ var COFantasy = COFantasy || function() { } var limiteAttr = getObj('attribute', cmd[4]); if (limiteAttr === undefined) { - sendPlayer(msg, "La manoeuvre a d\xE9j\xE0 \xE9t\xE9 choisie"); + sendPlayer(msg, "La manoeuvre a déjà été choisie"); return; } var attaquant = persoOfId(cmd[1], cmd[1]); @@ -36547,7 +36680,7 @@ var COFantasy = COFantasy || function() { } var cible = persoOfId(cmd[2], cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-appliquer-manoeuvre n'est pas un token valide", cmd); + error("Le deuxième argument de !cof-appliquer-manoeuvre n'est pas un token valide", cmd); return; } var effet = listeManoeuvres[cmd[3]]; @@ -36582,7 +36715,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-manoeuvre n'est pas un token valide", cmd); + error("Le deuxième argument de !cof-manoeuvre n'est pas un token valide", cmd); return; } const evt = { @@ -36605,7 +36738,7 @@ var COFantasy = COFantasy || function() { function(res, display, explications) { let dmSupp; if (res.succes) { - addLineToFramedDisplay(display, nomPerso(attaquant) + " r\xE9ussit \xE0 " + effet.verbe + " " + nomPerso(cible)); + addLineToFramedDisplay(display, nomPerso(attaquant) + " réussit à " + effet.verbe + " " + nomPerso(cible)); dmSupp = effet.appliquer(attaquant, cible, res.critique, evt); if (manoeuvreDuelliste && !dmSupp) { let pageId = cible.token.get('pageid'); @@ -36613,8 +36746,8 @@ var COFantasy = COFantasy || function() { dmSupp = res.rollAttaquant >= defense + 10; } } else { - addLineToFramedDisplay(display, nomPerso(attaquant) + " ne r\xE9ussit pas \xE0 " + effet.verbe + " " + nomPerso(cible)); - //Envoyer \xE0 la cible la possibilit\xE9 d'appliquer un effet de son choix + addLineToFramedDisplay(display, nomPerso(attaquant) + " ne réussit pas à " + effet.verbe + " " + nomPerso(cible)); + //Envoyer à la cible la possibilité d'appliquer un effet de son choix } explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); @@ -36622,9 +36755,9 @@ var COFantasy = COFantasy || function() { if (dmSupp) { let actionGratuite = "!cof-attack " + attaquant.token.id + " " + cible.token.id + " -1 --auto"; - addLineToFramedDisplay(display, nomPerso(attaquant) + " fait en plus des d\xE9g\xE2ts \xE0 " + nomPerso(cible) + boutonSimple(actionGratuite, "lancer une attaque pour d\xE9terminer le montant"), 80); + addLineToFramedDisplay(display, nomPerso(attaquant) + " fait en plus des dégâts à " + nomPerso(cible) + boutonSimple(actionGratuite, "lancer une attaque pour déterminer le montant"), 80); } - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); addEvent(evt); /*if (dmSupp) { turnAction(attaquant, playerId); @@ -36632,11 +36765,11 @@ var COFantasy = COFantasy || function() { if (!res.succes && !manoeuvreDuelliste) { let charCible = getObj('character', cible.charId); if (charCible === undefined) { - error("Cible sans personnage associ\xE9", cible); + error("Cible sans personnage associé", cible); return; } let titre = "Choisir un effet contre " + nomPerso(attaquant); - //On cr\xE9e un display sans le header + //On crée un display sans le header display = startFramedDisplay(undefined, titre, cible, { retarde: true }); @@ -36651,15 +36784,15 @@ var COFantasy = COFantasy || function() { let ligneManoeuvre = boutonSimple(appliquerManoeuvre, man); addLineToFramedDisplay(display, ligneManoeuvre, 90); } - // on envoie la liste aux joueurs qui g\xE8rent le voleur + // on envoie la liste aux joueurs qui gèrent le voleur let playerIds = getPlayerIds(cible); playerIds.forEach(function(playerid) { addFramedHeader(display, playerid, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); if (playerIds.length === 0) { addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } }); @@ -36673,7 +36806,7 @@ var COFantasy = COFantasy || function() { return; } if (cmd.length < 3) { - error("Il manque des arguments \xE0 !cof-expert-combat-bousculer", msg.content); + error("Il manque des arguments à !cof-expert-combat-bousculer", msg.content); return; } let expert = persoOfId(cmd[1], cmd[1]); @@ -36683,7 +36816,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-expert-combat-bousculer n'est pas un token valide", cmd); + error("Le deuxième argument de !cof-expert-combat-bousculer n'est pas un token valide", cmd); return; } if (!predicateAsBool(expert, 'expertDuCombat')) { @@ -36709,19 +36842,19 @@ var COFantasy = COFantasy || function() { var display = startFramedDisplay(playerId, "Bousculer", expert, { perso2: cible }); - explications.push("D\xE9 d'expertise : " + deExpertise.roll); + explications.push("Dé d'expertise : " + deExpertise.roll); if (resultat === 1) { - addLineToFramedDisplay(display, nomPerso(cible) + " est repouss\xE9 de " + - Math.ceil(deExpertise.val / 2) + " m\xE8tre" + (deExpertise.val > 1 ? "s" : "") + "
    S'il est accul\xE9 : " + + addLineToFramedDisplay(display, nomPerso(cible) + " est repoussé de " + + Math.ceil(deExpertise.val / 2) + " mètre" + (deExpertise.val > 1 ? "s" : "") + "
    S'il est acculé : " + boutonSimple("!cof-dmg " + deExpertise.val + " --target " + cmd[2], "Appliquer " + deExpertise.val + " DM")); setState(cible, "renverse", "true", evt); } else { - addLineToFramedDisplay(display, nomPerso(cible) + " n'est pas renvers\xE9"); + addLineToFramedDisplay(display, nomPerso(cible) + " n'est pas renversé"); } explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); } @@ -36827,7 +36960,7 @@ var COFantasy = COFantasy || function() { dm: 3, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }], abilities: [{ @@ -36878,7 +37011,7 @@ var COFantasy = COFantasy || function() { dm: 5, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }], abilities: [{ @@ -36929,7 +37062,7 @@ var COFantasy = COFantasy || function() { dm: 5, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }, { name: 'predicats_script', @@ -36943,7 +37076,7 @@ var COFantasy = COFantasy || function() { titre: 'Attaque en embuscade', code: '!cof-attack @{selected|token_id} @{target|token_id} 1 --sournoise 1 --if moins FOR --etat renverse --endif' }, { - titre: 'D\xE9vorer', + titre: 'Dévorer', code: '!cof-attack @{selected|token_id} @{target|token_id} 1' }] }, @@ -36985,7 +37118,7 @@ var COFantasy = COFantasy || function() { dm: 7, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }, { name: 'predicats_script', @@ -36999,7 +37132,7 @@ var COFantasy = COFantasy || function() { titre: 'Attaque en embuscade', code: '!cof-attack @{selected|token_id} @{target|token_id} 1 --sournoise 1 --if moins FOR --etat renverse --endif' }, { - titre: 'D\xE9vorer', + titre: 'Dévorer', code: '!cof-attack @{selected|token_id} @{target|token_id} 1' }] }, @@ -37050,7 +37183,7 @@ var COFantasy = COFantasy || function() { }, ] }, tigreDentsDeSabre: { - nom: 'Tigre \xE0 dents de sabre', + nom: 'Tigre à dents de sabre', avatar: "https://s3.amazonaws.com/files.d20.io/images/59486272/f5lUcN3Y9H0thmJPrqa6FQ/max.png?1533041702", token: "https://s3.amazonaws.com/files.d20.io/images/60186469/ShcrgpvgXKiQsLVOyg4SZQ/thumb.png?1533903741", attributesFiche: { @@ -37089,7 +37222,7 @@ var COFantasy = COFantasy || function() { dm: 12, }], attributes: [{ - name: 'discr\xE9tion', + name: 'discrétion', current: 5 }, { name: 'predicats_script', @@ -37103,12 +37236,12 @@ var COFantasy = COFantasy || function() { titre: 'Attaque en embuscade', code: '!cof-attack @{selected|token_id} @{target|token_id} 1 --sournoise 1 --if moins FOR --etat renverse --endif' }, { - titre: 'D\xE9vorer', + titre: 'Dévorer', ccode: '!cof-attack @{selected|token_id} @{target|token_id} 1' }] }, oursPrehistorique: { - nom: 'Ours pr\xE9historique', + nom: 'Ours préhistorique', avatar: "https://s3.amazonaws.com/files.d20.io/images/59486323/V6RVSlBbeRJi_aIaIuGGBw/max.png?1533041814", token: "https://s3.amazonaws.com/files.d20.io/images/60186633/lNHXvCOsvfPMZDQnqJKQVw/thumb.png?1533904189", attributesFiche: { @@ -37133,7 +37266,7 @@ var COFantasy = COFantasy || function() { pnj_init: 10, RDS: 2, race: 'ours', - taille: '\xE9norme' + taille: 'énorme' }, pv: 110, attaques: [{ @@ -37172,11 +37305,11 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - error("pas de lanceur pour la conjuration de pr\xE9dateurs", msg); + error("pas de lanceur pour la conjuration de prédateurs", msg); return; } let evt = { - type: 'conjuration de pr\xE9dateurs' + type: 'conjuration de prédateurs' }; let combat = initiative(selected, evt); let abort; @@ -37184,12 +37317,12 @@ var COFantasy = COFantasy || function() { if (abort) return; if (options.tempeteDeMana) { if (selected.length > 1) { - sendPlayerAndGM(msg, playerId, "Il faut s\xE9lectionner un seul token pour les options de temp\xEAte de mana"); + sendPlayerAndGM(msg, playerId, "Il faut sélectionner un seul token pour les options de tempête de mana"); abort = true; return; } if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, portee: false, @@ -37203,11 +37336,11 @@ var COFantasy = COFantasy || function() { return; } else { if (options.tempeteDeMana.cout > 1) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } - if (limiteRessources(invocateur, options, 'invocationPredateur', 'lancer une invocation de pr\xE9dateur', evt)) return; + if (limiteRessources(invocateur, options, 'invocationPredateur', 'lancer une invocation de prédateur', evt)) return; let pageId = invocateur.token.get('pageid'); let niveau = ficheAttributeAsInt(invocateur, 'niveau', 1); if (!renforce) { @@ -37259,13 +37392,13 @@ var COFantasy = COFantasy || function() { toFront(token); let charPredateur = createCharacter(nomPredateur, playerId, predateur.avatar, token, predateur, evt); - //Tous les pr\xE9dateurs sont des quadrup\xE8des + //Tous les prédateurs sont des quadrupèdes let persoPredateur = { token: token, charId: charPredateur.id }; setPredicate(persoPredateur, 'quadrupede', evt); - //Attribut de predateur conjur\xE9 pour la disparition automatique + //Attribut de predateur conjuré pour la disparition automatique let attr = createObj('attribute', { name: 'predateurConjure', _characterid: charPredateur.id, @@ -37287,7 +37420,7 @@ var COFantasy = COFantasy || function() { initiative([{ _id: token.id }], evt); - // Ajout du Pr\xE9dateur aux alli\xE9s de l'invocateur + // Ajout du Prédateur aux alliés de l'invocateur let alliesInvocateur = alliesParPerso[invocateur.charId] || new Set(); alliesInvocateur.add(charPredateur.id); alliesParPerso[invocateur.charId] = alliesInvocateur; @@ -37311,11 +37444,11 @@ var COFantasy = COFantasy || function() { return; } let evt = { - type: "invocation d'une sph\xE8re de feu", + type: "invocation d'une sphère de feu", }; let combat = initiative(selected, evt); iterSelected(selected, function(invocateur) { - if (limiteRessources(invocateur, options, 'sphereDeFeu', 'lancer un sort de sph\xE8re de feu', evt)) return; + if (limiteRessources(invocateur, options, 'sphereDeFeu', 'lancer un sort de sphère de feu', evt)) return; let character = getObj('character', invocateur.charId); if (character === undefined) { error("Impossible de trouver le personnage de " + nomPerso(invocateur), invocateur); @@ -37324,7 +37457,7 @@ var COFantasy = COFantasy || function() { let pageId = invocateur.token.get('pageid'); let niveau = ficheAttributeAsInt(invocateur, 'niveau', 1); let sphere = { - nom: 'Sph\xE8re de feu', + nom: 'Sphère de feu', avatar: "https://s3.amazonaws.com/files.d20.io/images/260057530/nL8O6US3f1BpeTJkodWNCg/max.png?16394116785", token: "https://s3.amazonaws.com/files.d20.io/images/260057530/nL8O6US3f1BpeTJkodWNCg/thumb.png?16394116785", attributesFiche: { @@ -37333,7 +37466,7 @@ var COFantasy = COFantasy || function() { }, pv: 1, attaques: [{ - nom: 'Br\xFBlure', + nom: 'Brûlure', atk: 0, dmnbde: 3, dmde: 6, @@ -37346,7 +37479,7 @@ var COFantasy = COFantasy || function() { name: 'predicats_script', current: 'nonVivant immunite_feu sansEsprit initiativeDeriveeDe::' + character.get('name') + '\n', }, { - name: 'predateurConjure', //Pas exactement \xE7a, mais \xE7a fait ce qu'il faut + name: 'predateurConjure', //Pas exactement ça, mais ça fait ce qu'il faut current: niveau, max: combat.init, lie: options.mana !== undefined @@ -37371,7 +37504,7 @@ var COFantasy = COFantasy || function() { has_limit_field_of_vision: true, }); if (token === undefined) { - error("Impossible de cr\xE9er le token de la sph\xE8re de feu ", sphere); + error("Impossible de créer le token de la sphère de feu ", sphere); return; } toFront(token); @@ -37382,7 +37515,7 @@ var COFantasy = COFantasy || function() { initiative([{ _id: token.id }], evt); - // Ajout du Pr\xE9dateur aux alli\xE9s de l'invocateur + // Ajout du Prédateur aux alliés de l'invocateur let alliesInvocateur = alliesParPerso[invocateur.charId] || new Set(); alliesInvocateur.add(charSphere.id); alliesParPerso[invocateur.charId] = alliesInvocateur; @@ -37391,18 +37524,18 @@ var COFantasy = COFantasy || function() { }); //end getSelected } - //!cof-conjuration-armee [d\xE9 de DM] --limiteParJour... + //!cof-conjuration-armee [dé de DM] --limiteParJour... function conjurationArmee(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Il faut s\xE9lectionner le lanceur de la conjuration d'arm\xE9\xE9", playerId); + sendPlayer(msg, "Il faut sélectionner le lanceur de la conjuration d'arméé", playerId); return; } let abort; @@ -37410,12 +37543,12 @@ var COFantasy = COFantasy || function() { if (abort) return; if (options.tempeteDeMana) { if (selected.length > 1) { - sendPlayerAndGM(msg, playerId, "Il faut s\xE9lectionner un seul token pour les options de temp\xEAte de mana"); + sendPlayerAndGM(msg, playerId, "Il faut sélectionner un seul token pour les options de tempête de mana"); abort = true; return; } if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, portee: false, @@ -37429,16 +37562,16 @@ var COFantasy = COFantasy || function() { return; } else { if (options.tempeteDeMana.cout > 1) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } let pageId = invocateur.token.get('pageid'); let niveau = ficheAttributeAsInt(invocateur, 'niveau', 1); const evt = { - type: "Conjuration d'arm\xE9e" + type: "Conjuration d'armée" }; - if (limiteRessources(invocateur, options, 'conjurationArmee', "conjurer une arm\xE9e", evt)) { + if (limiteRessources(invocateur, options, 'conjurationArmee', "conjurer une armée", evt)) { addEvent(evt); return; } @@ -37459,7 +37592,7 @@ var COFantasy = COFantasy || function() { dm.nbDe = 2; } } - let nomArmee = "Arm\xE9e de " + nomPerso(invocateur); + let nomArmee = "Armée de " + nomPerso(invocateur); let token = createObj('graphic', { name: nomArmee, subtype: 'token', @@ -37519,13 +37652,13 @@ var COFantasy = COFantasy || function() { } //!cof-tenebres token-lanceur token-cible - // possibilit\xE9 de --brumes pour un effet de brumes + // possibilité de --brumes pour un effet de brumes function tenebres(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("!cof-tenebres mal form\xE9, il faut un token comme premier argument", msg.content); + error("!cof-tenebres mal formé, il faut un token comme premier argument", msg.content); return; } let necromant = persoOfId(cmd[1], cmd[1], options.pageId); @@ -37542,7 +37675,7 @@ var COFantasy = COFantasy || function() { const playerId = getPlayerIdFromMsg(msg); if (options.tempeteDeMana) { if (options.tempeteDeMana.cout === 0) { - //On demande de pr\xE9ciser les options + //On demande de préciser les options let optMana = { mana: options.mana, portee: true, @@ -37554,7 +37687,7 @@ var COFantasy = COFantasy || function() { return; } else { if (options.tempeteDeMana.cout > 1) { - sendPlayerAndGM(msg, playerId, "Attention, le co\xFBt de la temp\xEAte de mana (" + options.tempeteDeMana.cout + ") est sup\xE9rieur au rang du sort"); + sendPlayerAndGM(msg, playerId, "Attention, le coût de la tempête de mana (" + options.tempeteDeMana.cout + ") est supérieur au rang du sort"); } } } @@ -37570,7 +37703,7 @@ var COFantasy = COFantasy || function() { if (distanceCombat(necromant.token, target.token, options.pageId, { strict2: true }) > portee) { - sendPlayer(msg, "Le point vis\xE9 est trop loin (port\xE9e " + portee + ")", playerId); + sendPlayer(msg, "Le point visé est trop loin (portée " + portee + ")", playerId); return; } let duree = 5; @@ -37586,7 +37719,7 @@ var COFantasy = COFantasy || function() { if (options.brumes) { if (limiteRessources(necromant, options, 'brumes', 'lancer un sort de brumes', evt)) return; } else { - if (limiteRessources(necromant, options, 'tenebres', 'lancer un sort de t\xE9n\xE8bres', evt)) return; + if (limiteRessources(necromant, options, 'tenebres', 'lancer un sort de ténèbres', evt)) return; } if (!stateCOF.combat) { initPerso(necromant, evt); @@ -37606,7 +37739,7 @@ var COFantasy = COFantasy || function() { tokSpec.height = rayonUnite * PIX_PER_UNIT; tokSpec.layer = 'map'; } else { - tokSpec.name = "T\xE9n\xE8bres de " + nomPerso(necromant); + tokSpec.name = "Ténèbres de " + nomPerso(necromant); tokSpec.imgsrc = 'https://s3.amazonaws.com/files.d20.io/images/192072874/eJXFx20fD931DuBDvzAnQQ/thumb.png?1610469273'; tokSpec.width = 70; tokSpec.height = 70; @@ -37626,9 +37759,9 @@ var COFantasy = COFantasy || function() { if (options.brumes) sendPerso(necromant, "lance un sort de brumes pour " + duree + " tours"); else - sendPerso(necromant, "lance un sort de t\xE9n\xE8bres pour " + duree + " tours"); + sendPerso(necromant, "lance un sort de ténèbres pour " + duree + " tours"); } - // Calcul des cibles \xE0 aveugler + // Calcul des cibles à aveugler let cibles = []; let allToksDisque = findObjs({ @@ -37678,8 +37811,8 @@ var COFantasy = COFantasy || function() { if (options.brumes) effetTenebres.effet = 'brumes'; setEffetTemporaire(necromant, effetTenebres, duree, evt, options); if (target.token.get('bar1_max') == 0) { // jshint ignore:line - //C'est juste un token utilis\xE9 pour d\xE9finir le disque - target.token.remove(); //On l'enl\xE8ve, normalement plus besoin + //C'est juste un token utilisé pour définir le disque + target.token.remove(); //On l'enlève, normalement plus besoin } if (options.messages) { options.messages.forEach(function(m) { @@ -37689,7 +37822,7 @@ var COFantasy = COFantasy || function() { } const demonInvoque = { - nom: 'D\xE9mon', + nom: 'Démon', avatar: "https://s3.amazonaws.com/files.d20.io/images/183633585/DWpHYp4SLPCDCMHdmTyKOw/thumb.png?1607339938", token: "https://s3.amazonaws.com/files.d20.io/images/183633585/DWpHYp4SLPCDCMHdmTyKOw/thumb.png?1607339938", attributesFiche: { @@ -37714,7 +37847,7 @@ var COFantasy = COFantasy || function() { DEFDIV: 3, pnj_def: 17, pnj_init: 16, - race: 'd\xE9mon', + race: 'démon', taille: 'moyen' }, attaques: [{ @@ -37726,7 +37859,7 @@ var COFantasy = COFantasy || function() { }], attributes: [{ name: 'predicats_script', - current: 'd\xE9mon' + current: 'démon' }], abilities: [] }; @@ -37736,7 +37869,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("!cof-invoquer-demon mal form\xE9, il faut un token comme premier argument", msg.content); + error("!cof-invoquer-demon mal formé, il faut un token comme premier argument", msg.content); return; } let necromant = persoOfId(cmd[1], cmd[1], options.pageId); @@ -37753,7 +37886,7 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - if (limiteRessources(necromant, options, 'invoquerDemon', 'lance une invocation de d\xE9mon', evt)) return; + if (limiteRessources(necromant, options, 'invoquerDemon', 'lance une invocation de démon', evt)) return; let d6 = rollDePlus(6); evt.action.rolls.invocationDemonDmg = d6; let r = { @@ -37768,7 +37901,7 @@ var COFantasy = COFantasy || function() { if (!stateCOF.combat) { initPerso(necromant, evt); } - let tokenDemon = "D\xE9mon de " + nomPerso(necromant); + let tokenDemon = "Démon de " + nomPerso(necromant); let token = createObj('graphic', { name: tokenDemon, showname: 'true', @@ -37796,7 +37929,7 @@ var COFantasy = COFantasy || function() { evt.characters = [charDemon]; evt.tokens = [token]; let duree = 5 + modCarac(necromant, 'intelligence'); - //Attribut de d\xE9mon invoqu\xE9 pour la disparition automatique + //Attribut de démon invoqué pour la disparition automatique createObj('attribute', { name: 'demonInvoque', _characterid: charDemon.id, @@ -37811,13 +37944,13 @@ var COFantasy = COFantasy || function() { initiative([{ _id: token.id }], evt); - // Ajout du D\xE9mon aux alli\xE9s du N\xE9cromant + // Ajout du Démon aux alliés du Nécromant var alliesNecromant = alliesParPerso[necromant.charId] || new Set(); alliesNecromant.add(charDemon.id); alliesParPerso[necromant.charId] = alliesNecromant; - var msg = "invoque un d\xE9mon"; + var msg = "invoque un démon"; if (stateCOF.options.affichage.val.duree_effets.val) msg += " pour " + duree + " tours"; - msg += " mais cela lui co\xFBte " + dmgDisplay + " PV"; + msg += " mais cela lui coûte " + dmgDisplay + " PV"; sendPerso(necromant, msg); }); }, options); @@ -37864,7 +37997,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined || cmd.length < 2) { - error("!cof-animer-mort mal form\xE9, il faut un token comme premier argument", msg.content); + error("!cof-animer-mort mal formé, il faut un token comme premier argument", msg.content); return; } const necromant = persoOfId(cmd[1], cmd[1], options.pageId); @@ -37875,7 +38008,7 @@ var COFantasy = COFantasy || function() { let zombiesControles = attributeAsInt(necromant, 'zombiesControles', 0); let rangVoie = predicateAsInt(necromant, 'voieOutreTombe', 1); if (zombiesControles >= rangVoie) { - sendPerso(necromant, "ne peut plus animer de Zombie car il en contr\xF4le d\xE9j\xE0 assez."); + sendPerso(necromant, "ne peut plus animer de Zombie car il en contrôle déjà assez."); return; } options.lanceur = necromant; @@ -37919,7 +38052,7 @@ var COFantasy = COFantasy || function() { let charZombie = createCharacter(nomToken, playerId, zombieAnime.avatar, token, zombie, evt); evt.characters.push(charZombie); evt.tokens.push(token); - // D\xE9gradation du Zombie + // Dégradation du Zombie createObj('attribute', { name: 'degradationZombie', _characterid: charZombie.id, @@ -37935,7 +38068,7 @@ var COFantasy = COFantasy || function() { initiative([{ _id: token.id }], evt); - // Ajout du Zombie aux alli\xE9s du N\xE9cromant + // Ajout du Zombie aux alliés du Nécromant let alliesNecromant = alliesParPerso[necromant.charId] || new Set(); alliesNecromant.add(charZombie.id); alliesParPerso[necromant.charId] = alliesNecromant; @@ -37953,7 +38086,7 @@ var COFantasy = COFantasy || function() { const MONTER = String.fromCharCode(0x2197); const DESCENDRE = String.fromCharCode(0x2198); - //Cr\xE9e les macros utiles au jeu + //Crée les macros utiles au jeu const gameMacros = [{ name: 'Actions', action: "!cof-liste-actions", @@ -38031,7 +38164,7 @@ var COFantasy = COFantasy || function() { istokenaction: true }, { name: 'Surprise', - action: "!cof-surprise ?{difficult\xE9}", + action: "!cof-surprise ?{difficulté}", visibleto: '', istokenaction: false, inBar: true @@ -38041,20 +38174,20 @@ var COFantasy = COFantasy || function() { visibleto: 'all', istokenaction: true, }, { - name: '\xC9teindre', - action: "!cof-eteindre-lumiere ?{Quelle lumi\xE8re?|Tout}", + name: 'Éteindre', + action: "!cof-eteindre-lumiere ?{Quelle lumière?|Tout}", visibleto: '', istokenaction: false, inBar: true }, { name: 'devient', - action: "!cof-set-state ?{\xC9tat|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blesse|encombre} true", + action: "!cof-set-state ?{État|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blesse|encombre} true", visibleto: '', istokenaction: false, inBar: true }, { - name: 'enl\xE8ve', - action: "!cof-set-state ?{\xC9tat|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blesse|encombre} false", + name: 'enlève', + action: "!cof-set-state ?{État|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blesse|encombre} false", visibleto: '', istokenaction: false, inBar: true @@ -38092,20 +38225,20 @@ var COFantasy = COFantasy || function() { if (prev === undefined) { m.playerid = playerId; createObj('macro', m); - sendPlayer(msg, "Macro " + m.name + " cr\xE9\xE9e."); + sendPlayer(msg, "Macro " + m.name + " créée."); if (m.inBar) inBar.push(m.name); } else if (force) { prev.set('action', m.action); prev.set('visibleto', m.visibleto); prev.set('istokenaction', m.istokenaction); - sendPlayer(msg, "Macro " + m.name + " r\xE9\xE9crite."); + sendPlayer(msg, "Macro " + m.name + " réécrite."); if (m.inBar) inBar.push(m.name); } else { - sendPlayer(msg, "Macro " + m.name + " d\xE9j\xE0 pr\xE9sente (utiliser --force pour r\xE9\xE9crire)."); + sendPlayer(msg, "Macro " + m.name + " déjà présente (utiliser --force pour réécrire)."); } }); if (inBar.length > 0) { - sendPlayer(msg, "Macros \xE0 mettre dans la barre d'action du MJ : " + inBar.join(', ')); + sendPlayer(msg, "Macros à mettre dans la barre d'action du MJ : " + inBar.join(', ')); } stateCOF.gameMacros = gameMacros; } @@ -38115,24 +38248,24 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd === undefined || cmd.length < 3) { - error("Il faut au moins 2 arguments \xE0 !cof-lumiere", cmd); + error("Il faut au moins 2 arguments à !cof-lumiere", cmd); return; } const cible = persoOfId(cmd[1]); if (cible === undefined) { - error("le premier argument de !cof-lumi\xE8re doit \xEAtre un token", cmd); + error("le premier argument de !cof-lumière doit être un token", cmd); return; } const radius = parseInt(cmd[2]); if (isNaN(radius) || radius <= 0) { - error("La distance de vue de la lumi\xE8re doit \xEAtre positive", cmd[2]); + error("La distance de vue de la lumière doit être positive", cmd[2]); return; } let dimRadius = ''; if (cmd.length > 3) { dimRadius = parseInt(cmd[3]); if (isNaN(dimRadius)) { - error("La distance de vue de la lumi\xE8re assombrie doit \xEAtre un nombre", cmd[3]); + error("La distance de vue de la lumière assombrie doit être un nombre", cmd[3]); dimRadius = ''; } } @@ -38145,7 +38278,7 @@ var COFantasy = COFantasy || function() { type: 'lumiere', }; addEvent(evt); - if (limiteRessources(options.lanceur, options, 'lumi\xE8re', "lumi\xE8re", evt)) return; + if (limiteRessources(options.lanceur, options, 'lumière', "lumière", evt)) return; ajouteUneLumiere(cible, nomToken, radius, dimRadius, evt); } @@ -38159,7 +38292,7 @@ var COFantasy = COFantasy || function() { } let lumId = al.get('max'); if (lumId == 'surToken') { - //Il faut enlever la lumi\xE8re sur tous les tokens + //Il faut enlever la lumière sur tous les tokens let allTokens = [perso.token]; if (perso.token.get('bar1_value') !== '') { allTokens = findObjs({ @@ -38187,7 +38320,7 @@ var COFantasy = COFantasy || function() { name: lumName }); if (tokensLumiere.length === 0) { - log("Pas de token pour la lumi\xE8re " + lumName); + log("Pas de token pour la lumière " + lumName); al.remove(); return; } @@ -38219,7 +38352,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lectionn\xE9e pour !cof-eteindre-lumiere", playerId); + sendPlayer(msg, "Pas de cible sélectionnée pour !cof-eteindre-lumiere", playerId); return; } const cmd = options.cmd; @@ -38228,7 +38361,7 @@ var COFantasy = COFantasy || function() { if (groupe && groupe.toLowerCase() == 'tout') groupe = ''; let pageId = options.pageId; const evt = { - type: "Eteindre la lumi\xE8re" + type: "Eteindre la lumière" }; iterSelected(selected, function(perso) { pageId = pageId || perso.token.get('pageid'); @@ -38247,7 +38380,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd.length < 2) { - error("Il faut pr\xE9ciser le token en argument de !cof-torche"); + error("Il faut préciser le token en argument de !cof-torche"); return; } let pageId = options.pageId; @@ -38259,15 +38392,15 @@ var COFantasy = COFantasy || function() { pageId = pageId || perso.token.get('pageid'); var diminueDuree = 0; if (cmd.length > 2) { - //Dans ce cas, c'est pour diminuer la dur\xE9e de vie de la torche + //Dans ce cas, c'est pour diminuer la durée de vie de la torche diminueDuree = parseInt(cmd[2]); if (isNaN(diminueDuree) || diminueDuree <= 0) { - sendPlayer(msg, "Le deuxi\xE8me argument de !cof-torche doit \xEAtre un nombre strictement positif " + msg.content); + sendPlayer(msg, "Le deuxième argument de !cof-torche doit être un nombre strictement positif " + msg.content); return; } } var evt; - //On commence par chercher si une torche est allum\xE9e + //On commence par chercher si une torche est allumée var torcheAllumee = false; var attrLumiere = tokenAttribute(perso, 'lumiere').filter(function(a) { return a.get('current').startsWith('torche'); @@ -38275,7 +38408,7 @@ var COFantasy = COFantasy || function() { if (!diminueDuree && attrLumiere.length > 0) { torcheAllumee = true; evt = { - type: "\xC9teindre les torches" + type: "Éteindre les torches" }; attrLumiere.forEach(function(al) { let lumName = al.get('current'); @@ -38303,8 +38436,8 @@ var COFantasy = COFantasy || function() { return; } if (tempsTorche === 0) { - if (nbTorches === 0) { //Donc forc\xE9ment torcheAllumee - //On remet l'attribut dans un \xE9tat convenable + if (nbTorches === 0) { //Donc forcément torcheAllumee + //On remet l'attribut dans un état convenable setTokenAttr(perso, 'torches', 0, evt, { maxVal: 60 }); @@ -38324,7 +38457,7 @@ var COFantasy = COFantasy || function() { nbTorches--; temps += tempsTorche; tempsTorche = 60; - var msgDiminue = "torche \xE9puis\xE9e."; + var msgDiminue = "torche épuisée."; if (nbTorches === 0) { msgDiminue += " Plus de torche !"; } else if (nbTorches == 1) { @@ -38337,23 +38470,23 @@ var COFantasy = COFantasy || function() { setTokenAttr(perso, 'torches', nbTorches, evt, { maxVal: tempsTorche }); - sendChar(perso.charId, '/w gm temps de torche diminu\xE9 de ' + temps + ' minutes'); + sendChar(perso.charId, '/w gm temps de torche diminué de ' + temps + ' minutes'); addEvent(evt); return; } if (torcheAllumee) { - var msgTorche = "/w gm torche \xE9teinte. "; + var msgTorche = "/w gm torche éteinte. "; if (nbTorches > 1) { msgTorche += "Reste " + (nbTorches - 1) + " torche"; if (nbTorches > 2) msgTorche += "s neuves"; else msgTorche += " neuve"; - msgTorche += ", et une torche pouvant encore \xE9clairer " + tempsTorche + " minutes."; + msgTorche += ", et une torche pouvant encore éclairer " + tempsTorche + " minutes."; } else { - msgTorche += "Elle peut encore \xE9clairer " + tempsTorche + " minutes."; + msgTorche += "Elle peut encore éclairer " + tempsTorche + " minutes."; } sendChar(perso.charId, msgTorche + - boutonSimple("!cof-torche " + perso.token.id + " ?{Dur\xE9e?}", "Temps depuis allumage")); + boutonSimple("!cof-torche " + perso.token.id + " ?{Durée?}", "Temps depuis allumage")); addEvent(evt); return; } @@ -38362,7 +38495,7 @@ var COFantasy = COFantasy || function() { }; ajouteUneLumiere(perso, 'torche', 13, 7, evt); var msgAllume = - "allume une torche, qui peut encore \xE9clairer pendant " + tempsTorche + + "allume une torche, qui peut encore éclairer pendant " + tempsTorche + " minute"; if (tempsTorche > 1) msgAllume += 's'; msgAllume += '.'; @@ -38375,9 +38508,9 @@ var COFantasy = COFantasy || function() { addEvent(evt); return; } - //On ne tient pas le compte pr\xE9cis des torches + //On ne tient pas le compte précis des torches if (torcheAllumee) { - whisperChar(perso.charId, "\xE9teint sa torche"); + whisperChar(perso.charId, "éteint sa torche"); } else { evt = { type: "Allumer une torche" @@ -38389,9 +38522,9 @@ var COFantasy = COFantasy || function() { } //!cof-options - //!cof-options opt1 [... optn] val, met l'option \xE0 val - //!cof-options [opt0 ... optk] reset remet toutes les options \xE0 leur valeur patr d\xE9faut - //Dans tous les cas, affiche les options du niveau demand\xE9 + //!cof-options opt1 [... optn] val, met l'option à val + //!cof-options [opt0 ... optk] reset remet toutes les options à leur valeur patr défaut + //Dans tous les cas, affiche les options du niveau demandé function setCofOptions(msg) { const playerId = getPlayerIdFromMsg(msg); if (!playerIsGM(playerId)) { @@ -38414,7 +38547,7 @@ var COFantasy = COFantasy || function() { cmd.shift(); cmd.forEach(function(c) { if (fini) { - sendPlayer(msg, "Option " + c + " ignor\xE9e", playerId); + sendPlayer(msg, "Option " + c + " ignorée", playerId); return; } if (c == 'reset') { @@ -38424,7 +38557,7 @@ var COFantasy = COFantasy || function() { } else if (cofOptions[c]) { if (cofOptions[c].type == 'options') { if (defOpt[c] === undefined) { - sendPlayer(msg, "Option " + c + " inconnue dans les options par d\xE9faut", playerId); + sendPlayer(msg, "Option " + c + " inconnue dans les options par défaut", playerId); fini = true; return; } @@ -38436,7 +38569,7 @@ var COFantasy = COFantasy || function() { newOption = cofOptions[c]; } } else { - if (newOption) { //on met newOption \xE0 c + if (newOption) { //on met newOption à c let val = c; switch (newOption.type) { case 'bool': @@ -38452,7 +38585,7 @@ var COFantasy = COFantasy || function() { val = false; break; default: - sendPlayer(msg, "L'option " + lastCmd + " ne peut \xEAtre que true ou false", playerId); + sendPlayer(msg, "L'option " + lastCmd + " ne peut être que true ou false", playerId); val = newOption.val; } fini = true; @@ -38460,7 +38593,7 @@ var COFantasy = COFantasy || function() { case 'int': val = parseInt(c); if (isNaN(val)) { - sendPlayer(msg, "L'option " + lastCmd + " est une valeur enti\xE8re", playerId); + sendPlayer(msg, "L'option " + lastCmd + " est une valeur entière", playerId); val = newOption.val; } fini = true; @@ -38501,7 +38634,7 @@ var COFantasy = COFantasy || function() { case 'bool': action += ' ?{Nouvelle valeur de ' + optVu + '|actif,true|inactif,false}'; if (displayedVal) - // Bizarrement, le caract\xE8re '*' modifie la suite du tableau + // Bizarrement, le caractère '*' modifie la suite du tableau displayedVal = '3'; else displayedVal = '*'; @@ -38531,8 +38664,8 @@ var COFantasy = COFantasy || function() { line += boutonSimple(action, displayedVal) + after; addLineToFramedDisplay(display, line); } - addLineToFramedDisplay(display, boutonSimple('!cof-options' + prefix + ' reset', 'Valeurs par d\xE9faut'), 70); - sendChat('', endFramedDisplay(display)); + addLineToFramedDisplay(display, boutonSimple('!cof-options' + prefix + ' reset', 'Valeurs par défaut'), 70); + sendFramedDisplay(display); } function lancerDefiSamourai(msg) { @@ -38547,20 +38680,20 @@ var COFantasy = COFantasy || function() { let pageId = options.pageId; let samourai = persoOfId(cmd[1], cmd[1], pageId); if (samourai === undefined) { - error("Le token s\xE9lectionn\xE9 n'est pas valide", msg.content); + error("Le token sélectionné n'est pas valide", msg.content); return; } if (attributeAsBool(samourai, 'defiSamourai')) { - sendPlayer(msg, nomPerso(samourai) + " a d\xE9j\xE0 lanc\xE9 un d\xE9fi durant ce combat."); + sendPlayer(msg, nomPerso(samourai) + " a déjà lancé un défi durant ce combat."); return; } let cible = persoOfId(cmd[2], cmd[2], pageId); if (cible === undefined) { - error("Le deuxi\xE8me token s\xE9lectionn\xE9 n'est pas valide", msg.content); + error("Le deuxième token sélectionné n'est pas valide", msg.content); return; } const evt = { - type: 'D\xE9fi samoura\xEF' + type: 'Défi samouraï' }; let explications = []; entrerEnCombat(samourai, [cible], explications, evt); @@ -38571,14 +38704,14 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3) { bonus = parseInt(cmd[3]); if (isNaN(bonus) || bonus < 1) { - error("Bonus de d\xE9fi de samoura\xEF incorrect", cmd[3]); + error("Bonus de défi de samouraï incorrect", cmd[3]); bonus = undefined; } } if (bonus === undefined) bonus = predicateAsInt(samourai, 'voieDeLHonneur', 2); setTokenAttr(samourai, 'defiSamourai', bonus, evt, { - msg: nomPerso(samourai) + " lance un d\xE9fi \xE0 " + nomPerso(cible), + msg: nomPerso(samourai) + " lance un défi à " + nomPerso(cible), maxVal: idName(cible) }); } @@ -38588,16 +38721,16 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; const cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 6) { - error("Il manque des arguments \xE0 !cof-enveloppement", cmd); + error("Il manque des arguments à !cof-enveloppement", cmd); return; } let cube = persoOfId(cmd[1]); if (cube === undefined) { - error("Token non d\xE9fini", cmd[1]); + error("Token non défini", cmd[1]); return; } if (!peutController(msg, cube)) { @@ -38606,12 +38739,12 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2]); if (cible === undefined) { - error("Token non d\xE9fini", cmd[2]); + error("Token non défini", cmd[2]); return; } let difficulte = parseInt(cmd[3]); if (isNaN(difficulte)) { - error("Difficult\xE9 n'est pas un nombre, on prend 15 par d\xE9faut", cmd[3]); + error("Difficulté n'est pas un nombre, on prend 15 par défaut", cmd[3]); difficulte = 15; } let exprDM; @@ -38623,18 +38756,18 @@ var COFantasy = COFantasy || function() { exprDM = cmd[4] + ' ' + cmd[5]; break; case 'etreinte': - type = '\xE9treinte'; + type = 'étreinte'; exprDM = cmd[4] + ' ' + cmd[5]; break; default: - error("Impossible de d\xE9terminer les d\xE9g\xE2ts quand envelopp\xE9", cmd[4]); + error("Impossible de déterminer les dégâts quand enveloppé", cmd[4]); return; } doEnveloppement(cube, cible, difficulte, type, exprDM, options); } //!cof-enveloppement cubeId targetId Difficulte Attaque - //Attaque peut \xEAtre soit label l, soit ability a, soit etreinte expr + //Attaque peut être soit label l, soit ability a, soit etreinte expr function doEnveloppement(attaquant, cible, difficulte, type, exprDM, options) { const evt = { type: type, @@ -38649,9 +38782,9 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - //Choix de la caract\xE9ristique pour r\xE9sister : FOR ou DEX + //Choix de la caractéristique pour résister : FOR ou DEX let caracRes = meilleureCarac('FOR', 'DEX', cible, 10 + modCarac(attaquant, 'force')); - let titre = (type == '\xE9treinte') ? '\xC9treinte' : 'Enveloppement'; + let titre = (type == 'étreinte') ? 'Étreinte' : 'Enveloppement'; let display = startFramedDisplay(options.playerId, titre, attaquant, { perso2: cible }); @@ -38660,14 +38793,14 @@ var COFantasy = COFantasy || function() { testOppose(rollId, attaquant, 'FOR', options, cible, caracRes, options, explications, evt, function(res, crit, rt1, rt2) { - let act = " a absorb\xE9 "; + let act = " a absorbé "; switch (res) { case 1: - if (type == '\xE9treinte') act = " s'est enroul\xE9 autour de "; + if (type == 'étreinte') act = " s'est enroulé autour de "; explications.push(nomPerso(attaquant) + act + nomPerso(cible)); let attaquantId = idName(attaquant); let maxval = difficulte; - if (type == '\xE9treinte') maxval = 'etreinte ' + difficulte; + if (type == 'étreinte') maxval = 'etreinte ' + difficulte; setTokenAttr(cible, 'enveloppePar', attaquantId, evt, { maxVal: maxval }); @@ -38677,28 +38810,28 @@ var COFantasy = COFantasy || function() { setTokenAttr(attaquant, 'enveloppe', cibleId, evt, { maxVal: exprDM }); - if (type == '\xE9treinte') setState(cible, 'immobilise', true, evt); + if (type == 'étreinte') setState(cible, 'immobilise', true, evt); break; case 2: if (caracRes == 'FOR') { - if (type == '\xE9treinte') act = '\xE9treindre'; + if (type == 'étreinte') act = 'étreindre'; else act = 'absorber'; - explications.push(nomPerso(cible) + " r\xE9siste et ne se laisse pas " + act); + explications.push(nomPerso(cible) + " résiste et ne se laisse pas " + act); } else { - if (type == '\xE9treinte') act = "l'\xE9treinte"; + if (type == 'étreinte') act = "l'étreinte"; else act = "l'absorption"; - explications.push(nomPerso(cible) + " \xE9vite " + act); + explications.push(nomPerso(cible) + " évite " + act); } break; default: //match null, la cible s'en sort - if (type == '\xE9treinte') act = "l'\xE9treinte"; + if (type == 'étreinte') act = "l'étreinte"; else act = "l'enveloppement"; - explications.push(nomPerso(cible) + " \xE9chappe de justesse \xE0 " + act); + explications.push(nomPerso(cible) + " échappe de justesse à " + act); } explications.forEach(function(e) { addLineToFramedDisplay(display, e); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); }); } @@ -38710,8 +38843,8 @@ var COFantasy = COFantasy || function() { options.cmd && options.cmd.length > 1 && options.cmd[1] == 'libere'; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "!cof-echapper-enveloppement sans s\xE9lection de token", playerId); - log("!cof-echapper-enveloppement requiert de s\xE9lectionner des tokens"); + sendPlayer(msg, "!cof-echapper-enveloppement sans sélection de token", playerId); + log("!cof-echapper-enveloppement requiert de sélectionner des tokens"); return; } iterSelected(selected, function(perso) { @@ -38723,7 +38856,7 @@ var COFantasy = COFantasy || function() { attr = attr[0]; let cube = persoOfIdName(attr.get('current'), options.pageId); if (cube === undefined) { - error("Attribut enveloppePar mal form\xE9, on le supprime", attr.get('current')); + error("Attribut enveloppePar mal formé, on le supprime", attr.get('current')); attr.remove(); unlockToken(perso); return; @@ -38736,7 +38869,7 @@ var COFantasy = COFantasy || function() { } if (libere) { let evt = { - type: 'Lib\xE9ration', + type: 'Libération', deletedAttributes: [attr] }; addEvent(evt); @@ -38751,12 +38884,12 @@ var COFantasy = COFantasy || function() { a.remove(); } }); - sendChar(cube.charId, "lib\xE8re " + nomPerso(perso)); + sendChar(cube.charId, "libère " + nomPerso(perso)); return; } let difficulte = parseInt(maxAttr); if (isNaN(difficulte)) { - error("Difficult\xE9 mal form\xE9e", attr.get('max')); + error("Difficulté mal formée", attr.get('max')); difficulte = 15; } doEchapperEnveloppement(perso, etreinte, cube, difficulte, options); @@ -38779,16 +38912,16 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); let titre = "Tentative de sortir de " + nomPerso(cube); - if (etreinte) titre = "Tentative de se lib\xE9rer de l'etreinte de " + cube.tokName; + if (etreinte) titre = "Tentative de se libérer de l'etreinte de " + cube.tokName; const display = startFramedDisplay(options.playerId, titre, perso, { chuchote: options.secret }); const testId = 'enveloppement_' + perso.token.id; testCaracteristique(perso, 'FOR', difficulte, testId, options, evt, function(tr) { - addLineToFramedDisplay(display, "R\xE9sultat : " + tr.texte); + addLineToFramedDisplay(display, "Résultat : " + tr.texte); if (tr.reussite) { - addLineToFramedDisplay(display, "C'est r\xE9ussi, " + nomPerso(perso) + " s'extirpe de " + cube.tokName + tr.modifiers); + addLineToFramedDisplay(display, "C'est réussi, " + nomPerso(perso) + " s'extirpe de " + cube.tokName + tr.modifiers); toFront(perso.token); evt.deletedAttributes = evt.deletedAttributes || []; let attr = tokenAttribute(perso, 'enveloppePar')[0]; @@ -38805,10 +38938,10 @@ var COFantasy = COFantasy || function() { } }); } else { - var msgRate = "C'est rat\xE9." + tr.rerolls + tr.modifiers; + let msgRate = "C'est raté." + tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, msgRate); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); } @@ -38817,7 +38950,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { @@ -38825,6 +38958,10 @@ var COFantasy = COFantasy || function() { return; } let perso = persoOfId(cmd[1], cmd[1], options.pageId); + if (!perso) { + error("Token invalide", cmd); + return; + } let attrName = 'estAgrippePar'; let attr = tokenAttribute(perso, 'estAgrippePar'); if (attr.length === 0) { @@ -38837,7 +38974,7 @@ var COFantasy = COFantasy || function() { attr = tokenAttribute(perso, 'estDevorePar'); attrName = 'estDevorePar'; if (attr.length === 0) { - sendPlayer(msg, nomPerso(perso) + " n'est pas agripp\xE9."); + sendPlayer(msg, nomPerso(perso) + " n'est pas agrippé."); return; } } @@ -38846,28 +38983,63 @@ var COFantasy = COFantasy || function() { attr = attr[0]; let agrippant = persoOfIdName(attr.get('current'), options.pageId); if (agrippant === undefined) { - error("Attribut " + attrName + " mal form\xE9, on le supprime", attr.get('current')); + error("Attribut " + attrName + " mal formé, on le supprime", attr.get('current')); attr.remove(); unlockToken(perso); return; } + if (cmd.length > 2 && cmd[2] == 'libere') { + finAgripper(perso, agrippant, attrName); + return; + } doLibererAgrippe(perso, agrippant, attrName, options); } + function finAgripper(perso, agrippant, attrName, evt) { + evt.deletedAttributes = evt.deletedAttributes || []; + let attr = tokenAttribute(perso, attrName); + attr[0].remove(); + unlockToken(perso, evt); + evt.deletedAttributes.push(attr[0]); + if (attrName == 'estAgrippePar') removeTokenAttr(perso, 'agrippeParUnDemon', evt); + if (attrName == 'etreinteImmolePar' || attrName == 'estDevorePar' || attr[0].get('max')) + setState(perso, 'immobilise', false, evt); + if (attrName == 'etreinteScorpionPar') { + let etrScorpAttr = tokenAttribute(perso, "etreinteScorpionRatee"); + if (etrScorpAttr && etrScorpAttr.length > 0) { + etrScorpAttr[0].remove(); + evt.deletedAttributes.push(etrScorpAttr[0]); + } + } + let attrAgrippant = 'agrippe'; + if (attrName == 'etreinteImmolePar') attrAgrippant = 'etreinteImmole'; + if (attrName == 'etreinteScorpionPar') attrAgrippant = 'etreinteScorpionSur'; + if (attrName == 'estDevorePar') attrAgrippant = 'devore'; + attr = tokenAttribute(agrippant, attrAgrippant); + attr.forEach(function(a) { + let ca = persoOfIdName(a.get('current')); + if (ca && ca.token.id == perso.token.id) { + evt.deletedAttributes.push(a); + a.remove(); + unlockToken(ca, evt); + } + }); + } + //!cof-liberer-agrippe token_id function doLibererAgrippe(perso, agrippant, attrName, options) { const evt = { type: 'libererAgrippe', action: { - titre: "Se lib\xE9rer", - perso: perso, - agrippant: agrippant, - attrName: attrName, - options: options + titre: "Se libérer", + perso, + agrippant, + attrName, + options } }; addEvent(evt); - let titre = "Tentative de se lib\xE9rer de " + nomPerso(agrippant); + let titre = "Tentative de se libérer de " + nomPerso(agrippant); let playerId = options.playerId; let display = startFramedDisplay(playerId, titre, perso, { chuchote: options.secret @@ -38884,14 +39056,14 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, e); }); if (tr == 2) { - let msgRate = "C'est rat\xE9, " + nomPerso(perso) + " est toujours "; + let msgRate = "C'est raté, " + nomPerso(perso) + " est toujours "; if (attrName == 'etreinteImmolePar' || attrName == 'etreinteScorpionPar') - msgRate += "prisonnier de l'\xE9treinte de " + nomPerso(agrippant); + msgRate += "prisonnier de l'étreinte de " + nomPerso(agrippant); else if (attrName == 'estDevorePar') msgRate += 'saisi' + eForFemale(perso) + '.'; - else msgRate += "agripp\xE9" + eForFemale(perso) + "."; + else msgRate += "agrippé" + eForFemale(perso) + "."; addLineToFramedDisplay(display, msgRate); - if (attrName == 'etreinteScorpionPar') { // Cas d'\xE9treinte de scorpion avec dommages automatiques + if (attrName == 'etreinteScorpionPar') { // Cas d'étreinte de scorpion avec dommages automatiques let d6 = evt.action.rolls.etreinteDmg || rollDePlus(6, { bonus: 3 }); @@ -38904,52 +39076,25 @@ var COFantasy = COFantasy || function() { let explications2 = []; perso.ignoreTouteRD = true; dealDamage(perso, r, [], evt, false, {}, explications2, function(dmgDisplay) { - let dmgMsg = "L'\xE9treinte du scorpion inflige " + dmgDisplay + " d\xE9g\xE2ts."; + let dmgMsg = "L'étreinte du scorpion inflige " + dmgDisplay + " dégâts."; setTokenAttr(perso, "etreinteScorpionRatee", true, evt); addLineToFramedDisplay(display, dmgMsg); explications2.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); } else { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } } else { if (tr === 0) - addLineToFramedDisplay(display, "R\xE9ussi de justesse, " + nomPerso(perso) + " se lib\xE8re."); + addLineToFramedDisplay(display, "Réussi de justesse, " + nomPerso(perso) + " se libère."); else //tr == 1 - addLineToFramedDisplay(display, "R\xE9ussi, " + nomPerso(perso) + " se lib\xE8re."); + addLineToFramedDisplay(display, "Réussi, " + nomPerso(perso) + " se libère."); toFront(perso.token); - evt.deletedAttributes = evt.deletedAttributes || []; - let attr = tokenAttribute(perso, attrName); - attr[0].remove(); - unlockToken(perso, evt); - evt.deletedAttributes.push(attr[0]); - if (attrName == 'estAgrippePar') removeTokenAttr(perso, 'agrippeParUnDemon', evt); - if (attrName == 'etreinteImmolePar' || attrName == 'estDevorePar' || attr[0].get('max')) - setState(perso, 'immobilise', false, evt); - if (attrName == 'etreinteScorpionPar') { - let etrScorpAttr = tokenAttribute(perso, "etreinteScorpionRatee"); - if (etrScorpAttr && etrScorpAttr.length > 0) { - etrScorpAttr[0].remove(); - evt.deletedAttributes.push(etrScorpAttr[0]); - } - } - let attrAgrippant = 'agrippe'; - if (attrName == 'etreinteImmolePar') attrAgrippant = 'etreinteImmole'; - if (attrName == 'etreinteScorpionPar') attrAgrippant = 'etreinteScorpionSur'; - if (attrName == 'estDevorePar') attrAgrippant = 'devore'; - attr = tokenAttribute(agrippant, attrAgrippant); - attr.forEach(function(a) { - let ca = persoOfIdName(a.get('current')); - if (ca && ca.token.id == perso.token.id) { - evt.deletedAttributes.push(a); - a.remove(); - unlockToken(ca, evt); - } - }); - sendChat('', endFramedDisplay(display)); + finAgripper(perso, agrippant, attrName, evt); + sendFramedDisplay(display); if (attrName == 'etreinteScorpionPar') { turnAction(perso); } @@ -38962,7 +39107,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { @@ -38973,13 +39118,13 @@ var COFantasy = COFantasy || function() { let attrName = 'estEcrasePar'; let attr = tokenAttribute(perso, attrName); if (attr.length === 0) { - sendPlayer(msg, nomPerso(perso) + " n'est pas \xE9cras\xE9."); + sendPlayer(msg, nomPerso(perso) + " n'est pas écrasé."); return; } attr = attr[0]; let agrippant = persoOfIdName(attr.get('current'), options.pageId); if (agrippant === undefined) { - error("Attribut " + attrName + " mal form\xE9, on le supprime", attr.get('current')); + error("Attribut " + attrName + " mal formé, on le supprime", attr.get('current')); attr.remove(); unlockToken(perso); return; @@ -38992,15 +39137,15 @@ var COFantasy = COFantasy || function() { estMauvais(agrippant)) { let bonusProtectionContreLeMal = getIntValeurOfEffet(perso, 'protectionContreLeMal', 2); bonus += bonusProtectionContreLeMal; - explications.push("Protection contre le mal => +" + bonusProtectionContreLeMal + " au jet pour se lib\xE9rer"); + explications.push("Protection contre le mal => +" + bonusProtectionContreLeMal + " au jet pour se libérer"); } if (predicateAsBool(perso, 'actionLibre')) { bonus += 5; - explications.push("Action libre => +5 pour r\xE9sister aux entraves"); + explications.push("Action libre => +5 pour résister aux entraves"); } let carac = meilleureCarac('FOR', 'DEX', perso, difficulte - bonus); if (bonus) options.bonus = bonus; - let titre = "Tentative de se lib\xE9rer de " + nomPerso(agrippant); + let titre = "Tentative de se libérer de " + nomPerso(agrippant); doLibererEcrase(perso, agrippant, titre, carac, difficulte, explications, options); } @@ -39039,7 +39184,7 @@ var COFantasy = COFantasy || function() { smsg += '">' + tr.texte + ''; } if (tr.reussite) { - smsg += " => r\xE9ussi, " + nomPerso(perso) + " se lib\xE8re."; + smsg += " => réussi, " + nomPerso(perso) + " se libère."; smsg += tr.modifiers; addLineToFramedDisplay(display, smsg); toFront(perso.token); @@ -39058,11 +39203,11 @@ var COFantasy = COFantasy || function() { } }); } else { - smsg += " => \xE9chec, " + nomPerso(perso) + " est toujours saisi dans les bras de " + nomPerso(agrippant); + smsg += " => échec, " + nomPerso(perso) + " est toujours saisi dans les bras de " + nomPerso(agrippant); smsg += tr.rerolls + tr.modifiers; addLineToFramedDisplay(display, smsg); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); if (tr.reussite) turnAction(perso); }); } @@ -39083,7 +39228,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2], cmd[2], options.pageId); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-animer-cadavre n'est pas un token valide", msg.content); + error("Le deuxième argument de !cof-animer-cadavre n'est pas un token valide", msg.content); return; } if (!getState(cible, 'mort')) { @@ -39091,13 +39236,13 @@ var COFantasy = COFantasy || function() { return; } if (attributeAsBool(cible, 'cadavreAnime')) { - sendPlayer(msg, nomPerso(cible) + " a d\xE9j\xE0 \xE9t\xE9 anim\xE9" + eForFemale(cible) + "."); + sendPlayer(msg, nomPerso(cible) + " a déjà été animé" + eForFemale(cible) + "."); return; } var niveauLanceur = ficheAttributeAsInt(lanceur, 'niveau', 1); var niveauCible = ficheAttributeAsInt(cible, 'niveau', 1); if (niveauCible > niveauLanceur) { - sendPlayer(msg, nomPerso(cible) + " est de NC " + niveauCible + ", sup\xE9rieur \xE0 celui de " + nomPerso(lanceur) + " (" + niveauLanceur + ")"); + sendPlayer(msg, nomPerso(cible) + " est de NC " + niveauCible + ", supérieur à celui de " + nomPerso(lanceur) + " (" + niveauLanceur + ")"); return; } var evt = { @@ -39105,27 +39250,27 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); if (limiteRessources(lanceur, options, 'animerUnCadavre', "animer un cadavre", evt)) return; - sendPerso(lanceur, 'r\xE9anime ' + nomPerso(cible)); + sendPerso(lanceur, 'réanime ' + nomPerso(cible)); setState(cible, 'mort', false, evt); var pvmax = parseInt(cible.token.get("bar1_max")); updateCurrentBar(cible, 1, pvmax, evt); setTokenAttr(cible, 'cadavreAnime', true, evt, { - msg: 'se rel\xE8ve' + msg: 'se relève' }); } var niveauxEbriete = [ "sobre", "pompette", - "bourr\xE9", + "bourré", "ivre-mort", - "en coma \xE9thylique" + "en coma éthylique" ]; function augmenteEbriete(personnage, evt, expliquer) { let n = attributeAsInt(personnage, 'niveauEbriete', 0) + 1; if (n >= niveauxEbriete.length) { - expliquer(nomPerso(personnage) + " est d\xE9j\xE0 en coma \xE9thylique."); + expliquer(nomPerso(personnage) + " est déjà en coma éthylique."); return; } expliquer(nomPerso(personnage) + " devient " + niveauxEbriete[n]); @@ -39147,7 +39292,7 @@ var COFantasy = COFantasy || function() { var cibles = []; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "pas de cible trouv\xE9e, action annul\xE9e", playerId); + sendPlayer(msg, "pas de cible trouvée, action annulée", playerId); return; } iterSelected(selected, function(perso) { @@ -39167,23 +39312,23 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - if (limiteRessources(options.lanceur, options, 'vapeursEthyliques', "lancer une fiole de vapeurs \xE9thyliques", evt)) { + if (limiteRessources(options.lanceur, options, 'vapeursEthyliques', "lancer une fiole de vapeurs éthyliques", evt)) { addEvent(evt); return; } - let display = startFramedDisplay(playerId, 'Vapeurs \xE9thyliques'); + let display = startFramedDisplay(playerId, 'Vapeurs éthyliques'); let expliquer = function(m) { addLineToFramedDisplay(display, m); }; const explications = []; if (options.save) { - explications.push(" Jet de " + options.save.carac + " " + options.save.seuil + " pour r\xE9sister \xE0 l'alcool"); + explications.push(" Jet de " + options.save.carac + " " + options.save.seuil + " pour résister à l'alcool"); } entrerEnCombat(options.lanceur, persos, explications, evt); explications.forEach(explication => expliquer(explications)); let count = persos.length; let finalize = function() { - if (count == 1) sendChat('', endFramedDisplay(display)); + if (count == 1) sendFramedDisplay(display); count--; }; persos.forEach(function(perso) { @@ -39216,11 +39361,11 @@ var COFantasy = COFantasy || function() { function desaouler(msg) { getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Aucune s\xE9lection pour !cof-desaouler", playerId); + sendPlayer(msg, "Aucune sélection pour !cof-desaouler", playerId); return; } var evt = { - type: 'desao\xFBler' + type: 'desaoûler' }; var expliquer = function(s) { sendChat('', s); @@ -39254,7 +39399,7 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - if (limiteRessources(options.lanceur, options, 'boireAlcool', "est affect\xE9 par l'alcool", evt)) { + if (limiteRessources(options.lanceur, options, 'boireAlcool', "est affecté par l'alcool", evt)) { return; } var display = startFramedDisplay(playerId, 'Alcool'); @@ -39262,11 +39407,11 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, m); }; if (options.save) { - expliquer("Jet de " + options.save.carac + " " + options.save.seuil + " pour r\xE9sister \xE0 l'alcool"); + expliquer("Jet de " + options.save.carac + " " + options.save.seuil + " pour résister à l'alcool"); } var count = persos.length; var finalize = function() { - if (count == 1) sendChat('', endFramedDisplay(display)); + if (count == 1) sendFramedDisplay(display); count--; }; persos.forEach(function(perso) { @@ -39298,7 +39443,7 @@ var COFantasy = COFantasy || function() { //On joue un son let son = msg.content.substring(sonIndex + 1); playSound(son); - } else { //On arr\xEAte tous les sons + } else { //On arrête tous les sons let AMdeclared; try { AMdeclared = Roll20AM; @@ -39335,7 +39480,7 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error('pas de token s\xE9lectionn\xE9 pour !cof-bonus-couvert'); + error('pas de token sélectionné pour !cof-bonus-couvert'); return; } var evt = { @@ -39346,12 +39491,12 @@ var COFantasy = COFantasy || function() { iterSelected(selected, function(perso) { if (nouveauBonus) { setTokenAttr(perso, 'bonusCouvert', nouveauBonus, evt, { - msg: "se met \xE0 couvert", + msg: "se met à couvert", secret: options.secret }); } else { removeTokenAttr(perso, 'bonusCouvert', evt, { - msg: "n'est plus \xE0 couvert", + msg: "n'est plus à couvert", secret: options.secret }); } @@ -39383,7 +39528,7 @@ var COFantasy = COFantasy || function() { return; }*/ if (selected.length === 0) { - error('pas de token s\xE9lectionn\xE9 pour !cof-set-attribute'); + error('pas de token sélectionné pour !cof-set-attribute'); return; } const evt = { @@ -39436,7 +39581,7 @@ var COFantasy = COFantasy || function() { let predicats = state.COFantasy.predicats; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error('pas de token s\xE9lectionn\xE9 pour !cof-set-predicate'); + error('pas de token sélectionné pour !cof-set-predicate'); return; } const evt = { @@ -39451,14 +39596,14 @@ var COFantasy = COFantasy || function() { case 'vrai': case 'oui': if (pred.includes(predicat)) { - sendPlayer(msg, 'Pr\xE9dicat ' + predicat + ' d\xE9j\xE0 pr\xE9sent', playerId); + sendPlayer(msg, 'Prédicat ' + predicat + ' déjà présent', playerId); return; } if (pred === '') pred = predicat; else pred = pred + ' ' + predicat; setFicheAttr(perso, 'predicats_script', pred, evt); if (predicats) predicats[perso.charId] = undefined; - sendPlayer(msg, 'Pr\xE9dicat ' + predicat + ' ajout\xE9', playerId); + sendPlayer(msg, 'Prédicat ' + predicat + ' ajouté', playerId); break; case 'false': case 'faux': @@ -39466,11 +39611,11 @@ var COFantasy = COFantasy || function() { let regPred = new RegExp('(^| |,|\n)' + predicat + '($| |,|\n)'); let newPred = pred.replace(regPred, ' '); if (newPred == pred) { - sendPlayer(msg, 'Pr\xE9dicat ' + predicat + ' non trouv\xE9', playerId); + sendPlayer(msg, 'Prédicat ' + predicat + ' non trouvé', playerId); } else { setFicheAttr(perso, 'predicats_script', newPred, evt); if (predicats) predicats[perso.charId] = undefined; - sendPlayer(msg, 'Pr\xE9dicat ' + predicat + ' enlev\xE9', playerId); + sendPlayer(msg, 'Prédicat ' + predicat + ' enlevé', playerId); } break; default: @@ -39498,11 +39643,11 @@ var COFantasy = COFantasy || function() { } var perso = persoOfId(cmd[1]); if (perso === undefined) { - error("Le token renseign\xE9 pour !cof-defense-armee-des-morts est inconnu", cmd); + error("Le token renseigné pour !cof-defense-armee-des-morts est inconnu", cmd); return; } if (!peutController(msg, perso)) { - sendPlayer(msg, "ne peut pas faire \xE7a."); + sendPlayer(msg, "ne peut pas faire ça."); return; } var evt = { @@ -39510,7 +39655,7 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); var opt = { - msg: "se d\xE9fend contre les morts" + msg: "se défend contre les morts" }; setTokenAttr(perso, "defenseArmeeDesMorts", true, evt, opt); } @@ -39530,8 +39675,8 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, ligne); } - //!cof-options-d-attaque, affiche les options d'attaque du token s\xE9lectionn\xE9 - // si on donne reset en argument, remet tout \xE0 z\xE9ro + //!cof-options-d-attaque, affiche les options d'attaque du token sélectionné + // si on donne reset en argument, remet tout à zéro // si on donne en argument option valeur, change la valeur de l'option function optionsDAttaque(msg) { const options = parseOptions(msg); @@ -39661,7 +39806,7 @@ var COFantasy = COFantasy || function() { break; default: error("Argument de !cof-options-d-attaque non reconnu", cmd); - //Mais on peut quand m\xEAme afficher les options + //Mais on peut quand même afficher les options } turnAction(perso, playerId); return; @@ -39673,7 +39818,7 @@ var COFantasy = COFantasy || function() { }; if (aepc || arc || aac || adtc || (persoEstPNJ(perso) && adg > 1)) { action = "!cof-options-d-attaque reset --target " + perso.token.id; - opt_display.action_right = boutonSimple(action, 'r\xE9init.'); + opt_display.action_right = boutonSimple(action, 'réinit.'); } var display = startFramedDisplay(playerId, title, perso, opt_display); var ligne = ''; @@ -39682,7 +39827,7 @@ var COFantasy = COFantasy || function() { ligne = "Attaque de groupe : "; action = "!cof-options-d-attaque attaque_de_groupe ?{Combien d'adversaires par jet?}"; action += " --target " + perso.token.id; - overlay = 'title="+2 Att. par cr\xE9ature, si Att > DEF + 5, DM x2, si critique DM x3"'; + overlay = 'title="+2 Att. par créature, si Att > DEF + 5, DM x2, si critique DM x3"'; ligne += boutonSimple(action, adg, overlay); if (adg < 2) { ligne += "attaquant"; @@ -39702,7 +39847,7 @@ var COFantasy = COFantasy || function() { } action += " --target " + perso.token.id; ligne = boutonSimple(action, text) + "Attaque en puissance"; - action = "!cof-options-d-attaque attaque_en_puissance ?{nombre de d\xE9s de bonus (-5 att par d\xE9)?}"; + action = "!cof-options-d-attaque attaque_en_puissance ?{nombre de dés de bonus (-5 att par dé)?}"; action += " --target " + perso.token.id; ligne += "(+" + boutonSimple(action, aep) + "d"; if (predicateAsBool(perso, 'tropPetit') && !attributeAsBool(perso, 'grandeTaille')) { @@ -39711,16 +39856,16 @@ var COFantasy = COFantasy || function() { ligne += "6 DM)"; } addLineToFramedDisplay(display, ligne); - addLigneOptionAttaque(display, perso, arc, "Attaque risqu\xE9e", 'attaque_risquee'); - addLigneOptionAttaque(display, perso, aac, "Attaque assur\xE9e", 'attaque_assuree'); + addLigneOptionAttaque(display, perso, arc, "Attaque risquée", 'attaque_risquee'); + addLigneOptionAttaque(display, perso, aac, "Attaque assurée", 'attaque_assuree'); addLigneOptionAttaque(display, perso, adtc, "Attaque pour assommer", 'attaque_dm_temp'); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); if (evt.attributes) addEvent(evt); } - //si evt est d\xE9fini, on ajoute les actions \xE0 evt + //si evt est défini, on ajoute les actions à evt function nePlusSuivre(perso, pageId, evt, reutilise) { let attrSuit = tokenAttribute(perso, 'suit'); if (attrSuit.length > 0) { @@ -39793,7 +39938,7 @@ var COFantasy = COFantasy || function() { } let perso = persoOfId(cmd[1], cmd[1], options.pageId); if (perso === undefined) { - error("Token s\xE9lectionne incorrect pour !cof-suivre", cmd); + error("Token sélectionne incorrect pour !cof-suivre", cmd); return; } let pageId = perso.token.get('pageid'); @@ -39806,7 +39951,7 @@ var COFantasy = COFantasy || function() { type: 'Suivre', attributes: [] }; - //D'abord on arr\xEAte de suivre si on suivait quelqu'un + //D'abord on arrête de suivre si on suivait quelqu'un let attrSuit = nePlusSuivre(perso, pageId, evt, true); let cibleId = idName(cible); let attr = tokenAttribute(cible, 'estSuiviPar'); @@ -39829,7 +39974,7 @@ var COFantasy = COFantasy || function() { let yc = cible.token.get('top'); let distance = Math.floor(Math.sqrt((xc - xt) * (xc - xt) + (yc - yt) * (yc - yt))); if (attrSuit) { - //alors evt contient d\xE9j\xE0 attrSuit + //alors evt contient déjà attrSuit attrSuit.set('current', cibleId); attrSuit.set('max', distance); } else { @@ -39849,7 +39994,7 @@ var COFantasy = COFantasy || function() { return c !== ''; }); if (cmd.length < 2) { - error("Il faut pr\xE9ciser un token sur lequel se centrer", cmd); + error("Il faut préciser un token sur lequel se centrer", cmd); return; } let playerId = getPlayerIdFromMsg(msg); @@ -39857,7 +40002,7 @@ var COFantasy = COFantasy || function() { if (playerIsGM(playerId)) { let p = getObj('player', playerId); if (p === undefined) { - error("Impossible de trouver le joueur qui a lanc\xE9 la commande", msg); + error("Impossible de trouver le joueur qui a lancé la commande", msg); return; } pageId = p.get('_lastpage'); @@ -39904,7 +40049,7 @@ var COFantasy = COFantasy || function() { else possede = true; msg += pc + " PC"; } - if (possede) msg = 'poss\xE8de ' + msg; + if (possede) msg = 'possède ' + msg; else msg = "n'a pas d'argent"; if (dest) sendPlayer(dest, nomPerso(perso) + ' ' + msg); else whisperChar(perso.charId, msg); @@ -39926,19 +40071,19 @@ var COFantasy = COFantasy || function() { let val = ficheAttributeAsInt(perso, 'bourse_' + unite, 0); let line = '
    '; let action = - "!cof-bourse fixer ?{Nouveau montant de pi\xE8ces " + piece + " ?} " + finAction; + "!cof-bourse fixer ?{Nouveau montant de pièces " + piece + " ?} " + finAction; line += boutonSimple(action, val) + '' + nom + ''; line += ''; - action = "!cof-bourse depenser ?{Pi\xE8ces " + piece + " \xE0 d\xE9penser ?} " + finAction; - line += boutonSimple(action, 'D\xE9penser'); - action = "!cof-bourse gagner ?{Pi\xE8ces " + piece + " ?} " + finAction; + action = "!cof-bourse depenser ?{Pièces " + piece + " à dépenser ?} " + finAction; + line += boutonSimple(action, 'Dépenser'); + action = "!cof-bourse gagner ?{Pièces " + piece + " ?} " + finAction; line += boutonSimple(action, 'Gagner'); line += '
    '; addLineToFramedDisplay(display, line); } //!cof-bourse [action] - //Les actions peuvent \xEAtre depenser val [unite], fixer val unite ou gagner val [unite] + //Les actions peuvent être depenser val [unite], fixer val unite ou gagner val [unite] function gestionBourse(msg) { var cmd = msg.content.split(' ').filter(function(c) { return c.trim() !== ''; @@ -39955,11 +40100,11 @@ var COFantasy = COFantasy || function() { if (cmd.length > 1) { switch (cmd[1]) { case 'depenser': - case 'd\xE9penser': + case 'dépenser': case 'gagner': case 'fixer': if (cmd.length < 3) { - error("Il faut sp\xE9cifier un montant \xE0 " + cmd[1], msg.content); + error("Il faut spécifier un montant à " + cmd[1], msg.content); return; } montant = parseInt(cmd[2]); @@ -39972,7 +40117,7 @@ var COFantasy = COFantasy || function() { action = 'depenser'; } else if (cmd[1] == 'fixer') { if (montant < 0) { - error("On ne peut avoir qu'un nombre positif de pi\xE8ces", cmd); + error("On ne peut avoir qu'un nombre positif de pièces", cmd); return; } action = 'fixer'; @@ -39980,12 +40125,12 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3 && !cmd[3].startsWith('--')) { unite = cmd[3].toLowerCase().trim(); if (unite != 'pp' && unite != 'po' && unite != 'pa' && unite != 'pc') { - error("Pi\xE8ces non reconnues : " + cmd[3], cmd); + error("Pièces non reconnues : " + cmd[3], cmd); return; } depense[unite] = montant; } else if (action == 'fixer') { - error("Il faut pr\xE9ciser les unit\xE9s pour !cof-bourse fixer", msg.content); + error("Il faut préciser les unités pour !cof-bourse fixer", msg.content); return; } depense.total = depense.pc + 10 * (depense.pa + 10 * (depense.po + 10 * depense.pp)); @@ -39993,7 +40138,7 @@ var COFantasy = COFantasy || function() { } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de personnage s\xE9lectionn\xE9 pour !cof-bourse", playerId); + sendPlayer(msg, "Pas de personnage sélectionné pour !cof-bourse", playerId); return; } var evt = { @@ -40037,7 +40182,7 @@ var COFantasy = COFantasy || function() { } var montantPossede = pc + 10 * (pa + 10 * (po + 10 * pp)); if (montantPossede < depense.total) { - sendPerso(perso, "ne poss\xE8de pas assez d'argent pour cette d\xE9pense"); + sendPerso(perso, "ne possède pas assez d'argent pour cette dépense"); afficherRichesse(perso, msg); return; } @@ -40047,7 +40192,7 @@ var COFantasy = COFantasy || function() { po: po, pp: pp }; - // On privil\xE9gie les d\xE9penses directes + // On privilégie les dépenses directes var dpp = depense.pp; if (dpp <= bourse.pp) { bourse.pp -= dpp; @@ -40080,14 +40225,14 @@ var COFantasy = COFantasy || function() { dpc -= bourse.pc; bourse.pc = 0; } - // Puis on d\xE9pense d'abord la petite monnaie + // Puis on dépense d'abord la petite monnaie var v = dpc + 10 * (dpa + 10 * (dpo + 10 * dpp)); v = depenserSous(perso, 'pc', bourse, v); v = depenserSous(perso, 'pa', bourse, v); v = depenserSous(perso, 'po', bourse, v); v = depenserSous(perso, 'pp', bourse, v); if (v > 0) { - error("Erreur interne de calcul, il reste " + v + " PP \xE0 d\xE9penser ??", bourse); + error("Erreur interne de calcul, il reste " + v + " PP à dépenser ??", bourse); return; } if (bourse.pc != pc) @@ -40131,7 +40276,7 @@ var COFantasy = COFantasy || function() { ajouteLignePieces(perso, display, 'po', 'Or', "d'or"); ajouteLignePieces(perso, display, 'pa', 'Argent', "d'argent"); ajouteLignePieces(perso, display, 'pc', 'Cuivre', "de cuivre"); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }); }); @@ -40146,7 +40291,7 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); if (options.lanceur) { - sendPerso(options.lanceur, "prononce un mot avec la Voix d'une puissance sup\xE9rieure. Tous ses ennemis sont immobilis\xE9s et ses alli\xE9s sont galvanis\xE9s."); + sendPerso(options.lanceur, "prononce un mot avec la Voix d'une puissance supérieure. Tous ses ennemis sont immobilisés et ses alliés sont galvanisés."); let allies = alliesParPerso[options.lanceur.charId]; if (allies) { let tokens = findObjs({ @@ -40182,8 +40327,8 @@ var COFantasy = COFantasy || function() { }, options); } - // Ajoute evt \xE0 l'historique si pr\xE9sent - // msg n'est pas forc\xE9ment pr\xE9sent + // Ajoute evt à l'historique si présent + // msg n'est pas forcément présent function nextTurnChargeFantastique(msg, oldTurnOrder) { if (oldTurnOrder) Campaign().set('turnorder', oldTurnOrder); let cf = stateCOF.chargeFantastique; @@ -40222,9 +40367,9 @@ var COFantasy = COFantasy || function() { stateCOF.chargeFantastique.activeTokenId = perso.token.id; setTokenInitAura(perso); let display = startFramedDisplay(playerId, "Charge fantastique", perso, optionsDisplay); - addLineToFramedDisplay(display, "Phase de mouvement : d\xE9placez votre token en ligne droite"); + addLineToFramedDisplay(display, "Phase de mouvement : déplacez votre token en ligne droite"); addLineToFramedDisplay(display, "puis " + boutonSimple("!cof-next-charge-fantastique", "cliquez ici")); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } if (cf.attaques && cf.attaques.length > 0) { @@ -40256,12 +40401,12 @@ var COFantasy = COFantasy || function() { } const chevalier = persoOfId(cmd[1], cmd[1], options.pageId); if (chevalier === undefined) { - error("Le token s\xE9lectionn\xE9 ne repr\xE9sente pas un personnage", cmd); + error("Le token sélectionné ne représente pas un personnage", cmd); return; } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error('pas de token s\xE9lectionn\xE9 pour !cof-charge-fantastique', msg.content); + error('pas de token sélectionné pour !cof-charge-fantastique', msg.content); return; } const evt = { @@ -40269,7 +40414,7 @@ var COFantasy = COFantasy || function() { }; addEvent(evt); if (limiteRessources(chevalier, options, 'chargeFantastique', 'charge fantastique', evt)) return; - sendPerso(chevalier, "m\xE8ne une charge fantastique !"); + sendPerso(chevalier, "mène une charge fantastique !"); initiative(selected, evt); stateCOF.chargeFantastique = {}; let ordreActions = []; @@ -40287,14 +40432,14 @@ var COFantasy = COFantasy || function() { ordreActions.sort(function(p1, p2) { if (p1.init < p2.init) return 1; if (p1.init > p2.init) return -1; - // Priorit\xE9 aux joueurs - // Premier crit\xE8re : la barre de PV des joueurs est li\xE9e + // Priorité aux joueurs + // Premier critère : la barre de PV des joueurs est liée if (p1.perso.token.get('bar1_link') === '') { if (p2.perso.token.get('bar1_link') === '') return 0; return 1; } if (p2.perso.token.get('bar1_link') === '') return -1; - // Deuxi\xE8me crit\xE8re : les joueurs ont un DV + // Deuxième critère : les joueurs ont un DV let dvA = ficheAttributeAsInt(p1.perso, "DV", 0); let dvB = ficheAttributeAsInt(p2.perso, "DV", 0); if (dvA === 0) { @@ -40302,7 +40447,7 @@ var COFantasy = COFantasy || function() { return 1; } if (dvB === 0) return -1; - //Entre joueurs, priorit\xE9 \xE0 la plus grosse sagesse + //Entre joueurs, priorité à la plus grosse sagesse let sagA = ficheAttributeAsInt(p1.perso, 'sagesse', 10); let sagB = ficheAttributeAsInt(p2.perso, 'sagesse', 10); if (sagA < sagB) return 1; @@ -40356,9 +40501,9 @@ var COFantasy = COFantasy || function() { error("Impossible d'utiliser la prescience car l'historique est vide", cmd); return; } - //Au cas o\xF9, on v\xE9rifie que l'\xE9v\xE9nement de d\xE9but de tour est bien pr\xE9sent + //Au cas où, on vérifie que l'événement de début de tour est bien présent if (!findEvent(stateCOF.prescience.evt.id)) { - error("Impossible de trouver le d\xE9but du tour dans l'historique.", stateCOF.prescience); + error("Impossible de trouver le début du tour dans l'historique.", stateCOF.prescience); return; } while (evt && evt.id != stateCOF.prescience.evt.id) { @@ -40398,7 +40543,7 @@ var COFantasy = COFantasy || function() { updateNextInit(ensorceleur); } - //Synchronise les tokens de m\xEAme nom entre les cartes + //Synchronise les tokens de même nom entre les cartes function multiCartes(msg) { let options = parseOptions(msg); let enlever = options && options.cmd && options.cmd.length > 1 && @@ -40413,13 +40558,13 @@ var COFantasy = COFantasy || function() { addEvent(evt); return; } - sendPlayer(msg, "Aucun token selectionn\xE9 pour !cof-multi-cartes", playerId); + sendPlayer(msg, "Aucun token selectionné pour !cof-multi-cartes", playerId); return; } addEvent(evt); if (enlever) { iterSelected(selected, function(perso) { - sendPlayer(msg, nomPerso(perso) + " n'est plus synchronis\xE9", playerId); + sendPlayer(msg, nomPerso(perso) + " n'est plus synchronisé", playerId); removeTokenAttr(perso, 'tokensSynchronises', evt); }); return; @@ -40434,7 +40579,7 @@ var COFantasy = COFantasy || function() { let left = perso.token.get('left'); let top = perso.token.get('top'); let listTokens = [perso.token.id]; - //On cherche les tokens de m\xEAme nom et on les met en m\xEAme position + //On cherche les tokens de même nom et on les met en même position allTokens.forEach(function(tok) { if (tok.get('represents') != perso.charId) return; if (tok.get('name') != name) return; @@ -40457,7 +40602,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof-ombre-mouvante", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof-ombre-mouvante", playerId); return; } iterSelected(selected, function(perso) { @@ -40476,16 +40621,16 @@ var COFantasy = COFantasy || function() { } }; addEvent(evt); - if (limiteRessources(voleur, options, 'ombreMouvante', 'dispara\xEEtre dans les ombres', evt)) return; + if (limiteRessources(voleur, options, 'ombreMouvante', 'disparaître dans les ombres', evt)) return; let optionsDisplay = { secret: options.secret }; let display = startFramedDisplay(playerId, 'Ombre mouvante', voleur, optionsDisplay); testCaracteristique(voleur, 'DEX', 10, 'ombreMouvante', options, evt, function(tr, explications) { - let msgRes = "R\xE9sultat : " + tr.texte; + let msgRes = "Résultat : " + tr.texte; if (tr.reussite) { - msgRes += ", " + nomPerso(voleur) + " dispara\xEEt dans les ombres"; + msgRes += ", " + nomPerso(voleur) + " disparaît dans les ombres"; addLineToFramedDisplay(display, msgRes + tr.modifiers); let ef = { effet: 'invisibleTemp', @@ -40496,7 +40641,7 @@ var COFantasy = COFantasy || function() { if (options.fx) spawnFx(voleur.token.get('left'), voleur.token.get('top'), options.fx, voleur.token.get('pageid')); } else { - msgRes += ", " + nomPerso(voleur) + " ne r\xE9ussit pas \xE0 se fondre dans les ombres."; + msgRes += ", " + nomPerso(voleur) + " ne réussit pas à se fondre dans les ombres."; addLineToFramedDisplay(display, msgRes + tr.rerolls + tr.modifiers); } explications.forEach(function(m) { @@ -40509,10 +40654,10 @@ var COFantasy = COFantasy || function() { } if (display.retarde) { addFramedHeader(display, playerId, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); - } else sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); + } else sendFramedDisplay(display); }); } @@ -40524,22 +40669,22 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9 pour !cof-reveler-nom", playerId); + sendPlayer(msg, "Pas de token sélectionné pour !cof-reveler-nom", playerId); return; } let nouveauNomToken; if (cmd.length > 1) nouveauNomToken = cmd.slice(1).join(' '); if (selected.length > 1 && nouveauNomToken) { - sendPlayer(msg, "Attention, on ne peut s\xE9lectionner qu'un seul token quand on pr\xE9cise le nouveau nom des tokens", playerId); + sendPlayer(msg, "Attention, on ne peut sélectionner qu'un seul token quand on précise le nouveau nom des tokens", playerId); return; } const evt = { - type: "R\xE9v\xE9lation de nom", + type: "Révélation de nom", characterNames: [], defaultTokens: [], attributes: [] @@ -40570,24 +40715,24 @@ var COFantasy = COFantasy || function() { }); ancienNom = ficheAttribute(perso, 'alias', ''); nouveauNom = character.get('name'); - sendChat('', ancienNom + " \xE9tait en r\xE9alit\xE9 " + nouveauNom + " !"); + sendChat('', ancienNom + " était en réalité " + nouveauNom + " !"); } else { nouveauNom = ficheAttribute(perso, 'alias', ''); ancienNom = character.get('name'); if (nouveauNom === '') { - sendPlayer(msg, ancienNom + " n'a pas d'alias, rien \xE0 r\xE9v\xE9ler."); + sendPlayer(msg, ancienNom + " n'a pas d'alias, rien à révéler."); return; } setFicheAttr(perso, 'alias', '', evt, { default: '' }); - sendChar(perso.charId, "\xE9tait en r\xE9alit\xE9 " + nouveauNom + " !"); + sendChar(perso.charId, "était en réalité " + nouveauNom + " !"); evt.characterNames.push({ character: character, name: ancienNom }); character.set('name', nouveauNom); - //On change aussi les pr\xE9dicats qui stoquent le nom du personnage + //On change aussi les prédicats qui stoquent le nom du personnage if (attrsWithCharNames === undefined) { attrsWithCharNames = allAttrs.filter(function(attr) { return attr.get('name') == 'predicats_script'; @@ -40680,7 +40825,7 @@ var COFantasy = COFantasy || function() { sendPlayer(msg, "Pas de renommage de " + tokName, playerId); } } else { - sendPlayer(msg, "Pas de token par d\xE9faut pour " + tokName + ", ce n'est pas encore g\xE9r\xE9 dans !cof-reveler-nom", playerId); + sendPlayer(msg, "Pas de token par défaut pour " + tokName + ", ce n'est pas encore géré dans !cof-reveler-nom", playerId); } } else { if (defaultTokenName && tokName == defaultTokenName) { @@ -40735,14 +40880,14 @@ var COFantasy = COFantasy || function() { } if (b) { if (stateCOF.tenebresMagiques) { - sendPlayer('GM', "Les personnages sont d\xE9j\xE0 dans des t\xE9n\xE8bres magiques"); + sendPlayer('GM', "Les personnages sont déjà dans des ténèbres magiques"); return; } - sendPlayer('GM', "Les personnages entrent dans des t\xE9n\xE8bres magiques"); + sendPlayer('GM', "Les personnages entrent dans des ténèbres magiques"); stateCOF.tenebresMagiques = {}; } else { stateCOF.tenebresMagiques = undefined; - sendPlayer('GM', "Les personnages sortent des t\xE9n\xE8bres magiques"); + sendPlayer('GM', "Les personnages sortent des ténèbres magiques"); } } @@ -40750,24 +40895,24 @@ var COFantasy = COFantasy || function() { let cmd = msg.content.split(' '); let tm = stateCOF.tenebresMagiques; if (tm === undefined) { - sendPlayer(msg, "Pas de t\xE9n\xE8bres magiques, pas d'effet de fiole"); + sendPlayer(msg, "Pas de ténèbres magiques, pas d'effet de fiole"); return; } cmd = cmd.filter(function(c) { return c.trim() !== ''; }); if (cmd.length < 2) { - error("Il faut un argument \xE0 !cof-fiole-de-lumiere", cmd); + error("Il faut un argument à !cof-fiole-de-lumiere", cmd); return; } var distance = parseInt(cmd[1]); getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - error("Aucun personnage s\xE9lectionn\xE9", cmd); + error("Aucun personnage sélectionné", cmd); return; } if (selected.length > 1) { - error("Il n'y a qu'une seule fiole de lumi\xE8re", cmd); + error("Il n'y a qu'une seule fiole de lumière", cmd); return; } var evt = { @@ -40788,7 +40933,7 @@ var COFantasy = COFantasy || function() { if (cmd.length > 3) { dimRadius = parseInt(cmd[3]); if (isNaN(dimRadius)) { - error("La distance de vue de la lumi\xE8re assombrie doit \xEAtre un nombre", cmd[3]); + error("La distance de vue de la lumière assombrie doit être un nombre", cmd[3]); dimRadius = ''; } } @@ -40805,25 +40950,25 @@ var COFantasy = COFantasy || function() { return c !== ''; }); if (cmd.length < 3) { - error("Il faut sp\xE9cifier un attaquant et un d\xE9fenseur pour !cof-agripper-de-demon", cmd); + error("Il faut spécifier un attaquant et un défenseur pour !cof-agripper-de-demon", cmd); return; } let attaquant = persoOfId(cmd[1], cmd[1]); let defenseur = persoOfId(cmd[2], cmd[2]); if (attaquant === undefined) { - error("Le premier argument de !cof-agripper-de-demon doit \xEAtre un token valide", cmd[1]); + error("Le premier argument de !cof-agripper-de-demon doit être un token valide", cmd[1]); return; } if (defenseur === undefined) { - error("Le deuxi\xE8me argument de !cof-agripper-de-demon doit \xEAtre un token valide", cmd[2]); + error("Le deuxième argument de !cof-agripper-de-demon doit être un token valide", cmd[2]); return; } if (attributeAsBool(defenseur, 'armureDEau')) { - sendChat("L'armure d'eau emp\xEAche " + nomPerso(defenseur) + " d'\xEAtre aggrip\xE9"); + sendChat("L'armure d'eau empêche " + nomPerso(defenseur) + " d'être aggripé"); return; } const evt = { - type: "Agripper (d\xE9mon)" + type: "Agripper (démon)" }; let options = { pasDeDmg: true @@ -40838,12 +40983,12 @@ var COFantasy = COFantasy || function() { setTokenAttr(defenseur, 'estAgrippePar', idName(attaquant), evt); setTokenAttr(defenseur, 'agrippeParUnDemon', true, evt); } else { - addLineToFramedDisplay(display, nomPerso(defenseur) + " \xE9chappe \xE0 la tentative de saisie."); + addLineToFramedDisplay(display, nomPerso(defenseur) + " échappe à la tentative de saisie."); } explications.forEach(function(expl) { addLineToFramedDisplay(display, expl, 80); }); - sendChat("", endFramedDisplay(display)); + sendFramedDisplay(display); addEvent(evt); }); } @@ -40889,7 +41034,7 @@ var COFantasy = COFantasy || function() { evt.attributes.push({ attribute: attr }); - if ((carac == 'DEX' && comp != 'crochetage' && comp != 'd\xE9samor\xE7age') || + if ((carac == 'DEX' && comp != 'crochetage' && comp != 'désamorçage') || (carac == 'CON' && comp == 'survie') || comp == 'natation' || comp == 'escalade') { attrSpec.name = prefix + 'malus'; @@ -40935,7 +41080,7 @@ var COFantasy = COFantasy || function() { if (treatedChars.has(perso.charId)) return; treatedChars.add(perso.charId); if (!charAttributeAsBool(perso, 'ac')) { - sendPlayer(msg, nomPerso(perso) + " d\xE9j\xE0 converti (pas d'attribut ac)"); + sendPlayer(msg, nomPerso(perso) + " déjà converti (pas d'attribut ac)"); return; } let attributes = findObjs({ @@ -40987,6 +41132,10 @@ var COFantasy = COFantasy || function() { race = "Humain"; c = c.substring(6).trim(); attr.set('current', c); + } else if (c.startsWith('kobold')) { + race = "Kobold"; + c = c.substring(7).trim(); + attr.set('current', c); } changeAttributeName(attr, 'profil', evt); return; @@ -41009,11 +41158,14 @@ var COFantasy = COFantasy || function() { return; case 'rejuvenation': return; //Pas d'effet en combat + case 'rock catching': + notes += d + '\n'; + return; default: if (d.startsWith('channel resistance ')) { let resChannel = parseInt(d.substring(19)); if (isNaN(resChannel)) { - log("Capacit\xE9 d\xE9fensive " + d + " non connue"); + log("Capacité défensive " + d + " non connue"); } else { predicats += 'bonusSaveContre_positif:' + resChannel + ' '; return; @@ -41021,16 +41173,16 @@ var COFantasy = COFantasy || function() { } else if (d.startsWith('bravery ')) { let courage = parseInt(d.substring(8)); if (isNaN(courage)) { - log("Capacit\xE9 d\xE9fensive " + d + " non connue"); + log("Capacité défensive " + d + " non connue"); } else { predicats += 'courage:' + courage + ' '; return; } } else { - log("Capacit\xE9 d\xE9fensive " + d + " non connue"); + log("Capacité défensive " + d + " non connue"); } if (nonPrisEnCompte === '') - nonPrisEnCompte = 'Capacit\xE9s d\xE9fensives : ' + d; + nonPrisEnCompte = 'Capacités défensives : ' + d; else nonPrisEnCompte += ', ' + d; } }); @@ -41046,24 +41198,30 @@ var COFantasy = COFantasy || function() { if (w === '') return; switch (w) { case 'resurrection vulnerability': - notes += "D\xE9truit par un sort de r\xE9surection \n"; + notes += "Détruit par un sort de résurection \n"; return; case 'vulnerable to acid': + case 'vulnerability to acid': predicats += 'vulnerableA_acide '; return; case 'vulnerable to cold': + case 'vulnerability to cold': predicats += 'vulnerableA_froid '; return; case 'vulnerable to disease': + case 'vulnerability to disease': predicats += 'vulnerableA_maladie '; return; case 'vulnerable to electricity': + case 'vulnerability to electricity': predicats += 'vulnerableA_electrique '; return; case 'vulnerable to fire': + case 'vulnerability to fire': predicats += 'vulnerableA_feu '; return; case 'vulnerable to poison': + case 'vulnerability to poison': predicats += 'vulnerableA_poison '; return; default: @@ -41130,24 +41288,31 @@ var COFantasy = COFantasy || function() { case 'poison': predicats += 'immunite_poison '; return; - case 'poison': - predicats += 'immunite_sommeil '; + case 'fear': + predicats += 'immunite_peur '; + return; + case 'sleep': + predicats += 'immunite_endormi '; return; case 'construct': - predicats += 'sansEsprit creatureArtificielle immuniteSaignement'; + predicats += 'sansEsprit creatureArtificielle immuniteSaignement '; + return; + case 'blindness': + predicats += 'immunite_aveugle '; return; case 'undead': case 'traits': case 'effects': case 'plants': + case 'and': return; default: - log("Immunit\xE9 \xE0 " + i + " non trait\xE9e"); + log("Immunité à " + i + " non traitée"); immunitesNonTraitees += i + ' '; } }); if (immunitesNonTraitees !== '') { - log("Immunit\xE9s non trait\xE9es : " + immunitesNonTraitees); + log("Immunités non traitées : " + immunitesNonTraitees); attributsIgnores += 'immune : ' + immunitesNonTraitees + '.\n'; } deleteAttribute(attr, evt); @@ -41193,13 +41358,17 @@ var COFantasy = COFantasy || function() { if (rd === '') rd = 'poison:' + resVal; else rd += ', poison:' + resVal; return; + case 'sonic': + if (rd === '') rd = 'sonique:' + resVal; + else rd += ', sonique:' + resVal; + return; default: - log("R\xE9sistance \xE0 " + res[0] + " non trait\xE9e"); + log("Résistance à " + res[0] + " non traitée"); resistancesNonTraitees += r + ', '; } }); if (resistancesNonTraitees !== '') { - log("Resistances non trait\xE9es : " + resistancesNonTraitees); + log("Resistances non traitées : " + resistancesNonTraitees); attributsIgnores += 'resist : ' + resistancesNonTraitees + '.\n'; } deleteAttribute(attr, evt); @@ -41246,13 +41415,13 @@ var COFantasy = COFantasy || function() { predicats += 'nonVivant '; break; case 'dragon': - predicats += 'nonVivant '; + predicats += 'dragon '; break; case 'fey': - predicats += 'f\xE9e '; + predicats += 'fée '; break; case 'outsider': - predicats += 'ext\xE9rieur '; + predicats += 'extérieur '; break; case 'undead': predicats += 'nonVivant mortVivant '; @@ -41282,7 +41451,7 @@ var COFantasy = COFantasy || function() { taille = 'minuscule'; break; case 'tiny': - taille = 'tr\xE8s petit'; + taille = 'très petit'; break; case 'small': taille = 'petite'; @@ -41293,7 +41462,7 @@ var COFantasy = COFantasy || function() { taille = 'grand'; break; case 'huge': - taille = '\xE9norme'; + taille = 'énorme'; break; case 'gargantuan': case 'colossal': @@ -41382,15 +41551,15 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); return; case 'disable_device': - ajouteCompetence(perso, 'd\xE9samor\xE7age', 'DEX', attr.get('current'), evt); + ajouteCompetence(perso, 'désamorçage', 'DEX', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'disguise': - ajouteCompetence(perso, 'd\xE9guisement', 'CHA', attr.get('current'), evt); + ajouteCompetence(perso, 'déguisement', 'CHA', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'escape_artist': - ajouteCompetence(perso, '\xE9vasion', 'DEX', attr.get('current'), evt); + ajouteCompetence(perso, 'évasion', 'DEX', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'fly': @@ -41418,11 +41587,11 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); return; case 'knowledge_engineering': - ajouteCompetence(perso, 'connaissance (ing\xE9ni\xE9rie)', 'INT', attr.get('current'), evt); + ajouteCompetence(perso, 'connaissance (ingéniérie)', 'INT', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'knowledge_geography': - ajouteCompetence(perso, 'connaissance (g\xE9ographie)', 'INT', attr.get('current'), evt); + ajouteCompetence(perso, 'connaissance (géographie)', 'INT', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'knowledge_history': @@ -41466,7 +41635,7 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); return; case 'ride': - ajouteCompetence(perso, '\xC9quitation', 'DEX', attr.get('current'), evt); + ajouteCompetence(perso, 'Équitation', 'DEX', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'sense_motive': @@ -41478,11 +41647,11 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); return; case 'spellcraft': - ajouteCompetence(perso, 'sortil\xE8ges', 'INT', attr.get('current'), evt); + ajouteCompetence(perso, 'sortilèges', 'INT', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'stealth': - ajouteCompetence(perso, 'discr\xE9tion', 'DEX', attr.get('current'), evt); + ajouteCompetence(perso, 'discrétion', 'DEX', attr.get('current'), evt); deleteAttribute(attr, evt); return; case 'survival': @@ -41493,7 +41662,7 @@ var COFantasy = COFantasy || function() { ajouteCompetence(perso, 'natation', 'FOR', attr.get('current'), evt); deleteAttribute(attr, evt); return; - //Attributs de toutes facons modifi\xE9s: + //Attributs de toutes facons modifiés: case 'tab': case 'type_personnage': return; @@ -41521,7 +41690,7 @@ var COFantasy = COFantasy || function() { case 'skills_racial_modifiers': case 'fortitude': case 'reflex': - case 'will': //On n'y touche pas pour l'instant. \xC0 voir plus tard + case 'will': //On n'y touche pas pour l'instant. À voir plus tard let x = attr.get('current'); if (x === undefined || x === '') deleteAttribute(attr, evt); return; @@ -41580,7 +41749,7 @@ var COFantasy = COFantasy || function() { case 'spellabilities_flag': case 'sq': case 'xp': - case 'l1mancer_status': //Attributs ignor\xE9s + case 'l1mancer_status': //Attributs ignorés deleteAttribute(attr, evt); return; default: @@ -41620,6 +41789,48 @@ var COFantasy = COFantasy || function() { deleteAttribute(attr, evt); } }); + let cleave = false; + for (let pref in feats) { + let feat = feats[pref]; + switch (feat.name) { + case undefined: + break; + case 'Improved Initiative': + case 'Toughness': + case 'Weapon Finesse': + case 'Dodge': + case 'Combat Casting': + case 'Brew Potion': + break; + case 'Alertness': + predicats += 'vigilance:2 '; + break; + case 'Cleave': + cleave = true; + break; + case 'Defect Arrows': + predicats += 'paradeDeProjectiles '; + break; + case 'Point-Blank Shot': + predicats += 'tirPrecis:1 '; + break; + case 'Iron Will': + predicats += 'bonusSagesseMagie:2 '; + break; + default: + if (feat.name.startsWith('Weapon Focus (')) continue; + if (feat.name.startsWith('Weapon Specialization (')) continue; + notes += feat.name + ' : '; + if (feat.benefits) notes += feat.benefits + '\n'; + else if (feat.description) notes += feat.description + '\n'; + attributsIgnores += 'Feat ' + feat.name + ' : {'; + for (let field in feat) { + if (field == 'name') continue; + attributsIgnores += ' ' + field + ' : ' + feat[field] + ','; + } + attributsIgnores += '} .\n'; + } + } let maxAttackLabel = 0; for (let pref in attaques) { let attaque = attaques[pref]; @@ -41676,7 +41887,7 @@ var COFantasy = COFantasy || function() { break; default: if (!e.startsWith('+')) { - log("Ennemi jur\xE9 non reconnu : " + e); + log("Ennemi juré non reconnu : " + e); } } } @@ -41696,6 +41907,7 @@ var COFantasy = COFantasy || function() { }); let spec = ''; let options = ''; + let portee = 0; for (let field in attaque) { switch (field) { case 'atkmod': @@ -41713,7 +41925,7 @@ var COFantasy = COFantasy || function() { }); break; case 'dmgbase': - let dm = parseDice(attaque.dmgbase, 'd\xE9g\xE2ts'); + let dm = parseDice(attaque.dmgbase, 'dégâts'); if (dm) { if (dm.nbDe) createObj('attribute', { @@ -41769,13 +41981,13 @@ var COFantasy = COFantasy || function() { } break; case 'atkrange': - let range = parseInt(attaque.atkrange); - if (isNaN(range) || range < 0) range = 1; - else range = Math.floor(range / 2); + portee = parseInt(attaque.atkrange); + if (isNaN(portee) || portee < 0) portee = 1; + else portee = Math.floor(portee / 2); createObj('attribute', { _characterid: perso.charId, name: prefix + 'portee', - current: range + current: portee }); break; case 'dmgcritmulti': @@ -41784,7 +41996,7 @@ var COFantasy = COFantasy || function() { options += '--incrCritCoef ' + (cm - 2) + ' '; } break; - case 'atkname': //d\xE9j\xE0 trait\xE9 plus haut + case 'atkname': //déjà traité plus haut case 'options-flag': case 'dmgflag': case 'dmg2type': @@ -41796,6 +42008,7 @@ var COFantasy = COFantasy || function() { spec += field + ' : ' + attaque[field]; } } + if (cleave && portee === 0) options += '--target @{target|Cible 2|token_id} '; if (spec) createObj('attribute', { _characterid: perso.charId, @@ -41825,43 +42038,8 @@ var COFantasy = COFantasy || function() { if (ab.name) notes += ab.name + ' : '; if (ab.description) notes += ab.description + '\n'; } - for (let pref in feats) { - let feat = feats[pref]; - switch (feat.name) { - case undefined: - continue; - case 'Improved Initiative': - case 'Toughness': - case 'Weapon Finesse': - case 'Dodge': - case 'Combat Casting': - case 'Brew Potion': - continue; - case 'Defect Arrows': - predicats += 'paradeDeProjectiles '; - break; - case 'Point-Blank Shot': - predicats += 'tirPrecis:1 '; - break; - case 'Iron Will': - predicats += 'bonusSagesseMagie:2 '; - break; - default: - if (feat.name.startsWith('Weapon Focus (')) continue; - if (feat.name.startsWith('Weapon Specialization (')) continue; - notes += feat.name + ' : '; - if (feat.benefits) notes += feat.benefits + '\n'; - else if (feat.description) notes += feat.description + '\n'; - attributsIgnores += 'Feat ' + feat.name + ' : {'; - for (let field in feat) { - if (field == 'name') continue; - attributsIgnores += ' ' + field + ' : ' + feat[field] + ','; - } - attributsIgnores += '} .\n'; - } - } if (maxAttackLabel > 0) setAttr('max_attack_label', maxAttackLabel); - //Puis on met les attributs n\xE9cessaires + //Puis on met les attributs nécessaires if (attributsIgnores !== '') setAttr('Attributs Pathfinder', attributsIgnores); if (predicats !== '') setAttr('predicats_script', predicats); @@ -41877,10 +42055,10 @@ var COFantasy = COFantasy || function() { let initiative = dexterite + init - mod_dex; if (isNaN(initiative)) initiative = 10 + 2 * init; setAttr('pnj_init', initiative); - // N\xE9cessaire pour \xE9viter que les sheetworkers re-calculent init et def + // Nécessaire pour éviter que les sheetworkers re-calculent init et def if (initiative != dexterite) setAttr('INIT_DIV', initiative - dexterite); if (def != 10 + mod_dex) setAttr('DEFDIV', def - 10 - mod_dex); - //Finalement, on change le token par d\xE9faut + //Finalement, on change le token par défaut let acAttr = perso.token.get('bar2_link'); affectToken(perso.token, 'bar2_link', acAttr, evt); perso.token.set('bar2_link', ''); @@ -41947,7 +42125,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { @@ -41955,15 +42133,15 @@ var COFantasy = COFantasy || function() { return; } let positif = true; - if (cmd[1] === 'false' || cmd[1] === 'negatif' || cmd[1] === 'n\xE9gatif') + if (cmd[1] === 'false' || cmd[1] === 'negatif' || cmd[1] === 'négatif') positif = false; if (options.soin === undefined && options.dm === undefined) { - sendPlayer(msg, "Rien \xE0 canaliser. Il faut pr\xE9ciser un montant de soins ou de d\xE9g\xE2ts"); + sendPlayer(msg, "Rien à canaliser. Il faut préciser un montant de soins ou de dégâts"); return; } getSelected(msg, function(selected, playerId) { if (selected.length != 1) { - sendPlayer(msg, "Il faut s\xE9lectionner un personnage", playerId); + sendPlayer(msg, "Il faut sélectionner un personnage", playerId); return; } let token = getObj('graphic', selected[0]._id); @@ -41973,7 +42151,7 @@ var COFantasy = COFantasy || function() { } let charId = token.get('represents'); if (charId === undefined || charId === '') { - error("Le token ne repr\xE9sente pas un personnage", token); + error("Le token ne représente pas un personnage", token); return; } let pretre = { @@ -42053,7 +42231,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, e); }); } - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } }; if (options.soin) { @@ -42068,18 +42246,18 @@ var COFantasy = COFantasy || function() { let soins = res[0].inlinerolls[0].results.total; let soinTxt = buildinline(res[0].inlinerolls[0], 'normal', true); if (soins <= 0) { - sendPerso(pretre, "ne r\xE9ussit pas \xE0 soigner (total de soins " + soinTxt + ")", true); + sendPerso(pretre, "ne réussit pas à soigner (total de soins " + soinTxt + ")", true); sync(); return; } - //TODO: tenir compte des PV partag\xE9s + //TODO: tenir compte des PV partagés soigneToken(target, soins, evt, function(soinsEffectifs) { let line = "" + nomPerso(target) + " : + "; if (soinsEffectifs == soins) { line += soinTxt + 'PV'; } else { - line += soinsEffectifs + 'PV (jet: ' + soinTxt + ')'; + line += soinsEffectifs + ' PV (jet: ' + soinTxt + ')'; } addLineToFramedDisplay(display, line); sync(); @@ -42090,7 +42268,7 @@ var COFantasy = COFantasy || function() { }, options); }); } catch (rollError) { - error("Jet " + options.soin + " mal form\xE9", options); + error("Jet " + options.soin + " mal formé", options); } }); } @@ -42124,7 +42302,7 @@ var COFantasy = COFantasy || function() { copyDmgOptionsToTarget(target, options); dealDamage(target, dmg, [], evt, false, options, explications, function(dmgDisplay, dmgFinal) { addLineToFramedDisplay(display, - nomPerso(target) + " re\xE7oit " + dmgDisplay + " DM"); + nomPerso(target) + " reçoit " + dmgDisplay + " DM"); explications.forEach(function(e) { addLineToFramedDisplay(display, e, 80, false); }); @@ -42132,7 +42310,7 @@ var COFantasy = COFantasy || function() { }); }); } catch (rollError) { - error("Jet " + options.dm + " mal form\xE9", dm); + error("Jet " + options.dm + " mal formé", dm); } }); } @@ -42143,7 +42321,7 @@ var COFantasy = COFantasy || function() { 1: { token: "https://s3.amazonaws.com/files.d20.io/images/250177368/mJsYWMFqDeEmJDJy8tJKWA/thumb.png?1634130296", avatar: "https://s3.amazonaws.com/files.d20.io/images/250177753/IMzDqEpNpuznVnAMYRil8A/max.jpg?1634130507", - taille: 'tr\xE8s petite', + taille: 'très petite', force: 4, pnj_for: -3, constitution: 4, @@ -42213,13 +42391,13 @@ var COFantasy = COFantasy || function() { }; //!cof-animation-des-objets lid niveau [tid] - // la cible optionelle correspond \xE0 un token existant non associ\xE9 \xE0 un personnage + // la cible optionelle correspond à un token existant non associé à un personnage function animationDesObjets(msg) { let options = parseOptions(msg); if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -42233,7 +42411,7 @@ var COFantasy = COFantasy || function() { } let niveauObjet = parseInt(cmd[2]); if (isNaN(niveauObjet) || niveauObjet < 1) { - error("Le niveau de l'objet anim\xE9 doit \xEAtre un nombre positif", cmd); + error("Le niveau de l'objet animé doit être un nombre positif", cmd); return; } if (niveauObjet > 10) niveauObjet = 10; @@ -42246,7 +42424,7 @@ var COFantasy = COFantasy || function() { let dejaAnime = attributeAsInt(lanceur, 'niveauDesObjetsAnimes', 0); let playerId = getPlayerIdFromMsg(msg); if (dejaAnime + niveauObjet > niveau) { - sendPlayer(msg, "Impossible d'animer plus d'objets pour le moment : somme des niveau anim\xE9s = " + dejaAnime, playerId); + sendPlayer(msg, "Impossible d'animer plus d'objets pour le moment : somme des niveau animés = " + dejaAnime, playerId); return; } let evt = { @@ -42256,7 +42434,7 @@ var COFantasy = COFantasy || function() { if (limiteRessources(lanceur, options, 'animationObjet', "animation d'un objet", evt)) return; let tokenSize = 70; switch (stats.taille) { - case 'tr\xE8s petite': + case 'très petite': tokenSize = 35; break; case 'petite': @@ -42275,7 +42453,7 @@ var COFantasy = COFantasy || function() { let pageId = lanceur.token.get('pageid'); tokenObjet = tokenObjet || createObj('graphic', { - name: 'Objet anim\xE9', + name: 'Objet animé', subtype: 'token', pageid: pageId, imgsrc: stats.token, @@ -42293,12 +42471,12 @@ var COFantasy = COFantasy || function() { limit_field_of_vision_total: 0, }); if (tokenObjet === undefined) { - error("Impossible de cr\xE9er le token", stats); + error("Impossible de créer le token", stats); return; } toFront(tokenObjet); let persoObjet = { - nom: 'Objet anim\xE9 par ' + nomPerso(lanceur), + nom: 'Objet animé par ' + nomPerso(lanceur), attributesFiche: { type_personnage: 'PNJ', niveau: niveauObjet, @@ -42365,7 +42543,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -42380,9 +42558,9 @@ var COFantasy = COFantasy || function() { break; case 'DEX': case 'dexterite': - case 'dexterit\xE9': - case 'dext\xE9rit\xE9': - case 'dext\xE9rite': + case 'dexterité': + case 'dextérité': + case 'dextérite': carac = 'dexterite'; break; case 'CON': @@ -42402,18 +42580,18 @@ var COFantasy = COFantasy || function() { carac = 'charisme'; break; default: - error("Caract\xE9ristique " + carac + " non reconnue", cmd); + error("Caractéristique " + carac + " non reconnue", cmd); return; } let valeur = parseInt(cmd[2]); if (isNaN(valeur) || valeur < 1) { - error("La valeur de soin d'affaiblissement doit \xEAtre un nombre positif", cmd); + error("La valeur de soin d'affaiblissement doit être un nombre positif", cmd); return; } let lanceur = options.lanceur; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour le soin d'affaiblissement", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour le soin d'affaiblissement", playerId); return; } if (lanceur === undefined) { @@ -42458,7 +42636,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -42473,9 +42651,9 @@ var COFantasy = COFantasy || function() { break; case 'DEX': case 'dexterite': - case 'dexterit\xE9': - case 'dext\xE9rit\xE9': - case 'dext\xE9rite': + case 'dexterité': + case 'dextérité': + case 'dextérite': carac = 'dexterite'; break; case 'CON': @@ -42500,18 +42678,18 @@ var COFantasy = COFantasy || function() { carac = 'random'; break; default: - error("Caract\xE9ristique " + carac + " non reconnue", cmd); + error("Caractéristique " + carac + " non reconnue", cmd); return; } - let valeur = parseInt(cmd[2]); - if (isNaN(valeur) || valeur < 1) { - error("La valeur d'affaiblissement doit \xEAtre un nombre positif", cmd); + let valeur = parseDice(cmd[2]); + if (!valeur || !dePositif(valeur)) { + error("La valeur d'affaiblissement doit être un nombre positif", cmd); return; } let lanceur = options.lanceur; getSelected(msg, function(selected, playerId) { if (selected === undefined || selected.length === 0) { - sendPlayer(msg, "Pas de cible s\xE9lection\xE9e pour l'affaiblissement", playerId); + sendPlayer(msg, "Pas de cible sélectionée pour l'affaiblissement", playerId); return; } if (lanceur === undefined) { @@ -42537,7 +42715,7 @@ var COFantasy = COFantasy || function() { } } if (options.type && immuniseAuType(perso, options.type, lanceur)) { - sendPerso(perso, "ne semble pas affect\xE9 par " + stringOfType(options.type)); + sendPerso(perso, "ne semble pas affecté par " + stringOfType(options.type)); return; } cibles.push(perso); @@ -42578,17 +42756,38 @@ var COFantasy = COFantasy || function() { return carac; } - //carac est une caract\xE9ristique enti\xE8re + //carac est une caractéristique entière + //valeur est soit un nombre, soit le résultat de parseDice function affaiblirCaracPerso(perso, carac, valeur, expliquer, evt) { let nomAttr = 'affaiblissementde' + carac; + let valeurText = valeur; + if (isNaN(valeur)) { + let rid = valeur.id; + if (rid === undefined) { + error("Résultat de parseDice sans id", valeur); + return; + } + if (perso.affaiblirCaracRoll && perso.affaiblirCaracRoll[rid]) { + let r = perso.affaiblirCaracRoll[rid]; + valeur = r.val; + valeurText = r.roll; + } else { + let r = rollDePlus(valeur); + valeur = r.val; + valeurText = r.roll; + perso.affaiblirCaracRoll = perso.affaiblirCaracRoll || {}; + perso.affaiblirCaracRoll[rid] = r; + } + } let malus = addToAttributeAsInt(perso, nomAttr, 0, valeur, evt); let cn = caracNormale(perso, carac); if (malus > cn) { valeur += cn - malus; + valeurText = valeur; setTokenAttr(perso, nomAttr, cn, evt); } if (valeur < 1) return; - expliquer("perd " + valeur + " points de " + carac); + expliquer("perd " + valeurText + " points de " + carac); if (carac == 'constitution') { if (malus >= cn) { mort(perso, expliquer, evt); @@ -42621,7 +42820,7 @@ var COFantasy = COFantasy || function() { updateCurrentBar(perso, 1, bar1, evt, pvmax); if (bar1 === 0) mort(perso, expliquer, evt); } - } else { //autre caract\xE9ristiques + } else { //autre caractéristiques if (malus >= cn) { setState(perso, 'renverse', true, evt); setState(perso, 'assomme', true, evt); @@ -42629,16 +42828,17 @@ var COFantasy = COFantasy || function() { } } + // valeur peut être un nombre ou le résultat de parseDice function affaiblirCarac(playerId, cibles, carac, valeur, options) { const evt = { type: 'affaiblissement', action: { titre: "Affaiblissement de " + carac, - playerId: playerId, - cibles: cibles, - carac: carac, - valeur: valeur, - options: options + playerId, + cibles, + carac, + valeur, + options, } }; let lanceur = options.lanceur; @@ -42664,8 +42864,8 @@ var COFantasy = COFantasy || function() { }; if (options.save) { let saveOpts = { - msgPour: " pour r\xE9sister \xE0 un affaiblissement de " + car, - msgRate: ", rat\xE9.", + msgPour: " pour résister à un affaiblissement de " + car, + msgRate: ", raté.", attaquant: lanceur, rolls: options.rolls, chanceRollId: options.chanceRollId, @@ -42690,7 +42890,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { @@ -42705,19 +42905,19 @@ var COFantasy = COFantasy || function() { let playerId = getPlayerIdFromMsg(msg); let attr = tokenAttribute(perso, 'reactionViolente'); if (attr.length === 0) { - sendPlayer(msg, "Action inutile, " + perso.token.ge('name') + " n'est pas sous l'effet d'une r\xE9action violente", playerId); + sendPlayer(msg, "Action inutile, " + perso.token.ge('name') + " n'est pas sous l'effet d'une réaction violente", playerId); return; } attr = attr[0]; let duree = parseInt(attr.get('current')); if (isNaN(duree) || duree < 1) duree = 1; let evt = { - type: "Fin de r\xE9action violente", + type: "Fin de réaction violente", deletedAttributes: [attr] }; addEvent(evt); attr.remove(); - sendPerso(perso, "prend sur " + onGenre(perso, 'lui', 'elle') + " pour contenir sa r\xE9action violente"); + sendPerso(perso, "prend sur " + onGenre(perso, 'lui', 'elle') + " pour contenir sa réaction violente"); options.ignoreRD = true; let de = 6; if (predicateAsBool(perso, 'sangFroid')) de = 4; @@ -42735,16 +42935,16 @@ var COFantasy = COFantasy || function() { }); } - //!cof-explosion correspond \xE0 !cof-attack token token --explosion pour chaque token s\xE9lectionn\xE9 + //!cof-explosion correspond à !cof-attack token token --explosion pour chaque token sélectionné function attaqueExplosion(msg) { if (!msg.content) return; let index = msg.content.indexOf(' '); if (index < 1) { - error("Il manque le label de l'attaque \xE0 utiliser pour !cof-explosion", msg.content); + error("Il manque le label de l'attaque à utiliser pour !cof-explosion", msg.content); return; } let args_msg = msg.content.substring(index); - //On va ensuite enlever tout ce qui vient apr\xE8s --target + //On va ensuite enlever tout ce qui vient après --target index = args_msg.indexOf(' --target '); if (index > 0) args_msg = args_msg.substring(0, index); args_msg += ' --explosion'; @@ -42759,7 +42959,7 @@ var COFantasy = COFantasy || function() { }, { ignoreAllies: true, ignoreDisque: true - }); //On ignore les options d'alli\xE9s dans le getSelected + }); //On ignore les options d'alliés dans le getSelected } const listeEffetsAuD20 = { @@ -42785,7 +42985,7 @@ var COFantasy = COFantasy || function() { function setEffetChaqueD20(msg) { let playerId = getPlayerIdFromMsg(msg); if (!playerIsGM(playerId)) { - sendPlayer(msg, "Commande r\xE9serv\xE9e au MJ", playerId); + sendPlayer(msg, "Commande réservée au MJ", playerId); return; } let cmd = msg.content.split(' '); @@ -42879,7 +43079,7 @@ var COFantasy = COFantasy || function() { } let playerId = getPlayerIdFromMsg(msg); if (!playerIsGM(playerId)) { - sendPlayer(msg, "Commande r\xE9serv\xE9e aux MJs", playerId); + sendPlayer(msg, "Commande réservée aux MJs", playerId); return; } let pageId = getPageId(playerId); @@ -42889,7 +43089,7 @@ var COFantasy = COFantasy || function() { } let page = getObj('page', pageId); if (page === undefined) { - error("Impossible de trouver la page correspondant \xE0 l'id", pageId); + error("Impossible de trouver la page correspondant à l'id", pageId); return; } let agrandir = function(o, field) { @@ -42928,31 +43128,31 @@ var COFantasy = COFantasy || function() { texts.forEach(function(t) { move(t); }); - sendPlayer('GM', "Agrandissement termin\xE9"); + sendPlayer('GM', "Agrandissement terminé"); } function decoincer(msg) { getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Pas de token s\xE9lectionn\xE9", playerId); + sendPlayer(msg, "Pas de token sélectionné", playerId); return; } if (!playerIsGM(playerId)) { - sendPlayer(msg, "Action r\xE9serv\xE9e au MJ", playerId); + sendPlayer(msg, "Action réservée au MJ", playerId); return; } const evt = { - type: "D\xE9coincer", + type: "Décoincer", tokens: [] }; let pageId; iterSelected(selected, function(perso) { if (attributeAsBool(perso, 'decoince')) { - sendPlayer(msg, nomPerso(perso) + " peut d\xE9j\xE0 \xEAtre d\xE9plac\xE9", playerId); + sendPlayer(msg, nomPerso(perso) + " peut déjà être déplacé", playerId); return; } if (!perso.token.get('lockMovement')) { - sendPlayer(msg, nomPerso(perso) + "n'est pas bloqu\xE9", playerId); + sendPlayer(msg, nomPerso(perso) + "n'est pas bloqué", playerId); return; } let nom = 'decoince ' + perso.token.get('name'); @@ -43006,14 +43206,14 @@ var COFantasy = COFantasy || function() { }; let tokenBouge = createObj('graphic', tokenFields); if (!tokenBouge) { - error("Impossible de cr\xE9er de token pour d\xE9coincer " + nomPerso(perso), tokenFields); + error("Impossible de créer de token pour décoincer " + nomPerso(perso), tokenFields); return; } evt.tokens.push(tokenBouge); toFront(tokenBouge); setTokenAttr(perso, 'bougeGraceA', tokenBouge.id, evt); }); - if (pageId) sendPlayer(msg, "Penser \xE0 supprimer le token invisible quand vous aurez termin\xE9 le d\xE9placement", playerId); + if (pageId) sendPlayer(msg, "Penser à supprimer le token invisible quand vous aurez terminé le déplacement", playerId); }); } @@ -43082,7 +43282,7 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { @@ -43096,7 +43296,7 @@ var COFantasy = COFantasy || function() { } let cible = persoOfId(cmd[2]); if (cible === undefined) { - error("Le deuxi\xE8me argument de !cof-sentir-la-corruption n'est pas un token valide", msg.content); + error("Le deuxième argument de !cof-sentir-la-corruption n'est pas un token valide", msg.content); return; } let portee = 30; @@ -43139,10 +43339,10 @@ var COFantasy = COFantasy || function() { } if (display.retarde) { addFramedHeader(display, playerId, true); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); addFramedHeader(display, undefined, 'gm'); - sendChat('', endFramedDisplay(display)); - } else sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); + } else sendFramedDisplay(display); }; if (tr.reussite) { addLineToFramedDisplay(display, msgRes + tr.modifiers); @@ -43150,7 +43350,7 @@ var COFantasy = COFantasy || function() { testCaracteristique(cible, 'INT', 15, 'sentirLaCorruptionCible', options, evt, function(tr, explications) { let msgRes = "Jet d'INT de " + nomPerso(cible) + " : " + tr.texte; - //On n'affiche pas les possibilit\xE9s de rerolls, sinon il faudrait un bouton pour "continuer" afin de ne pas afficher le r\xE9sultat. + //On n'affiche pas les possibilités de rerolls, sinon il faudrait un bouton pour "continuer" afin de ne pas afficher le résultat. addLineToFramedDisplay(display, msgRes + tr.modifiers); explications.forEach(function(m) { addLineToFramedDisplay(display, m, 80); @@ -43179,7 +43379,7 @@ var COFantasy = COFantasy || function() { } } else { addLineToFramedDisplay(display, msgRes + tr.rerolls + tr.modifiers); - addLineToFramedDisplay(display, nomPerso(chasseur) + " ne r\xE9ussit pas \xE0 sentir la corruption."); + addLineToFramedDisplay(display, nomPerso(chasseur) + " ne réussit pas à sentir la corruption."); endDisplay(); } }); @@ -43191,28 +43391,28 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } let nbBaies; if (cmd.length > 1) { nbBaies = parseInt(cmd[1]); if (isNaN(nbBaies) || nbBaies < 1) { - sendPlayer(msg, "Aucune baie cr\xE9\xE9e. la commnde en demandait " + cmd[1]); + sendPlayer(msg, "Aucune baie créée. la commnde en demandait " + cmd[1]); return; } } getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Utilisation de !cof-creer-baies sans s\xE9lection de token", playerId); + sendPlayer(msg, "Utilisation de !cof-creer-baies sans sélection de token", playerId); return; } const evt = { - type: "Cr\xE9ation de baies" + type: "Création de baies" }; addEvent(evt); iterSelected(selected, function(druide) { - if (limiteRessources(druide, options, 'creationDeBaies', "cr\xE9er des baies", evt)) return; + if (limiteRessources(druide, options, 'creationDeBaies', "créer des baies", evt)) return; let niveau = ficheAttributeAsInt(druide, 'niveau', 1); let mangerBaie = "!cof-consommer-baie " + niveau + " --limiteParJour 1 baieMagique"; let nb; @@ -43227,7 +43427,7 @@ var COFantasy = COFantasy || function() { }); } ajouterConsommable(druide, 'Baie magique', nb.val, mangerBaie, evt); - sendPerso(druide, "cr\xE9e " + nb.roll + " baies magiques"); + sendPerso(druide, "crée " + nb.roll + " baies magiques"); }); }); } @@ -43255,12 +43455,12 @@ var COFantasy = COFantasy || function() { if (attr.length > 0) { attr = attr[0]; if (attr.length > 1) { - error("Plus d'un attribut pour la quantit\xE9 d'armes de jet", attr); + error("Plus d'un attribut pour la quantité d'armes de jet", attr); attr[1].remove(); } max = parseInt(attr.get('max')); if (isNaN(max) || max < 1) { - error("Maximum de " + weaponStats.name + " mal form\xE9, v\xE9rifier sur la fiche", attr); + error("Maximum de " + weaponStats.name + " mal formé, vérifier sur la fiche", attr); max = 1; } evt.attributes.push({ @@ -43280,7 +43480,7 @@ var COFantasy = COFantasy || function() { }); } if (weaponStats.nbArmesDeJet >= max) { - error(nomPerso(lanceur) + " a d\xE9j\xE0 toutes ses armes de jet (" + max + ")", weaponStats); + error(nomPerso(lanceur) + " a déjà toutes ses armes de jet (" + max + ")", weaponStats); return; } attr.set('current', weaponStats.nbArmesDeJet + 1); @@ -43293,16 +43493,16 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 3) { - error("Il manque des arguments \xE0 !cof-retour-boomerang", cmd); + error("Il manque des arguments à !cof-retour-boomerang", cmd); return; } let lanceur = persoOfId(cmd[1]); if (!lanceur) { - error("L'id du token ayan lanc\xE9 les armes est incorrecte", cmd); + error("L'id du token ayan lancé les armes est incorrecte", cmd); return; } let evt = { @@ -43319,11 +43519,11 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { - error("Il manque un argument \xE0 !cof-open-door", cmd); + error("Il manque un argument à !cof-open-door", cmd); return; } let door = getObj('door', cmd[1]); @@ -43334,7 +43534,7 @@ var COFantasy = COFantasy || function() { door.set('isOpen', true); } - //Demande de bouger son token jusqu'\xE0 destination + //Demande de bouger son token jusqu'à destination function attaqueLigneBouger(msg) { const playerId = getPlayerIdFromMsg(msg); if (stateCOF.pause && !playerIsGM(playerId)) { @@ -43343,7 +43543,7 @@ var COFantasy = COFantasy || function() { } let args = msg.content.split(' '); if (args.length < 2) { - error("Il manque un argument \xE0 !cof-attack-line", args); + error("Il manque un argument à !cof-attack-line", args); return; } const attaquant = persoOfId(args[1]); @@ -43354,12 +43554,12 @@ var COFantasy = COFantasy || function() { let token = attaquant.token; let restArgs = args.slice(2).join(' '); let command = '!cof-attack-line-from ' + token.get('left') + ' ' + token.get('top') + ' ' + token.id + ' ' + restArgs; - sendPlayer(msg, "D\xE9placer votre token jusqu'au bout de la ligne (l'emplacement doit \xEAtre libre), et " + boutonSimple(command, "cliquer ici"), playerId); + sendPlayer(msg, "Déplacer votre token jusqu'au bout de la ligne (l'emplacement doit être libre), et " + boutonSimple(command, "cliquer ici"), playerId); return; } - //En partant de from, retourne la premi\xE8re position sur le segment [from, to] - // \xE0 distance dist de pt. S'il n'y en a pas, retourne la projection de pt sur le segment + //En partant de from, retourne la première position sur le segment [from, to] + // à distance dist de pt. S'il n'y en a pas, retourne la projection de pt sur le segment function positionLigne(from, to, token, dist) { let fx = from.x; let fy = from.y; @@ -43405,7 +43605,7 @@ var COFantasy = COFantasy || function() { let originLeft = parseInt(args[1]); let originTop = parseInt(args[2]); if (isNaN(originLeft) || isNaN(originTop)) { - error("Coordonn\xE9es non num\xE9riques dans !co-attack-line", args); + error("Coordonnées non numériques dans !co-attack-line", args); return; } const attaquant = persoOfId(args[3]); @@ -43415,7 +43615,7 @@ var COFantasy = COFantasy || function() { } let destLeft = attaquant.token.get('left'); let destTop = attaquant.token.get('top'); - //On remet l'attaquant \xE0 sa place + //On remet l'attaquant à sa place attaquant.token.set('left', originLeft); attaquant.token.set('top', originTop); let combat = stateCOF.combat; @@ -43442,12 +43642,12 @@ var COFantasy = COFantasy || function() { y: originTop }; let tropLoin = false; - //On cherche si argument --distanceMax, pas utilis\xE9 par cof-attack + //On cherche si argument --distanceMax, pas utilisé par cof-attack optArgs = optArgs.filter(function(cmd) { if (!cmd.startsWith('distanceMax')) return true; let a = cmd.split(' '); if (a.length < 2) { - error("Il manque un argument \xE0 --distanceMax", cmd); + error("Il manque un argument à --distanceMax", cmd); return false; } let distanceMax = parseInt(a[1]); @@ -43500,14 +43700,14 @@ var COFantasy = COFantasy || function() { return; } } - //On d\xE9termine les cibles sur le trajet + //On détermine les cibles sur le trajet let cibles = []; tokens.forEach(function(tok) { let cible = { token: tok, charId: tok.get('represents') }; - if (nePeutPlusPrendreDM(cible, {})) return; //pas de d\xE9g\xE2ts aux morts + if (nePeutPlusPrendreDM(cible, {})) return; //pas de dégâts aux morts let distToTrajectory = distancePixTokenSegment(tok, ptOrigin, ptDest); if (distToTrajectory > attRayon + tokenSize(tok, 0)) return; @@ -43534,7 +43734,7 @@ var COFantasy = COFantasy || function() { }); combat.attackId = combat.attackId || 0; combat.attackCallbacks = combat.attackCallBacks || {}; - //On trie les cibles selon leur distance \xE0 l'origine. + //On trie les cibles selon leur distance à l'origine. cibles.sort(function(c1, c2) { return c1.distanceOrigine - c2.distanceOrigine; }); @@ -43583,11 +43783,11 @@ var COFantasy = COFantasy || function() { if (options === undefined) return; let cmd = options.cmd; if (cmd === undefined) { - error("Probl\xE8me de parse options", msg.content); + error("Problème de parse options", msg.content); return; } if (cmd.length < 2) { - error("Il manque un argument \xE0 !cof-vision-nocturne", cmd); + error("Il manque un argument à !cof-vision-nocturne", cmd); return; } let distance = parseInt(cmd[1]); @@ -43598,7 +43798,7 @@ var COFantasy = COFantasy || function() { let pageId = options.pageId; getSelected(msg, function(selected, playerId) { if (selected.length === 0) { - sendPlayer(msg, "Utilisation de !cof-vision-nocturne sans s\xE9lection de token", playerId); + sendPlayer(msg, "Utilisation de !cof-vision-nocturne sans sélection de token", playerId); return; } const evt = { @@ -43618,27 +43818,27 @@ var COFantasy = COFantasy || function() { const listeDesRunesMortes = { Melianil: { - description: "+2 en attaque et +1d6 aux DM (\xE0 tous les sorts ou aux attaques au contact avec le b\xE2ton)", + description: "+2 en attaque et +1d6 aux DM (à tous les sorts ou aux attaques au contact avec le bâton)", }, Isulys: { - description: "une fois par tour, par une action d'attaque, peut produire un rayon d\x2019\xE9nergie n\xE9gative d\x2019une port\xE9e de 40 m\xE8tres. Sur test d\x2019attaque magique r\xE9ussit, la victime subit [2d6 + Mod. %SAGINT] DM et doit utiliser un d12 \xE0 tous ses tests au lieu d\x2019un d20 pendant un tour.", + description: "une fois par tour, par une action d'attaque, peut produire un rayon d’énergie négative d’une portée de 40 mètres. Sur test d’attaque magique réussit, la victime subit [2d6 + Mod. %SAGINT] DM et doit utiliser un d12 à tous ses tests au lieu d’un d20 pendant un tour.", }, Bryniza: { - description: "permet de voir parfaitement dans le noir \xE0 une port\xE9e de 30 m, et comme dans la p\xE9nombre jusqu'\xE0 50 m. Au prix d'une action limit\xE9e, le porteur peut utiliser le sort D\xE9tection de la magie 3 fois par jour.", + description: "permet de voir parfaitement dans le noir à une portée de 30 m, et comme dans la pénombre jusqu'à 50 m. Au prix d'une action limitée, le porteur peut utiliser le sort Détection de la magie 3 fois par jour.", activation: "Les yeux de %NOM deviennent d'un noir d'encre.", fin: "Les yeux de %NOM redeviennent normaux.", }, Lizura: { - description: "immunit\xE9 au souffle de Swarathnak, \xE0 l'acide et au poison.", - activation: "La boue noire du b\xE2ton s'\xE9coule le long du bras de %NOM et recouvre tout son corps \xE0 l'exception des yeux.", - fin: "La boue se retire dans le b\xE2ton, %NOM retrouve une apparence normale.", + description: "immunité au souffle de Swarathnak, à l'acide et au poison.", + activation: "La boue noire du bâton s'écoule le long du bras de %NOM et recouvre tout son corps à l'exception des yeux.", + fin: "La boue se retire dans le bâton, %NOM retrouve une apparence normale.", memeEffetQue: 'Mitrah', }, Mitrah: { - description: "RD 5 \xE0 tous les DM.", - activation: "La boue noire du b\xE2ton s'\xE9coule le long du bras de %NOM et recouvre tout son corps \xE0 l'exception des yeux.", - fin: "La boue se retire dans le b\xE2ton, %NOM retrouve une apparence normale.", + description: "RD 5 à tous les DM.", + activation: "La boue noire du bâton s'écoule le long du bras de %NOM et recouvre tout son corps à l'exception des yeux.", + fin: "La boue se retire dans le bâton, %NOM retrouve une apparence normale.", memeEffetQue: 'Lizura', }, }; @@ -43650,13 +43850,13 @@ var COFantasy = COFantasy || function() { function gererRunesMortes(msg) { let cmd = msg.content.split(' '); if (cmd.length < 2) { - error("il manque l'id du personnage qui g\xE8re ses runes mortes", cmd); + error("il manque l'id du personnage qui gère ses runes mortes", cmd); return; } let perso = persoOfId(cmd[1]); if (perso === undefined) return; if (!predicateAsBool(perso, 'batonDesRunesMortes')) { - sendPerso(perso, "ne porte pas le b\xE2ton des runes mortes"); + sendPerso(perso, "ne porte pas le bâton des runes mortes"); return; } let niveau = ficheAttributeAsInt(perso, 'niveau', 1); @@ -43680,7 +43880,7 @@ var COFantasy = COFantasy || function() { error("Rune " + cmd[3] + " non reconnue", cmd); break; } - //V\xE9rification qu'on n'a pas d\xE9j\xE0 le max de runes + //Vérification qu'on n'a pas déjà le max de runes let runesLibres = Math.ceil(niveau / 4); for (let rune in listeDesRunesMortes) { if (attributeAsBool(perso, 'rune' + rune)) runesLibres--; @@ -43694,11 +43894,11 @@ var COFantasy = COFantasy || function() { if (attr[0].get('current') == 'false') { let donne = attr[0].get('max'); if (donne) { - sendPerso(perso, "a donn\xE9 " + cmd[3] + " \xE0 " + donne + ". Impossible de l'activer.", true); + sendPerso(perso, "a donné " + cmd[3] + " à " + donne + ". Impossible de l'activer.", true); break; } } else { - sendPerso(perso, cmd[3] + " est d\xE9j\xE0 active", true); + sendPerso(perso, cmd[3] + " est déjà active", true); break; } } @@ -43738,7 +43938,7 @@ var COFantasy = COFantasy || function() { break; } if (!attributeAsBool(perso, 'rune' + cmd[3])) { - sendPerso(perso, cmd[3] + " n'est pas activ\xE9e.", true); + sendPerso(perso, cmd[3] + " n'est pas activée.", true); break; } let msg; @@ -43750,7 +43950,7 @@ var COFantasy = COFantasy || function() { msg }); if (cmd[3] == 'Bryniza') { - //On enl\xE8ve la vision dans le noir + //On enlève la vision dans le noir let token = perso.token; let pageId = token.get('pageid'); let visionNoir = predicateAsInt(perso, 'visionDansLeNoir', 0); @@ -43773,12 +43973,12 @@ var COFantasy = COFantasy || function() { case 'donner': { if (cmd.length < 4) { - error("Il faut pr\xE9ciser le token \xE0 qui donner la rune", cmd); + error("Il faut préciser le token à qui donner la rune", cmd); break; } let cible = persoOfId(cmd[4]); if (!cible) { - error("Impossible de trouver \xE0 qui donner la rune", cmd); + error("Impossible de trouver à qui donner la rune", cmd); break; } let attr = tokenAttribute(perso, 'rune' + cmd[3]); @@ -43786,11 +43986,11 @@ var COFantasy = COFantasy || function() { if (attr[0].get('current') == 'false') { let donne = attr[0].get('max'); if (donne) { - sendPerso(perso, "a d\xE9j\xE0 donn\xE9 " + cmd[3] + " \xE0 " + donne + ".", true); + sendPerso(perso, "a déjà donné " + cmd[3] + " à " + donne + ".", true); break; } } else { - sendPerso(perso, "Il faut d'abord d\xE9sactiver " + cmd[3] + " avant de la donner", true); + sendPerso(perso, "Il faut d'abord désactiver " + cmd[3] + " avant de la donner", true); break; } } @@ -43799,14 +43999,14 @@ var COFantasy = COFantasy || function() { error("Rune " + cmd[3] + " non reconnue", cmd); break; } - let msg = nomPerso(perso) + " donne une rune \xE0 " + nomPerso(cible); + let msg = nomPerso(perso) + " donne une rune à " + nomPerso(cible); let maxVal = nomPerso(cible); setTokenAttr(perso, 'rune' + cmd[3], 'false', evt, { msg, maxVal }); - sendPerso(perso, "peut maintenant communiquer par t\xE9l\xE9pathie avec " + nomPerso(cible), true); - sendPerso(cible, "peut maintenant communiquer par t\xE9l\xE9pathie avec " + nomPerso(perso), true); + sendPerso(perso, "peut maintenant communiquer par télépathie avec " + nomPerso(cible), true); + sendPerso(cible, "peut maintenant communiquer par télépathie avec " + nomPerso(perso), true); break; } case 'recuperer': @@ -43818,23 +44018,23 @@ var COFantasy = COFantasy || function() { } let attr = tokenAttribute(perso, 'rune' + cmd[3]); if (attr.length === 0) { - sendPerso(perso, "a d\xE9j\xE0 " + cmd[3], true); + sendPerso(perso, "a déjà " + cmd[3], true); break; } if (attr[0].get('current') != 'false') { - sendPerso(perso, "a d\xE9j\xE0 " + cmd[3], true); + sendPerso(perso, "a déjà " + cmd[3], true); break; } let donne = attr[0].get('max'); if (!donne) { - sendPerso(perso, "a d\xE9j\xE0 " + cmd[3], true); + sendPerso(perso, "a déjà " + cmd[3], true); break; } - let msg = nomPerso(perso) + " rappelle une rune sur le b\xE2ton"; + let msg = nomPerso(perso) + " rappelle une rune sur le bâton"; removeTokenAttr(perso, 'rune' + cmd[3], evt, { msg }); - sendPerso(perso, "ne peut plus communiquer par t\xE9l\xE9pathie avec " + donne, true); + sendPerso(perso, "ne peut plus communiquer par télépathie avec " + donne, true); break; } default: @@ -43871,13 +44071,13 @@ var COFantasy = COFantasy || function() { if (er.actif) { ligne = ' 0) { ef = ef.substring(0, pu); if (messageEffetTemp[ef]) return ef; } - //Ensuite on enl\xE8ve les parties entre parenth\xE8se pour les effets g\xE9n\xE9riques + //Ensuite on enlève les parties entre parenthèse pour les effets génériques pu = ef.indexOf('('); if (pu > 0) { ef = ef.substring(0, pu); if (messageEffetTemp[ef]) return ef; } - error("Impossible de d\xE9terminer l'effet correspondant \xE0 " + ef, attr); + error("Impossible de déterminer l'effet correspondant à " + ef, attr); } function messageOfEffetTemp(effetC) { @@ -45670,61 +45910,61 @@ var COFantasy = COFantasy || function() { res = messageEffetTemp[ef]; return res; } - error("Effet temporaire non trouv\xE9", effetC); + error("Effet temporaire non trouvé", effetC); } const messageEffetCombat = { a0PVDepuis: { - activation: "est \xE0 0 PV", - actif: "est \xE0 0 PV", + activation: "est à 0 PV", + actif: "est à 0 PV", fin: "" }, armureMagique: { - activation: "est entour\xE9 d'un halo magique", - activationF: "est entour\xE9e d'un halo magique", - actif: "est prot\xE9g\xE9 par une armure magique", - actifF: "est prot\xE9g\xE9e par une armure magique", - fin: "n'est plus entour\xE9 d'un halo magique", - finF: "n'est plus entour\xE9e d'un halo magique" + activation: "est entouré d'un halo magique", + activationF: "est entourée d'un halo magique", + actif: "est protégé par une armure magique", + actifF: "est protégée par une armure magique", + fin: "n'est plus entouré d'un halo magique", + finF: "n'est plus entourée d'un halo magique" }, armureDuMage: { - activation: "fait appara\xEEtre un nuage magique argent\xE9 qui le prot\xE8ge", - activationF: "fait appara\xEEtre un nuage magique argent\xE9 qui la prot\xE8ge", - actif: "est entour\xE9 d'une armure du mage", - actifF: "est entour\xE9e d'une armure du mage", + activation: "fait apparaître un nuage magique argenté qui le protège", + activationF: "fait apparaître un nuage magique argenté qui la protège", + actif: "est entouré d'une armure du mage", + actifF: "est entourée d'une armure du mage", fin: "n'a plus son armure du mage" }, armureDEau: { - activation: "fait appara\xEEtre une couche d'eau de quelques centim\xE8tres qui le prot\xE8ge", - activationF: "fait appara\xEEtre une couche d'eau de quelques centim\xE8tres qui la prot\xE8ge", - actif: "est entour\xE9 d'une armure d'eau'", - actifF: "est entour\xE9e d'une armure d'eau'", + activation: "fait apparaître une couche d'eau de quelques centimètres qui le protège", + activationF: "fait apparaître une couche d'eau de quelques centimètres qui la protège", + actif: "est entouré d'une armure d'eau'", + actifF: "est entourée d'une armure d'eau'", fin: "n'a plus son armure d'eau'" }, armeDArgent: { - activation: "cr\xE9e une arme d'argent et de lumi\xE8re", - actif: "poss\xE8de une arme d'argent et de lumi\xE8re", - fin: "ne poss\xE8de plus d'arme d'argent et de lumi\xE8re", + activation: "crée une arme d'argent et de lumière", + actif: "possède une arme d'argent et de lumière", + fin: "ne possède plus d'arme d'argent et de lumière", dm: true }, attaqueAOutrance: { - activation: "attaque \xE0 outrance", - actif: "attaque \xE0 outrance", + activation: "attaque à outrance", + actif: "attaque à outrance", fin: "attaque normalement", }, - bonusInitEmbuscade: { //Effet interne pour la capacit\xE9 Surveillance + bonusInitEmbuscade: { //Effet interne pour la capacité Surveillance activation: "a un temps d'avance en cas d'embuscade", actif: "a un temps d'avance", fin: "" }, criDeGuerre: { activation: "pousse son cri de guerre", - actif: "a effray\xE9 ses adversaires", + actif: "a effrayé ses adversaires", fin: "" }, criDuPredateur: { activation: "pousse un hurlement effrayant", - actif: "a lib\xE9r\xE9 son \xE2me de pr\xE9dateur", + actif: "a libéré son âme de prédateur", fin: "" }, danseDesLames: { @@ -45733,22 +45973,22 @@ var COFantasy = COFantasy || function() { fin: "termine sa danse des lames" }, detournerLeRegard: { - activation: "d\xE9tourne le regard", - actif: "d\xE9tourne le regard", + activation: "détourne le regard", + actif: "détourne le regard", fin: "regarde normalement", }, enflamme: { activation: "prend feu !", actif: "est en feu", - fin: "les flammes s'\xE9teignent", + fin: "les flammes s'éteignent", dm: true, statusMarker: 'red', }, enrage: { - activation: "devient enrag\xE9", - activationF: "devient enrag\xE9e", - actif: "est enrag\xE9", - actifF: "est enrag\xE9e", + activation: "devient enragé", + activationF: "devient enragée", + actif: "est enragé", + actifF: "est enragée", fin: "retrouve son calme", msgSave: "retrouver son calme", }, @@ -45759,17 +45999,17 @@ var COFantasy = COFantasy || function() { fin: "retrouve son calme" }, protectionContreLeMal: { - activation: "re\xE7oit une b\xE9n\xE9diction de protection contre le mal", - actif: "est prot\xE9g\xE9 contre le mal", - actifF: "est prot\xE9g\xE9e contre le mal", - fin: "n'est plus prot\xE9g\xE9 contre le mal", - finF: "n'est plus prot\xE9g\xE9e contre le mal", + activation: "reçoit une bénédiction de protection contre le mal", + actif: "est protégé contre le mal", + actifF: "est protégée contre le mal", + fin: "n'est plus protégé contre le mal", + finF: "n'est plus protégée contre le mal", }, putrefactionOutreTombe: { activation: "sent ses chairs pourrir", - actif: "subit le contrecoup d'une putr\xE9faction", - fin: "se remet de la putr\xE9faction", - msgSave: "ne plus \xEAtre putr\xE9fi\xE9", + actif: "subit le contrecoup d'une putréfaction", + fin: "se remet de la putréfaction", + msgSave: "ne plus être putréfié", prejudiciable: true, dm: true }, @@ -45791,8 +46031,8 @@ var COFantasy = COFantasy || function() { fin: '' }, defiSamourai: { - activation: "lance un d\xE9fi", - actif: "a lanc\xE9 un d\xE9fi", + activation: "lance un défi", + actif: "a lancé un défi", fin: '' }, agrippe: { @@ -45801,12 +46041,12 @@ var COFantasy = COFantasy || function() { fin: "lache sa cible" }, estAgrippePar: { - activation: "est agripp\xE9", - activationF: "est agripp\xE9e", - actif: "est agripp\xE9", - actifF: "est agripp\xE9e", - fin: "se lib\xE8re", - msgSave: "se lib\xE9rer", + activation: "est agrippé", + activationF: "est agrippée", + actif: "est agrippé", + actifF: "est agrippée", + fin: "se libère", + msgSave: "se libérer", entrave: true }, devore: { @@ -45819,8 +46059,8 @@ var COFantasy = COFantasy || function() { activationF: "est saisie", actif: "est saisi", actifF: "est saisie", - fin: "se lib\xE8re", - msgSave: "se lib\xE9rer", + fin: "se libère", + msgSave: "se libérer", entrave: true }, ecrase: { @@ -45833,34 +46073,34 @@ var COFantasy = COFantasy || function() { activationF: "est saisie", actif: "est saisi", actifF: "est saisie", - fin: "se lib\xE8re", - msgSave: "se lib\xE9rer", + fin: "se libère", + msgSave: "se libérer", entrave: true }, aGobe: { activation: "avale sa cible", - actif: "a aval\xE9 une cr\xE9ature vivante", - fin: "dig\xE8re sa cible" + actif: "a avalé une créature vivante", + fin: "digère sa cible" }, estGobePar: { - activation: "est aval\xE9", - activationF: "est aval\xE9e", - actif: "est dans le ventre d'une cr\xE9ature", + activation: "est avalé", + activationF: "est avalée", + actif: "est dans le ventre d'une créature", fin: "fin de la digestion, sort du ventre", msgSave: "sortir du ventre", entrave: true }, inconfort: { - activation: "commence \xE0 \xEAtre g\xEAn\xE9 par son armure", - activationF: "commence \xE0 \xEAtre g\xEAn\xE9e par son armure", - actif: "est g\xEAn\xE9 par son armure", - actifF: "est g\xEAn\xE9e par son armure", - fin: "r\xE9ajuste son armure", + activation: "commence à être gêné par son armure", + activationF: "commence à être gênée par son armure", + actif: "est gêné par son armure", + actifF: "est gênée par son armure", + fin: "réajuste son armure", }, noyade: { - activation: "commence \xE0 se noyer", + activation: "commence à se noyer", actif: "se noie", - fin: "peut \xE0 nouveau respirer", + fin: "peut à nouveau respirer", msgSave: "surnager", prejudiciable: true, seulementVivant: true, @@ -45868,8 +46108,8 @@ var COFantasy = COFantasy || function() { visible: true }, blessureQuiSaigne: { - activation: "re\xE7oit une blessure qui saigne", - actif: "saigne \xE0 cause d'une blessure", + activation: "reçoit une blessure qui saigne", + actif: "saigne à cause d'une blessure", fin: "saigne beaucoup moins", msgSave: "ne plus saigner", prejudiciable: true, @@ -45877,10 +46117,10 @@ var COFantasy = COFantasy || function() { }, poisonAffaiblissant: { activation: "sent le poison ralentir ses mouvements", - actif: "est empoisonn\xE9", - actifF: "est empoisonn\xE9e", + actif: "est empoisonné", + actifF: "est empoisonnée", fin: "le poison n'agit plus", - msgSave: "r\xE9sister au poison", + msgSave: "résister au poison", prejudiciable: true, seulementVivant: true, }, @@ -45902,16 +46142,16 @@ var COFantasy = COFantasy || function() { function effetCombatOfAttribute(attr) { let ef = attr.get('name'); if (ef === undefined || messageEffetCombat[ef]) return ef; - //D'abord on enl\xE8ve le nom du token + //D'abord on enlève le nom du token let pu = ef.indexOf('_'); if (pu > 0) { ef = ef.substring(0, pu); if (messageEffetCombat[ef]) return ef; } - error("Impossible de d\xE9terminer l'effet correspondant \xE0 " + ef, attr); + error("Impossible de déterminer l'effet correspondant à " + ef, attr); } - // Si un effet est prejudiciable, enlev\xE9 par d\xE9livrance + // Si un effet est prejudiciable, enlevé par délivrance const messageEffetIndetermine = { armesNaturelles: { activation: "se fait pousser griffes et crocs", @@ -45932,29 +46172,29 @@ var COFantasy = COFantasy || function() { }, constructionTailleHumaine: { activation: "rentre dans une construction de taille humaine.", - actif: "est un peu \xE0 l'\xE9troit, le b\xE2timent est trop petit", + actif: "est un peu à l'étroit, le bâtiment est trop petit", fin: "sort de la construction de taille humains." }, dominationPsy: { - activation: "est maintenant sous le contr\xF4le de quelqu'un", + activation: "est maintenant sous le contrôle de quelqu'un", actif: "est sous l'effet d'une domination psy", - fin: "retrouve le contr\xF4le de son corps", + fin: "retrouve le contrôle de son corps", prejudiciable: true, }, fievreux: { - activation: "se sent fi\xE9vreux", - activationF: "se sent fi\xE9vreuse", - actif: "est fi\xE9vreux", - actifF: "est fi\xE9vreuse", + activation: "se sent fiévreux", + activationF: "se sent fiévreuse", + actif: "est fiévreux", + actifF: "est fiévreuse", fin: "se sent mieux", prejudiciable: true }, foretVivanteEnnemie: { - activation: "est g\xEAn\xE9 par la for\xEAt", - activationF: "est g\xEAn\xE9e par la for\xEAt", - actif: "est d\xE9sorient\xE9 par la for\xEAt", - actifF: "est d\xE9sorient\xE9e par la for\xEAt", - fin: "se retrouve dans une for\xEAt normale", + activation: "est gêné par la forêt", + activationF: "est gênée par la forêt", + actif: "est désorienté par la forêt", + actifF: "est désorientée par la forêt", + fin: "se retrouve dans une forêt normale", entrave: true }, grandeTaille: { @@ -45965,9 +46205,9 @@ var COFantasy = COFantasy || function() { fin: "retrouve sa taille normale" }, lameDeLigneePerdue: { - activation: "perd sa lame de lign\xE9e", - actif: "a perdu sa lame de lign\xE9e", - fin: "retrouve sa lame de lign\xE9e", + activation: "perd sa lame de lignée", + actif: "a perdu sa lame de lignée", + fin: "retrouve sa lame de lignée", }, marcheSylvestre: { activation: "se deplace maintenant en terrain difficile", @@ -45980,8 +46220,8 @@ var COFantasy = COFantasy || function() { fin: "retrouve une peau normale" }, mutationEcaillesRouges: { - activation: "recouvre sa peau d'\xE9cailles rouges", - actif: "a la peau recouverte d'\xE9cailles rouges", + activation: "recouvre sa peau d'écailles rouges", + actif: "a la peau recouverte d'écailles rouges", fin: "retrouve une peau normale" }, mutationFourrureViolette: { @@ -45990,15 +46230,15 @@ var COFantasy = COFantasy || function() { fin: "retrouve une peau normale" }, mutationMusclesHypertrophies: { - activation: "devient plus muscl\xE9", - activationF: "devient plus muscl\xE9e", - actif: "a les muscles hypertrophi\xE9s", + activation: "devient plus musclé", + activationF: "devient plus musclée", + actif: "a les muscles hypertrophiés", fin: "retrouve des muscles normaux", }, mutationOuies: { - activation: "se fait pousser des ou\xEFes", - actif: "poss\xE8de des ou\xEFes", - fin: "n'a plus d'ou\xEFes" + activation: "se fait pousser des ouïes", + actif: "possède des ouïes", + fin: "n'a plus d'ouïes" }, mutationSangNoir: { activation: "prend un teint plus sombre", @@ -46019,8 +46259,8 @@ var COFantasy = COFantasy || function() { }, presenceGlaciale: { activation: "transforme son corps en glace vivante", - actif: "est form\xE9 de glace", - actifF: "est form\xE9e de glace", + actif: "est formé de glace", + actifF: "est formée de glace", fin: "retrouve un corps normal", }, sensDuDevoir: { @@ -46030,12 +46270,12 @@ var COFantasy = COFantasy || function() { }, sixiemeSens: { activation: "fait un rituel de divination", - actif: "sait un peu \xE0 l'avance ce qu'il va se passer", + actif: "sait un peu à l'avance ce qu'il va se passer", fin: "l'effet du rituel de divination prend fin", }, espaceExigu: { activation: "entre dans un espace exigu.", - actif: "est \xE0 l'\xE9troit.", + actif: "est à l'étroit.", fin: "sort de l'espace exigu." }, sangDeLArbreCoeur: { @@ -46043,36 +46283,36 @@ var COFantasy = COFantasy || function() { actif: "a bu une potion de Sang de l'Arbre-Coeur", fin: "les effets de la potion de Sang de l'Arbre-Coeur diminuent un peu" }, - ondesCorruptrices: { //nombre, \xE0 mettre avec !cof-effet ondesCorruptrices 2 - activation: "se sent naus\xE9eux", - activationF: "se sent naus\xE9euse", - actif: "se sent naus\xE9eux", - actifF: "se sent naus\xE9euse", + ondesCorruptrices: { //nombre, à mettre avec !cof-effet ondesCorruptrices 2 + activation: "se sent nauséeux", + activationF: "se sent nauséeuse", + actif: "se sent nauséeux", + actifF: "se sent nauséeuse", fin: "se sent un peu mieux", prejudiciable: true }, petrifie: { activation: "se change en pierre", - actif: "est transform\xE9 en pierre", - actifF: "est transform\xE9e en pierre", - fin: "n'est plus p\xE9trifi\xE9", - finF: "n'est plus p\xE9trifi\xE9e", + actif: "est transformé en pierre", + actifF: "est transformée en pierre", + fin: "n'est plus pétrifié", + finF: "n'est plus pétrifiée", prejudiciable: true, - msgSave: "r\xE9sister \xE0 la p\xE9trification", + msgSave: "résister à la pétrification", }, poisonAffaiblissantLong: { activation: "sent le poison ralentir ses mouvements", - actif: "est empoisonn\xE9", - actifF: "est empoisonn\xE9e", + actif: "est empoisonné", + actifF: "est empoisonnée", fin: "le poison n'agit plus", - msgSave: "r\xE9sister au poison", + msgSave: "résister au poison", prejudiciable: true, seulementVivant: true, }, reactionAllergique: { - activation: "ressent de fortes d\xE9mangeaisons", - actif: "est victime d'une r\xE9action allergique", - fin: "les d\xE9mangeaisons cessent", + activation: "ressent de fortes démangeaisons", + actif: "est victime d'une réaction allergique", + fin: "les démangeaisons cessent", prejudiciable: true }, }; @@ -46086,13 +46326,13 @@ var COFantasy = COFantasy || function() { function effetIndetermineOfAttribute(attr) { let ef = attr.get('name'); if (ef === undefined || messageEffetIndetermine[ef]) return ef; - //D'abord on enl\xE8ve le nom du token + //D'abord on enlève le nom du token let pu = ef.indexOf('_'); if (pu > 0) { ef = ef.substring(0, pu); if (messageEffetIndetermine[ef]) return ef; } - error("Impossible de d\xE9terminer l'effet correspondant \xE0 " + ef, attr); + error("Impossible de déterminer l'effet correspondant à " + ef, attr); } function attributeExtending(charId, attrName, effetC, extension) { @@ -46104,10 +46344,10 @@ var COFantasy = COFantasy || function() { }); } - //Nom de l'effet, avec la partie g\xE9n\xE9rique, mais sans le nom de token + //Nom de l'effet, avec la partie générique, mais sans le nom de token function effetComplet(effet, attrName) { if (effet == attrName) return effet; - //On a un effet li\xE9 \xE0 un token ou bien un effet g\xE9n\xE9rique + //On a un effet lié à un token ou bien un effet générique if (attrName.charAt(effet.length) == '(') { let p = attrName.indexOf(')', effet.length); if (p > 0) return attrName.substring(0, p + 1); @@ -46148,7 +46388,7 @@ var COFantasy = COFantasy || function() { //alors dmg = '' et type = '' let valAttr = tokenAttribute(perso, effet + 'Valeur'); if (valAttr.length === 0) { - //Par d\xE9faut, 1d6 DM normaux + //Par défaut, 1d6 DM normaux dmgExpr = "1d6"; type = 'normal'; } else { @@ -46183,7 +46423,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, m); }); addLineToFramedDisplay(display, nomPerso(perso) + ' ' + msgDm + " subit " + dmgDisplay + " DM"); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); } else if (effet == attrName) { sendPerso(perso, msgDm + " subit " + dmgDisplay + " DM"); } else { @@ -46194,7 +46434,7 @@ var COFantasy = COFantasy || function() { count.v--; if (count.v === 0) callback(); }); - }); //fin sendChat du jet de d\xE9 + }); //fin sendChat du jet de dé } //asynchrone @@ -46225,7 +46465,7 @@ var COFantasy = COFantasy || function() { let expliquer = function(m) { addLineToFramedDisplay(display, m); }; - let msgPour = " pour ne pas prendre de d\xE9g\xE2ts de " + nameEffet; + let msgPour = " pour ne pas prendre de dégâts de " + nameEffet; let sujet = onGenre(perso, 'il', 'elle'); let msgReussite = ", " + sujet + " ne perd pas de PV ce tour"; let saveOpts = { @@ -46237,7 +46477,7 @@ var COFantasy = COFantasy || function() { }; save(options.save, perso, saveId, expliquer, saveOpts, evt, function(reussite, texte) { if (reussite) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } rollAndDealDmg(perso, dmg, type, effet, attrName, msg, count, evt, options, callback, display); @@ -46277,8 +46517,8 @@ var COFantasy = COFantasy || function() { let displaySoins = buildinline(soinRoll, 'normal', true); soigneToken(perso, soins, evt, function(s) { - if (s < soins) sendPerso(perso, "r\xE9cup\xE8re tous ses PV."); - else sendPerso(perso, "r\xE9cup\xE8re " + displaySoins + " PV."); + if (s < soins) sendPerso(perso, "récupère tous ses PV."); + else sendPerso(perso, "récupère " + displaySoins + " PV."); count--; if (count === 0) callback(); }, @@ -46286,7 +46526,7 @@ var COFantasy = COFantasy || function() { count--; if (count === 0) callback(); }); - }); //fin sendChat du jet de d\xE9 + }); //fin sendChat du jet de dé }); //fin iterTokensOfAttribute } @@ -46300,9 +46540,9 @@ var COFantasy = COFantasy || function() { return options; } - // gestion des effets qui se d\xE9clenchent \xE0 la fin de chaque tour - // N'ajoute pas evt \xE0 l'historique - // Asynchrone (\xE0 cause des saves par tour) + // gestion des effets qui se déclenchent à la fin de chaque tour + // N'ajoute pas evt à l'historique + // Asynchrone (à cause des saves par tour) function changementDeTour(tour, attrs, evt, combat, pageId, options) { // Enlever les bonus d'un tour attrs = removeAllAttributes('limiteParTour', evt, attrs); @@ -46313,7 +46553,7 @@ var COFantasy = COFantasy || function() { attrs = removeAllAttributes('prescienceUtilisee', evt, attrs); attrs = removeAllAttributes('increvableHumainUtilise', evt, attrs); resetAttr(attrs, 'cercleDeProtectionActif', evt); - // Pour d\xE9faut dans la cuirasse, on diminue si la valeur est 2, et on supprime si c'est 1 + // Pour défaut dans la cuirasse, on diminue si la valeur est 2, et on supprime si c'est 1 let defautsDansLaCuirasse = allAttributesNamed(attrs, 'defautDansLaCuirasse'); defautsDansLaCuirasse.forEach(function(attr) { if (attr.get('current') < 2) { @@ -46345,7 +46585,7 @@ var COFantasy = COFantasy || function() { attr.set('current', 1); } }); - //Les tests rat\xE9s + //Les tests ratés let trTour = allAttributesNamed(attrs, 'testsRatesDuTour'); trTour.forEach(function(tr) { let curTr = tr.get('current'); @@ -46374,7 +46614,7 @@ var COFantasy = COFantasy || function() { attr.set('current', ve + 1); let veCharId = attr.get('characterid'); if (veCharId === undefined || veCharId === '') { - error("Attribut sans personnage associ\xE9", attr); + error("Attribut sans personnage associé", attr); return; } let veSeuil = parseInt(attr.get('max')); @@ -46389,9 +46629,9 @@ var COFantasy = COFantasy || function() { }; let testId = 'vapeursEthyliques_' + perso.token.id; testCaracteristique(perso, 'CON', veSeuil, testId, options, evt, function(testRes) { - let res = "tente un jet de CON " + veSeuil + " pour combattre les vapeurs \xE9thyliques " + testRes.texte; + let res = "tente un jet de CON " + veSeuil + " pour combattre les vapeurs éthyliques " + testRes.texte; if (testRes.reussite) { - res += " => r\xE9ussi." + testRes.modifiers; + res += " => réussi." + testRes.modifiers; let expliquer; if (attr.get('name') == 'vapeursEthyliques') { expliquer = function(s) { @@ -46405,14 +46645,14 @@ var COFantasy = COFantasy || function() { expliquer(res); diminueEbriete(perso, evt, expliquer); } else { - res += " => rat\xE9" + testRes.rerolls + testRes.modifiers; + res += " => raté" + testRes.rerolls + testRes.modifiers; sendPerso(perso, res); } }); }); }); // nouveau tour : enlever le statut surpris - // et faire les actions de d\xE9but de tour + // et faire les actions de début de tour let selected = []; updateNextInitSet.forEach(function(id) { selected.push({ @@ -46457,14 +46697,14 @@ var COFantasy = COFantasy || function() { }; dealDamage(perso, dmg, [], evt, false, {}, undefined, function(dmgDisplay, dmgFinal) { - sendPerso(perso, " est \xE9cras\xE9 ! " + + sendPerso(perso, " est écrasé ! " + onGenre(perso, 'Il', 'Elle') + " subit " + dmgDisplay + " DM"); }); } let enflammeAttr = tokenAttribute(perso, 'enflamme'); if (enflammeAttr.length > 0) { let enflamme = parseInt(enflammeAttr[0].get('current')); - // Pour ne pas faire les d\xE9g\xE2ts plusieurs fois (plusieurs tokens pour un m\xEAme personnage), on utilise la valeur max de l'attribut + // Pour ne pas faire les dégâts plusieurs fois (plusieurs tokens pour un même personnage), on utilise la valeur max de l'attribut let dernierTourEnflamme = parseInt(enflammeAttr[0].get('max')); if ((isNaN(dernierTourEnflamme) || dernierTourEnflamme < tour) && !isNaN(enflamme) && enflamme > 0) { @@ -46483,7 +46723,7 @@ var COFantasy = COFantasy || function() { display: roll }; if (getState(perso, 'mort')) { - sendChat('', "Le cadavre de " + nomPerso(perso) + " continue de br\xFBler"); + sendChat('', "Le cadavre de " + nomPerso(perso) + " continue de brûler"); } else { dealDamage(perso, dmgEnflamme, [], evt, false, {}, undefined, function(dmgDisplay, dmgFinal) { @@ -46492,7 +46732,7 @@ var COFantasy = COFantasy || function() { }); } if (d6Enflamme < 3) { - sendPerso(perso, ": les flammes s'\xE9teignent"); + sendPerso(perso, ": les flammes s'éteignent"); removeTokenAttr(perso, 'enflamme', evt); let ms = messageEffetCombat.enflamme.statusMarker; if (ms) { @@ -46509,14 +46749,14 @@ var COFantasy = COFantasy || function() { nbDes: 3 }); let dmg = { - type: 'normal', //correspond \xE0 de l'asphyxie + type: 'normal', //correspond à de l'asphyxie total: jet.val, display: jet.roll }; if (immuniseAsphyxie(perso)) dmg.type = 'acide'; dealDamage(perso, dmg, [], evt, false, {}, undefined, function(dmgDisplay, dmgFinal) { - sendPerso(perso, "est en train d'\xEAtre dig\xE9r\xE9. " + onGenre(perso, 'Il', 'Elle') + " perd " + dmgDisplay + " PVs"); + sendPerso(perso, "est en train d'être digéré. " + onGenre(perso, 'Il', 'Elle') + " perd " + dmgDisplay + " PVs"); }); } if (attributeAsBool(perso, 'blessureQuiSaigne') && @@ -46542,7 +46782,7 @@ var COFantasy = COFantasy || function() { let expliquer = function(m) { addLineToFramedDisplay(display, m); }; - let msgPour = " pour ne pas prendre de d\xE9g\xE2ts de noyade"; + let msgPour = " pour ne pas prendre de dégâts de noyade"; let sujet = onGenre(perso, 'il', 'elle'); let msgReussite = ", " + sujet + " ne perd pas de PV ce tour"; let saveOpts = { @@ -46558,7 +46798,7 @@ var COFantasy = COFantasy || function() { }; save(saveNoyade, perso, saveId, expliquer, saveOpts, evt, function(reussite, texte) { if (reussite) { - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); return; } let jetNoyade = rollDePlus(6); @@ -46574,7 +46814,7 @@ var COFantasy = COFantasy || function() { addLineToFramedDisplay(display, m); }); addLineToFramedDisplay(display, nomPerso(perso) + "se noie et subit " + dmgDisplay + " DM"); - sendChat('', endFramedDisplay(display)); + sendFramedDisplay(display); }); }); } @@ -46598,7 +46838,7 @@ var COFantasy = COFantasy || function() { saufDMType = vitaliteSurnaturelle.substring(indexType + 1).split(','); soigneToken(perso, vitaliteSurnat, evt, function(s) { - whisperChar(perso.charId, 'r\xE9cup\xE8re ' + s + ' PVs.'); + whisperChar(perso.charId, 'récupère ' + s + ' PVs.'); }, function() {}, { saufDMType @@ -46610,7 +46850,7 @@ var COFantasy = COFantasy || function() { if (attributeAsBool(perso, 'sangDeLArbreCoeur') && !getState(perso, 'mort')) { soigneToken(perso, 5, evt, function(s) { - whisperChar(perso.charId, "r\xE9g\xE9n\xE8re " + s + " PVs. (gr\xE2ce \xE0 la potion de sang de l'Arbre Coeur)"); + whisperChar(perso.charId, "régénère " + s + " PVs. (grâce à la potion de sang de l'Arbre Coeur)"); }, function() {} ); @@ -46620,9 +46860,9 @@ var COFantasy = COFantasy || function() { increvableActif[0].remove(); let soins = randomInteger(6) + randomInteger(6) + randomInteger(6) + modCarac(perso, 'constitution'); soigneToken(perso, soins, evt, function(soinsEffectifs) { - let msgSoins = "est increvable et r\xE9cup\xE8re "; + let msgSoins = "est increvable et récupère "; if (soinsEffectifs == soins) msgSoins += soins + " points de vie"; - else msgSoins += soinsEffectifs + " PV (le jet \xE9tait " + soins + ")"; + else msgSoins += soinsEffectifs + " PV (le jet était " + soins + ")"; whisperChar(perso.charId, msgSoins); }); } @@ -46635,16 +46875,16 @@ var COFantasy = COFantasy || function() { }; perso.ignoreTouteRD = true; dealDamage(perso, r, [], evt, false, {}, [], function() { - // V\xE9rification si le Zombie est toujours vivant + // Vérification si le Zombie est toujours vivant let token = getObj('graphic', perso.token.id); - if (token) whisperChar(perso.charId, "se d\xE9grade et perd 1 PV"); + if (token) whisperChar(perso.charId, "se dégrade et perd 1 PV"); }); } }); setActiveToken(combat, undefined, evt); - initiative(selected, evt, true); // met Tour \xE0 la fin et retrie + initiative(selected, evt, true); // met Tour à la fin et retrie updateNextInitSet = new Set(); - // Saves \xE0 faire \xE0 la fin de chaque tour. Asynchrone, mais pas grave ? + // Saves à faire à la fin de chaque tour. Asynchrone, mais pas grave ? attrs.forEach(function(attr) { let attrName = attr.get('name'); let indexSave = attrName.indexOf('SaveParTour'); @@ -46656,12 +46896,12 @@ var COFantasy = COFantasy || function() { if (!cof_states[effetC] && !effetTemp && !estEffetCombat(effetC)) return; let carac = attr.get('current'); if (!isCarac(carac)) { - error("Save par tour " + attrName + " mal form\xE9", carac); + error("Save par tour " + attrName + " mal formé", carac); return; } let seuil = parseInt(attr.get('max')); if (isNaN(seuil)) { - error("Save par tour " + attrName + " mal form\xE9", seuil); + error("Save par tour " + attrName + " mal formé", seuil); return; } let charId = attr.get('characterid'); @@ -46690,7 +46930,7 @@ var COFantasy = COFantasy || function() { let se = stringOfEtat(effetC, perso); met = { etat: true, - msgSave: "ne plus \xEAtre " + se, + msgSave: "ne plus être " + se, fin: "n'est plus " + se, actif: "est toujours " + se }; @@ -46698,7 +46938,7 @@ var COFantasy = COFantasy || function() { let msgPour = " pour "; if (met.msgSave) msgPour += met.msgSave; else { - msgPour += "ne plus \xEAtre sous l'effet de "; + msgPour += "ne plus être sous l'effet de "; if (effetC.startsWith('dotGen(')) msgPour += effetC.substring(7, effetC.indexOf(')')); else msgPour += effetC; @@ -46784,7 +47024,7 @@ var COFantasy = COFantasy || function() { //Pour chaque token representant ce perso allPersos.forEach(function(perso) { if (perso.charId != charId) return; - //On cherche ensuite les tokens \xE0 portee + //On cherche ensuite les tokens à portee allPersos.forEach(function(target) { if (target.token.id == perso.token.id) return; let tokRepresents = target.charId; @@ -46813,19 +47053,19 @@ var COFantasy = COFantasy || function() { targetLine += " --target " + tokId; }); if (targetLine != "") - sendChat('player|' + gmId, "!cof-dmg 3d6" + targetLine + " --titre D\xE9g\xE2ts des morts-vivants anim\xE9s"); + sendChat('player|' + gmId, "!cof-dmg 3d6" + targetLine + " --titre Dégâts des morts-vivants animés"); targetLine = ""; Object.keys(degatsArmeeDefense).forEach(function(tokId) { targetLine += " --target " + tokId; }); if (targetLine != "") - sendChat('player|' + gmId, "!cof-dmg 1d6" + targetLine + " --titre D\xE9g\xE2ts des morts-vivants anim\xE9s sur les cibles qui les combattent"); + sendChat('player|' + gmId, "!cof-dmg 1d6" + targetLine + " --titre Dégâts des morts-vivants animés sur les cibles qui les combattent"); removeAllAttributes("defenseArmeeDesMorts", evt, attrs); if (stateCOF.prescience) { - //On affiche la prescience aux joueurs concern\xE9s + //On affiche la prescience aux joueurs concernés allPersos.forEach(function(perso) { if (capaciteDisponible(perso, 'prescience', 'combat')) { - whisperChar(perso.charId, "Possibilit\xE9 d'utiliser la " + boutonSimple('!cof-prescience ' + perso.token.id + ' --mana 2', "Prescience")); + whisperChar(perso.charId, "Possibilité d'utiliser la " + boutonSimple('!cof-prescience ' + perso.token.id + ' --mana 2', "Prescience")); } }); stateCOF.nextPrescience = { @@ -46846,7 +47086,7 @@ var COFantasy = COFantasy || function() { } //evt a un champ attributes et un champ deletedAttributes - //evt n'est pas ajout\xE9 \xE0 l'historique dans cette fonction + //evt n'est pas ajouté à l'historique dans cette fonction function nextTurnOfActive(active, attrs, evt, combat, pageId, options) { if (active === undefined) return; if (active.id == "-1" && active.custom == "Tour") { //Nouveau tour @@ -46859,8 +47099,8 @@ var COFantasy = COFantasy || function() { }; evt.combat.tour = tour - 1; evt.updateNextInitSet = updateNextInitSet; - active.pr = tour - 1; // pr\xE9paration au calcul de l'undo - sendChat("GM", "D\xE9but du tour " + tour); + active.pr = tour - 1; // préparation au calcul de l'undo + sendChat("GM", "Début du tour " + tour); combat.tour = tour; combat.init = 1000; changementDeTour(tour, attrs, evt, combat, pageId, options); @@ -46923,7 +47163,7 @@ var COFantasy = COFantasy || function() { nbDe: 1, de: 4 }, 'feu', - "br\xFBle dans son armure", evt, { + "brûle dans son armure", evt, { valeur: 'armureBrulanteValeur' }, callBack); return; @@ -46931,7 +47171,7 @@ var COFantasy = COFantasy || function() { degatsParTour(charId, pageId, effet, attrName, { cst: 1 }, 'normal', - "est piqu\xE9 par les insectes", evt, { + "est piqué par les insectes", evt, { valeur: 'nueeDInsectesValeur' }, callBack); return; @@ -46939,31 +47179,31 @@ var COFantasy = COFantasy || function() { degatsParTour(charId, pageId, effet, attrName, { cst: 2 }, 'normal', - "est piqu\xE9 par les criquets", evt, {}, callBack); + "est piqué par les criquets", evt, {}, callBack); return; case 'nueeDeScorpions': //prend 1D6 DM degatsParTour(charId, pageId, effet, attrName, { nbDe: 1, de: 6 }, 'normal', - "est piqu\xE9 par les scorpions", evt, {}, callBack); + "est piqué par les scorpions", evt, {}, callBack); return; case 'armeBrulante': //prend 1 DM degatsParTour(charId, pageId, effet, attrName, { cst: 1 }, 'feu', - "se br\xFBle avec son arme", evt, { + "se brûle avec son arme", evt, { valeur: 'armeBrulanteValeur' }, callBack); return; case 'regeneration': //soigne - soigneParTour(charId, pageId, effet, attrName, 3, "r\xE9g\xE9n\xE8re", evt, { + soigneParTour(charId, pageId, effet, attrName, 3, "régénère", evt, { valeur: 'regenerationValeur' }, callBack); return; case 'strangulation': let nameDureeStrang = 'dureeStrangulation'; - if (effet != attrName) { //concerne un token non li\xE9 + if (effet != attrName) { //concerne un token non lié nameDureeStrang += attrName.substring(attrName.indexOf('_')); } let dureeStrang = findObjs({ @@ -46983,18 +47223,18 @@ var COFantasy = COFantasy || function() { }); } else { let strangUpdate = dureeStrang[0].get('max'); - if (strangUpdate) { //a \xE9t\xE9 mis \xE0 jour il y a au plus 1 tour + if (strangUpdate) { //a été mis à jour il y a au plus 1 tour evt.attributes.push({ attribute: dureeStrang[0], current: dureeStrang[0].get('current'), max: strangUpdate }); dureeStrang[0].set('max', false); - } else { //Ça fait trop longtemps, on arr\xEAte tout + } else { //Ça fait trop longtemps, on arrête tout sendChar(charId, messageFin({ charId }, messageEffetTemp[effet]), true); - evt.attributes.pop(); //On enl\xE8ve des attributs modifi\xE9s pour mettre dans les attribute supprim\xE9s. + evt.attributes.pop(); //On enlève des attributs modifiés pour mettre dans les attribute supprimés. evt.deletedAttributes.push(attr); attr.remove(); evt.deletedAttributes.push(dureeStrang[0]); @@ -47072,8 +47312,8 @@ var COFantasy = COFantasy || function() { fin(); return; } - count --; //On a fini avec perso. - count += cibles.length;//On ajoute les cibles + count--; //On a fini avec perso. + count += cibles.length; //On ajoute les cibles cibles.forEach(function(cible) { sendChat('', "[[2d6]]", function(res) { let rolls = res[0]; @@ -47082,14 +47322,14 @@ var COFantasy = COFantasy || function() { let displaySoins = buildinline(soinRoll, 'normal', true); soigneToken(cible, soins, evt, function(s) { - if (s < soins) sendPerso(cible, "r\xE9cup\xE8re tous ses PV."); + if (s < soins) sendPerso(cible, "récupère tous ses PV."); else if (s == soins) - sendPerso(cible, "r\xE9cup\xE8re " + displaySoins + " PV."); + sendPerso(cible, "récupère " + displaySoins + " PV."); else - sendPerso(cible, "r\xE9cup\xE8re " + s + " PV. (Le jet \xE9tait "+displaySoins+")"); + sendPerso(cible, "récupère " + s + " PV. (Le jet était " + displaySoins + ")"); fin(); }, fin); - }); //fin sendChat du jet de d\xE9 + }); //fin sendChat du jet de dé }); }); return; @@ -47100,8 +47340,8 @@ var COFantasy = COFantasy || function() { } } - //Appel\xE9 si le turn order change, mais aussi en interne - //si evt est d\xE9j\xE0 d\xE9fini, ne l'ajoute pas au turn order + //Appelé si le turn order change, mais aussi en interne + //si evt est déjà défini, ne l'ajoute pas au turn order function nextTurn(cmp, options, evt) { if (!cmp.get('initiativepage')) return; let combat = stateCOF.combat; @@ -47160,7 +47400,7 @@ var COFantasy = COFantasy || function() { let attrs = findObjs({ _type: 'attribute' }); - // Si on a chang\xE9 d'initiative, alors diminue les effets temporaires + // Si on a changé d'initiative, alors diminue les effets temporaires if (combat.init > init) { if (stateCOF.tokensTemps && stateCOF.tokensTemps.length > 0) { stateCOF.tokensTemps = stateCOF.tokensTemps.filter(function(tt) { @@ -47190,7 +47430,7 @@ var COFantasy = COFantasy || function() { } }); } - //attrsTemp ne contient que les attributs dont la dur\xE9e doit baisser + //attrsTemp ne contient que les attributs dont la durée doit baisser let attrsTemp = attrs.filter(function(obj) { if (!estEffetTemp(obj.get('name'))) return false; let obji = obj.get('max'); @@ -47199,7 +47439,7 @@ var COFantasy = COFantasy || function() { if (!evt.combat) evt.combat = {...stateCOF.combat }; combat.init = init; - // Boucle sur les effets temps peut \xEAtre asynchrone \xE0 cause des DM + // Boucle sur les effets temps peut être asynchrone à cause des DM let count = attrsTemp.length; if (count === 0) { nextTurnOfActive(active, attrs, evt, combat, pageId, options); @@ -47222,8 +47462,8 @@ var COFantasy = COFantasy || function() { let effetC = effetComplet(effet, attrName); let v = parseInt(attr.get('current')); if (isNaN(v)) v = 1; - if (v <= 1) { //L'effet arrive en fin de vie, doit \xEAtre supprim\xE9 - //Sauf si on a accumul\xE9 plusieurs fois l'effet + if (v <= 1) { //L'effet arrive en fin de vie, doit être supprimé + //Sauf si on a accumulé plusieurs fois l'effet let accumuleAttr = attributeExtending(charId, attrName, effetC, 'DureeAccumulee'); if (accumuleAttr.length > 0) { accumuleAttr = accumuleAttr[0]; @@ -47274,16 +47514,16 @@ var COFantasy = COFantasy || function() { if (v > 1) attr.set('current', v - 1); actionEffet(attr, effet, attrName, charId, pageId, evt, fin); }); //fin de la boucle sur tous les attributs d'effets temporaires - } else { //L'initiative n'a pas boug\xE9e + } else { //L'initiative n'a pas bougée nextTurnOfActive(active, attrs, evt, combat, pageId, options); } } - //Fonction appel\xE9e par !cof-tour-suivant + //Fonction appelée par !cof-tour-suivant function tourSuivant(msg) { let combat = stateCOF.combat; if (!combat) { - sendPlayer(msg, "Vous n'\xEAtes pas en combat"); + sendPlayer(msg, "Vous n'êtes pas en combat"); return; } let cmp = Campaign(); @@ -47321,10 +47561,10 @@ var COFantasy = COFantasy || function() { nextTurn(cmp); } - //nb \xE0 11 pour ne pas retenter de lire les attributs + //nb à 11 pour ne pas retenter de lire les attributs function scriptVersionToCharacter(character, nb) { let charId = character.id; - //On v\xE9rifie que les attributs sont peupl\xE9s + //On vérifie que les attributs sont peuplés let attrs = findObjs({ _type: 'attribute', _characterid: charId, @@ -47390,7 +47630,7 @@ var COFantasy = COFantasy || function() { removeTokenAttr(perso, 'bougeGraceA'); return; } - //On regarde si il existe une copie de ce token, par exemple \xE0 cause de l'invisibilit\xE9 + //On regarde si il existe une copie de ce token, par exemple à cause de l'invisibilité let otherTokens = findObjs({ _type: 'graphic', _pageid: pageId, @@ -47502,7 +47742,7 @@ var COFantasy = COFantasy || function() { activerEffetTemporaire(origine, cibles, 'drainDeForce', mEffet, 1, options, evtEffet, '', [], display); } - //retourne le nombre de cibles affect\xE9es + //retourne le nombre de cibles affectées function appliquerAura(origine, cibles, pageId, aura, evt, renew) { let effet; cibles = cibles.filter(function(perso) { @@ -47523,7 +47763,7 @@ var COFantasy = COFantasy || function() { save: { carac: 'CON', seuil: 12, - msgPour: ' pour ne pas \xEAtre affaibli' + eForFemale(cibles[0]) + msgPour: ' pour ne pas être affaibli' + eForFemale(cibles[0]) } }; let mEffet = messageEffetTemp.drainDeForce; @@ -47555,8 +47795,8 @@ var COFantasy = COFantasy || function() { return cibles.length; } - //R\xE9agit au d\xE9placement manuel d'un token. - // suivis est l'ensemble des tokens qui a d\xE9j\xE0 \xE9t\xE9 boug\xE9 suite \xE0 ce d\xE9placement + //Réagit au déplacement manuel d'un token. + // suivis est l'ensemble des tokens qui a déjà été bougé suite à ce déplacement function moveToken(token, prev, synchronisation, suivis) { let charId = token.get('represents'); if (charId === '') return; @@ -47609,7 +47849,7 @@ var COFantasy = COFantasy || function() { if (tid == token.id) return; let tok = getObj('graphic', tid); if (tok === undefined) { - error("Impossible de trouver le token d'id " + tid + " synchronis\xE9 avec " + token.get('name'), attr); + error("Impossible de trouver le token d'id " + tid + " synchronisé avec " + token.get('name'), attr); return; } tok.set('left', x); @@ -47676,7 +47916,7 @@ var COFantasy = COFantasy || function() { type: "initiative" }; updateInit(monture.token, evt); - // R\xE9adapter l'init_dynamique au token du perso + // Réadapter l'init_dynamique au token du perso if (stateCOF.options.affichage.val.init_dynamique.val) { setTokenInitAura(perso); } @@ -47758,7 +47998,7 @@ var COFantasy = COFantasy || function() { autreInvisible.set('top', y); } } - //si non, perso est peut-\xEAtre une monture + //si non, perso est peut-être une monture let attrMontePar = tokenAttribute(perso, 'estMontePar'); attrMontePar.forEach(function(a) { let cavalier = persoOfIdName(a.get('current'), pageId); @@ -47784,7 +48024,7 @@ var COFantasy = COFantasy || function() { //Si le token suivait quelqu'un, ce n'est plus le cas if (prev.suit === undefined) nePlusSuivre(perso, pageId); //On bouge tous les tokens qui suivent le personnage - //sauf si on a d\xE9j\xE0 \xE9t\xE9 boug\xE9. + //sauf si on a déjà été bougé. if (!suivis.has(token.id)) { suivis.add(token.id); let attrSuivi = tokenAttribute(perso, 'estSuiviPar'); @@ -47818,7 +48058,7 @@ var COFantasy = COFantasy || function() { if (sh > width) return false; let sx = suivant.token.get('left'); let sy = suivant.token.get('top'); - //On essaie de garder la m\xEAme position par rapport au token, en supposant qu'on \xE9tait derri\xE8re lui + //On essaie de garder la même position par rapport au token, en supposant qu'on était derrière lui let attrSuit = tokenAttribute(suivant, 'suit'); let dp; if (attrSuit.length > 0) { @@ -47833,10 +48073,10 @@ var COFantasy = COFantasy || function() { if (nsy < 0) nsy = 0; if (nsx + sw / 2 > width) nsx = Math.floor(width - sw / 2); if (nsy + sh / 2 > height) nsy = Math.floor(height - sh / 2); - //v\xE9rifie si de la nouvelle position on peut voir le suivi + //vérifie si de la nouvelle position on peut voir le suivi if (obstaclePresent(nsx, nsy, pt, murs)) { - //On essaie de suivre le chemin du token, \xE0 la place - //D'abord se d\xE9placer vers l'ancienne position de perso, au maximum de distance pixels + //On essaie de suivre le chemin du token, à la place + //D'abord se déplacer vers l'ancienne position de perso, au maximum de distance pixels let distLoc = distance; if (distLoc - dp < 5) { nsx = prev.left; @@ -47893,7 +48133,7 @@ var COFantasy = COFantasy || function() { roundMarker.set('left', x); roundMarker.set('top', y); } else { - // Cas sp\xE9ciaux du cavaliers : au tour du cavalier, l'init_dynamique suit la monture + // Cas spéciaux du cavaliers : au tour du cavalier, l'init_dynamique suit la monture let estMontePar = tokenAttribute(perso, 'estMontePar'); if (estMontePar.length > 0) { let sp = splitIdName(estMontePar[0].get('current')); @@ -47905,7 +48145,7 @@ var COFantasy = COFantasy || function() { } } } - //On d\xE9place les tokens de lumi\xE8re, si il y en a + //On déplace les tokens de lumière, si il y en a let attrLumiere = tokenAttribute(perso, 'lumiere'); attrLumiere.forEach(function(al) { let lumId = al.get('max'); @@ -47925,13 +48165,13 @@ var COFantasy = COFantasy || function() { }); if (tokensLumiere.length === 0) { if (lumiereExiste) return; - log("Pas de token pour la lumi\xE8re " + al.get('current')); + log("Pas de token pour la lumière " + al.get('current')); al.remove(); return; } lumiere = tokensLumiere.shift(); if (tokensLumiere.length > 0) { - //On cherche le token le plus proche de la position pr\xE9c\xE9dente + //On cherche le token le plus proche de la position précédente let d = distanceTokenPrev(lumiere, prev); tokensLumiere.forEach(function(tl) { let d2 = distanceTokenPrev(tl, prev); @@ -47944,7 +48184,7 @@ var COFantasy = COFantasy || function() { } if (lumiere === undefined) { if (lumiereExiste) return; - log("Pas de token pour la lumi\xE8re " + al.get('current')); + log("Pas de token pour la lumière " + al.get('current')); al.remove(); return; } @@ -47967,7 +48207,7 @@ var COFantasy = COFantasy || function() { function synchronisationDesEtats(perso) { for (let etat in cof_states) { - // R\xE9cup\xE8re la valeur de l'\xE9tat sur la fiche + // Récupère la valeur de l'état sur la fiche let valEtat; if (etat == 'affaibli') { // Cas particulier affaibli sur la fiche perso valEtat = (ficheAttributeAsInt(perso, 'affaibli', 20) == 12); @@ -47979,10 +48219,10 @@ var COFantasy = COFantasy || function() { } } - //Op\xE9rations diverses au moment o\xF9 on pose un token. - //Si le token repr\xE9sente un personnage et avec la barre de vie non li\xE9e, - // assure un nom unique en ajoutant un num\xE9ro - // On en profite aussi pour mettre certaines valeurs par d\xE9faut + //Opérations diverses au moment où on pose un token. + //Si le token représente un personnage et avec la barre de vie non liée, + // assure un nom unique en ajoutant un numéro + // On en profite aussi pour mettre certaines valeurs par défaut // retourne un perso si c'est un token de personnage function renameToken(token, tokenName) { let charId = token.get('represents'); @@ -48045,11 +48285,11 @@ var COFantasy = COFantasy || function() { } return perso; } - //cas des mooks : num\xE9rotation + //cas des mooks : numérotation let copyOf = 0; let tokenBaseName = tokenName; if (tokenBaseName.includes('%%NUMBERED%%')) { - if (typeof TokenNameNumber !== 'undefined') return perso; //On laisse tokenNameNumber g\xE9rer \xE7a + if (typeof TokenNameNumber !== 'undefined') return perso; //On laisse tokenNameNumber gérer ça tokenBaseName = tokenBaseName.replace('%%NUMBERED%%', ''); } else { // On regarde si le nom se termine par un entier @@ -48101,7 +48341,7 @@ var COFantasy = COFantasy || function() { function addToken(token, nb) { let tokenName = token.get('name'); - //La plupart du temps, il faut attendre un peu que le nom soit affect\xE9 + //La plupart du temps, il faut attendre un peu que le nom soit affecté if (tokenName !== '') { let perso = renameToken(token, tokenName); if (perso === undefined) return; @@ -48115,16 +48355,16 @@ var COFantasy = COFantasy || function() { return; } nb = nb || 1; - if (nb > 10) return; //Tant pis, peut-\xEAtre que le nom est vide + if (nb > 10) return; //Tant pis, peut-être que le nom est vide _.delay(function() { addToken(token, nb + 1); }, 50); } - // Surveillance sur le changement d'\xE9tat du token + // Surveillance sur le changement d'état du token function changeMarker(token, prev) { const charId = token.get('represents'); - if (charId === undefined || charId === '') return; // Uniquement si token li\xE9 \xE0 un perso + if (charId === undefined || charId === '') return; // Uniquement si token lié à un perso const perso = { token, charId @@ -48190,7 +48430,7 @@ var COFantasy = COFantasy || function() { let lumId = al.get('max'); if (lumId == 'surToken') { if (!token.get('emits_bright_light') && !token.get('emits_low_light')) { - //On cherche un token qui repr\xE9sente le m\xEAme personnage et \xE9met de la lumi\xE8re + //On cherche un token qui représente le même personnage et émet de la lumière let allTokens = findObjs({ type: 'graphic', represents: perso.charId @@ -48209,7 +48449,7 @@ var COFantasy = COFantasy || function() { } return; } - //Lumi\xE8re sur un token qui suit le perso. + //Lumière sur un token qui suit le perso. let lumiere = getObj('graphic', lumId); if (lumiere && lumiere.get('pageid') != pageId) { let copyLum = createObj('graphic', { @@ -48235,7 +48475,7 @@ var COFantasy = COFantasy || function() { } } - //Actions \xE0 faire pour maintenir la coh\xE9rence des tokens qui repr\xE9sentent le m\xEAme personnage. + //Actions à faire pour maintenir la cohérence des tokens qui représentent le même personnage. function changePlayerPage(campaign) { let currentMap = getObj('page', campaign.get('playerpageid')); let tokens = findObjs({ @@ -48245,7 +48485,7 @@ var COFantasy = COFantasy || function() { }); tokens.forEach(function(token) { let charId = token.get('represents'); - if (charId === undefined || charId === '') return; // Si token li\xE9 \xE0 un perso + if (charId === undefined || charId === '') return; // Si token lié à un perso if (token.get('bar1_link') === '') return; // Si unique let perso = { token, @@ -48287,8 +48527,8 @@ var COFantasy = COFantasy || function() { function changeTokenLock(token, prev) { const charId = token.get('represents'); - if (charId === undefined || charId === '') return; // Uniquement si token li\xE9 \xE0 un perso - if (token.get('lockMovement')) return; //Rien de sp\xE9cial \xE0 faire + if (charId === undefined || charId === '') return; // Uniquement si token lié à un perso + if (token.get('lockMovement')) return; //Rien de spécial à faire const perso = { token, charId @@ -48317,8 +48557,8 @@ var COFantasy = COFantasy || function() { state.COFantasy.eventId = 0; } if (version < 1.0) { - log("Mise \xE0 jour des attributs et macros vers la version 1.0"); - //Mise \xE0 jour des effets temporaires avec _ + log("Mise à jour des attributs et macros vers la version 1.0"); + //Mise à jour des effets temporaires avec _ let strReg = "(rayon_affaiblissant|peau_d_ecorce|chant_des_heros|image_decalee|a_couvert|sous_tension|forgeron_|armeEnflammee)"; let regName = new RegExp("^" + strReg); let regText = new RegExp(strReg); @@ -48371,10 +48611,10 @@ var COFantasy = COFantasy || function() { m.set('action', action); } }); - log("Mise \xE0 jour effectu\xE9e."); + log("Mise à jour effectuée."); } if (version < 2.0) { - log("Mise \xE0 jour des attributs et macros vers la version 2.0"); + log("Mise à jour des attributs et macros vers la version 2.0"); let strReg = "(--argent)"; let regName = new RegExp("^" + strReg); let regText = new RegExp(strReg); @@ -48406,7 +48646,7 @@ var COFantasy = COFantasy || function() { m.set('action', action); } }); - log("Mise \xE0 jour effectu\xE9e."); + log("Mise à jour effectuée."); } if (version < 2.02) { let attrs = findObjs({ @@ -48416,7 +48656,7 @@ var COFantasy = COFantasy || function() { let attrName = attr.get('name'); if (attrName == 'mort-vivant') attr.set('name', 'mortVivant'); }); - log("Mise \xE0 jour effectu\xE9e."); + log("Mise à jour effectuée."); } if (version < 2.03) { let attrs = findObjs({ @@ -48424,13 +48664,13 @@ var COFantasy = COFantasy || function() { }); attrs.forEach(function(attr) { let attrName = attr.get('name'); - if (attrName == 'runeDEnergie') attr.set('name', 'runeForgesort_\xE9nergie'); + if (attrName == 'runeDEnergie') attr.set('name', 'runeForgesort_énergie'); if (attrName == 'runeDeProtection') attr.set('name', 'runeForgesort_protection'); if (attrName.includes('runeDePuissance')) { attr.set('name', 'runeForgesort_puissance(' + attrName.substring(attrName.indexOf("(") + 1, attrName.indexOf(")")) + ')'); } }); - log("Mise \xE0 jour des runes effectu\xE9e."); + log("Mise à jour des runes effectuée."); } if (version < 2.04) { let attrs = findObjs({ @@ -48478,7 +48718,7 @@ var COFantasy = COFantasy || function() { attrRDS.set('current', rdPerso); a.remove(); }); - log("Mise \xE0 jour de la RD effectu\xE9e"); + log("Mise à jour de la RD effectuée"); } if (version < 2.05) { let attrs = findObjs({ @@ -48493,7 +48733,7 @@ var COFantasy = COFantasy || function() { let message = action.substring(19); a.set("max", "!cof-lancer-sort --message " + message + " --mana " + mana); }); - log("Mise \xE0 jour des consommables !cof-lancer-sort effectu\xE9e"); + log("Mise à jour des consommables !cof-lancer-sort effectuée"); let macros = findObjs({ _type: 'macro' }).concat(findObjs({ @@ -48506,7 +48746,7 @@ var COFantasy = COFantasy || function() { let message = macro.substring(19); m.set("action", "!cof-lancer-sort --message " + message + " --mana " + mana); }); - log("Mise \xE0 jour des ability & macros !cof-lancer-sort effectu\xE9e"); + log("Mise à jour des ability & macros !cof-lancer-sort effectuée"); } if (version < 2.10) { let tokens = findObjs({ @@ -48535,7 +48775,7 @@ var COFantasy = COFantasy || function() { let removeAttrs = function() { charsToTreat--; if (charsToTreat > 0) return; - log("Supression des attributs obsol\xE8tes"); + log("Supression des attributs obsolètes"); let attrs = findObjs({ _type: 'attribute', }); @@ -48600,13 +48840,13 @@ var COFantasy = COFantasy || function() { setDefaultTokenForCharacter(character, newToken); newToken.remove(); } else { - log('Impossible de cr\xE9er un token pour ' + token.name); + log('Impossible de créer un token pour ' + token.name); log(token); } removeAttrs(); }); }); - log("Mise \xE0 jour des attributs et tokens effectu\xE9e"); + log("Mise à jour des attributs et tokens effectuée"); } if (version < 2.11) { let attrs = findObjs({ @@ -48622,7 +48862,7 @@ var COFantasy = COFantasy || function() { }; a.set(na); }); - log("Mise \xE0 jour des attributs de capitaine effectu\xE9e"); + log("Mise à jour des attributs de capitaine effectuée"); } if (version < 2.12) { let attrs = findObjs({ @@ -48691,10 +48931,10 @@ var COFantasy = COFantasy || function() { } a.remove(); }); - log("D\xE9placement des attributs de consommables vers la fiche"); + log("Déplacement des attributs de consommables vers la fiche"); } if (version < 2.13) { - //On enl\xE8ve les attributs obsol\xE8tes de la verison 4.00 de la fiche + //On enlève les attributs obsolètes de la verison 4.00 de la fiche let attrs = findObjs({ _type: 'attribute', }); @@ -48734,7 +48974,7 @@ var COFantasy = COFantasy || function() { }); } if (version < 2.14) { - //Migration des \xE9l\xE9ments de r\xE8gles optionnels + //Migration des éléments de règles optionnels //Divers if (state.COFantasy.options.regles.val.poudre_explosif) { state.COFantasy.options.regles.val.divers.val.poudre_explosif.val = state.COFantasy.options.regles.val.poudre_explosif.val; @@ -48767,13 +49007,13 @@ var COFantasy = COFantasy || function() { delete state.COFantasy.options.regles.val.usure_DEF; } if (state.COFantasy.options.regles.val.generer_options_attaques) { - log("Options d'attaques supprim\xE9es ; veuiller utiliser le bouton 'Options' de la liste d'Actions \xE0 la place"); - sendChat('COFantasy', "Options d'attaques supprim\xE9es ; veuiller utiliser le bouton 'Options' de la liste d'Actions \xE0 la place"); + log("Options d'attaques supprimées ; veuiller utiliser le bouton 'Options' de la liste d'Actions à la place"); + sendChat('COFantasy', "Options d'attaques supprimées ; veuiller utiliser le bouton 'Options' de la liste d'Actions à la place"); delete state.COFantasy.options.regles.val.generer_options_attaques; } if (state.COFantasy.options.regles.val.generer_attaque_groupe) { - log("Attaques de groupe supprim\xE9es ; veuiller utiliser le bouton 'Options' de la liste d'Actions \xE0 la place"); - sendChat('COFantasy', "Options d'attaques supprim\xE9es ; veuiller utiliser le bouton 'Options' de la liste d'Actions \xE0 la place"); + log("Attaques de groupe supprimées ; veuiller utiliser le bouton 'Options' de la liste d'Actions à la place"); + sendChat('COFantasy', "Options d'attaques supprimées ; veuiller utiliser le bouton 'Options' de la liste d'Actions à la place"); delete state.COFantasy.options.regles.val.generer_attaque_groupe; } if (state.COFantasy.options.regles.val.bonus_attaque_groupe) { @@ -48802,7 +49042,7 @@ var COFantasy = COFantasy || function() { state.COFantasy.options.regles.val.mana.val.elixirs_sorts.val = state.COFantasy.options.regles.val.elixirs_sorts.val; delete state.COFantasy.options.regles.val.elixirs_sorts; } - log("R\xE8gles optionelles mises \xE0 jour"); + log("Règles optionelles mises à jour"); } if (version < 2.15) { let attrs = findObjs({ @@ -48844,7 +49084,7 @@ var COFantasy = COFantasy || function() { }); a.remove(); }); - log("D\xE9placement des attributs de consommables de PNJs vers la fiche"); + log("Déplacement des attributs de consommables de PNJs vers la fiche"); } if (version < 2.16) { let attrs = findObjs({ @@ -48855,7 +49095,7 @@ var COFantasy = COFantasy || function() { }); let handhoutComp = handouts.find(function(h) { let handName = h.get('name'); - return (handName == 'Comp\xE9tences' || handName == 'Competences'); + return (handName == 'Compétences' || handName == 'Competences'); }); if (handhoutComp) { let listeCompetences = { @@ -48868,7 +49108,7 @@ var COFantasy = COFantasy || function() { nombre: 0 }; handhoutComp.get('notes', function(note) { // asynchronous - let carac; //La carac dont on sp\xE9cifie les comp\xE9tences actuellement + let carac; //La carac dont on spécifie les compétences actuellement note = note.trim(); if (note.startsWith('

    ')) note = note.substring(3); note = note.trim().replace(/]*>|<\/span>/g, ''); @@ -48886,7 +49126,7 @@ var COFantasy = COFantasy || function() { } if (ligne.length === 0) return; if (carac === undefined) { - log("Comp\xE9tences sans caract\xE9ristique associ\xE9e"); + log("Compétences sans caractéristique associée"); return; } let comps = ligne.split(/, |\/| /); @@ -48964,9 +49204,9 @@ var COFantasy = COFantasy || function() { a.set('name', 'charisme'); return; } - //Les comp\xE9tences + //Les compétences let charId = a.get('characterid'); - //On ne bouge les comp\xE9tences que pour les persos de type PJ + //On ne bouge les compétences que pour les persos de type PJ let typePerso = findObjs({ _type: 'attribute', _characterid: charId, @@ -48992,7 +49232,7 @@ var COFantasy = COFantasy || function() { attrSpec.current = compToCarac[attrName]; createObj('attribute', attrSpec); let attrMalus; - if ((attrSpec.current == 'DEX' && attrName != 'crochetage' && attrName != 'd\xE9samor\xE7age') || + if ((attrSpec.current == 'DEX' && attrName != 'crochetage' && attrName != 'désamorçage') || (attrSpec.current == 'CON' && attrName == 'survie') || attrName == 'natation' || attrName == 'escalade') { attrSpec.name = prefix + 'malus'; @@ -49056,7 +49296,7 @@ var COFantasy = COFantasy || function() { } }); } - log("Mise \xE0 jour des attributs de comp\xE9tence effectu\xE9"); + log("Mise à jour des attributs de compétence effectué"); } if (version < 2.17) { let macros = findObjs({ @@ -49071,7 +49311,7 @@ var COFantasy = COFantasy || function() { if (macro !== newMacro) m.set("action", newMacro); }); - log("Mise \xE0 jour des ability T\xE9n\xE8bres effectu\xE9e"); + log("Mise à jour des ability Ténèbres effectuée"); } let updateReset = function(a, nom, typ) { let c = parseInt(a.get('current')); @@ -49113,7 +49353,7 @@ var COFantasy = COFantasy || function() { } }); } - log("Mise \xE0 jour des attributs effectu\xE9e"); + log("Mise à jour des attributs effectuée"); } if (version < 3.00) { let macros = findObjs({ @@ -49361,7 +49601,7 @@ var COFantasy = COFantasy || function() { characterid: cid, }); if (abilitiesInList.has(actionCmd) || abilitie.get('istokenaction')) { - //On garde le texte partag\xE9 de l'ability. + //On garde le texte partagé de l'ability. createObj('attribute', { name: pref + 'actiontitre', current: action, @@ -49408,7 +49648,7 @@ var COFantasy = COFantasy || function() { characterid: cid, }); // Macro - //D'abord le cas de #Attaque, car le nom affich\xE9 est celui de l'arme + //D'abord le cas de #Attaque, car le nom affiché est celui de l'arme if (actionCmd == '#Attaque' && actionCommands.length > 1) { createObj('attribute', { name: pref + 'actiontitre', @@ -49471,7 +49711,7 @@ var COFantasy = COFantasy || function() { state.COFantasy.options.affichage && state.COFantasy.options.affichage.val && state.COFantasy.options.affichage.val.actions_par_defaut.val) { - //Par d\xE9faut, on montrait la liste de toutes les abilities + //Par défaut, on montrait la liste de toutes les abilities abilities.forEach(function(a) { n++; let pref = 'repeating_actions_' + generateRowID() + '_'; @@ -49522,17 +49762,17 @@ var COFantasy = COFantasy || function() { } if (n > 0) attrRang.set('current', n); }); - log("Mise \xE0 jour des listes d'action effectu\xE9e"); - //Ensuite les pr\xE9dicats bool\xE9ens + log("Mise à jour des listes d'action effectuée"); + //Ensuite les prédicats booléens let predicates = '^(' + 'actionLibre|agripper|ambidextreDuelliste|animal|argumentDeTaille' + '|armureProtection|aucuneActionCombat|baroudHonneur' + '|botteMortelle|bouclierPsi|briseurDOs|bucheron|champion' + '|chasseurEmerite|chatimentDuMale|chimiste|ciblesMultiples' + '|combatEnPhalange|combatKinetique|commandant|controleDuMetabolisme' + - '|creatureArtificielle|crocEnJambe|defenseIntuitive|d\xE9mon|devorer' + + '|creatureArtificielle|crocEnJambe|defenseIntuitive|démon|devorer' + '|durACuire|ecuyer|elfeNoir|enchainement|energieDeLaMort' + - '|estUneIllusion|exsangue|f\xE9e|fievreChene|frappeChirurgicale|gober' + + '|estUneIllusion|exsangue|fée|fievreChene|frappeChirurgicale|gober' + '|graceFeline|graceFelineVoleur|grosMonstreGrosseArme|grosseTete' + '|hachesEtMarteaux|hausserLeTon|horsDePortee|humanoide' + '|ignorerLaDouleur|immuniteAuxArmes|immuniteAuxSournoises' + @@ -49583,7 +49823,7 @@ var COFantasy = COFantasy || function() { { let charId = attribute.get('characterid'); parChar[charId] = parChar[charId] || new Set(); - parChar[charId].add('g\xE9ant'); + parChar[charId].add('géant'); attribute.remove(); } break; @@ -49614,7 +49854,7 @@ var COFantasy = COFantasy || function() { attr.set('current', predText + attr.get('current')); } } - log("Transformation des attributs bool\xE9ens en pr\xE9dicats"); + log("Transformation des attributs booléens en prédicats"); } let getPredicateAttr = function(charId) { let attr = findObjs({ @@ -49682,7 +49922,7 @@ var COFantasy = COFantasy || function() { } attr.set('current', predText); } - log("Transformation des attributs num\xE9riques en pr\xE9dicats"); + log("Transformation des attributs numériques en prédicats"); } if (version < 3.02) { const regPJ = new RegExp("^(repeating_armes_[^_]*_)(.*)$"); @@ -49751,7 +49991,7 @@ var COFantasy = COFantasy || function() { taux = parseInt(cmd[2]); if (isNaN(taux) || taux < 0 || taux > 100) taux = 0; } else { - taux = 100; //La valeur par d\xE9faut en option. + taux = 100; //La valeur par défaut en option. } return false; }); @@ -49798,7 +50038,7 @@ var COFantasy = COFantasy || function() { } }); }); - log("Mise \xE0 jour des armes de jet effectu\xE9e"); + log("Mise à jour des armes de jet effectuée"); } if (version < 3.03) { findObjs({ @@ -49817,7 +50057,7 @@ var COFantasy = COFantasy || function() { if (arme.trim() !== '') predText += ':' + arme; attr.set('current', predText); }); - log("Mise \xE0 jour de pr\xE9dicats effectu\xE9e"); + log("Mise à jour de prédicats effectuée"); } if (version < 3.04) { let attrs = findObjs({ @@ -49898,7 +50138,7 @@ var COFantasy = COFantasy || function() { } attr.set('current', predText); } - log("Transformation d'attributs de combat en pr\xE9dicats"); + log("Transformation d'attributs de combat en prédicats"); } if (version < 3.05) { let attrs = findObjs({ @@ -49911,7 +50151,7 @@ var COFantasy = COFantasy || function() { log("Suppression des attributs pnj d'armure et de bouclier"); } if (version < 3.07) { - //Collecte des persos ayant un pr\xE9dicat charge_ ou eclaire_ + //Collecte des persos ayant un prédicat charge_ ou eclaire_ let charIds = {}; let attrs = findObjs({ _type: 'attribute', @@ -50004,7 +50244,7 @@ var COFantasy = COFantasy || function() { } } } - log("Copie des pr\xE9dicats de charge et \xE9clairage vers les attaques des armes"); + log("Copie des prédicats de charge et éclairage vers les attaques des armes"); } if (version < 3.08) { let attrs = findObjs({ @@ -50045,10 +50285,10 @@ var COFantasy = COFantasy || function() { a.set('current', preds); } }); - log("Changement du pr\xE9dicat laissez-le-moi"); + log("Changement du prédicat laissez-le-moi"); } if (version < 3.11) { - //aura sera pass\xE9 en actions plus tard + //aura sera passé en actions plus tard let predicates = '^(' + 'attributsDeStatut|chairACanonDe|defDeriveeDe|dmSiToucheContact' + '|ecuyerDe|ennemiJure|entrerEnCombatAvec|familier|guetteur' + @@ -50087,7 +50327,7 @@ var COFantasy = COFantasy || function() { for (let charId in parChar) { parChar[charId].attr.set('current', parChar[charId].predText); } - log("Transformation des attributs complexes en pr\xE9dicats"); + log("Transformation des attributs complexes en prédicats"); } if (version < 3.12) { if (state.COFantasy.foudresDuTemps) { @@ -50111,7 +50351,7 @@ var COFantasy = COFantasy || function() { charAttr: true }); }); - log("Mise \xE0 jour effectu\xE9e"); + log("Mise à jour effectuée"); } } @@ -50157,7 +50397,7 @@ on('ready', function() { handout.forEach(function(hand) { COFantasy.changeHandout(hand); }); - //V\xE9rification de la version sur les fiches + //Vérification de la version sur les fiches characters.forEach(function(c) { COFantasy.scriptVersionToCharacter(c, 11); }); @@ -50176,8 +50416,8 @@ on("chat:message", function(msg) { try { COFantasy.apiCommand(msg); } catch (e) { - sendChat('COF', "Erreur durant l'ex\xE9cution de " + msg.content); - log("Erreur durant l'ex\xE9cution de " + msg.content); + sendChat('COF', "Erreur durant l'exécution de " + msg.content); + log("Erreur durant l'exécution de " + msg.content); log(msg); let errMsg = e.name; if (e.lineNumber) errMsg += " at " + e.lineNumber; diff --git a/COFantasy/ChangeLog.md b/COFantasy/ChangeLog.md index bad241039c..6b0a05e7a4 100644 --- a/COFantasy/ChangeLog.md +++ b/COFantasy/ChangeLog.md @@ -8,6 +8,10 @@ * Expertise (rang 1 de la Voie de prestige spécialisée) ### Autres améliorations +* Possibilité que la peur paralyse. +* Ajout d'une commande !cof-clean-global-state. +* Ajout d'une action pour relacher une cible agrippée. +* Ajout d'une option --succes à !cof-jet * Possibilité d'utiliser les options de triche avec les --if * Ajout d'un prédicat pour les armes de l'été. * Ajout d'un effet armeGlacee. diff --git a/COFantasy/doc.html b/COFantasy/doc.html index 555b52488f..c71932c9e4 100644 --- a/COFantasy/doc.html +++ b/COFantasy/doc.html @@ -4,7 +4,7 @@ - Scripts pour Chroniques Oubliées Fantasy sous Roll20 + Scripts pour Chroniques Oubli\xE9es Fantasy sous Roll20 @@ -57,26 +57,26 @@

    Sommaire

  • Actions principales
  • -
  • Capacités par Classe
  • +
  • Capacit\xE9s par Classe
  • -
  • Autres capacités
  • +
  • Autres capacit\xE9s
  • Terres d'Arran
  • -
  • Markers personnalisés
  • +
  • Markers personnalis\xE9s
  • Console API
  • Conversion depuis Pathfinder
  • @@ -135,129 +136,129 @@

    1. Comment utiliser Le scr

    1.1 Tokens et personnages

    -

    Ces scripts ont été écrits pour fonctionner avec les fiches de personnages développées par Natha.

    +

    Ces scripts ont \xE9t\xE9 \xE9crits pour fonctionner avec les fiches de personnages d\xE9velopp\xE9es par Natha.

    -
    A choisir pendant la création de la partie sur Roll20.
    +
    A choisir pendant la cr\xE9ation de la partie sur Roll20.
    -

    Chaque token avec lequel vous souhaitez interagir doit représenter un personnage.

    -

    La barre 1 représente toujours les points de vie du token.
    - La barre 2 est soit la mana, pour les personnages qui ont des points de mana, soit les dégâts temporaires pour les personnages qui n’ont pas de points de mana
    - La barre 3 est utilisée pour donner un modificateur temporaire à l’attaque du token. +

    Chaque token avec lequel vous souhaitez interagir doit repr\xE9senter un personnage.

    +

    La barre 1 repr\xE9sente toujours les points de vie du token.
    + La barre 2 est soit la mana, pour les personnages qui ont des points de mana, soit les d\xE9g\xE2ts temporaires pour les personnages qui n\x2019ont pas de points de mana
    + La barre 3 est utilis\xE9e pour donner un modificateur temporaire \xE0 l\x2019attaque du token.

    -

    Les statuts des tokens sont en partie utilisés pour représenter des états. Voir plus loin pour la liste des statuts utilisés par les scripts.
    - Pour tenir compte d'autre états non visibles sur les tokens, les scripts utilisent des attributs supplémentaires (hors fiche). Parfois, le MJ devra créer et remplir lui-même certains attributs, d'autres fois cela sera géré par les scripts. +

    Les statuts des tokens sont en partie utilis\xE9s pour repr\xE9senter des \xE9tats. Voir plus loin pour la liste des statuts utilis\xE9s par les scripts.
    + Pour tenir compte d'autre \xE9tats non visibles sur les tokens, les scripts utilisent des attributs suppl\xE9mentaires (hors fiche). Parfois, le MJ devra cr\xE9er et remplir lui-m\xEAme certains attributs, d'autres fois cela sera g\xE9r\xE9 par les scripts.

    -

    Il est important de noter la différence entre les tokens liés à un personnage (la barre 1 est liée aux points de vie du personnage, tout changement sur la fiche se répercute sur le token), et les tokens non liés (dans ce cas, la fiche de personnage est générique, et chaque token est une instance différente, avec des PV indépendants).

    -

    Pour gérer les états spécifiques à un token non lié, les scripts utilisent des conventions de nom d'attribut utilisant le nom du token. Pour que cela fonctionne correctement, il est important que deux tokens indépendants ne portent pas le même nom, même si ils représentent le même personnage. Pour cette raison, le script va automatiquement renommer les tokens indépendants, en leur associant un numéro. Il est toujours possible de remodifier le nom après la création du token, mais dans ce cas, c'est vous qui gérez...

    -

    Certains messages tiennent compte du genre (masculin ou féminin) des personnages. Ils utilisent le champ Sexe de la fiche de personnage. Un personnage est reconnu comme féminin si ce champ commence par la lettre F. +

    Il est important de noter la diff\xE9rence entre les tokens li\xE9s \xE0 un personnage (la barre 1 est li\xE9e aux points de vie du personnage, tout changement sur la fiche se r\xE9percute sur le token), et les tokens non li\xE9s (dans ce cas, la fiche de personnage est g\xE9n\xE9rique, et chaque token est une instance diff\xE9rente, avec des PV ind\xE9pendants).

    +

    Pour g\xE9rer les \xE9tats sp\xE9cifiques \xE0 un token non li\xE9, les scripts utilisent des conventions de nom d'attribut utilisant le nom du token. Pour que cela fonctionne correctement, il est important que deux tokens ind\xE9pendants ne portent pas le m\xEAme nom, m\xEAme si ils repr\xE9sentent le m\xEAme personnage. Pour cette raison, le script va automatiquement renommer les tokens ind\xE9pendants, en leur associant un num\xE9ro. Il est toujours possible de remodifier le nom apr\xE8s la cr\xE9ation du token, mais dans ce cas, c'est vous qui g\xE9rez...

    +

    Certains messages tiennent compte du genre (masculin ou f\xE9minin) des personnages. Ils utilisent le champ Sexe de la fiche de personnage. Un personnage est reconnu comme f\xE9minin si ce champ commence par la lettre F.

    1.2 Macros et Abilities

    -

    Comme tous les scripts, ces scripts sont utilisables tels quels dans le chat, mais ils sont pensés pour être utilisés par des macros qui permettent un autre niveau d'automatisation parfois difficile d'accès au sein des scripts. le script génère d'ailleurs la plupart des macros utiles à la première utilisation, et il met automatiquement les macros à jour à chaque changement de version. Il est possible de demander des les re-créer en tapant la commande !cof-set-macros dans le chat.

    +

    Comme tous les scripts, ces scripts sont utilisables tels quels dans le chat, mais ils sont pens\xE9s pour \xEAtre utilis\xE9s par des macros qui permettent un autre niveau d'automatisation parfois difficile d'acc\xE8s au sein des scripts. le script g\xE9n\xE8re d'ailleurs la plupart des macros utiles \xE0 la premi\xE8re utilisation, et il met automatiquement les macros \xE0 jour \xE0 chaque changement de version. Il est possible de demander des les re-cr\xE9er en tapant la commande !cof-set-macros dans le chat.

    - Le script ne peut pas mettre les macros dans la barre de raccourci. Je recommande que chaque joueur se crée sa macro Centrer, contenant le code !cof-centrer-sur-token nom_de_leur_token_principal, qui leur permettra en un click de centrer la vue de la carte sur leur token. Pour le MJ, le script suggère de mettre un certain nombre des macros qu'il crée, au moment de la première utilisation.

    -

    Une partie des capacités et attaques des personnages devraient être utilisées au sein d'abilities de personnages, accessibles comme "Token action". Si ces abilities utilisent des macros, ne pas oublier de rendre ces macros accessibles aux joueurs.

    + Le script ne peut pas mettre les macros dans la barre de raccourci. Je recommande que chaque joueur se cr\xE9e sa macro Centrer, contenant le code !cof-centrer-sur-token nom_de_leur_token_principal, qui leur permettra en un click de centrer la vue de la carte sur leur token. Pour le MJ, le script sugg\xE8re de mettre un certain nombre des macros qu'il cr\xE9e, au moment de la premi\xE8re utilisation.

    +

    Une partie des capacit\xE9s et attaques des personnages devraient \xEAtre utilis\xE9es au sein d'abilities de personnages, accessibles comme "Token action". Si ces abilities utilisent des macros, ne pas oublier de rendre ces macros accessibles aux joueurs.

    -

    1.3 Prédicats

    +

    1.3 Pr\xE9dicats

    -

    Une façon courante d'informer le script qu'un personnage dispose d'une capacité particulière (que ce soit dû à son entraînement ou à un objet porté) consiste à utiliser des prédicats. Il s'agit de mots clés à rentrer dans la zone de texte Prédicats, visible depuis l'onglet Script de la fiche. Ces mots clés peuvent être séparés de blancs ou de retours à la ligne.

    -

    On peut associer une valeur à un prédicat (le plus souvent un nombre, mais en fait n'importe quel mot qui ne contienne ni virgule, ni blanc, ni :). Pour cela, faire suivre le prédicat de : puis de la valeur.

    -

    Dans chaque ligne de la zone de prédicats, tout ce qui vient après // est considéré comme du commentaire et ignoré (exception: les valeurs complexes, si le // vient après ::, voir plus bas).

    +

    Une fa\xE7on courante d'informer le script qu'un personnage dispose d'une capacit\xE9 particuli\xE8re (que ce soit d\xFB \xE0 son entra\xEEnement ou \xE0 un objet port\xE9) consiste \xE0 utiliser des pr\xE9dicats. Il s'agit de mots cl\xE9s \xE0 rentrer dans la zone de texte Pr\xE9dicats, visible depuis l'onglet Script de la fiche. Ces mots cl\xE9s peuvent \xEAtre s\xE9par\xE9s de blancs ou de retours \xE0 la ligne.

    +

    On peut associer une valeur \xE0 un pr\xE9dicat (le plus souvent un nombre, mais en fait n'importe quel mot qui ne contienne ni virgule, ni blanc, ni :). Pour cela, faire suivre le pr\xE9dicat de : puis de la valeur.

    +

    Dans chaque ligne de la zone de pr\xE9dicats, tout ce qui vient apr\xE8s // est consid\xE9r\xE9 comme du commentaire et ignor\xE9 (exception: les valeurs complexes, si le // vient apr\xE8s ::, voir plus bas).

    -
    Exemple de prédicats.
    -

    Certains prédicats ont des valeurs complexes, qui peuvent contenir des blancs, des virgules, des guillements, ou même des : ou //. Afin de pouvoir utliser ces valeurs, vous pouvez faire suivre le nom du prédicat de ::. Tout ce qui viendra après jusqu'à la fin de la ligne sera considéré comme étant la valeur associée à ce prédicat. Un exemple typique d'utilisation : quand la valeur est un nom de personnage.

    -

    Il est aussi possible d'associer des prédicats à des attaques. Ces prédicats sont pris en compte quand ses attaques sont des armes, et ce que ces armes sont tenues en main. Cela permet de coder une grande variété d'effets magiques des armes. Attention, cela ne fonctionne pas pour les mooks avec les prédicats animeAPartirDExistant, intercepter, lienEpique, attaqueEnTraitre, sansPeur, immuniteSaignement, et controleSanguin.

    +
    Exemple de pr\xE9dicats.
    +

    Certains pr\xE9dicats ont des valeurs complexes, qui peuvent contenir des blancs, des virgules, des guillements, ou m\xEAme des : ou //. Afin de pouvoir utliser ces valeurs, vous pouvez faire suivre le nom du pr\xE9dicat de ::. Tout ce qui viendra apr\xE8s jusqu'\xE0 la fin de la ligne sera consid\xE9r\xE9 comme \xE9tant la valeur associ\xE9e \xE0 ce pr\xE9dicat. Un exemple typique d'utilisation : quand la valeur est un nom de personnage.

    +

    Il est aussi possible d'associer des pr\xE9dicats \xE0 des attaques. Ces pr\xE9dicats sont pris en compte quand ses attaques sont des armes, et ce que ces armes sont tenues en main. Cela permet de coder une grande vari\xE9t\xE9 d'effets magiques des armes. Attention, cela ne fonctionne pas pour les mooks avec les pr\xE9dicats animeAPartirDExistant, intercepter, lienEpique, attaqueEnTraitre, sansPeur, immuniteSaignement, et controleSanguin.

    -
    Une épée +1 affûtée avec le prédicat enchainement (actif pour toute attaque, tant que cette épée est en main).
    +
    Une \xE9p\xE9e +1 aff\xFBt\xE9e avec le pr\xE9dicat enchainement (actif pour toute attaque, tant que cette \xE9p\xE9e est en main).
    -

    1.4 Méthodes de sélection de groupes

    +

    1.4 M\xE9thodes de s\xE9lection de groupes

    -

    Comme les joueurs ne peuvent pas sélectionner un nombre arbitraire d'ennemis, 7 méthodes sont disponibles :

    +

    Comme les joueurs ne peuvent pas s\xE9lectionner un nombre arbitraire d'ennemis, 7 m\xE9thodes sont disponibles :

      -
    • Le MJ lance la macro en sélectionnant les cibles
    • -
    • option --allies : cela fait chercher tous les handout dont le nom est Equipe suivi d'un nom, et tels que le handout contienne une liste de noms (un par ligne), parmis lesquels, celui du personnage qui agit. Le personnage qui agit est celui qui est sélectionné. Les cibles sont tous les alliés du personnage sélectionné, mais pas le personnage lui-même. Attention, les noms de personnages ne doivent pas contenir de balise XML (texte encadré par des < et >). Optionellement, on peut préciser une distance maximale entre le personnage sélectionné et ses allies.
    • -
    • option --alliesEnVue : comme --allies, mais ne garde que les alliés en vue (en fonction des murs sur le layer lumière).
    • -
    • option --equipe nom : agit sur tous les personnages mentionnés dans le handout s'appelant Equipe nom.
    • -
    • option --self : pour rajouter le personnage sélectionné. Utile si on veut le personnage et ses alliés, par exemple.
    • -
    • option --target : pour ajouter une seule cible, avec une id de token. Le personnage qui agit est celui qui est sélectionné.
    • -
    • option --disque : le premier argument, optionnel, est l'id ou le nom d'un token qui représente un personnage, le deuxième argument un rayon. Cela sélectionne tous les tokens à une distance de moins que le rayon du premier argument (ou du personnage à l'origine de l'effet, si le premier argument est absent). Si un troisième argument est donné, il est interprété comme la portée maximum entre le centre du disque et le token du personnage à l'origine de l'effet. Si le premier argument représente un personnage avec un max de PV à 0, il est compris comme un personnage fictif créé juste pour définir le disque, et il sera supprimé après la sélection. À noter que le script crée par défaut un tel personnage, utilisable par tous, et appelé Cible.
    • +
    • Le MJ lance la macro en s\xE9lectionnant les cibles
    • +
    • option --allies : cela fait chercher tous les handout dont le nom est Equipe suivi d'un nom, et tels que le handout contienne une liste de noms (un par ligne), parmis lesquels, celui du personnage qui agit. Le personnage qui agit est celui qui est s\xE9lectionn\xE9. Les cibles sont tous les alli\xE9s du personnage s\xE9lectionn\xE9, mais pas le personnage lui-m\xEAme. Attention, les noms de personnages ne doivent pas contenir de balise XML (texte encadr\xE9 par des < et >). Optionellement, on peut pr\xE9ciser une distance maximale entre le personnage s\xE9lectionn\xE9 et ses allies.
    • +
    • option --alliesEnVue : comme --allies, mais ne garde que les alli\xE9s en vue (en fonction des murs sur le layer lumi\xE8re).
    • +
    • option --equipe nom : agit sur tous les personnages mentionn\xE9s dans le handout s'appelant Equipe nom.
    • +
    • option --self : pour rajouter le personnage s\xE9lectionn\xE9. Utile si on veut le personnage et ses alli\xE9s, par exemple.
    • +
    • option --target : pour ajouter une seule cible, avec une id de token. Le personnage qui agit est celui qui est s\xE9lectionn\xE9.
    • +
    • option --disque : le premier argument, optionnel, est l'id ou le nom d'un token qui repr\xE9sente un personnage, le deuxi\xE8me argument un rayon. Cela s\xE9lectionne tous les tokens \xE0 une distance de moins que le rayon du premier argument (ou du personnage \xE0 l'origine de l'effet, si le premier argument est absent). Si un troisi\xE8me argument est donn\xE9, il est interpr\xE9t\xE9 comme la port\xE9e maximum entre le centre du disque et le token du personnage \xE0 l'origine de l'effet. Si le premier argument repr\xE9sente un personnage avec un max de PV \xE0 0, il est compris comme un personnage fictif cr\xE9\xE9 juste pour d\xE9finir le disque, et il sera supprim\xE9 apr\xE8s la s\xE9lection. \xC0 noter que le script cr\xE9e par d\xE9faut un tel personnage, utilisable par tous, et appel\xE9 Cible.
    • option --disquePasseMur : comme --disque, mais l'effet traverse les murs.
    • -
    • option --enVue : sélectionne tous les tokens en vue du personnage qui lance l'effet. Accepte aussi un argument d'id de token, dans ce cas on garde les token en vue de celui avec cette id.
    • -
    • option --saufAllies permet d'exclure les alliés de la sélection (voir plus haut pour la définition des alliés).
    • +
    • option --enVue : s\xE9lectionne tous les tokens en vue du personnage qui lance l'effet. Accepte aussi un argument d'id de token, dans ce cas on garde les token en vue de celui avec cette id.
    • +
    • option --saufAllies permet d'exclure les alli\xE9s de la s\xE9lection (voir plus haut pour la d\xE9finition des alli\xE9s).

    -
    Exemple d'handout avec différentes équipes.
    +
    Exemple d'handout avec diff\xE9rentes \xE9quipes.

    1.5 Options de mana

    -

    COF sous ses différentes formes est une boîte à outils et nombreuses sont les variantes de système de magie qui peuvent être utilisées. Le script propose un support pour les plus populaires d'entre elles. Voici quelques consignes pour les implémenter.

    -

    Spécifier un coût en mana

    +

    COF sous ses diff\xE9rentes formes est une bo\xEEte \xE0 outils et nombreuses sont les variantes de syst\xE8me de magie qui peuvent \xEAtre utilis\xE9es. Le script propose un support pour les plus populaires d'entre elles. Voici quelques consignes pour les impl\xE9menter.

    +

    Sp\xE9cifier un co\xFBt en mana

      -
    • Les points de mana sont dépensés en ajoutant l'option --mana X à une action ou dans les options d'une attaque. Toutes les capacités implémentées dans la documentation donnent par défaut le coût en mana selon les règles de base.
    • -
    • Même un sort qui ne coûte pas de mana devrait utiliser --mana 0. Cela permet au script de dissiper automatiquement un effet généré par un lanceur de sort mis hors de combat.
    • -
    • Une option d'affichage disponible via !cof-options permet de demander au script d'afficher explicitement dans le chat toute dépense de PM effectuée par un personnage.
    • +
    • Les points de mana sont d\xE9pens\xE9s en ajoutant l'option --mana X \xE0 une action ou dans les options d'une attaque. Toutes les capacit\xE9s impl\xE9ment\xE9es dans la documentation donnent par d\xE9faut le co\xFBt en mana selon les r\xE8gles de base.
    • +
    • M\xEAme un sort qui ne co\xFBte pas de mana devrait utiliser --mana 0. Cela permet au script de dissiper automatiquement un effet g\xE9n\xE9r\xE9 par un lanceur de sort mis hors de combat.
    • +
    • Une option d'affichage disponible via !cof-options permet de demander au script d'afficher explicitement dans le chat toute d\xE9pense de PM effectu\xE9e par un personnage.
    -

    Système de base (COF p. 79)

    -

    Le support des effets supplémentaires à disposition du lanceur de sort sont gérées via l'utilisation d'options sur les commandes utilisées.

    +

    Syst\xE8me de base (COF p. 79)

    +

    Le support des effets suppl\xE9mentaires \xE0 disposition du lanceur de sort sont g\xE9r\xE9es via l'utilisation d'options sur les commandes utilis\xE9es.

    • Magie rapide : pas de support particulier
    • -
    • Magie puissante (dés) : utiliser l'option --puissant dans vos abilities ou attaques
    • -
    • Magie puissante (portée) : utiliser l'option --puissant portee dans vos abilities ou attaques
    • -
    • Magie puissante (durée) : utiliser l'option --puissant duree dans vos abilities ou attaques
    • +
    • Magie puissante (d\xE9s) : utiliser l'option --puissant dans vos abilities ou attaques
    • +
    • Magie puissante (port\xE9e) : utiliser l'option --puissant portee dans vos abilities ou attaques
    • +
    • Magie puissante (dur\xE9e) : utiliser l'option --puissant duree dans vos abilities ou attaques
    -

    On peut facilement combiner ces options avec un input de choix roll20 qui permettra au joueur de choisir le type d'incantation lorsqu'il lance le sort, tout en spécifiant la dépense de Mana.

    -

    --mana X ?{Incantation ?|Rapide,&#32;|Puissante (L),--puissant|Portée étendue (L),--puissant portee|Durée étendue (L),--puissant duree}

    +

    On peut facilement combiner ces options avec un input de choix roll20 qui permettra au joueur de choisir le type d'incantation lorsqu'il lance le sort, tout en sp\xE9cifiant la d\xE9pense de Mana.

    +

    --mana X ?{Incantation ?|Rapide,&#32;|Puissante (L),--puissant|Port\xE9e \xE9tendue (L),--puissant portee|Dur\xE9e \xE9tendue (L),--puissant duree}

    Mana Totale (COF p. 180)

    -

    La première chose à faire est d'activer l'option Mana totale via !cof-options. Pour le reste, vous pouvez réutiliser le principe du système de base ci-dessus.

    -
    Coût aléatoire
    -

    Vous pouvez utiliser des lancers de dés dans vos options --mana. Par exemple pour un sort de rang 1, on peut renseigner --mana [[1d3]]. L'option d'affichage de la dépense de mana prend ici tout son sens, activable via !cof-options.

    +

    La premi\xE8re chose \xE0 faire est d'activer l'option Mana totale via !cof-options. Pour le reste, vous pouvez r\xE9utiliser le principe du syst\xE8me de base ci-dessus.

    +
    Co\xFBt al\xE9atoire
    +

    Vous pouvez utiliser des lancers de d\xE9s dans vos options --mana. Par exemple pour un sort de rang 1, on peut renseigner --mana [[1d3]]. L'option d'affichage de la d\xE9pense de mana prend ici tout son sens, activable via !cof-options.

    Contrecoup
    -

    Vous pouvez activer la règle spécifique de Contrecoup via !cof-options.

    -

    Tempête de Mana (COF Compagnon p. 105)

    -

    Le script implémente un support complet des règles de Tempête de Mana. Pour ce faire, il faut ajouter les options --tempeteDeMana --rang X sur les sorts combinables avec Tempête de Mana. L'option rang permet d'indiquer le rang du sort afin que le script puisse calculer le maximum de PM qu'on peut dépenser lors du lancement du sort. Pour mettre ça de manière générique sur une action ou une attaque et permettre au joueur de choisir de faire appel à Tempête de Mana ou pas, on peut utiliser :

    -

    --mana X --rang Y ?{Tempête de Mana ?|Non,&#32;|Oui,--tempeteDeMana}

    -

    Tempête de Mana est compatible avec Mana Totale et Brûlure de Magie.

    +

    Vous pouvez activer la r\xE8gle sp\xE9cifique de Contrecoup via !cof-options.

    +

    Temp\xEAte de Mana (COF Compagnon p. 105)

    +

    Le script impl\xE9mente un support complet des r\xE8gles de Temp\xEAte de Mana. Pour ce faire, il faut ajouter les options --tempeteDeMana --rang X sur les sorts combinables avec Temp\xEAte de Mana. L'option rang permet d'indiquer le rang du sort afin que le script puisse calculer le maximum de PM qu'on peut d\xE9penser lors du lancement du sort. Pour mettre \xE7a de mani\xE8re g\xE9n\xE9rique sur une action ou une attaque et permettre au joueur de choisir de faire appel \xE0 Temp\xEAte de Mana ou pas, on peut utiliser :

    +

    --mana X --rang Y ?{Temp\xEAte de Mana ?|Non,&#32;|Oui,--tempeteDeMana}

    +

    Temp\xEAte de Mana est compatible avec Mana Totale et Br\xFBlure de Magie.

    Option altruiste
    -

    Si vous désirez jouer avec l'option de Magie altruiste, il suffit de changer l'option en --tempeteDeMana altruiste sur les sorts où c'est utile.

    +

    Si vous d\xE9sirez jouer avec l'option de Magie altruiste, il suffit de changer l'option en --tempeteDeMana altruiste sur les sorts o\xF9 c'est utile.

    Terres d'Arran (COTA p. 112)

    -

    Première chose à faire, activer l'option Brûlure de Magie via !cof-options. Note : si vous utilisez l'option de Brûlure de Magie avec l'option Mana Totale, vous pouvez utiliser un prédicat coefPVMana qui va diviser le nombre de PVs dépensé par point de mana.

    -

    Vous pouvez ensuite réutiliser le même principe que le système de base en combinant dépense de Mana et effets supplémentaires. Voici un exemple pour une Boule de Feu (Voie de l'élémentaliste, rang 4) :

    -

    --mana 2 ?{Incantation ?|Normale,--mana 2|Économe (L),&#32;|Puissante (L),--mana 2 --puissant|Portée étendue (L),--mana 2 --puissant portee} (notez que les coût total pour une incantation normale sera de 4 points de mana)

    +

    Premi\xE8re chose \xE0 faire, activer l'option Br\xFBlure de Magie via !cof-options. Note : si vous utilisez l'option de Br\xFBlure de Magie avec l'option Mana Totale, vous pouvez utiliser un pr\xE9dicat coefPVMana qui va diviser le nombre de PVs d\xE9pens\xE9 par point de mana.

    +

    Vous pouvez ensuite r\xE9utiliser le m\xEAme principe que le syst\xE8me de base en combinant d\xE9pense de Mana et effets suppl\xE9mentaires. Voici un exemple pour une Boule de Feu (Voie de l'\xE9l\xE9mentaliste, rang 4) :

    +

    --mana 2 ?{Incantation ?|Normale,--mana 2|\xC9conome (L),&#32;|Puissante (L),--mana 2 --puissant|Port\xE9e \xE9tendue (L),--mana 2 --puissant portee} (notez que les co\xFBt total pour une incantation normale sera de 4 points de mana)

    -

    1.6 Règles optionnelles utilisées

    +

    1.6 R\xE8gles optionnelles utilis\xE9es

    -

    Le script supporte l'utilisation de la règle des points de chance et des points de récupération.

    -

    J'ai aussi choisi, comme proposé par Kegron, de diminuer la DEF de tous les protagonistes après un certain nombre de tours de combat (-2 tous les 5 tours, peut être désactivé pendant un combat par la commande !cof-usure-off, ou bien dans les options de jeu).

    -

    Le script utilise aussi par défaut une règle de blessure grave : chaque fois qu'un personnage tombe à 0 PV, il encaisse une perte d'un point de récupération. S'il était à 0 points de récupération, il devient gravement blessé, ce qui le rend affaibli. Si le personnage était déjà gravement blessé, il meurt. Pour récupérer d'une blessure grave, le personnage doit se reposer une nuit, et réussir un test de CON difficulté 8 (avec le d12). Il est impossible de régénérer les points de récupération quand on est gravement blessé.

    -

    Le script utilise également une règle de dommages importants : chaque fois qu'un PJ reçoit plus de dommages en une fois que la somme de sa valeur de constitution et de son niveau, il perd 1PR et la règle de blessure grave s'applique. S'il était déjà blessé mais qu'il lui reste des PV, il tombe inconscient. Les deux règles sont désactivables séparément via !cof-options, dans la section dommages.

    -

    Le script propose également quelques autres options qui sont activables et/ou modifiables via la commande !cof-options. Quelques exemples :

    +

    Le script supporte l'utilisation de la r\xE8gle des points de chance et des points de r\xE9cup\xE9ration.

    +

    J'ai aussi choisi, comme propos\xE9 par Kegron, de diminuer la DEF de tous les protagonistes apr\xE8s un certain nombre de tours de combat (-2 tous les 5 tours, peut \xEAtre d\xE9sactiv\xE9 pendant un combat par la commande !cof-usure-off, ou bien dans les options de jeu).

    +

    Le script utilise aussi par d\xE9faut une r\xE8gle de blessure grave : chaque fois qu'un personnage tombe \xE0 0 PV, il encaisse une perte d'un point de r\xE9cup\xE9ration. S'il \xE9tait \xE0 0 points de r\xE9cup\xE9ration, il devient gravement bless\xE9, ce qui le rend affaibli. Si le personnage \xE9tait d\xE9j\xE0 gravement bless\xE9, il meurt. Pour r\xE9cup\xE9rer d'une blessure grave, le personnage doit se reposer une nuit, et r\xE9ussir un test de CON difficult\xE9 8 (avec le d12). Il est impossible de r\xE9g\xE9n\xE9rer les points de r\xE9cup\xE9ration quand on est gravement bless\xE9.

    +

    Le script utilise \xE9galement une r\xE8gle de dommages importants : chaque fois qu'un PJ re\xE7oit plus de dommages en une fois que la somme de sa valeur de constitution et de son niveau, il perd 1PR et la r\xE8gle de blessure grave s'applique. S'il \xE9tait d\xE9j\xE0 bless\xE9 mais qu'il lui reste des PV, il tombe inconscient. Les deux r\xE8gles sont d\xE9sactivables s\xE9par\xE9ment via !cof-options, dans la section dommages.

    +

    Le script propose \xE9galement quelques autres options qui sont activables et/ou modifiables via la commande !cof-options. Quelques exemples :

    • Initiative variable (individuelle / de groupe)
    • -
    • Versions alternatives de capacités (interchangeable, forme d'arbre, rune de protection)
    • -
    • Critiques étendus
    • +
    • Versions alternatives de capacit\xE9s (interchangeable, forme d'arbre, rune de protection)
    • +
    • Critiques \xE9tendus
    • Dommages minimums
    • Attaques de groupe

    2. Actions principales

    -

    Pour la plupart des actions ci-dessous, il est généralement utile de créer des macros facilitant leur utilisation. Pour mettre en place un jeu de macros par défaut, vous pouvez taper !cof-set-macros dans le chat. Si vous souhaitez redéfinir des macros existantes, vous pouvez taper !cof-set-macros --force.

    +

    Pour la plupart des actions ci-dessous, il est g\xE9n\xE9ralement utile de cr\xE9er des macros facilitant leur utilisation. Pour mettre en place un jeu de macros par d\xE9faut, vous pouvez taper !cof-set-macros dans le chat. Si vous souhaitez red\xE9finir des macros existantes, vous pouvez taper !cof-set-macros --force.

    2.1 Le combat

    Initiative : !cof-init

    -

    Les tokens sélectionnés sont ajouté au tracker de tour. Si celui-ci n'existe pas, un nouveau est créé, avec compteur de tour à 1, et on rentre en combat. Les tokens ayant un prédicat aucuneActionCombat ne sont jamais ajoutés au turn tracker.

    -

    Une option du script (ajustable en utilisant !cof-options) permet d'utiliser la règle de l'initiative variable (ajout d'un d6 explosif à l'initiative). Il est alors possible de faire lancer les dés d'initiative par les joueurs.

    -

    Les règles de tri suivent ce qui est donné p 70 : priorité aux PJs. Pour l'instant, on distingue un PJ d'un PNJ au dé de vie : si le personnage d'a pas de dé de vie, c'est un PNJ. Ensuite, entre PJs, priorité à la plus haute sagesse. Pour les PNJ, c'est aléatoire.

    -

    À chaque instant, le token dont c'est le tour d'agir est signalé par une aura qui bouge lentement. L'image de cette aura peut être modifiée dans les options (!cof-options images), et il est possible de spécifier une aura pour chaque token, en ajoutant une ligne dans le champ GM Notes du token (en bas de la partie basique de l'édition du token). Cette ligne doit commencer par init_aura:, et contenir une url valide pour un token. N'oubliez pas de sauvegarder le token comme token par défaut our un personnage si vous voulez que ce personnage ait toujours cette aura.

    +

    Les tokens s\xE9lectionn\xE9s sont ajout\xE9 au tracker de tour. Si celui-ci n'existe pas, un nouveau est cr\xE9\xE9, avec compteur de tour \xE0 1, et on rentre en combat. Les tokens ayant un pr\xE9dicat aucuneActionCombat ne sont jamais ajout\xE9s au turn tracker.

    +

    Une option du script (ajustable en utilisant !cof-options) permet d'utiliser la r\xE8gle de l'initiative variable (ajout d'un d6 explosif \xE0 l'initiative). Il est alors possible de faire lancer les d\xE9s d'initiative par les joueurs.

    +

    Les r\xE8gles de tri suivent ce qui est donn\xE9 p 70 : priorit\xE9 aux PJs. Pour l'instant, on distingue un PJ d'un PNJ au d\xE9 de vie : si le personnage d'a pas de d\xE9 de vie, c'est un PNJ. Ensuite, entre PJs, priorit\xE9 \xE0 la plus haute sagesse. Pour les PNJ, c'est al\xE9atoire.

    +

    \xC0 chaque instant, le token dont c'est le tour d'agir est signal\xE9 par une aura qui bouge lentement. L'image de cette aura peut \xEAtre modifi\xE9e dans les options (!cof-options images), et il est possible de sp\xE9cifier une aura pour chaque token, en ajoutant une ligne dans le champ GM Notes du token (en bas de la partie basique de l'\xE9dition du token). Cette ligne doit commencer par init_aura:, et contenir une url valide pour un token. N'oubliez pas de sauvegarder le token comme token par d\xE9faut our un personnage si vous voulez que ce personnage ait toujours cette aura.

    Il est possible de laisser les joueurs passer leur tour, en utilisant la commande !cof-tour-suivant. Une utilisation possible est de le mettre en macro dans les actions du tour (voir Actions du tour ci-dessous).

    Astuces :
      -
    • !cof-attendre ?{Nouvelle initiative} : Permet d'attendre avant d'agir en réduisant temporairement son initiative.

    • -
    • Il est possible de se passer de l'aura qui bouge, et d'utiliser à la place une icône de drapeau ou avec la syntaxe - !cof-init --aura une aura autour du Token de couleur verte (ou rouge si le personnage n'est pas contrôlé par un joueur ou dans une équipe contenant un personnage contrôlé par un joueur). Pour cela, désactiver l'initiative dynamique dans les options d'affichage (!cof-options affichage). +
    • !cof-attendre ?{Nouvelle initiative} : Permet d'attendre avant d'agir en r\xE9duisant temporairement son initiative.

    • +
    • Il est possible de se passer de l'aura qui bouge, et d'utiliser \xE0 la place une ic\xF4ne de drapeau ou avec la syntaxe + !cof-init --aura une aura autour du Token de couleur verte (ou rouge si le personnage n'est pas contr\xF4l\xE9 par un joueur ou dans une \xE9quipe contenant un personnage contr\xF4l\xE9 par un joueur). Pour cela, d\xE9sactiver l'initiative dynamique dans les options d'affichage (!cof-options affichage).
    @@ -265,349 +266,349 @@
    Astuces :

    Liste d'actions pour le personnage dont c'est le tour

    -

    Le script affiche, pour le personnage dont c'est le tour, une liste d'actions. Cette liste est chuchotée au joueur qui contrôle le personnage, ou si aucun joueur le contrôlant n'est connecté, au MJ. Elle se compose par défaut des attaques du personnage et des actions d'attendre, se défendre et faire une manoeuvre. - Pour voir ce message en dehors du changement d'initiative, ou pour le MJ, on peut utiliser !cof-liste-actions en sélectionnant le token (un bon candidat pour une macro de type token action, d'ailleurs généré par la commande !cof-set-macros). - Pour contrôler ce qui est affiché dans cette liste, vous pouvez principalement utiliser la liste des attaques du personnage et surtout la partie script de la fiche.

    -
    Les attaques affichées
    -

    Il est possible de ne pas afficher une attaque en décochant la case sous le dé dans les options d'attaque. Les attaques sont affichées dans l'ordre des labels d'attaques. les attaques avec des conditions impossibles (du genre limite par jour épuisée, etc.) ne sont pas affichées.

    -

    À cela se rajoute éventuellement l'attaque avec l'arme en main. À côté de cette attaque, le script propose un bouton pour rengainer l'arme ou en dégainer une autre (parmis les armes de la fiche cochées). On peut modifier cette liste des armes à dégainer en utilisant des prédicats actionDegainern, de valeur le label de l'arme à afficher en position n dans la liste (seulement pour les premières armes, il n'est pas possible de ne spécifier que la 2nde arme ou la 1ère et le 3ème). On peut ainsi faire afficher 2 armes à dégainer en même temps en séparant les labels d'un - (par exemple pour faire dégainer l'arme 1 en main droite et l'arme 4 en main gauche, en première position dans la liste, on écrira actionDegainer1:1-4). À noter que si aucune arme n'est en main, et qu'aucune attaque naturelle n'est cochée, le script va tout de même afficher une des attaques naturelles non cochées à la place de l'arme en main. Cela permet d'avoir une attaque que l'on n'affiche que quand on n'a pas d'arme en main.

    -

    Notez qu'il est possible d'avoir une arme par défaut en main, en ajoutant un prédicat armeParDefaut, de valeur le label de l'attaque correspondante. C'est parfois bien pratique pour ne pas avoir à dégainer les armes de chacun des orques en embuscade, par exemple.

    -
    Choisir les actions à afficher
    -

    Pour changer les attaques affichées par défaut, rajouter des actions à la liste d'actions du tour, ou utiliser de nouvelles listes, il faut aller dans l'onglet Script de la fiche de personnage.

    +

    Le script affiche, pour le personnage dont c'est le tour, une liste d'actions. Cette liste est chuchot\xE9e au joueur qui contr\xF4le le personnage, ou si aucun joueur le contr\xF4lant n'est connect\xE9, au MJ. Elle se compose par d\xE9faut des attaques du personnage et des actions d'attendre, se d\xE9fendre et faire une manoeuvre. + Pour voir ce message en dehors du changement d'initiative, ou pour le MJ, on peut utiliser !cof-liste-actions en s\xE9lectionnant le token (un bon candidat pour une macro de type token action, d'ailleurs g\xE9n\xE9r\xE9 par la commande !cof-set-macros). + Pour contr\xF4ler ce qui est affich\xE9 dans cette liste, vous pouvez principalement utiliser la liste des attaques du personnage et surtout la partie script de la fiche.

    +
    Les attaques affich\xE9es
    +

    Il est possible de ne pas afficher une attaque en d\xE9cochant la case sous le d\xE9 dans les options d'attaque. Les attaques sont affich\xE9es dans l'ordre des labels d'attaques. les attaques avec des conditions impossibles (du genre limite par jour \xE9puis\xE9e, etc.) ne sont pas affich\xE9es.

    +

    \xC0 cela se rajoute \xE9ventuellement l'attaque avec l'arme en main. \xC0 c\xF4t\xE9 de cette attaque, le script propose un bouton pour rengainer l'arme ou en d\xE9gainer une autre (parmis les armes de la fiche coch\xE9es). On peut modifier cette liste des armes \xE0 d\xE9gainer en utilisant des pr\xE9dicats actionDegainern, de valeur le label de l'arme \xE0 afficher en position n dans la liste (seulement pour les premi\xE8res armes, il n'est pas possible de ne sp\xE9cifier que la 2nde arme ou la 1\xE8re et le 3\xE8me). On peut ainsi faire afficher 2 armes \xE0 d\xE9gainer en m\xEAme temps en s\xE9parant les labels d'un - (par exemple pour faire d\xE9gainer l'arme 1 en main droite et l'arme 4 en main gauche, en premi\xE8re position dans la liste, on \xE9crira actionDegainer1:1-4). \xC0 noter que si aucune arme n'est en main, et qu'aucune attaque naturelle n'est coch\xE9e, le script va tout de m\xEAme afficher une des attaques naturelles non coch\xE9es \xE0 la place de l'arme en main. Cela permet d'avoir une attaque que l'on n'affiche que quand on n'a pas d'arme en main.

    +

    Notez qu'il est possible d'avoir une arme par d\xE9faut en main, en ajoutant un pr\xE9dicat armeParDefaut, de valeur le label de l'attaque correspondante. C'est parfois bien pratique pour ne pas avoir \xE0 d\xE9gainer les armes de chacun des orques en embuscade, par exemple.

    +
    Choisir les actions \xE0 afficher
    +

    Pour changer les attaques affich\xE9es par d\xE9faut, rajouter des actions \xE0 la liste d'actions du tour, ou utiliser de nouvelles listes, il faut aller dans l'onglet Script de la fiche de personnage.

    Exemple d'une liste d'actions pour un magicien
    -

    Pour rajouter des actions à montrer, il faut ajouter des lignes en-dessous de Montrer l'arme en main et dégainer. La case cochée devant chaque action peut être décochée pour ne pas afficher l'action. Les actions seront affichée dans l'ordre des numéros d'action. Attention, si deux actions ont le même numéro, une des deux ne sera pas affichée. Le titre de l'action peut soit être directement une commande (commençant par %, # ou !), et dans ce cas l'action affichée sera déterminée par le script, soit du texte qui sera affiché tel quel. Dans ce cas, il sera souvent nécessaire de préciser le code de l'action : cliquer sur la roue au bout à droite de la ligne de l'action pour faire apparaître les lignes de condition et de code. La ligne de conditions n'est pas encore utilisée par le script.

    -

    Il existe un certain nombre de commandes spéciales, qui peuvent être rentrée dans le titre ou le code : +

    Pour rajouter des actions \xE0 montrer, il faut ajouter des lignes en-dessous de Montrer l'arme en main et d\xE9gainer. La case coch\xE9e devant chaque action peut \xEAtre d\xE9coch\xE9e pour ne pas afficher l'action. Les actions seront affich\xE9e dans l'ordre des num\xE9ros d'action. Attention, si deux actions ont le m\xEAme num\xE9ro, une des deux ne sera pas affich\xE9e. Le titre de l'action peut soit \xEAtre directement une commande (commen\xE7ant par %, # ou !), et dans ce cas l'action affich\xE9e sera d\xE9termin\xE9e par le script, soit du texte qui sera affich\xE9 tel quel. Dans ce cas, il sera souvent n\xE9cessaire de pr\xE9ciser le code de l'action : cliquer sur la roue au bout \xE0 droite de la ligne de l'action pour faire appara\xEEtre les lignes de condition et de code. La ligne de conditions n'est pas encore utilis\xE9e par le script.

    +

    Il existe un certain nombre de commandes sp\xE9ciales, qui peuvent \xEAtre rentr\xE9e dans le titre ou le code :

      -
    • !attaques fera afficher toutes les attaques cochées de la fiche
    • -
    • !arme-en-main affichera l'attaque correspondant à l'arme en main, ou si aucune arme n'est en main, une attaque naturelle non cochée, et si il n'y en a pas non plus, une attaque à mains nues. Vous pouvez faire suivre cette commandes d'options d'attaque, comme --m2d20.
    • -
    • !options passera en option à toutes les actions suivantes tout ce que vous écrirez dans la même ligne (par exemple !options --traquenard passe l'option --traquenard à toutes les actions suivantes).
    • +
    • !attaques fera afficher toutes les attaques coch\xE9es de la fiche
    • +
    • !arme-en-main affichera l'attaque correspondant \xE0 l'arme en main, ou si aucune arme n'est en main, une attaque naturelle non coch\xE9e, et si il n'y en a pas non plus, une attaque \xE0 mains nues. Vous pouvez faire suivre cette commandes d'options d'attaque, comme --m2d20.
    • +
    • !options passera en option \xE0 toutes les actions suivantes tout ce que vous \xE9crirez dans la m\xEAme ligne (par exemple !options --traquenard passe l'option --traquenard \xE0 toutes les actions suivantes).

    Autres listes d'action
    -

    Il est possible d'ouvrir d'autre listes d'actions, à partir des commandes ou même d'une liste d'actions. La fiche propose 4 emplacements pour ces listes d'action, mais si cela ne suffit pas, vous pouvez utiliser des abilities dont le nom commence et termine par #. Pour faire référence à une liste dans une action, inscrivez simplement le nom de la liste dans le titre de l'action et sélectionnez Liste d'actions dans le menu déroulant à côté. Les listes d'action sur la fiche fonctionnent de la même façon que la liste des actions du tour, sauf qu'il n'y a pas d'affichage par défaut des attaques ou de l'arme en main (pour cela, une simple ligne avec en titre #Attaque -1 permet d'y remédier), et que la liste peut avoir une liste d'options globales (cliquer sur la roue à droite du nom de la liste).

    -

    Pour les listes d'actions supplémentaires, dans les abilities, il faut respecter la syntaxe suivante : +

    Il est possible d'ouvrir d'autre listes d'actions, \xE0 partir des commandes ou m\xEAme d'une liste d'actions. La fiche propose 4 emplacements pour ces listes d'action, mais si cela ne suffit pas, vous pouvez utiliser des abilities dont le nom commence et termine par #. Pour faire r\xE9f\xE9rence \xE0 une liste dans une action, inscrivez simplement le nom de la liste dans le titre de l'action et s\xE9lectionnez Liste d'actions dans le menu d\xE9roulant \xE0 c\xF4t\xE9. Les listes d'action sur la fiche fonctionnent de la m\xEAme fa\xE7on que la liste des actions du tour, sauf qu'il n'y a pas d'affichage par d\xE9faut des attaques ou de l'arme en main (pour cela, une simple ligne avec en titre #Attaque -1 permet d'y rem\xE9dier), et que la liste peut avoir une liste d'options globales (cliquer sur la roue \xE0 droite du nom de la liste).

    +

    Pour les listes d'actions suppl\xE9mentaires, dans les abilities, il faut respecter la syntaxe suivante :

    • une action par ligne
    • chaque ligne est donc soit un commentaire, soit une macro (qui commence par #), soit une ability (qui commence par %), soit une commande qui commence par !
    • -
    • l'action affichée sera le nom de la macro ou de l'ability (sauf pour les attaques, pour lesquelles le nom de l'arme sera affichée)
    • +
    • l'action affich\xE9e sera le nom de la macro ou de l'ability (sauf pour les attaques, pour lesquelles le nom de l'arme sera affich\xE9e)
    • les commandes disponibles sont !options et !attaques.
    • -
    • pour les listes d'actions, il suffit de mettre %# suivi du nom de la liste et terminé par #.
    • +
    • pour les listes d'actions, il suffit de mettre %# suivi du nom de la liste et termin\xE9 par #.
    -

    Il est aussi possible de faire afficher une liste quelconque avec une commande, avec !cof-liste-actions nom (où le nom est celui de la liste, ou bien de l'ability sans les #). Par exemple, si on ne souhaite pas afficher la liste complète des sorts d'un personnage à son tour, on peut faire une liste Sorts, puis faire une macro qui lance !cof-liste-actions Sorts pour que le joueur puisse afficher la liste quand il le souhaite.

    +

    Il est aussi possible de faire afficher une liste quelconque avec une commande, avec !cof-liste-actions nom (o\xF9 le nom est celui de la liste, ou bien de l'ability sans les #). Par exemple, si on ne souhaite pas afficher la liste compl\xE8te des sorts d'un personnage \xE0 son tour, on peut faire une liste Sorts, puis faire une macro qui lance !cof-liste-actions Sorts pour que le joueur puisse afficher la liste quand il le souhaite.

    Attaquer une (ou plusieurs) cible : !cof-attack @{selected|token_id} @{target|token_id} n

    -

    n est un argument optionnel qui peut soit correspondre au label de l'attaque sur la fiche du personnage (ce label est automatiquement généré par la fiche et affiché juste devant le nom), soit être le nom de l'attaque. Si cet argument est -1, le script cherchera si le personnage a une arme en main et utilisera cette arme. Si c'est -2, il va chercher l'arme en main gauche. Si cet argument est absent ou qu'il ne correspond pas à un label de la fiche du personnage, l'attaque aura les valeurs par défaut d'une attaque au contact infligeant 1d4 DM. Pour plus de facilité, vous pouvez utiliser la macro Attaque qui fait !cof-attack @{selected|token_id} @{target|token_id}

    +

    o\xF9 n est un argument optionnel qui peut soit correspondre au label de l'attaque sur la fiche du personnage (ce label est automatiquement g\xE9n\xE9r\xE9 par la fiche et affich\xE9 juste devant le nom), soit \xEAtre le nom de l'attaque. Si cet argument est -1, le script cherchera si le personnage a une arme en main et utilisera cette arme. Si c'est -2, il va chercher l'arme en main gauche. Si cet argument est absent ou qu'il ne correspond pas \xE0 un label de la fiche du personnage, l'attaque aura les valeurs par d\xE9faut d'une attaque au contact infligeant 1d4 DM. Pour plus de facilit\xE9, vous pouvez utiliser la macro Attaque qui fait !cof-attack @{selected|token_id} @{target|token_id}

    -

    L'attaque tient alors compte de toutes les informations de l'attaque, y compris chances de critique, portée, type d'attaque, type de dégâs et autres options spécifiées sur la fiche. Par défaut, l'attaque montre le label, le nom de l'attaque, le calcul du bonus d'attaque, le calcul des dégâts, la portée et un champ SPÉCIAL (ou encore appelé divers). En cliquant sur la roue au bout à droite de cette ligne, on affiche une deuxième ligne, avec un case à décocher pour ne pas faire apparaître l'attaque à chaque tour, un choix de type d'attaque, des modificateurs, un choix de type de degâts et un champ d'options. Les modificateurs sont constitués d'options sans argument, séparée par une espace. Les options sont reprises telles quels comme un argument à l'attaque (voir plus bas pour le liste de ces options). Attention, pour l'instant ne traite correctment les jets (parties entre crochets) et les demandes au joueur (de type ?{question?}) que si on passe par une liste d'actions (donc pas directement en faisant #Attaque 1 dans le chat). Une troisième ligne peut aussi s'afficher, pour gérer le nombre d'armes de jet, ou pour les armes portées, pour indiquer des prédicats actifs seulement quand on porte l'arme. Il est possible de spécifier une arme batarde (pouvant se porter à une ou deux mains) en renseignant un prédicat batarde de valeur le dé de DM à utiliser quand on porte l'arme à deux mains.

    +

    L'attaque tient alors compte de toutes les informations de l'attaque, y compris chances de critique, port\xE9e, type d'attaque, type de d\xE9g\xE2s et autres options sp\xE9cifi\xE9es sur la fiche. Par d\xE9faut, l'attaque montre le label, le nom de l'attaque, le calcul du bonus d'attaque, le calcul des d\xE9g\xE2ts, la port\xE9e et un champ SP\xC9CIAL (ou encore appel\xE9 divers). En cliquant sur la roue au bout \xE0 droite de cette ligne, on affiche une deuxi\xE8me ligne, avec un case \xE0 d\xE9cocher pour ne pas faire appara\xEEtre l'attaque \xE0 chaque tour, un choix de type d'attaque, des modificateurs, un choix de type de deg\xE2ts et un champ d'options. Les modificateurs sont constitu\xE9s d'options sans argument, s\xE9par\xE9e par une espace. Les options sont reprises telles quels comme un argument \xE0 l'attaque (voir plus bas pour le liste de ces options). Attention, pour l'instant ne traite correctment les jets (parties entre crochets) et les demandes au joueur (de type ?{question?}) que si on passe par une liste d'actions (donc pas directement en faisant #Attaque 1 dans le chat). Une troisi\xE8me ligne peut aussi s'afficher, pour g\xE9rer le nombre d'armes de jet, ou pour les armes port\xE9es, pour indiquer des pr\xE9dicats actifs seulement quand on porte l'arme. Il est possible de sp\xE9cifier une arme batarde (pouvant se porter \xE0 une ou deux mains) en renseignant un pr\xE9dicat batarde de valeur le d\xE9 de DM \xE0 utiliser quand on porte l'arme \xE0 deux mains.

    Exemple d'attaques.
    -

    En l'absence de label, on peut spécifier ces informations sous forme d'options d'attaque

    +

    En l'absence de label, on peut sp\xE9cifier ces informations sous forme d'options d'attaque

    -

    Malus ou bonus temporaire à une attaque : utiliser la barre 3.

    -

    Toutes les attaques ayant une portée non nulles sont considérées par le script comme des attaques à distance.

    -

    Le test d'attaque à distance tient compte de la portée (malus de -1 à -5 si distance entre portée et deux fois cette valeur), ainsi que des tokens sur le trajet de l'attaque. Une attaque de trop loin ne porte jamais.

    +

    Malus ou bonus temporaire \xE0 une attaque : utiliser la barre 3.

    +

    Toutes les attaques ayant une port\xE9e non nulles sont consid\xE9r\xE9es par le script comme des attaques \xE0 distance.

    +

    Le test d'attaque \xE0 distance tient compte de la port\xE9e (malus de -1 \xE0 -5 si distance entre port\xE9e et deux fois cette valeur), ainsi que des tokens sur le trajet de l'attaque. Une attaque de trop loin ne porte jamais.

    Utiliser une attaque fait rentrer l'attaquant en combat (et le rajoute au turn tracker).

    -

    Il existe une version spécialisée permettant de faire des dégâts dans un disque centré sur un token, !cof-explosion, dont le premier argument doit être le label d'une attaque.

    +

    Il existe une version sp\xE9cialis\xE9e permettant de faire des d\xE9g\xE2ts dans un disque centr\xE9 sur un token, !cof-explosion, dont le premier argument doit \xEAtre le label d'une attaque.

    Options pour l'attaque :

    - Toutes les options sans arguments peuvent être directement utilisées comme modificateurs dans le liste des modifcateurs d'une attaque. + Toutes les options sans arguments peuvent \xEAtre directement utilis\xE9es comme modificateurs dans le liste des modifcateurs d'une attaque.
      -
    • --nom txt : nom de l'attaque à afficher. Remplace le nom dans la ligne d'attaque si on a donné un label en argument. Le nom ne doit pas comporte de blanc usivi de 2 tirets ( --).
    • -
    • --toucher n : bonus de base de l'attaque. Remplace les valeurs dans la ligne d'attaque si on a donné un label en argument. Pour référence, sur les fiches de PJ, l'attaque au contact est [[@{selected|ATKCAC}]], l'attaque à distance [[@{selected|ATKTIR}]], et l'attaque magique [[@{selected|ATKMAG}]].
    • -
    • --crit n : valeur à partir de laquelle le jet de dé est un critique. Remplace les valeurs dans la ligne d'attaque si on a donné un label en argument.
    • -
    • --dm expr : Dégâts de base de l'attaque. Remplace les valeurs dans la ligne d'attaque si on a donné un label en argument. expr peut être un entier ou bien une expression du type adb+c. La partie constante de cette expression est optionnelle et peut être négative.
    • -
    • --portee n : la portée de l'attaque exprimée en mètres. Remplace les valeurs dans la ligne d'attaque si on a donné un label en argument.
    • -
    • --special txt : remplace le champ spécial de l'attaque sur la fiche.
    • -
    • --tempDmg : l'attaque fait des dégâts temporaires (tient compte de la force de l'adversaire, utilise la barre 2 pour les dmg temp, sauf si le token a des PM, auquel cas on utilisera un attribut temporaire).
    • +
    • --nom txt : nom de l'attaque \xE0 afficher. Remplace le nom dans la ligne d'attaque si on a donn\xE9 un label en argument. Le nom ne doit pas comporte de blanc usivi de 2 tirets ( --).
    • +
    • --toucher n : bonus de base de l'attaque. Remplace les valeurs dans la ligne d'attaque si on a donn\xE9 un label en argument. Pour r\xE9f\xE9rence, sur les fiches de PJ, l'attaque au contact est [[@{selected|ATKCAC}]], l'attaque \xE0 distance [[@{selected|ATKTIR}]], et l'attaque magique [[@{selected|ATKMAG}]].
    • +
    • --crit n : valeur \xE0 partir de laquelle le jet de d\xE9 est un critique. Remplace les valeurs dans la ligne d'attaque si on a donn\xE9 un label en argument.
    • +
    • --dm expr : D\xE9g\xE2ts de base de l'attaque. Remplace les valeurs dans la ligne d'attaque si on a donn\xE9 un label en argument. expr peut \xEAtre un entier ou bien une expression du type adb+c. La partie constante de cette expression est optionnelle et peut \xEAtre n\xE9gative.
    • +
    • --portee n : la port\xE9e de l'attaque exprim\xE9e en m\xE8tres. Remplace les valeurs dans la ligne d'attaque si on a donn\xE9 un label en argument.
    • +
    • --special txt : remplace le champ sp\xE9cial de l'attaque sur la fiche.
    • +
    • --tempDmg : l'attaque fait des d\xE9g\xE2ts temporaires (tient compte de la force de l'adversaire, utilise la barre 2 pour les dmg temp, sauf si le token a des PM, auquel cas on utilisera un attribut temporaire).
    • --pasDeDmg : l'attaque ne fait pas de DM.
    • -
    • --poudre : l'arme est une arme à poudre, utilisation d'un dé de poudre. Une arme est aussi considérée comme une arme à poudre si elle contient poudre dans le nom de l'arme ou dans le champ modifcateur ou de prédicats.
    • -
    • --epieu : l'arme est un épieu. À noter que l'arme est aussi considérée comme un épieu si elle contient épieu dans son nom ou epieu dans son champs modificateurs ou prédicats. Cette option augmente de 1 le nombre de dés contre un adversaire sans armure.
    • -
    • --hache : l'arme est une hache. À noter que l'arme est aussi considérée comme une hache si elle contient hache dans son nom ou dans son champs modificateurs ou prédicats. Cette option permet de passer la RD/hache (pour les sylvaniens, par exemple).
    • -
    • --marteau : l'arme est un marteau. À noter que l'arme est aussi considérée comme un marteau si elle contient marteau dans son nom ou dans son champs modificateurs ou prédicats.
    • -
    • --auto : l'attaque réussit automatiquement
    • +
    • --poudre : l'arme est une arme \xE0 poudre, utilisation d'un d\xE9 de poudre. Une arme est aussi consid\xE9r\xE9e comme une arme \xE0 poudre si elle contient poudre dans le nom de l'arme ou dans le champ modifcateur ou de pr\xE9dicats.
    • +
    • --epieu : l'arme est un \xE9pieu. \xC0 noter que l'arme est aussi consid\xE9r\xE9e comme un \xE9pieu si elle contient \xE9pieu dans son nom ou epieu dans son champs modificateurs ou pr\xE9dicats. Cette option augmente de 1 le nombre de d\xE9s contre un adversaire sans armure.
    • +
    • --hache : l'arme est une hache. \xC0 noter que l'arme est aussi consid\xE9r\xE9e comme une hache si elle contient hache dans son nom ou dans son champs modificateurs ou pr\xE9dicats. Cette option permet de passer la RD/hache (pour les sylvaniens, par exemple).
    • +
    • --marteau : l'arme est un marteau. \xC0 noter que l'arme est aussi consid\xE9r\xE9e comme un marteau si elle contient marteau dans son nom ou dans son champs modificateurs ou pr\xE9dicats.
    • +
    • --auto : l'attaque r\xE9ussit automatiquement
    • --bonusAttaque n : ajoute n au jet d'attaque
    • -
    • --bonusCritique n : augmente n à la plage de coups critiques
    • -
    • --modifiePortee n : ajoute n à la portée de l'attaque.
    • -
    • --divisePortee n : divise la portée de base par n. C'est appliqué avant toute modification de portée.
    • -
    • --bonusContreBouclier n : ajoute n au jet d'attaque si le défenseur porte un bouclier. Utile par exemple pour le fléau d'arme.
    • -
    • --bonusContreArmure n : ajoute n au jet d'attaque si le défenseur porte une armure.
    • -
    • --psave carac seuil : jet de carac, si le jet est supérieur à seuil, les dégâts sont divisés par 2. carac est l'abbréviation de caractéristiques de 3 lettres standard (FOR, DEX, ...). Il est possible de prendre la meilleure de 2 caractéristiques pour le save : pour cela indiquer les 2 caractéristiques collées (donc 6 caractères, par exemple FORDEX, pour le meilleur de FOR et de DEX). Le script choisira automatiquement la caractéristique qui donne les meilleures chances de réussite (en tenant compte de la difficulté et des caractéristiques supérieures).
    • Enfin on peut encore ajouter un ou des arguments optionnels. Si vous avez besoin de plus d'un argument optionnel, séparez-les par +: +
    • --bonusCritique n : augmente n \xE0 la plage de coups critiques
    • +
    • --modifiePortee n : ajoute n \xE0 la port\xE9e de l'attaque.
    • +
    • --divisePortee n : divise la port\xE9e de base par n. C'est appliqu\xE9 avant toute modification de port\xE9e.
    • +
    • --bonusContreBouclier n : ajoute n au jet d'attaque si le d\xE9fenseur porte un bouclier. Utile par exemple pour le fl\xE9au d'arme.
    • +
    • --bonusContreArmure n : ajoute n au jet d'attaque si le d\xE9fenseur porte une armure.
    • +
    • --psave carac seuil : jet de carac, si le jet est sup\xE9rieur \xE0 seuil, les d\xE9g\xE2ts sont divis\xE9s par 2. carac est l'abbr\xE9viation de caract\xE9ristiques de 3 lettres standard (FOR, DEX, ...). Il est possible de prendre la meilleure de 2 caract\xE9ristiques pour le save : pour cela indiquer les 2 caract\xE9ristiques coll\xE9es (donc 6 caract\xE8res, par exemple FORDEX, pour le meilleur de FOR et de DEX). Le script choisira automatiquement la caract\xE9ristique qui donne les meilleures chances de r\xE9ussite (en tenant compte de la difficult\xE9 et des caract\xE9ristiques sup\xE9rieures).
    • Enfin on peut encore ajouter un ou des arguments optionnels. Si vous avez besoin de plus d'un argument optionnel, s\xE9parez-les par +:
        -
      • Si on souhaite que le jet ne permette de réduire qu'une partie des dommages (la dernière ajoutée avec --plus), on peut ajouter local. La syntaxe complète est alors --psave carac seuil local.
      • -
      • Si on souhaite que la difficulté soit augmentée en cas de tempête de mana, on peut utiliser le mot clé tempete suivi si besoin de l'incrément en fonction de la mana (par defaut 1 mana augmente de 1 la difficulté).
      • -
      • Si on souhaite indiquer une difficulté alternative pour les cibles au contact, ajouter contact n, où n est la difficulté en question.
      • +
      • Si on souhaite que le jet ne permette de r\xE9duire qu'une partie des dommages (la derni\xE8re ajout\xE9e avec --plus), on peut ajouter local. La syntaxe compl\xE8te est alors --psave carac seuil local.
      • +
      • Si on souhaite que la difficult\xE9 soit augment\xE9e en cas de temp\xEAte de mana, on peut utiliser le mot cl\xE9 tempete suivi si besoin de l'incr\xE9ment en fonction de la mana (par defaut 1 mana augmente de 1 la difficult\xE9).
      • +
      • Si on souhaite indiquer une difficult\xE9 alternative pour les cibles au contact, ajouter contact n, o\xF9 n est la difficult\xE9 en question.
      -
    • --demiAuto : si l'attaque rate, on considère juste que les saves partiels sont automatiquemet réussi. Ça signifie en général que la cible prend au moins la moitié des dégâts.
    • -
    • --dmSiRate dmg : si l'attaque rate, la cible est quand même touchée et se voit infliger dmg dégâts.
    • -
    • --toucheDoubleDmg : si l'attaque rate, elle inflige les dégâts normaux, et si elle touche, elle double les dégâts de base. Pas cumulable avec dmSiRate ou demiAuto.
    • -
    • --save carac seuil : même effet que --psave, mais pour annuler le dernier --effet ou etat (aucun effet sur les DM). Si on rajoute un argument demiDuree au save, alors la réussite du save ne fait que diviser par 2 sa durée.
    • -
    • --saveDM carac seuil : même effet que --psave, mais pour annuler l'ensemble des dégâts.
    • -
    • --saveParTour carac seuil : même effet que --save, mais donne droit à un jet à la fin de chaque tour au lieu d'un jet au moment de l'attaque.
    • -
    • --saveActifParTour carac seuil : même effet que --save, mais affiche un bouton pour faire le save dans la liste d'actions à chaque tour. Utile si les joueurs préfèrent jeter "eux-mêmes" le dé, ou si le save est sensé arriver au tour du joueur.
    • -
    • --saveParJour carac seuil : même effet que --save, mais donne droit à un jet à la fin de chaque jour au lieu d'un jet au moment de l'attaque.
    • -
    • --fx effet : ajoute un effet qui part de l'attaquant à la cible. Si l'attaque rate, l'effet rate aussi, d'autant plus que le jet d'attaque est loin de la défense. Il est possible d'utiliser un effet que vous avez défini vous-même en utilisant l'option --fx custom nom, où nom est le nom de votre effet.
    • -
    • --targetFx effet : ajoute un effet au niveau de la cible (l'effet ne doit pas être directionnel). Comme avec --fx, on peut utiliser un effet qu'on a créé.
    • +
    • --demiAuto : si l'attaque rate, on consid\xE8re juste que les saves partiels sont automatiquemet r\xE9ussi. Ça signifie en g\xE9n\xE9ral que la cible prend au moins la moiti\xE9 des d\xE9g\xE2ts.
    • +
    • --dmSiRate dmg : si l'attaque rate, la cible est quand m\xEAme touch\xE9e et se voit infliger dmg d\xE9g\xE2ts.
    • +
    • --toucheDoubleDmg : si l'attaque rate, elle inflige les d\xE9g\xE2ts normaux, et si elle touche, elle double les d\xE9g\xE2ts de base. Pas cumulable avec dmSiRate ou demiAuto.
    • +
    • --save carac seuil : m\xEAme effet que --psave, mais pour annuler le dernier --effet ou etat (aucun effet sur les DM). Si on rajoute un argument demiDuree au save, alors la r\xE9ussite du save ne fait que diviser par 2 sa dur\xE9e.
    • +
    • --saveDM carac seuil : m\xEAme effet que --psave, mais pour annuler l'ensemble des d\xE9g\xE2ts.
    • +
    • --saveParTour carac seuil : m\xEAme effet que --save, mais donne droit \xE0 un jet \xE0 la fin de chaque tour au lieu d'un jet au moment de l'attaque.
    • +
    • --saveActifParTour carac seuil : m\xEAme effet que --save, mais affiche un bouton pour faire le save dans la liste d'actions \xE0 chaque tour. Utile si les joueurs pr\xE9f\xE8rent jeter "eux-m\xEAmes" le d\xE9, ou si le save est sens\xE9 arriver au tour du joueur.
    • +
    • --saveParJour carac seuil : m\xEAme effet que --save, mais donne droit \xE0 un jet \xE0 la fin de chaque jour au lieu d'un jet au moment de l'attaque.
    • +
    • --fx effet : ajoute un effet qui part de l'attaquant \xE0 la cible. Si l'attaque rate, l'effet rate aussi, d'autant plus que le jet d'attaque est loin de la d\xE9fense. Il est possible d'utiliser un effet que vous avez d\xE9fini vous-m\xEAme en utilisant l'option --fx custom nom, o\xF9 nom est le nom de votre effet.
    • +
    • --targetFx effet : ajoute un effet au niveau de la cible (l'effet ne doit pas \xEAtre directionnel). Comme avec --fx, on peut utiliser un effet qu'on a cr\xE9\xE9.
    • - --si condition : l'attaque n'est possible que si condition est validée. Une condition peut être + --si condition : l'attaque n'est possible que si condition est valid\xE9e. Une condition peut \xEAtre
      • moins attribut : vrai si l'attribut attribut de la cible est moins haute que celle de l'attaquant
      • -
      • etat e : vrai si l'état e est actif sur l'attaquant. Cet état peut être un des états définis plus bas, ou un attribut quelconque.
      • -
      • attribut attr val: vrai si l'attaquant possède un attribut attr, de valeur val, aux majuscules près. On peut optionnellement préciser qu'il s'agit d'un attribut par token en rajoutant le mot clé local, ou encore qu'il sagit d'un attribut de la fiche, avec éventuellement sa valeur par défaut, en ajoutant le mot clé fiche defaut.
      • -
      • etatCible e : vrai si l'état e est actif sur toutes la cible. Cet état peut être un des états définis plus bas, ou un attribut quelconque.
      • -
      • attributCible attr val: vrai si la cible possède un attribut attr, de valeur val, aux majuscules près. On peut optionnellement préciser qu'il s'agit d'un attribut par token en rajoutant le mot clé local, ou encore qu'il sagit d'un attribut de la fiche, avec éventuellement sa valeur par défaut, en ajoutant le mot clé fiche defaut.
      • -
      • predicatCible predicat: vrai si la cible possède un prédicat predicat. On peut aussi spécifier une valeur auquel le prédicat doit être égal.
      • -
      • typeCible type: vrai si la cible est du type spécifié. Les types reconnus sont animal, démon, dragon, fée, insecte, mauvais, mort-vivant, géant, gobelin, et si le type n'est pas reconnu, va chercher si la race ou un prédicat correspondant.
      • -
      • deAttaque n : vrai si le jet de dé d'attaque est supérieur ou égal à n.
      • +
      • etat e : vrai si l'\xE9tat e est actif sur l'attaquant. Cet \xE9tat peut \xEAtre un des \xE9tats d\xE9finis plus bas, ou un attribut quelconque.
      • +
      • attribut attr val: vrai si l'attaquant poss\xE8de un attribut attr, de valeur val, aux majuscules pr\xE8s. On peut optionnellement pr\xE9ciser qu'il s'agit d'un attribut par token en rajoutant le mot cl\xE9 local, ou encore qu'il sagit d'un attribut de la fiche, avec \xE9ventuellement sa valeur par d\xE9faut, en ajoutant le mot cl\xE9 fiche defaut.
      • +
      • etatCible e : vrai si l'\xE9tat e est actif sur toutes la cible. Cet \xE9tat peut \xEAtre un des \xE9tats d\xE9finis plus bas, ou un attribut quelconque.
      • +
      • attributCible attr val: vrai si la cible poss\xE8de un attribut attr, de valeur val, aux majuscules pr\xE8s. On peut optionnellement pr\xE9ciser qu'il s'agit d'un attribut par token en rajoutant le mot cl\xE9 local, ou encore qu'il sagit d'un attribut de la fiche, avec \xE9ventuellement sa valeur par d\xE9faut, en ajoutant le mot cl\xE9 fiche defaut.
      • +
      • predicatCible predicat: vrai si la cible poss\xE8de un pr\xE9dicat predicat. On peut aussi sp\xE9cifier une valeur auquel le pr\xE9dicat doit \xEAtre \xE9gal.
      • +
      • typeCible type: vrai si la cible est du type sp\xE9cifi\xE9. Les types reconnus sont animal, d\xE9mon, dragon, f\xE9e, insecte, mauvais, mort-vivant, g\xE9ant, gobelin, et si le type n'est pas reconnu, va chercher si la race ou un pr\xE9dicat correspondant.
      • +
      • deAttaque n : vrai si le jet de d\xE9 d'attaque est sup\xE9rieur ou \xE9gal \xE0 n.
      • touche : vrai si l'attaque touche.
      • critique : vrai si l'attaque est un critique.
      • -
      • echecCritique : vrai si l'attaque est un échec critique.
      • +
      • echecCritique : vrai si l'attaque est un \xE9chec critique.
    • -
    • --if condition options --endif: permet de ne prendre en compte des options que si certaines conditions sont réalisées. Il est possible d'utiliser un --else pour activer des options quand les conditions ne sont pas réalisées. Attention, les options qui modifient une option précédente (comme --valeur) doivent apparaître au même niveau que l'option qu'elles modifient. Comme les conditions peuvent dépendre du dé d'attaque, un certain nombre d'options ne sont pas affectées par cette conditionnelle : tempeteDeMana, les options d'aoe (ligne, cone, disque, target), avecd12, avantage, auto, demiAuto, test, pointsVitaux, tempsRecharge, sortilege, bonusCritique, disparition, affute, munition, tirDouble, semonce, tirDeBarrage, poudre, traquenard, feinte, asDeLaGachette, magique, tranchant, percant, contondant, pasDeDmg. Ne pas hésiter à me demander si vous aviez besoin que l'une de ces options puissent être conditionnelle.
    • -
    • --ifSaveFails carac seuil options --endif : comme --if, mais fait réaliser une jet de sauvegarde à la cible (comme avec --save), et si le test est raté, applique les options qui suivent. Un --else permet de choisir des options à appliquer quand le test est réussi. À utiliser seulement si on ne peut pas se contenter d'un --save, car ça marche moins bien.
    • -
    • --decrAttribute nom : l'attaque n'est possible que si l'attribut existe et si sa valeur est strictement positive. L'attaque diminue cette valeur de 1. Si cette option est utilisée à l'intérieur d'un --if, alors l'option se contente de diminuer l'attribut (on peut savoir si la valeur est positive grâce à --if etat nom).
    • -
    • --decrLimitePredicatParTour nom : l'attaque n'est possible que si un prédicat nom existe et si elle n'a pas été utilisée plus de fois dans le tour que la valeur de ce prédicat. L'attaque augmente ce nombre de 1.
    • -
    • --tempsRecharge effet duree : l'attaque n'est possible que si l'effet est inactif sur l'attaquant, et de plus active l'effet sur l'attaquant pour la durée indiquée si l'attaque est possible. Il existe un effet temporaire générique, rechargeGen(desc) que vous pouvez utiliser si aucun effet existant ne correspond pour votre attaque.
    • -
    • --etat e: si l'attaque touche, la cible passe dans l'état e. Il est aussi possible de spécifier une caractéristique et un seuil (comme pour !cof-set-state) pour faire afficher à chaque tour une action permettant de se libérer de l'état.
    • -
    • --effet e duree : ajoute à la cible l'effet temporaire e pour la duree spécifiée. Pour que cela soit automatiquement mis à jour, il faut utiliser le turn tracker. Noter que l'argument de durée peut être omis pour certains effets, comme ceux qui par définition durent tout le combat.
    • -
    • --valeur v : spécifie une valeur au dernier effet mentionné.
    • -
    • --optionEffet opt arg1 arg2 ... : spécifie une option au dernier effet mentionné. L'option opt doit être donnée sans le -- et sera passée telle quelle à l'effet, par exemple pour les dégâts périodiques, si on ne veut pas que la RD s'applique, on pourra ajouter --optionEffet ignoreRD.
    • -
    • --peur seuil duree : fait un effet de peur si l'attaque touche. Le seuil sert pour le test de sagesse de résistance à la peur (tient compte de la capacité sans peur du chevalier).
    • -
    • --affaiblirCarac carac n : l'attaque diminue la caractéristique carac de n. Si carac est random, le script tire une caractéristique au hasard.
    • -
    • --plus dmg : ajoute dmg dégâts. Attention, si dmg est un simple nombre, ces dégâts sont multipliés par les critiques (sauf si de type différent de l'attaque principale). Ainsi, --plus [[1d6]] donnera des dégâts multipliés par les critiques (car la fonction ne voit que le résultat du jet), alors que --plus 1d6 ne le sera pas.
    • -
    • --plusCrit dmg : ajoute dmg dégâts en cas de réussite critique
    • -
    • --test pour voir le résultat du jet d'attaque. On n'applique pas les résultats d'un touché.
    • -
    • --sournoise n : ajoute nd6 de dégâts d'attaque sournoise ou par surprise. Si l'option n'a pas d'argument, le nombre de dés rajoutés sera celui associé à un prédicat attaqueSournoise, et si l'attaquant n'a pas de prédicat attaqueSournoise, l'attaque ajoute juste 1d6. Le script limite le nombre d'attaque sournoise par personnage à 1 par tour. On peut augmenter ce nombre en utilisant un prédicat sournoisesParTour, de valeur la limite au nombre de sournoises pour ce personnage.
    • -
    • --magique : les dégâts sont magiques. On peut passer en argument le niveau de magie. Il est utilisé contre les créatures immunisées aux armes. Le niveau par défaut est 1.
    • -
    • --+k : l'attaque utilise une arme magique +k. Pratique à mettre dans les modificateurs de l'attaque (dans ce cas, on n'a pas les --), cela rajoute les bonus au toucher et aux dégâts, et indique que les dégâts sont magiques. Si un niveau de magie est spécifié, rajoute k à ce niveau.
    • -
    • --feu, --acide, --electrique, --froid, --sonique, --poison, --maladie, --argent, --drain, --energie : les dégâts sont de type feu, acide, électrique, froid, sonique, poison, maladie, argent, drain ou énergie. Le type spécifie uniquement le dernier --plus précédent cette option, ou si il n'y en a pas, celui des dégâts principaux. Seul le dernier type spécifié est pris en compte (pas de type multiple pour l'instant). Le type affecte différents attributs, et aussi la couleur d'affichage des dégâts.
    • -
    • --beni : les dégâts sont d'une source sainte ou bénie. Sert principalement à signaler pour les résistances aux dégâts qui peuvent dépendre de cela (genre RD 5/beni).
    • -
    • --spectral : L'attaque peut toucher les créatures intangibles.
    • -
    • --tranchant, --percant, --contondant : précise le type d'arme (si pertinent), pour pouvoir utiliser les RD spécifiques à un type d'arme.
    • -
    • --ignoreRD : l'attaque ignore les RD et division de DMs. Il est possible de donner en argument une valeur de RD ignorée, de sorte que l'attaque ignore les RD jusqu'à cette valeur. Par exemple on pourra écrire --ignoreRD 5.
    • -
    • --ignoreMoitieRD : l'attaque ignore la moitié de la RD.
    • -
    • --sortilege pour indiquer qu'il s'agit d'un sortilège, de façons à pouvoir appliquer tous les effets spécifiques aux sorts. Cette options devrait être passées pour toutes les capacités suivies d'une étoile dans le livre des règles. En particulier, tout sortilege ignore les malus d'obstacles.
    • -
    • --reroll1 : relance les 1 aux dés de dégats. À noter que cela ne concerne que les dés de base de l'attaque, pas les DM supplémentaire.
    • -
    • --explodeMax : relance les valeurs maximum aux dés de DM de base, et rajoute le nouveau résultat (qui lui-même explose).
    • -
    • --mana n : l'attaque coûte n points de mana. Si l'attaque provoque un effet temporaire, le script essaiera de le supprimer à la mort du lanceur (même avec un coût nul).
    • -
    • --magieRapide : augmente le coût en mana (1 avec la mana normale, 3 avec la mana totale) et affiche un petit message indiquant que le lancement est rapide. Il est possible de préciser un coût en mana différent.
    • -
    • --rang n : indique le rang de la capacité utilisée, si besoin. Utilisé par l'option --tempeteDeMana.
    • -
    • --tempeteDeMana liste : indique des effets de tempête de mana. La liste peut contenir un nombre (pour l'effet intense), duree, rapide, portee et altruiste id. Si le rang du sort est spécifié (par l'option --rang, un message est affichée si le coût en mana est supérieur au rang. Si la liste d'options est vide ou ne contient que altruiste, le script affiche un menu dans le chat pour spécifier les options de tempête de mana. Il est possible d'utiliser les règles de mana totale pour les coûts de tempête de mana (à activer avec !cof-options).
    • -
    • --magieEnArmure : applique un malus à l'attaque égale au rang du sort + le malus d'armure de l'attaquant. On peut ajouter un argument optionnel : soit un nombre qui va remplacer le rang dans cette formule, soit mana qui va augmenter le coût en mana de l'attaque en fonction de l'armure portée.
    • -
    • --frappeDesArcanes n : ajoute +5 à l'attaque et +nd6 aux DM, mais empêche de lancer des sorts pendant 1d6 tours si l'attaque touche. Si le nombre n n'est pas présent, le bonus est de 2d6.
    • -
    • --limiteParJour l : limite le nombre d'utilisations de cette attaque à l fois par jour. On peut préciser un nom après l, qui va correspondre à une ressource pouvant être partagée avec d'autres attaques ou d'autres effets (voir !cof-effet-temp). Par défaut, le nom de cette ressource est le label de l'attaque.
    • -
    • --limiteParCombat : même effet que la limite par jour. Si aucun argument n'est donné, la limite est de une fois par combat.
    • -
    • --limiteParTour : même effet que la limite par jour. Si aucun argument n'est donné, la limite est de une fois par tour.
    • -
    • --munition label : l'attaque utilise les munitions de label label (notées dans l'onglet équipement de la fiche). À chaque attaque portée, une munition est utilisée, et le script teste si elle sera récupérable (en fonction du taux de pertes notée sur la fiche). En fin de combat, on considère que le personnage récupère toutes les munitions récupérables. Si une arme est reconnue comme étant un arc,une arbalète ou une arme à poudre, et que les options de l'attaque ne contiennent pas l'option --munition, alors le script propose automatiquement de choisir parmis les munitions normales (supposées illimitées) et celles encores présentes du bon type. À noter que cette option devrait être inutile pour les armes de jet qui ont déjà leur propre case associée à l'attaque.
    • -
    • --aussiArmeDeJet L : permet d'indiquer que l'arme peut aussi être employée comme arme de jet. L doit être le label de l'attaque avec cette arme en tant qu'arme de jet. Cela permet de tenir compte des cas où l'arme a été lancée et ne peut donc plus être utilisée au corps à corps. Si l'arme est utilisée à distance, le script va automatiquement utiliser l'attaque L.
    • -
    • --arcComposite n : augmente les DM du modificateur de force, (qui peut être négatif), mais sans dépasser n. Si le modificateur est strictement inférieur à n, l'attaque se fait avec un malus de -2.
    • -
    • --seulementDistance : l'attaque ne peut être réalisée que contre un adversaire à distance.
    • -
    • --vampirise : soigne de tous les DM infligés, quel que soit leur type. Il est possible de soigner un pourcentage des dégâts : pour cela, préciser le pourcentage entier après l'option. Par exemple, pour une attaque qui soigne de la moitié des dégâts infligés, on pourra mettre --vampirise 50. À noter que les soins se cumulent avec les dégâts de type drain.
    • +
    • --if condition options --endif: permet de ne prendre en compte des options que si certaines conditions sont r\xE9alis\xE9es. Il est possible d'utiliser un --else pour activer des options quand les conditions ne sont pas r\xE9alis\xE9es. Attention, les options qui modifient une option pr\xE9c\xE9dente (comme --valeur) doivent appara\xEEtre au m\xEAme niveau que l'option qu'elles modifient. Comme les conditions peuvent d\xE9pendre du d\xE9 d'attaque, un certain nombre d'options ne sont pas affect\xE9es par cette conditionnelle : tempeteDeMana, les options d'aoe (ligne, cone, disque, target), avecd12, avantage, auto, demiAuto, test, pointsVitaux, tempsRecharge, sortilege, bonusCritique, disparition, affute, munition, tirDouble, semonce, tirDeBarrage, poudre, traquenard, feinte, asDeLaGachette, magique, tranchant, percant, contondant, pasDeDmg. Ne pas h\xE9siter \xE0 me demander si vous aviez besoin que l'une de ces options puissent \xEAtre conditionnelle.
    • +
    • --ifSaveFails carac seuil options --endif : comme --if, mais fait r\xE9aliser une jet de sauvegarde \xE0 la cible (comme avec --save), et si le test est rat\xE9, applique les options qui suivent. Un --else permet de choisir des options \xE0 appliquer quand le test est r\xE9ussi. \xC0 utiliser seulement si on ne peut pas se contenter d'un --save, car \xE7a marche moins bien.
    • +
    • --decrAttribute nom : l'attaque n'est possible que si l'attribut existe et si sa valeur est strictement positive. L'attaque diminue cette valeur de 1. Si cette option est utilis\xE9e \xE0 l'int\xE9rieur d'un --if, alors l'option se contente de diminuer l'attribut (on peut savoir si la valeur est positive gr\xE2ce \xE0 --if etat nom).
    • +
    • --decrLimitePredicatParTour nom : l'attaque n'est possible que si un pr\xE9dicat nom existe et si elle n'a pas \xE9t\xE9 utilis\xE9e plus de fois dans le tour que la valeur de ce pr\xE9dicat. L'attaque augmente ce nombre de 1.
    • +
    • --tempsRecharge effet duree : l'attaque n'est possible que si l'effet est inactif sur l'attaquant, et de plus active l'effet sur l'attaquant pour la dur\xE9e indiqu\xE9e si l'attaque est possible. Il existe un effet temporaire g\xE9n\xE9rique, rechargeGen(desc) que vous pouvez utiliser si aucun effet existant ne correspond pour votre attaque.
    • +
    • --etat e: si l'attaque touche, la cible passe dans l'\xE9tat e. Il est aussi possible de sp\xE9cifier une caract\xE9ristique et un seuil (comme pour !cof-set-state) pour faire afficher \xE0 chaque tour une action permettant de se lib\xE9rer de l'\xE9tat.
    • +
    • --effet e duree : ajoute \xE0 la cible l'effet temporaire e pour la duree sp\xE9cifi\xE9e. Pour que cela soit automatiquement mis \xE0 jour, il faut utiliser le turn tracker. Noter que l'argument de dur\xE9e peut \xEAtre omis pour certains effets, comme ceux qui par d\xE9finition durent tout le combat.
    • +
    • --valeur v : sp\xE9cifie une valeur au dernier effet mentionn\xE9.
    • +
    • --optionEffet opt arg1 arg2 ... : sp\xE9cifie une option au dernier effet mentionn\xE9. L'option opt doit \xEAtre donn\xE9e sans le -- et sera pass\xE9e telle quelle \xE0 l'effet, par exemple pour les d\xE9g\xE2ts p\xE9riodiques, si on ne veut pas que la RD s'applique, on pourra ajouter --optionEffet ignoreRD.
    • +
    • --peur seuil duree : fait un effet de peur si l'attaque touche. Le seuil sert pour le test de sagesse de r\xE9sistance \xE0 la peur (tient compte de la capacit\xE9 sans peur du chevalier).
    • +
    • --affaiblirCarac carac n : l'attaque diminue la caract\xE9ristique carac de n. Si carac est random, le script tire une caract\xE9ristique au hasard.
    • +
    • --plus dmg : ajoute dmg d\xE9g\xE2ts. Attention, si dmg est un simple nombre, ces d\xE9g\xE2ts sont multipli\xE9s par les critiques (sauf si de type diff\xE9rent de l'attaque principale). Ainsi, --plus [[1d6]] donnera des d\xE9g\xE2ts multipli\xE9s par les critiques (car la fonction ne voit que le r\xE9sultat du jet), alors que --plus 1d6 ne le sera pas.
    • +
    • --plusCrit dmg : ajoute dmg d\xE9g\xE2ts en cas de r\xE9ussite critique
    • +
    • --test pour voir le r\xE9sultat du jet d'attaque. On n'applique pas les r\xE9sultats d'un touch\xE9.
    • +
    • --sournoise n : ajoute nd6 de d\xE9g\xE2ts d'attaque sournoise ou par surprise. Si l'option n'a pas d'argument, le nombre de d\xE9s rajout\xE9s sera celui associ\xE9 \xE0 un pr\xE9dicat attaqueSournoise, et si l'attaquant n'a pas de pr\xE9dicat attaqueSournoise, l'attaque ajoute juste 1d6. Le script limite le nombre d'attaque sournoise par personnage \xE0 1 par tour. On peut augmenter ce nombre en utilisant un pr\xE9dicat sournoisesParTour, de valeur la limite au nombre de sournoises pour ce personnage.
    • +
    • --magique : les d\xE9g\xE2ts sont magiques. On peut passer en argument le niveau de magie. Il est utilis\xE9 contre les cr\xE9atures immunis\xE9es aux armes. Le niveau par d\xE9faut est 1.
    • +
    • --+k : l'attaque utilise une arme magique +k. Pratique \xE0 mettre dans les modificateurs de l'attaque (dans ce cas, on n'a pas les --), cela rajoute les bonus au toucher et aux d\xE9g\xE2ts, et indique que les d\xE9g\xE2ts sont magiques. Si un niveau de magie est sp\xE9cifi\xE9, rajoute k \xE0 ce niveau.
    • +
    • --feu, --acide, --electrique, --froid, --sonique, --poison, --maladie, --argent, --drain, --energie : les d\xE9g\xE2ts sont de type feu, acide, \xE9lectrique, froid, sonique, poison, maladie, argent, drain ou \xE9nergie. Le type sp\xE9cifie uniquement le dernier --plus pr\xE9c\xE9dent cette option, ou si il n'y en a pas, celui des d\xE9g\xE2ts principaux. Seul le dernier type sp\xE9cifi\xE9 est pris en compte (pas de type multiple pour l'instant). Le type affecte diff\xE9rents attributs, et aussi la couleur d'affichage des d\xE9g\xE2ts.
    • +
    • --beni : les d\xE9g\xE2ts sont d'une source sainte ou b\xE9nie. Sert principalement \xE0 signaler pour les r\xE9sistances aux d\xE9g\xE2ts qui peuvent d\xE9pendre de cela (genre RD 5/beni).
    • +
    • --spectral : L'attaque peut toucher les cr\xE9atures intangibles.
    • +
    • --tranchant, --percant, --contondant : pr\xE9cise le type d'arme (si pertinent), pour pouvoir utiliser les RD sp\xE9cifiques \xE0 un type d'arme.
    • +
    • --ignoreRD : l'attaque ignore les RD et division de DMs. Il est possible de donner en argument une valeur de RD ignor\xE9e, de sorte que l'attaque ignore les RD jusqu'\xE0 cette valeur. Par exemple on pourra \xE9crire --ignoreRD 5.
    • +
    • --ignoreMoitieRD : l'attaque ignore la moiti\xE9 de la RD.
    • +
    • --sortilege pour indiquer qu'il s'agit d'un sortil\xE8ge, de fa\xE7ons \xE0 pouvoir appliquer tous les effets sp\xE9cifiques aux sorts. Cette options devrait \xEAtre pass\xE9es pour toutes les capacit\xE9s suivies d'une \xE9toile dans le livre des r\xE8gles. En particulier, tout sortilege ignore les malus d'obstacles.
    • +
    • --reroll1 : relance les 1 aux d\xE9s de d\xE9gats. \xC0 noter que cela ne concerne que les d\xE9s de base de l'attaque, pas les DM suppl\xE9mentaire.
    • +
    • --explodeMax : relance les valeurs maximum aux d\xE9s de DM de base, et rajoute le nouveau r\xE9sultat (qui lui-m\xEAme explose).
    • +
    • --mana n : l'attaque co\xFBte n points de mana. Si l'attaque provoque un effet temporaire, le script essaiera de le supprimer \xE0 la mort du lanceur (m\xEAme avec un co\xFBt nul).
    • +
    • --magieRapide : augmente le co\xFBt en mana (1 avec la mana normale, 3 avec la mana totale) et affiche un petit message indiquant que le lancement est rapide. Il est possible de pr\xE9ciser un co\xFBt en mana diff\xE9rent.
    • +
    • --rang n : indique le rang de la capacit\xE9 utilis\xE9e, si besoin. Utilis\xE9 par l'option --tempeteDeMana.
    • +
    • --tempeteDeMana liste : indique des effets de temp\xEAte de mana. La liste peut contenir un nombre (pour l'effet intense), duree, rapide, portee et altruiste id. Si le rang du sort est sp\xE9cifi\xE9 (par l'option --rang, un message est affich\xE9e si le co\xFBt en mana est sup\xE9rieur au rang. Si la liste d'options est vide ou ne contient que altruiste, le script affiche un menu dans le chat pour sp\xE9cifier les options de temp\xEAte de mana. Il est possible d'utiliser les r\xE8gles de mana totale pour les co\xFBts de temp\xEAte de mana (\xE0 activer avec !cof-options).
    • +
    • --magieEnArmure : applique un malus \xE0 l'attaque \xE9gale au rang du sort + le malus d'armure de l'attaquant. On peut ajouter un argument optionnel : soit un nombre qui va remplacer le rang dans cette formule, soit mana qui va augmenter le co\xFBt en mana de l'attaque en fonction de l'armure port\xE9e.
    • +
    • --frappeDesArcanes n : ajoute +5 \xE0 l'attaque et +nd6 aux DM, mais emp\xEAche de lancer des sorts pendant 1d6 tours si l'attaque touche. Si le nombre n n'est pas pr\xE9sent, le bonus est de 2d6.
    • +
    • --limiteParJour l : limite le nombre d'utilisations de cette attaque \xE0 l fois par jour. On peut pr\xE9ciser un nom apr\xE8s l, qui va correspondre \xE0 une ressource pouvant \xEAtre partag\xE9e avec d'autres attaques ou d'autres effets (voir !cof-effet-temp). Par d\xE9faut, le nom de cette ressource est le label de l'attaque.
    • +
    • --limiteParCombat : m\xEAme effet que la limite par jour. Si aucun argument n'est donn\xE9, la limite est de une fois par combat.
    • +
    • --limiteParTour : m\xEAme effet que la limite par jour. Si aucun argument n'est donn\xE9, la limite est de une fois par tour.
    • +
    • --munition label : l'attaque utilise les munitions de label label (not\xE9es dans l'onglet \xE9quipement de la fiche). \xC0 chaque attaque port\xE9e, une munition est utilis\xE9e, et le script teste si elle sera r\xE9cup\xE9rable (en fonction du taux de pertes not\xE9e sur la fiche). En fin de combat, on consid\xE8re que le personnage r\xE9cup\xE8re toutes les munitions r\xE9cup\xE9rables. Si une arme est reconnue comme \xE9tant un arc,une arbal\xE8te ou une arme \xE0 poudre, et que les options de l'attaque ne contiennent pas l'option --munition, alors le script propose automatiquement de choisir parmis les munitions normales (suppos\xE9es illimit\xE9es) et celles encores pr\xE9sentes du bon type. \xC0 noter que cette option devrait \xEAtre inutile pour les armes de jet qui ont d\xE9j\xE0 leur propre case associ\xE9e \xE0 l'attaque.
    • +
    • --aussiArmeDeJet L : permet d'indiquer que l'arme peut aussi \xEAtre employ\xE9e comme arme de jet. L doit \xEAtre le label de l'attaque avec cette arme en tant qu'arme de jet. Cela permet de tenir compte des cas o\xF9 l'arme a \xE9t\xE9 lanc\xE9e et ne peut donc plus \xEAtre utilis\xE9e au corps \xE0 corps. Si l'arme est utilis\xE9e \xE0 distance, le script va automatiquement utiliser l'attaque L.
    • +
    • --arcComposite n : augmente les DM du modificateur de force, (qui peut \xEAtre n\xE9gatif), mais sans d\xE9passer n. Si le modificateur est strictement inf\xE9rieur \xE0 n, l'attaque se fait avec un malus de -2.
    • +
    • --seulementDistance : l'attaque ne peut \xEAtre r\xE9alis\xE9e que contre un adversaire \xE0 distance.
    • +
    • --vampirise : soigne de tous les DM inflig\xE9s, quel que soit leur type. Il est possible de soigner un pourcentage des d\xE9g\xE2ts : pour cela, pr\xE9ciser le pourcentage entier apr\xE8s l'option. Par exemple, pour une attaque qui soigne de la moiti\xE9 des d\xE9g\xE2ts inflig\xE9s, on pourra mettre --vampirise 50. \xC0 noter que les soins se cumulent avec les d\xE9g\xE2ts de type drain.
    • --seulementVivant : n'affecte que les cibles vivantes
    • --forceMinimum n : l'attaque n'est possible que si l'attaquant a au moins n en force.
    • -
    • --necromancie : l'attaque est de la nécromancie
    • -
    • --ferFroid : multiplie par 2 les dégâts contre les fées et les démons (le script reconnaît certaines races et les prédicats démon et fée).
    • -
    • --adamantium : l'arme utilisée est en adamantium. Reconnu pour la RD.
    • -
    • --tueurDe categorie : bonus de +2 en attaque et +2d6 DM contre les espèces appartenant à la catégorie (voir la condition typeCible.
    • -
    • --tueurDeGrands : bonus de +1d6 DM contre les créatures de taille grande et +2d6 DM contre les créatures de taille énorme ou plus.
    • -
    • --ignoreObstacles : ignore les tokens sur le trajet. Ça semble nécessaire pour les attaques magiques d'après Kegron.
    • -
    • --retourneEnMain : L'arme de jet revient en main après l'attaque.
    • -
    • --puissant : augmente la valeur max des dés de dégâts de 2. Si --puissant est suivi d'un argument effet, on teste la présence d'un attribut effetPuissant pour décider si l'attaque est puissante ou non. Il est aussi possible de donner oui ou non en argument (ce n'est alors pas considéré comme un effet). --puissant portee permet de doubler la portée de l'attaque (utile pour l'option de Magie Puissante)
    • -
    • --attaqueAssuree : implémente une attaque assurée (+5 à l'attaque, dégâts divisés par 2, critique impossible).
    • -
    • --attaqueRisquee : implémente une attaque risquée (+2 à l'attaque au contact, -4 en DEF pendant un tour).
    • -
    • --attaqueDeGroupe n : n est le nombre de créatures qui attaquent ; implémente une attaque de groupe (+2 à l'attaque par attaquant au-delà du premier, x2 DMG si l'attaque dépasse la DEF de 5 ou plus, x3 DMG si critique).
    • -
    • --attaqueAcrobatique : l'attaquant effectue un test d'acrobatie difficulté 15, et s'il réussit, l'attaque bénéficie des effets d'une sournoise. On peut en option préciser le nombre de dés de cette attaque sournoise.
    • -
    • --strigeSuce : option spécifique aux striges. Donne le malus de -3 en DEF et compte la quantite sucée. Quand cette quantité arrive à 6, enlève le malus de DEF et rend la cible affaiblie.
    • -
    • --mainsDEnergie : +2 à +5 à l'attaque, selon l'armure de la cible
    • -
    • --semonce : +5 au touché et +1d6 aux DM (ne change pas les charges de l'arme).
    • -
    • --avantage : lance un dé de plus en attaque et garde le meilleur. plusieurs arguments avantage se cumulent et sont annulés par les désavantages (syntaxe alertnative: (--m2d20)
    • -
    • --desavantage : lance un dé de plus en attaque et garde le moins bon. plusieurs arguments désavantage se cumulent et sont annulés par les avantages.
    • -
    • --avecd12 : lance un d12 au lieu du d20 pour le jet d'attaque. L'attaque est impossible si l'attaquant est déjà affaibli.
    • -
    • --avecd12crit : comme --avecd12, mais le jet peut faire un critique. La plage de critique est divisée par 2, arrondie à l'inférieur. Ainsi si le d20 sevait critiquer sur un 20 seulement, le d12 ne fait pas de critique. Il fait un critique sur un 12 si le d20 devait faire un critique sur un 19 ou un 18, et ainsi de suite.
    • -
    • --incrDmgCoef n : augmente le coefficient des dégâts de base de 1. Les dégâts de base comprennent les dés de dommage de l'arme (ou du sort), plus tous les bonus constants. Le coefficient par défaut est de 1, et une réussite critique augmente ce coefficient de 1.
    • -
    • --incrCritCoef n : augmente le coefficient des dégâts critiques de n (1 si on ne donne pas d'argument).
    • -
    • --diviseDmg n : divise les dégâts de base par n.
    • -
    • --maxDmg : l'attaque inflige le maximum de DM permis par les dés de base.
    • -
    • --runeDePuissance : l'arme est enchantée avec une rune de puissance permanente.
    • -
    • --difficultePVmax : la difficulté du jet d'attaque est le maximum de PVs au lieu de la défense.
    • -
    • --difficultePV : la difficulté du jet d'attaque est la valeur courante des PVs au lieu de la défense.
    • -
    • --difficulteCarac carac : la difficulté du jet d'attaque est une des caractéristiques de la cible (sous forme de code à 3 lettres, FOR, DEX, etc). Il est possible de prendre le meilleur de 2 caractéristiques en écrivant les 2 noms collés. Par exemple, pour viser le meilleur de l'intelligence et du charisme, on écrira --difficuletCarac INTCHA.
    • +
    • --necromancie : l'attaque est de la n\xE9cromancie
    • +
    • --ferFroid : multiplie par 2 les d\xE9g\xE2ts contre les f\xE9es et les d\xE9mons (le script reconna\xEEt certaines races et les pr\xE9dicats d\xE9mon et f\xE9e).
    • +
    • --adamantium : l'arme utilis\xE9e est en adamantium. Reconnu pour la RD.
    • +
    • --tueurDe categorie : bonus de +2 en attaque et +2d6 DM contre les esp\xE8ces appartenant \xE0 la cat\xE9gorie (voir la condition typeCible.
    • +
    • --tueurDeGrands : bonus de +1d6 DM contre les cr\xE9atures de taille grande et +2d6 DM contre les cr\xE9atures de taille \xE9norme ou plus.
    • +
    • --ignoreObstacles : ignore les tokens sur le trajet. Ça semble n\xE9cessaire pour les attaques magiques d'apr\xE8s Kegron.
    • +
    • --retourneEnMain : L'arme de jet revient en main apr\xE8s l'attaque.
    • +
    • --puissant : augmente la valeur max des d\xE9s de d\xE9g\xE2ts de 2. Si --puissant est suivi d'un argument effet, on teste la pr\xE9sence d'un attribut effetPuissant pour d\xE9cider si l'attaque est puissante ou non. Il est aussi possible de donner oui ou non en argument (ce n'est alors pas consid\xE9r\xE9 comme un effet). --puissant portee permet de doubler la port\xE9e de l'attaque (utile pour l'option de Magie Puissante)
    • +
    • --attaqueAssuree : impl\xE9mente une attaque assur\xE9e (+5 \xE0 l'attaque, d\xE9g\xE2ts divis\xE9s par 2, critique impossible).
    • +
    • --attaqueRisquee : impl\xE9mente une attaque risqu\xE9e (+2 \xE0 l'attaque au contact, -4 en DEF pendant un tour).
    • +
    • --attaqueDeGroupe n : n est le nombre de cr\xE9atures qui attaquent ; impl\xE9mente une attaque de groupe (+2 \xE0 l'attaque par attaquant au-del\xE0 du premier, x2 DMG si l'attaque d\xE9passe la DEF de 5 ou plus, x3 DMG si critique).
    • +
    • --attaqueAcrobatique : l'attaquant effectue un test d'acrobatie difficult\xE9 15, et s'il r\xE9ussit, l'attaque b\xE9n\xE9ficie des effets d'une sournoise. On peut en option pr\xE9ciser le nombre de d\xE9s de cette attaque sournoise.
    • +
    • --strigeSuce : option sp\xE9cifique aux striges. Donne le malus de -3 en DEF et compte la quantite suc\xE9e. Quand cette quantit\xE9 arrive \xE0 6, enl\xE8ve le malus de DEF et rend la cible affaiblie.
    • +
    • --mainsDEnergie : +2 \xE0 +5 \xE0 l'attaque, selon l'armure de la cible
    • +
    • --semonce : +5 au touch\xE9 et +1d6 aux DM (ne change pas les charges de l'arme).
    • +
    • --avantage : lance un d\xE9 de plus en attaque et garde le meilleur. plusieurs arguments avantage se cumulent et sont annul\xE9s par les d\xE9savantages (syntaxe alertnative: (--m2d20)
    • +
    • --desavantage : lance un d\xE9 de plus en attaque et garde le moins bon. plusieurs arguments d\xE9savantage se cumulent et sont annul\xE9s par les avantages.
    • +
    • --avecd12 : lance un d12 au lieu du d20 pour le jet d'attaque. L'attaque est impossible si l'attaquant est d\xE9j\xE0 affaibli.
    • +
    • --avecd12crit : comme --avecd12, mais le jet peut faire un critique. La plage de critique est divis\xE9e par 2, arrondie \xE0 l'inf\xE9rieur. Ainsi si le d20 sevait critiquer sur un 20 seulement, le d12 ne fait pas de critique. Il fait un critique sur un 12 si le d20 devait faire un critique sur un 19 ou un 18, et ainsi de suite.
    • +
    • --incrDmgCoef n : augmente le coefficient des d\xE9g\xE2ts de base de 1. Les d\xE9g\xE2ts de base comprennent les d\xE9s de dommage de l'arme (ou du sort), plus tous les bonus constants. Le coefficient par d\xE9faut est de 1, et une r\xE9ussite critique augmente ce coefficient de 1.
    • +
    • --incrCritCoef n : augmente le coefficient des d\xE9g\xE2ts critiques de n (1 si on ne donne pas d'argument).
    • +
    • --diviseDmg n : divise les d\xE9g\xE2ts de base par n.
    • +
    • --maxDmg : l'attaque inflige le maximum de DM permis par les d\xE9s de base.
    • +
    • --runeDePuissance : l'arme est enchant\xE9e avec une rune de puissance permanente.
    • +
    • --difficultePVmax : la difficult\xE9 du jet d'attaque est le maximum de PVs au lieu de la d\xE9fense.
    • +
    • --difficultePV : la difficult\xE9 du jet d'attaque est la valeur courante des PVs au lieu de la d\xE9fense.
    • +
    • --difficulteCarac carac : la difficult\xE9 du jet d'attaque est une des caract\xE9ristiques de la cible (sous forme de code \xE0 3 lettres, FOR, DEX, etc). Il est possible de prendre le meilleur de 2 caract\xE9ristiques en \xE9crivant les 2 noms coll\xE9s. Par exemple, pour viser le meilleur de l'intelligence et du charisme, on \xE9crira --difficuletCarac INTCHA.
    • --affute : augmente de 1 les chances de crit et +1d6 aux DM des crit.
    • --tirDeBarrage : ignore la charge, multiplie les DM par 2 et message pour undo si la cible bouge.
    • --tirAveugle : ignore le malus de tir sur une cible invisible.
    • -
    • --vicieux : ajoute 2d6 DM mais inflige 1d6 DM à l'attaquant.
    • -
    • --enflamme : enflamme la cible, lui infligeant 1d6 DM par tour. Les flammes s'éteindent sur un 1 ou 2. Si l'option --puissant est donnée en conjonction, les DM augmentent de 1.
    • +
    • --vicieux : ajoute 2d6 DM mais inflige 1d6 DM \xE0 l'attaquant.
    • +
    • --enflamme : enflamme la cible, lui infligeant 1d6 DM par tour. Les flammes s'\xE9teindent sur un 1 ou 2. Si l'option --puissant est donn\xE9e en conjonction, les DM augmentent de 1.
    • --malediction : maudit la cible pour 3 jets.
    • -
    • --asDeLaGachette : ajoute 1d6 DM si le jet d'attaque dépasse une DEF de 25.
    • -
    • --armeDArgent : bonus de +2 en attaque et 1d6 aux DM si la cible est un mort-vivant ou un démon (utilise le champ Race de la fiche ou si présent un prédicat mortVivant).
    • -
    • --pietine : si l'attaquant est de taille au moins égale à celle de la cible (ou si la taille de l'un des deux n'est pas connue), fait un test opposé de FOR. En cas d'échec de la cible, elle est renversée et les DM sont doublés.
    • -
    • --percute : comme --pietine, mais la cible est en plus projetée à 1d6+1 mètres et étourdie si elle rate un test de CON difficulté 15, renouvelable chaque tour.
    • -
    • --feinte : L'attaque ne fait pas de dégât, mais un bonus de +5 en attaque est donné sur les attaques du tour suivant sur cette cible (par celui qui a fait la feinte), et +2d6 DM si l'attaque fictive était un succès. Si l'attaquant possède un prédicat bonusFeinte, c'est la valeur de ce prédicat qui est donné en bonus aux attaques, à la place de +5.
    • -
    • --enveloppe difficulte type expr : si l'attaque touche, elle a une chance d'envelopper la cible. Dans ce cas, un bouton apparaît qui lance un test en opposition. Si celui-ci est remporté par l'attaquant, difficulte est la difficulté du test pour se sortir de l'enveloppement, type est soit label, et dans ce cas, expr doit être le label d'une attaque de l'attaquant, soit ability, et dans ce cas, expr est le nom d'une ability de l'attaquant. Cette attaque ou ability est appelée pour les dégâts périodiques. Si les deux derniers arguments sont ommis, le script prend label et le label de l'attaque courante, et si le premier argument est ommis, la difficulté est de 15.
    • -
    • --etreinte difficulte : si l'attaque touche, il y a une chance que l'attaquant puisse s'enrouler autour de la cible. Dans ce cas, un bouton apparaît qui lance un test en opposition. Si celui-ci est remporté par l'attaquant, difficulte est la difficulté du test pour se sortir de l'enveloppement. Cela fera apparaître un bouton pour les dégâts de l'étreinte, par défaut 1d6, mais on peut spécifier une autre expression pour les dégâts (optionelle, juste après la difficulté).
    • -
    • --ouvertureMortelle : touche automatiquement, fait des dégât comme en cas de critique et multiplie par 2 les dégâts d'attaque sournoise (si il y en a).
    • -
    • --rate, --touche, --critique, --echecCritique, --pasDEchecCritique : options pour tricher : le résultat des dés donne toujours le résultat voulu.
    • -
    • --ligne : l'attaque porte sur toutes les cibles à portée, entre l'attaquant et le token ciblé. Si le token ciblé est plus proche que la portée de l'attaque, les tokens derrière le token ciblé sont aussi visés. Pour permettre de viser un point quelconque, on peut utiliser un personnage dédié avec un maximum de 0 pv. À chaque fois qu'un token représentant ce personnage est utilisé comme cible de --ligne, le token est enlevé de la carte.
    • -
    • --disque r : l'attaque porte sur toutes les cibles dans le disque de centre le token ciblé et de rayon r. Comme pour --ligne, on peut utiliser un token cible qui sera supprimé après l'attaque. À noter que l'attaquant lui-même peut prendre des dégâts, sauf si l'attaque a une portée nulle et que l'attaquant se cible lui-même (attaque centrée sur le lanceur). On peut donner en argument optionel le mot souffleDeMort pour ne valider l'attaque que si le centre du disque est un personnage mort depuis moins d'un tour et ne garder que les alliés de ce personnage de niveau inférieur ou égal.
    • -
    • --cone angle : cible toutes les créatures dans un cône de sommet l'attaquant, d'angle angle degrés (90 degrés par défaut), et séparé en deux par le segment joignant l'attaquant et le token visé.
    • -
    • --explosion : si l'attaque n'est pas déjà un disque, considère qu'elle forme un disque de rayon égal à la portée. L'attaquant est automatiquement exclus de la zone.
    • -
    • --dmCible dmg : utilisé conjointement aux options de zone ci-dessus, cette option permet de remplacer les dommages de base de l'attaque spécifiquement sur la cible sélectionnée lors de l'attaque
    • -
    • --saufAllies : ne cible pas les allies dans la zone ou les cibles spécifiées.
    • -
    • --target id : ajoute une cible à l'attaque (s'ajoute à la cible principale et aux options d'aoe).
    • -
    • --ciblesDansDisque n : impose que les différentes cibles soient dans un disque de rayon n.
    • -
    • --ricochets n : l'arme de jet peut faire n ricochets. Une cible ne peut être touchée qu'une fois par attaque.
    • -
    • --message texte : ajoute une ligne avec le message dans la fenêtre de l'attaque. Attention, texte ne doit pas contenir la séquence --.
    • -
    • --secret : affiche les jets et résultats de l'attaque seulement aux joueurs qui contrôlent l'attaquant ou ses cibles, ainsi qu'au MJ.
    • -
    • --allonge n : ajoute n mètres à la portée d'une attaque au contact. L'allonge peut être un nombre à virgule et même négative.
    • -
    • --canaliseParFamilier : le point de départ de l'attaque est le familier s'il est actif sur la carte.
    • -
    • --peutAgripper : l'attaque peut agripper comme si l'attaquant avait le prédicat agripper.
    • -
    • --soundAttack son : joue le son son, à moins qu'une version plus longue de l'option (voir ci-dessous) n'existe et qu'elle soit active.
    • -
    • --soundAttackEchec son : joue le son son lorque l'arme fait un echec, sauf si c'est un échec particulier et une version plus longue existe.
    • +
    • --asDeLaGachette : ajoute 1d6 DM si le jet d'attaque d\xE9passe une DEF de 25.
    • +
    • --armeDArgent : bonus de +2 en attaque et 1d6 aux DM si la cible est un mort-vivant ou un d\xE9mon (utilise le champ Race de la fiche ou si pr\xE9sent un pr\xE9dicat mortVivant).
    • +
    • --pietine : si l'attaquant est de taille au moins \xE9gale \xE0 celle de la cible (ou si la taille de l'un des deux n'est pas connue), fait un test oppos\xE9 de FOR. En cas d'\xE9chec de la cible, elle est renvers\xE9e et les DM sont doubl\xE9s.
    • +
    • --percute : comme --pietine, mais la cible est en plus projet\xE9e \xE0 1d6+1 m\xE8tres et \xE9tourdie si elle rate un test de CON difficult\xE9 15, renouvelable chaque tour.
    • +
    • --feinte : L'attaque ne fait pas de d\xE9g\xE2t, mais un bonus de +5 en attaque est donn\xE9 sur les attaques du tour suivant sur cette cible (par celui qui a fait la feinte), et +2d6 DM si l'attaque fictive \xE9tait un succ\xE8s. Si l'attaquant poss\xE8de un pr\xE9dicat bonusFeinte, c'est la valeur de ce pr\xE9dicat qui est donn\xE9 en bonus aux attaques, \xE0 la place de +5.
    • +
    • --enveloppe difficulte type expr : si l'attaque touche, elle a une chance d'envelopper la cible. Dans ce cas, un bouton appara\xEEt qui lance un test en opposition. Si celui-ci est remport\xE9 par l'attaquant, difficulte est la difficult\xE9 du test pour se sortir de l'enveloppement, type est soit label, et dans ce cas, expr doit \xEAtre le label d'une attaque de l'attaquant, soit ability, et dans ce cas, expr est le nom d'une ability de l'attaquant. Cette attaque ou ability est appel\xE9e pour les d\xE9g\xE2ts p\xE9riodiques. Si les deux derniers arguments sont ommis, le script prend label et le label de l'attaque courante, et si le premier argument est ommis, la difficult\xE9 est de 15.
    • +
    • --etreinte difficulte : si l'attaque touche, il y a une chance que l'attaquant puisse s'enrouler autour de la cible. Dans ce cas, un bouton appara\xEEt qui lance un test en opposition. Si celui-ci est remport\xE9 par l'attaquant, difficulte est la difficult\xE9 du test pour se sortir de l'enveloppement. Cela fera appara\xEEtre un bouton pour les d\xE9g\xE2ts de l'\xE9treinte, par d\xE9faut 1d6, mais on peut sp\xE9cifier une autre expression pour les d\xE9g\xE2ts (optionelle, juste apr\xE8s la difficult\xE9).
    • +
    • --ouvertureMortelle : touche automatiquement, fait des d\xE9g\xE2t comme en cas de critique et multiplie par 2 les d\xE9g\xE2ts d'attaque sournoise (si il y en a).
    • +
    • --rate, --touche, --critique, --echecCritique, --pasDEchecCritique : options pour tricher : le r\xE9sultat des d\xE9s donne toujours le r\xE9sultat voulu.
    • +
    • --ligne : l'attaque porte sur toutes les cibles \xE0 port\xE9e, entre l'attaquant et le token cibl\xE9. Si le token cibl\xE9 est plus proche que la port\xE9e de l'attaque, les tokens derri\xE8re le token cibl\xE9 sont aussi vis\xE9s. Pour permettre de viser un point quelconque, on peut utiliser un personnage d\xE9di\xE9 avec un maximum de 0 pv. \xC0 chaque fois qu'un token repr\xE9sentant ce personnage est utilis\xE9 comme cible de --ligne, le token est enlev\xE9 de la carte.
    • +
    • --disque r : l'attaque porte sur toutes les cibles dans le disque de centre le token cibl\xE9 et de rayon r. Comme pour --ligne, on peut utiliser un token cible qui sera supprim\xE9 apr\xE8s l'attaque. \xC0 noter que l'attaquant lui-m\xEAme peut prendre des d\xE9g\xE2ts, sauf si l'attaque a une port\xE9e nulle et que l'attaquant se cible lui-m\xEAme (attaque centr\xE9e sur le lanceur). On peut donner en argument optionel le mot souffleDeMort pour ne valider l'attaque que si le centre du disque est un personnage mort depuis moins d'un tour et ne garder que les alli\xE9s de ce personnage de niveau inf\xE9rieur ou \xE9gal.
    • +
    • --cone angle : cible toutes les cr\xE9atures dans un c\xF4ne de sommet l'attaquant, d'angle angle degr\xE9s (90 degr\xE9s par d\xE9faut), et s\xE9par\xE9 en deux par le segment joignant l'attaquant et le token vis\xE9.
    • +
    • --explosion : si l'attaque n'est pas d\xE9j\xE0 un disque, consid\xE8re qu'elle forme un disque de rayon \xE9gal \xE0 la port\xE9e. L'attaquant est automatiquement exclus de la zone.
    • +
    • --dmCible dmg : utilis\xE9 conjointement aux options de zone ci-dessus, cette option permet de remplacer les dommages de base de l'attaque sp\xE9cifiquement sur la cible s\xE9lectionn\xE9e lors de l'attaque
    • +
    • --saufAllies : ne cible pas les allies dans la zone ou les cibles sp\xE9cifi\xE9es.
    • +
    • --target id : ajoute une cible \xE0 l'attaque (s'ajoute \xE0 la cible principale et aux options d'aoe).
    • +
    • --ciblesDansDisque n : impose que les diff\xE9rentes cibles soient dans un disque de rayon n.
    • +
    • --ricochets n : l'arme de jet peut faire n ricochets. Une cible ne peut \xEAtre touch\xE9e qu'une fois par attaque.
    • +
    • --message texte : ajoute une ligne avec le message dans la fen\xEAtre de l'attaque. Attention, texte ne doit pas contenir la s\xE9quence --.
    • +
    • --secret : affiche les jets et r\xE9sultats de l'attaque seulement aux joueurs qui contr\xF4lent l'attaquant ou ses cibles, ainsi qu'au MJ.
    • +
    • --allonge n : ajoute n m\xE8tres \xE0 la port\xE9e d'une attaque au contact. L'allonge peut \xEAtre un nombre \xE0 virgule et m\xEAme n\xE9gative.
    • +
    • --canaliseParFamilier : le point de d\xE9part de l'attaque est le familier s'il est actif sur la carte.
    • +
    • --peutAgripper : l'attaque peut agripper comme si l'attaquant avait le pr\xE9dicat agripper.
    • +
    • --soundAttack son : joue le son son, \xE0 moins qu'une version plus longue de l'option (voir ci-dessous) n'existe et qu'elle soit active.
    • +
    • --soundAttackEchec son : joue le son son lorque l'arme fait un echec, sauf si c'est un \xE9chec particulier et une version plus longue existe.
    • --soundAttackEchecCritique son : joue le son n lorque l'arme fait un echec critique
    • --soundAttackEchecClignotement son : joue le son son lorque l'arme fait un echec par clignotement
    • -
    • --soundAttackSucces son : joue le son son lorque l'arme fait un succès
    • -
    • --soundAttackSuccesCritique son : joue le son n lorque l'arme fait un succès critique
    • -
    • --soundAttackSuccesChampion son : joue le son son lorque l'arme fait un succès champion
    • -
    • --imgAttack img : Affiche dans le chat l'image (.jpg/.png/.gif) img, à moins qu'une version plus longue de l'option (voir ci-dessous) n'existe et qu'elle soit active.
    • +
    • --soundAttackSucces son : joue le son son lorque l'arme fait un succ\xE8s
    • +
    • --soundAttackSuccesCritique son : joue le son n lorque l'arme fait un succ\xE8s critique
    • +
    • --soundAttackSuccesChampion son : joue le son son lorque l'arme fait un succ\xE8s champion
    • +
    • --imgAttack img : Affiche dans le chat l'image (.jpg/.png/.gif) img, \xE0 moins qu'une version plus longue de l'option (voir ci-dessous) n'existe et qu'elle soit active.
    • --imgAttackEchecCritique img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec critique
    • --imgAttackEchec img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec
    • --imgAttackEchecClignotement img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec par clignotement
    • -
    • --imgAttackSuccesCritique img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès critique
    • -
    • --imgAttackSucces img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès
    • -
    • --imgAttackSuccesChampion img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès champion
    • +
    • --imgAttackSuccesCritique img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s critique
    • +
    • --imgAttackSucces img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s
    • +
    • --imgAttackSuccesChampion img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s champion
    -

    Réduction des dégâts

    +

    R\xE9duction des d\xE9g\xE2ts

    Fonctionnement de base
      -
    • Le script utilise les cases RD et Casque présentes sur les fiches.
    • -
    • Il est possible d'indiquer plusieurs RD différentes, il suffit de les séparer par une virgule.
    • +
    • Le script utilise les cases RD et Casque pr\xE9sentes sur les fiches.
    • +
    • Il est possible d'indiquer plusieurs RD diff\xE9rentes, il suffit de les s\xE9parer par une virgule.
    • Toutes les RD se cumulent.
    • -
    • Le script se base sur les types de dégâts pour choisir d'appliquer ou non les dégâts.
    • -
    • Pour les armes magiques, il est possible de spécifier à la fois le type de l'arme (par exemple --tranchant) et --magique.
    • +
    • Le script se base sur les types de d\xE9g\xE2ts pour choisir d'appliquer ou non les d\xE9g\xE2ts.
    • +
    • Pour les armes magiques, il est possible de sp\xE9cifier \xE0 la fois le type de l'arme (par exemple --tranchant) et --magique.
    RD simple
    -

    Dans le cas d'une RD simple (résistance à tous les dégâts), il suffit d'indiquer un nombre. Exemple : 3

    -
    RD à un type de dégâts particuliers
    -

    Pour une RD qui ne s'applique qu'à un type de dégâts particuliers, indiquer le type et la valeur séparés par :. Exemple : feu:5. On peut aussi spécifier une RD conte tous les types élémentaires avec le mot clé elementaire. On peut aussi avoir une RD qui ne s'applique qu'aux attaques à distance avec le mot clé distance.

    -
    RD sauf un ou plusieurs types de dégâts particuliers
    -

    Pour une RD qui s'applique tout le temps sauf un ou plusieurs types de dégâts particuliers, indiquer la valeur puis / puis les différents types séparés par _. Exemple /. Exemple : 5/argent_magique
    - Pour une RD qui s'appliquerait à tous les types d'armes sauf une, utiliser à la place une résistance aux 2 autres types d'armes. Exemple, pour 5/tranchant, utiliser percant:5,contondant:5.

    +

    Dans le cas d'une RD simple (r\xE9sistance \xE0 tous les d\xE9g\xE2ts), il suffit d'indiquer un nombre. Exemple : 3

    +
    RD \xE0 un type de d\xE9g\xE2ts particuliers
    +

    Pour une RD qui ne s'applique qu'\xE0 un type de d\xE9g\xE2ts particuliers, indiquer le type et la valeur s\xE9par\xE9s par :. Exemple : feu:5. On peut aussi sp\xE9cifier une RD conte tous les types \xE9l\xE9mentaires avec le mot cl\xE9 elementaire. On peut aussi avoir une RD qui ne s'applique qu'aux attaques \xE0 distance avec le mot cl\xE9 distance.

    +
    RD sauf un ou plusieurs types de d\xE9g\xE2ts particuliers
    +

    Pour une RD qui s'applique tout le temps sauf un ou plusieurs types de d\xE9g\xE2ts particuliers, indiquer la valeur puis / puis les diff\xE9rents types s\xE9par\xE9s par _. Exemple /. Exemple : 5/argent_magique
    + Pour une RD qui s'appliquerait \xE0 tous les types d'armes sauf une, utiliser \xE0 la place une r\xE9sistance aux 2 autres types d'armes. Exemple, pour 5/tranchant, utiliser percant:5,contondant:5.

    RD critique
    -

    Utiliser un prédicat RD_critique avec comme valeur la résistance aux critiques. Se combine avec une éventuelle RD critique fournie par le port d'un casque.

    -
    Résistances
    -

    Pour les effets qui divisent la dégâts subits d'un type donné, utilisez un prédicat resistanceA_type. Une resistance à tous les dégâts non-magiques est possible avec resistanceA_nonMagique.Il est aussi possible d'octroyer une résistance temporaire, par exemple une potion de résistance au feu pourra être simulée par la commande !cof-set-attribute resistanceA_feu true. Cela ne sera pas visible dans les prédicats, local à un mook, et il faut ensuite effacer l'attribut à la fin de l'effet.

    -

    Pour les effets qui divisent par 2 les dégâts ou la durée, utiliser un prédicat diviseEffet_type.

    -

    Pour les effets qui donnent un bonus aux tests pour résister aux effets ou dégâts d'un certain type, utiliser un prédicat bonusSaveContre_type de valeur le bonus accordé. Par exemple, un objet qui donnerait +5 à tous les tests pour résister au poison pourrait être encodé par un prédicat bonusSaveContre_poison de valeur 5.

    +

    Utiliser un pr\xE9dicat RD_critique avec comme valeur la r\xE9sistance aux critiques. Se combine avec une \xE9ventuelle RD critique fournie par le port d'un casque.

    +
    R\xE9sistances
    +

    Pour les effets qui divisent la d\xE9g\xE2ts subits d'un type donn\xE9, utilisez un pr\xE9dicat resistanceA_type. Une resistance \xE0 tous les d\xE9g\xE2ts non-magiques est possible avec resistanceA_nonMagique.Il est aussi possible d'octroyer une r\xE9sistance temporaire, par exemple une potion de r\xE9sistance au feu pourra \xEAtre simul\xE9e par la commande !cof-set-attribute resistanceA_feu true. Cela ne sera pas visible dans les pr\xE9dicats, local \xE0 un mook, et il faut ensuite effacer l'attribut \xE0 la fin de l'effet.

    +

    Pour les effets qui divisent par 2 les d\xE9g\xE2ts ou la dur\xE9e, utiliser un pr\xE9dicat diviseEffet_type.

    +

    Pour les effets qui donnent un bonus aux tests pour r\xE9sister aux effets ou d\xE9g\xE2ts d'un certain type, utiliser un pr\xE9dicat bonusSaveContre_type de valeur le bonus accord\xE9. Par exemple, un objet qui donnerait +5 \xE0 tous les tests pour r\xE9sister au poison pourrait \xEAtre encod\xE9 par un pr\xE9dicat bonusSaveContre_poison de valeur 5.

    Armures/Boucliers de Protection (COF p. 203)
    -

    ajoutez un prédicat armureProtection ou bouclierProtection. Le script détecte si l'équipement est porté ou pas via la fiche, et fonctionne spécifiquement contre les attaques qui utilisent --sournoise. Il est aussi possible de spécifier le port d'un anneau de protection ayant le même effet (prédicat anneauProtection.

    +

    ajoutez un pr\xE9dicat armureProtection ou bouclierProtection. Le script d\xE9tecte si l'\xE9quipement est port\xE9 ou pas via la fiche, et fonctionne sp\xE9cifiquement contre les attaques qui utilisent --sournoise. Il est aussi possible de sp\xE9cifier le port d'un anneau de protection ayant le m\xEAme effet (pr\xE9dicat anneauProtection.

    Manoeuvres

    -

    !cof-action-defensive avec comme argument soit simple, soit totale donne le bonus en défense de l'action défensive (p 71). Cette action est disponible par défaut dans la liste des actions du tour. Alternativement, si vous n'utilisez pas cette méthode, vous pouvez créer une macro accessible à tous les tokens, !cof-action-defensive ?{Action défensive|simple|totale}.

    -

    Les manoeuvres risquées peuvent être lancées avec la commande !cof-manoeuvre @{selected|token_id} @{target|token_id} effet. Liste des manoeuvres : aveugler, bloquer, desarmer, faireDiversion, menacer, renverser, repousser, tenirADistance.

    -

    Il est aussi possible de faire un test d'attaque opposée avec la commande !cof-test-attaque-opposee @{selected|token_id} @{target|token_id}.

    +

    !cof-action-defensive avec comme argument soit simple, soit totale donne le bonus en d\xE9fense de l'action d\xE9fensive (p 71). Cette action est disponible par d\xE9faut dans la liste des actions du tour. Alternativement, si vous n'utilisez pas cette m\xE9thode, vous pouvez cr\xE9er une macro accessible \xE0 tous les tokens, !cof-action-defensive ?{Action d\xE9fensive|simple|totale}.

    +

    Les manoeuvres risqu\xE9es peuvent \xEAtre lanc\xE9es avec la commande !cof-manoeuvre @{selected|token_id} @{target|token_id} effet. Liste des manoeuvres : aveugler, bloquer, desarmer, faireDiversion, menacer, renverser, repousser, tenirADistance.

    +

    Il est aussi possible de faire un test d'attaque oppos\xE9e avec la commande !cof-test-attaque-opposee @{selected|token_id} @{target|token_id}.

    Recharger des armes : !cof-recharger N

    -

    Il faut un prédicat charge dans le champ de prédicat des armes qui ont besoin d'être chargées pour fonctionner. On peut associer un nombre au prédicat, pour indiquer un maximum de charges supérieur à 1. Noter que si on a 2 armes à une charge, il faut utiliser un maximum de 2.
    - Recharge l'arme N (augmente les charges d'un). Les armes sont toutes rechargées à la fin d'un combat.
    - La commande admet un argment optionel --grenaille pour charger (une arme à poudre) avec de la grenaille. +

    Il faut un pr\xE9dicat charge dans le champ de pr\xE9dicat des armes qui ont besoin d'\xEAtre charg\xE9es pour fonctionner. On peut associer un nombre au pr\xE9dicat, pour indiquer un maximum de charges sup\xE9rieur \xE0 1. Noter que si on a 2 armes \xE0 une charge, il faut utiliser un maximum de 2.
    + Recharge l'arme N (augmente les charges d'un). Les armes sont toutes recharg\xE9es \xE0 la fin d'un combat.
    + La commande admet un argment optionel --grenaille pour charger (une arme \xE0 poudre) avec de la grenaille.

    -

    Dégainer une arme : !cof-degainer N

    +

    D\xE9gainer une arme : !cof-degainer N

    -

    Pour certaines capacités, (commme Plus vite que son ombre ou Désarmer), il peut être utile de savoir quelle arme est en main. Pour cela, le script peut utiliser deux méthodes : +

    Pour certaines capacit\xE9s, (commme Plus vite que son ombre ou D\xE9sarmer), il peut \xEAtre utile de savoir quelle arme est en main. Pour cela, le script peut utiliser deux m\xE9thodes :

      -
    • !cof-degainer LL est le label d'une des attaques sur la fiche de personnage : cela fait rengainer l'arme en main et dégainer l'arme correspondant à cette attaque. Si le label ne correspond à aucune attaque (ou qu'on ne donne pas de label), l'action fait rengainer l'arme en main. On peut donner en argument 2 labels d'armes, pour faire dégainer à la fois une arme dans la main droite (le premier label) et une arme dans la main gauche. !cof-degainer l gauche permet de dégainer uniquement une arme dans la main gauche. À noter que si une arme est notée comme arme gauche dans l'attaque, alors elle est toujours portée en main gauche. L'ordre de rengainer fait rengainer les deux armes si le personnage porte une arme en main gauche.
    • -
    • Si on attaque avec !cof-attack tok1 tok2 L, et que l'attaque est de type Arme 1 main, Arme 2 mains ou Arme gauche, alors on considère qu'on doit dégainer cette arme pour pouvoir l'utiliser. Le script envoie le message et considère ensuite l'arme comme étant en main, au MJ de vérifier que le joueur dispose bien d'une action de mouvement pour le faire.
    • -
    • En fin de combat, si le personnage a la capacité frappe du vide, le script va automatiquement lui faire rengainer son arme.
    • -
    • Enfin, en fin de combat, si le personnage possède un prédicat armeParDefaut, le script va lui faire dégainer l'arme dont le label est la valeur du prédicat. Donc si le prédicat n'a pas de label associé, le personnage va rengainer son arme.
    • +
    • !cof-degainer L o\xF9 L est le label d'une des attaques sur la fiche de personnage : cela fait rengainer l'arme en main et d\xE9gainer l'arme correspondant \xE0 cette attaque. Si le label ne correspond \xE0 aucune attaque (ou qu'on ne donne pas de label), l'action fait rengainer l'arme en main. On peut donner en argument 2 labels d'armes, pour faire d\xE9gainer \xE0 la fois une arme dans la main droite (le premier label) et une arme dans la main gauche. !cof-degainer l gauche permet de d\xE9gainer uniquement une arme dans la main gauche. \xC0 noter que si une arme est not\xE9e comme arme gauche dans l'attaque, alors elle est toujours port\xE9e en main gauche. L'ordre de rengainer fait rengainer les deux armes si le personnage porte une arme en main gauche.
    • +
    • Si on attaque avec !cof-attack tok1 tok2 L, et que l'attaque est de type Arme 1 main, Arme 2 mains ou Arme gauche, alors on consid\xE8re qu'on doit d\xE9gainer cette arme pour pouvoir l'utiliser. Le script envoie le message et consid\xE8re ensuite l'arme comme \xE9tant en main, au MJ de v\xE9rifier que le joueur dispose bien d'une action de mouvement pour le faire.
    • +
    • En fin de combat, si le personnage a la capacit\xE9 frappe du vide, le script va automatiquement lui faire rengainer son arme.
    • +
    • Enfin, en fin de combat, si le personnage poss\xE8de un pr\xE9dicat armeParDefaut, le script va lui faire d\xE9gainer l'arme dont le label est la valeur du pr\xE9dicat. Donc si le pr\xE9dicat n'a pas de label associ\xE9, le personnage va rengainer son arme.
    -

    Dans tous les cas, si le personnage dégaine une arme à 2 mains, le script fait enlever le bouclier, et il le fait remettre si on passe d'une arme à 2 mains à une arme à 1 main.

    -

    Il existe un prédicat DEF qui permet d'ajouter sa valeur à la défense d'un personnage. C'est particulièrement utile pour coder une arme de parade. Par exemple avecDEF:2 dans les prédicats de l'arme, elle augmentera la défense de 2 quand elle sera portée.

    +

    Dans tous les cas, si le personnage d\xE9gaine une arme \xE0 2 mains, le script fait enlever le bouclier, et il le fait remettre si on passe d'une arme \xE0 2 mains \xE0 une arme \xE0 1 main.

    +

    Il existe un pr\xE9dicat DEF qui permet d'ajouter sa valeur \xE0 la d\xE9fense d'un personnage. C'est particuli\xE8rement utile pour coder une arme de parade. Par exemple avecDEF:2 dans les pr\xE9dicats de l'arme, elle augmentera la d\xE9fense de 2 quand elle sera port\xE9e.

    Couvert :!cof-bonus-couvert b

    - Pour donner un bonus en DEF contre toutes les attaques à distance, on peut utiliser !cof-bonus-couvert ?{Bonus du couvert?} en sélectionnant les tokens bénéficiant du couvert. La commande accepte un argument --secret permettant de ne pas faire connaître l'action du personnage à tous les joueurs. Pour ne plus être à couvert, il suffit de lancer la commande sans argument. + Pour donner un bonus en DEF contre toutes les attaques \xE0 distance, on peut utiliser !cof-bonus-couvert ?{Bonus du couvert?} en s\xE9lectionnant les tokens b\xE9n\xE9ficiant du couvert. La commande accepte un argument --secret permettant de ne pas faire conna\xEEtre l'action du personnage \xE0 tous les joueurs. Pour ne plus \xEAtre \xE0 couvert, il suffit de lancer la commande sans argument.
    -

    Échecs critiques :

    -

    En cas d'échec critique à une attaque, le script va suggérer des effets d'échec critique inspirés de cette table suggérée par l'auteur du jeu. Le script proposera même dans la plupart des cas un bouton qui automatisera les lancers de dés et l'application de l'effet, si relevant.

    -

    Il est aussi possible d'utiliser une table personnelle, non-automatisée (voir les options d'affichage, !cof-options affichage). La table utilisée (Echec-Critique-Contact) peut être modifiée par le MJ.

    -

    Dégâts directs (sans attaquant, ou aire d'effet trop complexe pour !cof-attack) : !cof-dmg dm

    +

    \xC9checs critiques :

    +

    En cas d'\xE9chec critique \xE0 une attaque, le script va sugg\xE9rer des effets d'\xE9chec critique inspir\xE9s de cette table sugg\xE9r\xE9e par l'auteur du jeu. Le script proposera m\xEAme dans la plupart des cas un bouton qui automatisera les lancers de d\xE9s et l'application de l'effet, si relevant.

    +

    Il est aussi possible d'utiliser une table personnelle, non-automatis\xE9e (voir les options d'affichage, !cof-options affichage). La table utilis\xE9e (Echec-Critique-Contact) peut \xEAtre modifi\xE9e par le MJ.

    +

    D\xE9g\xE2ts directs (sans attaquant, ou aire d'effet trop complexe pour !cof-attack) : !cof-dmg dm

    -

    Applique des dégâts à tous les tokens sélectionnés. L'argument dm peut être un inline roll. Utile par exemple pour les chutes, ou bien les dégâts d'environnement, voire de pièges.
    - Arguments optionels: une partie des options de !cof-attack, dont le type, et par exemple --psave carac seuil (jet de carac, si supérieur au seuil, les dégâts sont divisés par 2). On peut aussi donner un titre aux dégâts en utilisant l'option --titre +

    Applique des d\xE9g\xE2ts \xE0 tous les tokens s\xE9lectionn\xE9s. L'argument dm peut \xEAtre un inline roll. Utile par exemple pour les chutes, ou bien les d\xE9g\xE2ts d'environnement, voire de pi\xE8ges.
    + Arguments optionels: une partie des options de !cof-attack, dont le type, et par exemple --psave carac seuil (jet de carac, si sup\xE9rieur au seuil, les d\xE9g\xE2ts sont divis\xE9s par 2). On peut aussi donner un titre aux d\xE9g\xE2ts en utilisant l'option --titre

    -

    Il est possible d'infliger des dégâts sur la durée en utilisant la commande !cof-effet-temp dotGen(nom) duree --valeur expr type. Les arguments de --valeur donnent l'expression à évaluer, de type lancé de dé, et le type de dégâts. Par défaut, si rien n'est précisé, c'est 1d6 et normal. On peut utiliser les options habituelles de !cof-effet-temp. Ainsi, si on souhaite infliger des dégâts de poison de 1d4+1 par tour, pendant 10 tours, avec un jet de CON difficulté 12 pour arrêter l'effet, on pourra écrire !cof-effet-temp dotGen(monPoison) 10 --saveParTour CON 12 --valeur 1d4+1 poison. +

    Il est possible d'infliger des d\xE9g\xE2ts sur la dur\xE9e en utilisant la commande !cof-effet-temp dotGen(nom) duree --valeur expr type. Les arguments de --valeur donnent l'expression \xE0 \xE9valuer, de type lanc\xE9 de d\xE9, et le type de d\xE9g\xE2ts. Par d\xE9faut, si rien n'est pr\xE9cis\xE9, c'est 1d6 et normal. On peut utiliser les options habituelles de !cof-effet-temp. Ainsi, si on souhaite infliger des d\xE9g\xE2ts de poison de 1d4+1 par tour, pendant 10 tours, avec un jet de CON difficult\xE9 12 pour arr\xEAter l'effet, on pourra \xE9crire !cof-effet-temp dotGen(monPoison) 10 --saveParTour CON 12 --valeur 1d4+1 poison.

    Sortir du combat : !cof-fin-combat

    -

    Ferme aussi le tracker de tour. Encore à mettre en macro dans la barre du MJ (macro automatiquement générée par !cof-set-macros). Permet de tenir compte de pleins de capacités qui durent un combat, ou utilisables une seule fois par combat,...

    +

    Ferme aussi le tracker de tour. Encore \xE0 mettre en macro dans la barre du MJ (macro automatiquement g\xE9n\xE9r\xE9e par !cof-set-macros). Permet de tenir compte de pleins de capacit\xE9s qui durent un combat, ou utilisables une seule fois par combat,...

    -

    Utilisation spéciale des images et son des armes

    +

    Utilisation sp\xE9ciale des images et son des armes

    -

    Les images des armes et les sons peuvent être redéfinis dans le champ détail de l'arme.

    +

    Les images des armes et les sons peuvent \xEAtre red\xE9finis dans le champ d\xE9tail de l'arme.

    Pour ce faire vous devez ajouter les urls des images au format suivant dans la description de l'arme :

    -

    [Type de réussite] url de l'image [Type de réussite]

    +

    [Type de r\xE9ussite] url de l'image [Type de r\xE9ussite]

    Par exemple : [img-attack-echec-critique]https://media0.giphy.com/media/3og0INyCmHlNylks9O/giphy.gif[img-attack-echec-critique]

    -

    Les types de réussite que vous pouvez mettre en image sont :

    +

    Les types de r\xE9ussite que vous pouvez mettre en image sont :

    • [img-attack-echec-critique] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec critique
    • [img-attack-echec] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec
    • [img-attack-echec-clignotement] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un echec par clignotement
    • -
    • [img-attack-succes-critique] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès critique
    • -
    • [img-attack-succes] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès
    • -
    • [img-attack-succes-champion] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succès champion
    • +
    • [img-attack-succes-critique] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s critique
    • +
    • [img-attack-succes] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s
    • +
    • [img-attack-succes-champion] img : Affiche dans le chat l'image (.jpg/.png/.gif) img lorque l'arme fait un succ\xE8s champion
    -

    De la même manière vous pouvez ajouter des sons :

    -

    [Type de réussite] Nom du son dans votre jukebox [Type de réussite]

    +

    De la m\xEAme mani\xE8re vous pouvez ajouter des sons :

    +

    [Type de r\xE9ussite] Nom du son dans votre jukebox [Type de r\xE9ussite]

    • [sound-attack-echec-critique] son : joue le son n lorque l'arme fait un echec critique
    • [sound-attack-echec] son : joue le son son lorque l'arme fait un echec
    • [sound-attack-echec-clignotement] son : joue le son son lorque l'arme fait un echec par clignotement
    • -
    • [sound-attack-succes-critique] son : joue le son n lorque l'arme fait un succès critique
    • -
    • [sound-attack-succes] son : joue le son son lorque l'arme fait un succès
    • -
    • [sound-attack-succes-champion] son : joue le son son lorque l'arme fait un succès champion
    • +
    • [sound-attack-succes-critique] son : joue le son n lorque l'arme fait un succ\xE8s critique
    • +
    • [sound-attack-succes] son : joue le son son lorque l'arme fait un succ\xE8s
    • +
    • [sound-attack-succes-champion] son : joue le son son lorque l'arme fait un succ\xE8s champion

    Par exemple : [sound-attack-echec-critique]bang[sound-attack-echec-critique]

    -

    Dans cette exemple le son nomé "bang" dans votre jutbox serra joué a chaque echec critique de cette arme

    +

    Dans cette exemple le son nom\xE9 "bang" dans votre jutbox serra jou\xE9 a chaque echec critique de cette arme

    2.2 Soins :

    !cof-soin @{selected|token_id} @{target|token_id} x

    -

    x peut être un nombre, un jet de dé ou leger, modere, groupe ou secondSouffle.

    -

    Les deux premiers arguments sont optionnels. Si !cof-soin n'a qu'un seul argument, c'est interprété comme le montant des soins, et les tokens soignés sont ceux sélectionnés. Si !cof-soin n'a que 2 arguments, le premier argument est le token du soigneur, et les cibles doivent être désignées avec une option de sélection de groupe.

    +

    x peut \xEAtre un nombre, un jet de d\xE9 ou leger, modere, groupe ou secondSouffle.

    +

    Les deux premiers arguments sont optionnels. Si !cof-soin n'a qu'un seul argument, c'est interpr\xE9t\xE9 comme le montant des soins, et les tokens soign\xE9s sont ceux s\xE9lectionn\xE9s. Si !cof-soin n'a que 2 arguments, le premier argument est le token du soigneur, et les cibles doivent \xEAtre d\xE9sign\xE9es avec une option de s\xE9lection de groupe.

    Options (en plus de options normales de commandes):
      -
    • --portee n : permet de spécifier une distance maximum entre le soigneur et le soigné (au-delà, le soin échoue)
    • -
    • --transfer : le soin est payé avec les PV du soigneur
    • +
    • --portee n : permet de sp\xE9cifier une distance maximum entre le soigneur et le soign\xE9 (au-del\xE0, le soin \xE9choue)
    • +
    • --transfer : le soin est pay\xE9 avec les PV du soigneur
    • --mana n : demande au lanceur de payer n points de mana
    • -
    • --depasseLimite n : permet de lancer les sorts de soins léger, modéré ou de groupe quand la limite journalière est dépassée, mais en augmentant le coût en mana de n à chaque nouveau dépassement.
    • -
    • --limiteSoinsParJour n : limite le nombre total de PVs soignés par jour. Cette limite peut être associée à une ressource (spécifier en deuxième argument de l'option, peut contenir des espaces), de sorte que seuls les soins qui mentionnent cette ressource sont concernés par cette limitation. Cette option n'a de sens que si un soigneur est précisé.
    • -
    • --sacrifierPV : le soigneur doit sacrifier autant de PV que le montant des soins (que ces soins soient utilisés ou non).
    • +
    • --depasseLimite n : permet de lancer les sorts de soins l\xE9ger, mod\xE9r\xE9 ou de groupe quand la limite journali\xE8re est d\xE9pass\xE9e, mais en augmentant le co\xFBt en mana de n \xE0 chaque nouveau d\xE9passement.
    • +
    • --limiteSoinsParJour n : limite le nombre total de PVs soign\xE9s par jour. Cette limite peut \xEAtre associ\xE9e \xE0 une ressource (sp\xE9cifier en deuxi\xE8me argument de l'option, peut contenir des espaces), de sorte que seuls les soins qui mentionnent cette ressource sont concern\xE9s par cette limitation. Cette option n'a de sens que si un soigneur est pr\xE9cis\xE9.
    • +
    • --sacrifierPV : le soigneur doit sacrifier autant de PV que le montant des soins (que ces soins soient utilis\xE9s ou non).
    @@ -615,33 +616,33 @@

    2.3 Repos et changement de jour

    Changement de jour

    -

    !cof-nouveau-jour : remise à zéro de toutes les limites journalières.

    +

    !cof-nouveau-jour : remise \xE0 z\xE9ro de toutes les limites journali\xE8res.

    Repos de plus de 8 h

    -

    Fait récupérer 1 PR ou les points de vie correspondant à 1 PR, plus les points de mana.

    +

    Fait r\xE9cup\xE9rer 1 PR ou les points de vie correspondant \xE0 1 PR, plus les points de mana.

      -
    • !cof-nouveau-jour --repos : Pour une nuit qui se passe bien : fait l'effet d'un nouveau jour sur le monde, et, si aucun token n'est sélectionné, applique un repos de 8 h à tous les tokens de la page, sinon applique ce repos uniquement aux tokens sélectionnés.
    • -
    • !cof-recuperation --reposLong : applique le repos aux tokens selectionnés, sans remettre à zéro les limites journalières. +
    • !cof-nouveau-jour --repos : Pour une nuit qui se passe bien : fait l'effet d'un nouveau jour sur le monde, et, si aucun token n'est s\xE9lectionn\xE9, applique un repos de 8 h \xE0 tous les tokens de la page, sinon applique ce repos uniquement aux tokens s\xE9lectionn\xE9s.
    • +
    • !cof-recuperation --reposLong : applique le repos aux tokens selectionn\xE9s, sans remettre \xE0 z\xE9ro les limites journali\xE8res.

    Repos de 10 minutes

    -

    !cof-recuperation : dépense 1 PR pour se soigner. À mettre en macro associée aux tokens, car tous les joueurs en ont besoin (généré par !cof-set-macros.

    +

    !cof-recuperation : d\xE9pense 1 PR pour se soigner. \xC0 mettre en macro associ\xE9e aux tokens, car tous les joueurs en ont besoin (g\xE9n\xE9r\xE9 par !cof-set-macros.

    -

    2.4 Statut et états

    +

    2.4 Statut et \xE9tats

    -

    !cof-statut affiche l'état courant de tous les tokens sélectionnés. Utile pour connaître facilement les états qui ne sont pas directement visibles sur un token (points de récupération, armes chargées, ...). Il est possible de rajouter l'affichage d'autres attributs que ceux sélectionnés par défaut par le script. Pour cela, utiliser un prédicat attributsDeStatut, de valeur la liste des noms d'attributs à afficher, séparés par des virgules. Attention, si vous avez besoin de séparer vos attributs par des virgules, pensez à utiliser la syntaxe avec ::. Si vous le souhaitez, vous pouvez utiliser plusieurs prédicats nommés attributsDeStatut.

    -

    États gérés en utilisant le statut des tokens

    +

    !cof-statut affiche l'\xE9tat courant de tous les tokens s\xE9lectionn\xE9s. Utile pour conna\xEEtre facilement les \xE9tats qui ne sont pas directement visibles sur un token (points de r\xE9cup\xE9ration, armes charg\xE9es, ...). Il est possible de rajouter l'affichage d'autres attributs que ceux s\xE9lectionn\xE9s par d\xE9faut par le script. Pour cela, utiliser un pr\xE9dicat attributsDeStatut, de valeur la liste des noms d'attributs \xE0 afficher, s\xE9par\xE9s par des virgules. Attention, si vous avez besoin de s\xE9parer vos attributs par des virgules, pensez \xE0 utiliser la syntaxe avec ::. Si vous le souhaitez, vous pouvez utiliser plusieurs pr\xE9dicats nomm\xE9s attributsDeStatut.

    +

    \xC9tats g\xE9r\xE9s en utilisant le statut des tokens

    -

    !cof-set-state etat [true|false] permet de changer l'état des tokens sélectionnés. Si cet état concerne un personnage avec tokens liés (en liant la barre 1 aux points de vie), alors l'état persiste si on change de carte (utilisation d'un attribut hors fiche).

    -

    Liste des états et markers correspondants :

    +

    !cof-set-state etat [true|false] permet de changer l'\xE9tat des tokens s\xE9lectionn\xE9s. Si cet \xE9tat concerne un personnage avec tokens li\xE9s (en liant la barre 1 aux points de vie), alors l'\xE9tat persiste si on change de carte (utilisation d'un attribut hors fiche).

    +

    Liste des \xE9tats et markers correspondants :

    - + @@ -652,40 +653,40 @@

    États gérés en utilisant le statut des

    - + - - - - - @@ -699,14 +700,14 @@

    États gérés en utilisant le statut des

    - - @@ -715,19 +716,19 @@

    États gérés en utilisant le statut des

    - + - + - @@ -741,7 +742,7 @@

    États gérés en utilisant le statut des

    - @@ -755,7 +756,7 @@

    États gérés en utilisant le statut des

    - @@ -763,391 +764,393 @@

    États gérés en utilisant le statut des

    LdB : Livre de Base, Comp : Compagnon
    État\xC9tat Source Remarque Marker Std.
    Affaibli LdB p70Apparaît sur la fiche persoAppara\xEEt sur la fiche perso half-heart cof-affaibli
    Apeuré + Apeur\xE9 Victime d'un sort de Peur screaming cof-apeure
    Assommé + Assomm\xE9 LdB p72 pummeled cof-assomme
    Aveuglé + Aveugl\xE9 LdB p70 Change aussi la vision du token bleeding-eye cof-aveugle
    Blessé + Bless\xE9 LdB p177 arrowed cof-blesse
    Encombré + Encombr\xE9 Comp p103 frozen-orbcof-endormi
    Étourdi + \xC9tourdi LdB p70 half-haze cof-etourdi
    Immobilisé + Immobilis\xE9 LdB p70 cobweb
    Invisible Sort d'invisibilitéSort d'invisibilit\xE9 ninja-mask cof-invisible
    Mort LdB p73Même état pour un PJ juste inconscient à 0 PVM\xEAme \xE9tat pour un PJ juste inconscient \xE0 0 PV dead dead
    Paralysé + Paralys\xE9 LdB p70 fishing-netcof-ralenti
    Renversé + Renvers\xE9 LdB p70 back-paincof-surpris
    Pénombre + P\xE9nombre LdB p71 archery-target
    -

    Pour faciliter la gestion des états, on peut deux macros dans la barre du GM, !cof-set-state ?{État|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|blessé|encombre} true, et la même avec false. (N'oubliez pas que la commande !cof-set-macros permet de générer automatiquement les macros utiles au script). Une fois qu'on connaît bien les icônes, on peut directement les changer sur les tokens pour le même effet (et même faire un undo de ces changements si besoin).

    -

    À noter qu'un personnage ayant un prédicat nommé immunite_etat ne pourra pas être mis dans l'état etat.

    -

    Enfin, il est possible de faire réaliser un jet pour se libérer d'un état, en utilisant la commande !cof-save-state etat carac seuil. Il est possible de remplacer seuil par une id de token pour faire faire un test en opposition avec ce token. On peut aussi passer la caractéristique et le seuil en argument à !cof-set-state pour proposer le jet à chaque fois qu'on affiche les actions du tour ou qu'on affiche le statut du personnage.

    +

    Pour faciliter la gestion des \xE9tats, on peut deux macros dans la barre du GM, !cof-set-state ?{\xC9tat|mort|surpris|assomme|renverse|aveugle|affaibli|etourdi|paralyse|ralenti|immobilise|endormi|apeure|invisible|bless\xE9|encombre} true, et la m\xEAme avec false. (N'oubliez pas que la commande !cof-set-macros permet de g\xE9n\xE9rer automatiquement les macros utiles au script). Une fois qu'on conna\xEEt bien les ic\xF4nes, on peut directement les changer sur les tokens pour le m\xEAme effet (et m\xEAme faire un undo de ces changements si besoin).

    +

    \xC0 noter qu'un personnage ayant un pr\xE9dicat nomm\xE9 immunite_etat ne pourra pas \xEAtre mis dans l'\xE9tat etat.

    +

    Enfin, il est possible de faire r\xE9aliser un jet pour se lib\xE9rer d'un \xE9tat, en utilisant la commande !cof-save-state etat carac seuil. Il est possible de remplacer seuil par une id de token pour faire faire un test en opposition avec ce token. On peut aussi passer la caract\xE9ristique et le seuil en argument \xE0 !cof-set-state pour proposer le jet \xE0 chaque fois qu'on affiche les actions du tour ou qu'on affiche le statut du personnage.

    -

    Affaiblissements de caractéristiques

    +

    Affaiblissements de caract\xE9ristiques

    - !cof-affaiblir-carac carac valeur permet d'affaiblir temporairement une caractéristique (force, dextérité, constitution, intelligence, sagesse, charisme ou random) d'une valeur positive. Il existe aussi une option pour les attaques, --affaiblirCarac, qui permet de n'affaiblir une caractéristique que si une attaque est réussie. + !cof-affaiblir-carac carac valeur permet d'affaiblir temporairement une caract\xE9ristique (force, dext\xE9rit\xE9, constitution, intelligence, sagesse, charisme ou random) d'une valeur positive. Il existe aussi une option pour les attaques, --affaiblirCarac, qui permet de n'affaiblir une caract\xE9ristique que si une attaque est r\xE9ussie.

    -

    Une caractéristique affaiblie remonte de 1 après chaque nuit de repos. Le sort de régénération permet de récupérer 1d4 points d'une seule caractéristique physique (d'abord constitution, puis force puis dextérité). Le sort délivrance permet de récupérer 1d4 point d'une seule caractéristique, et comme indiqué dans les règles, le sort de guérison annule tous les affaiblissements de caractéritiques. Enfin le script propose une commande dédiée, !cof-soigner-affaiblissement carac valeur pour soigner les affaiblissements. +

    Une caract\xE9ristique affaiblie remonte de 1 apr\xE8s chaque nuit de repos. Le sort de r\xE9g\xE9n\xE9ration permet de r\xE9cup\xE9rer 1d4 points d'une seule caract\xE9ristique physique (d'abord constitution, puis force puis dext\xE9rit\xE9). Le sort d\xE9livrance permet de r\xE9cup\xE9rer 1d4 point d'une seule caract\xE9ristique, et comme indiqu\xE9 dans les r\xE8gles, le sort de gu\xE9rison annule tous les affaiblissements de caract\xE9ritiques. Enfin le script propose une commande d\xE9di\xE9e, !cof-soigner-affaiblissement carac valeur pour soigner les affaiblissements.

    -

    À noter que la diminution de constitution fait baisser les points de vie maximum, et qu'une constitution de 0 conduit à la mort.

    +

    \xC0 noter que la diminution de constitution fait baisser les points de vie maximum, et qu'une constitution de 0 conduit \xE0 la mort.

    -

    Conditions hostiles et extrêmes

    +

    Conditions hostiles et extr\xEAmes

    -

    Pour des conditions hostiles, faire !cof-effet conditionsHostiles oui en sélectionnant les personnages concernés. Pour des conditions extrêmes, !cof-effet conditionsHostiles 5. À noter que le script permet de passer en argument n'importe quel nombre, qui sera appliqué en malus à la DEX, FOR, DEF et attaque.

    +

    Pour des conditions hostiles, faire !cof-effet conditionsHostiles oui en s\xE9lectionnant les personnages concern\xE9s. Pour des conditions extr\xEAmes, !cof-effet conditionsHostiles 5. \xC0 noter que le script permet de passer en argument n'importe quel nombre, qui sera appliqu\xE9 en malus \xE0 la DEX, FOR, DEF et attaque.

    Autres bufs et debufs

    !cof-buf-def n : buf ou debuf de la DEF.

    -

    !cof-remove-buf-def : enlève tout buf ou debuf de la def.

    -

    !cof-effet-temp effet duree : ajoute l'effet effet à la cible pour la durée, !cof-effet-combat effet ajoute l'effet pour le combat, et !cof-effet effet ajoute ou enlève un effet à durée indéterminée. À noter que si la durée est 0 ou fin, alors la commande met fin à l'effet (utile pour des effets temporaires qui ont une action en fin d'effet, comme agrandissement ou formeDArbre). Un personnage ayant un prédicat nommé immunite_effetTemp est immunisé à l'effet temporaire de nom effetTemp.

    +

    !cof-remove-buf-def : enl\xE8ve tout buf ou debuf de la def.

    +

    !cof-effet-temp effet duree : ajoute l'effet effet \xE0 la cible pour la dur\xE9e, !cof-effet-combat effet ajoute l'effet pour le combat, et !cof-effet effet ajoute ou enl\xE8ve un effet \xE0 dur\xE9e ind\xE9termin\xE9e. \xC0 noter que si la dur\xE9e est 0 ou fin, alors la commande met fin \xE0 l'effet (utile pour des effets temporaires qui ont une action en fin d'effet, comme agrandissement ou formeDArbre). Un personnage ayant un pr\xE9dicat nomm\xE9 immunite_effetTemp est immunis\xE9 \xE0 l'effet temporaire de nom effetTemp.

    • --lanceur id : indique quel est le lanceur. Utile pour un certain nombre d'autres options.
    • -
    • --mana id cout : impose au token id de dépenser cout mana. Si --lanceur est donné, id est inutile. La présence de cette option, même avec un coût de 0, indique au script que l'effet devrait être supprimé à la mort du lanceur.
    • -
    • --limiteParJour l : limite le nombre d'utilisations de cette effet à l fois par jour. On peut préciser un nom après l, qui va correspondre à une ressource pouvant être partagée avec d'autres attaques ou d'autres effets (voir !cof-attack). Par défaut, le nom de cette ressource est effet. Attention, il faut un lanceur auquel appliquer la limite par jour !
    • -
    • --limiteParCombat : même effet que la limite par jour. Si aucun argument n'est donné, la limite est de une fois par combat. Attention, il faut un lanceur auquel appliquer la limite par combat !
    • -
    • --tempsRecharge effet duree : l'action n'est possible que si l'effet est inactif sur le personnage qui génère l'effet, et de plus active l'effet sur celui-ci pour la durée indiquée. Il existe un effet temporaire générique, rechargeGen(desc) que vous pouvez utiliser si aucun effet existant ne correspond.
    • -
    • --dose nom: définie une ressource nommée dose_nom, dont la valeur doit être positive. Utile par exemple pour les parchemins, les potions ou les baguettes.
    • -
    • --portee id d : impose aux cibles de l'effet d'être à moins de d mètres du token id. Si --lanceur est précisé, inutile de donner id.
    • +
    • --mana id cout : impose au token id de d\xE9penser cout mana. Si --lanceur est donn\xE9, id est inutile. La pr\xE9sence de cette option, m\xEAme avec un co\xFBt de 0, indique au script que l'effet devrait \xEAtre supprim\xE9 \xE0 la mort du lanceur.
    • +
    • --limiteParJour l : limite le nombre d'utilisations de cette effet \xE0 l fois par jour. On peut pr\xE9ciser un nom apr\xE8s l, qui va correspondre \xE0 une ressource pouvant \xEAtre partag\xE9e avec d'autres attaques ou d'autres effets (voir !cof-attack). Par d\xE9faut, le nom de cette ressource est effet. Attention, il faut un lanceur auquel appliquer la limite par jour !
    • +
    • --limiteParCombat : m\xEAme effet que la limite par jour. Si aucun argument n'est donn\xE9, la limite est de une fois par combat. Attention, il faut un lanceur auquel appliquer la limite par combat !
    • +
    • --tempsRecharge effet duree : l'action n'est possible que si l'effet est inactif sur le personnage qui g\xE9n\xE8re l'effet, et de plus active l'effet sur celui-ci pour la dur\xE9e indiqu\xE9e. Il existe un effet temporaire g\xE9n\xE9rique, rechargeGen(desc) que vous pouvez utiliser si aucun effet existant ne correspond.
    • +
    • --dose nom: d\xE9finie une ressource nomm\xE9e dose_nom, dont la valeur doit \xEAtre positive. Utile par exemple pour les parchemins, les potions ou les baguettes.
    • +
    • --portee id d : impose aux cibles de l'effet d'\xEAtre \xE0 moins de d m\xE8tres du token id. Si --lanceur est pr\xE9cis\xE9, inutile de donner id.
    • --puissant : lance la version puissante de l'effet
    • --puissant oui : idem
    • --puissant non : lance la version non puissante (efface le dernier effet puissant)
    • -
    • --puissant duree : multiplie la durée par 2
    • -
    • --puissant portee : multiplie la portée par 2
    • -
    • --saveParTour carac seuil : la cible peut se sortir de l'effet chaque tour grâce à un test de carac de difficulte seuil.
    • -
    • --saveActifParTour carac seuil : la cible peut se sortir de l'effet à tour grâce à un test de carac de difficulte seuil (utilisation dans bouton dans la liste d'actions).
    • -
    • --save carac seuil : la cible peut faire un jet pour échapper à l'effet. Si on ajoute l'argument demiDuree, alors réussir la sauvegarde ne fait que diviser la durée.
    • +
    • --puissant duree : multiplie la dur\xE9e par 2
    • +
    • --puissant portee : multiplie la port\xE9e par 2
    • +
    • --saveParTour carac seuil : la cible peut se sortir de l'effet chaque tour gr\xE2ce \xE0 un test de carac de difficulte seuil.
    • +
    • --saveActifParTour carac seuil : la cible peut se sortir de l'effet \xE0 tour gr\xE2ce \xE0 un test de carac de difficulte seuil (utilisation dans bouton dans la liste d'actions).
    • +
    • --save carac seuil : la cible peut faire un jet pour \xE9chapper \xE0 l'effet. Si on ajoute l'argument demiDuree, alors r\xE9ussir la sauvegarde ne fait que diviser la dur\xE9e.
    • --seulementVivant : l'effet ne peut s'appliquer qu'aux personnages vivants.
    • -
    • --tempeteDeMana liste : indique des effets de tempête de mana. La liste peut contenir un nombre (pour l'effet intense), duree, rapide et portee. Si le rang du sort est spécifié (par l'option --rang, un message est affichée si le coût en mana est supérieur au rang. Si la liste d'options est vide, le script affiche un menu dans le chat pour spécifier les options de tempête de mana.
    • -
    • --magieEnArmure : indique d'appliquer les règles pour la magie en armure pour un profil hybride. Il faut pour cela un lanceur défini. Par defaut, va faire test l'intelligence par un jet de difficulté 10 + rang + malus d'armure. Le rang est obtenu par l'option --rang. J'utilise le malus d'armure car il n'y a pas moyen de distinguer la DEF intrinsèque de l'armure de ses bonus de DEF dûs à un bonus magique. Enfin, on peut utiliser la règle de dépense supplémentaire de mana à la place du jet d'INT en utilisant l'option --magieEnarmure mana. Encore une fois, je prends le malus d'armure, divisé par 3 et arrondi au supérieur pour les règles de mana de base.
    • -
    • --accumuleDuree n : l'effet peut être accumulé : chaque fois qu'on applique à nouveau l'effet avec une durée donnée, on ajoute cette durée à la durée courante de l'effet sur la cible. On ne peut cumuler ainsi que n instances de l'effet.
    • -
    • --valeur n : pour certains effet, permet de spécifier une valeur qui remplace la valeur par défaut de l'effet.
    • -
    • --optionEffet opt arg1 arg2 ... : spécifie une option à l'effet. L'option opt doit être donnée sans le -- et sera passée telle quelle à l'effet, par exemple pour les dégâts périodiques. Si on a besoin de plusieurs options, il faut utiliser plusieurs fois --optionEffet.
    • -
    • --secret : le résultat de l'effet est chuchoté au joueur qui lance la commande.
    • -
    • --fx effet : affiche l'effet spécial entre le lanceur et ses cibles. Il est possible d'utiliser un effet que vous avez défini vous-même en utilisant l'option --fx custom nom, où nom est le nom de votre effet.
    • -
    • --targetFx effet : affiche l'effet spécial sur toutes les cibles (l'effet ne doit pas être directionnel).
    • +
    • --tempeteDeMana liste : indique des effets de temp\xEAte de mana. La liste peut contenir un nombre (pour l'effet intense), duree, rapide et portee. Si le rang du sort est sp\xE9cifi\xE9 (par l'option --rang, un message est affich\xE9e si le co\xFBt en mana est sup\xE9rieur au rang. Si la liste d'options est vide, le script affiche un menu dans le chat pour sp\xE9cifier les options de temp\xEAte de mana.
    • +
    • --magieEnArmure : indique d'appliquer les r\xE8gles pour la magie en armure pour un profil hybride. Il faut pour cela un lanceur d\xE9fini. Par defaut, va faire test l'intelligence par un jet de difficult\xE9 10 + rang + malus d'armure. Le rang est obtenu par l'option --rang. J'utilise le malus d'armure car il n'y a pas moyen de distinguer la DEF intrins\xE8que de l'armure de ses bonus de DEF d\xFBs \xE0 un bonus magique. Enfin, on peut utiliser la r\xE8gle de d\xE9pense suppl\xE9mentaire de mana \xE0 la place du jet d'INT en utilisant l'option --magieEnarmure mana. Encore une fois, je prends le malus d'armure, divis\xE9 par 3 et arrondi au sup\xE9rieur pour les r\xE8gles de mana de base.
    • +
    • --accumuleDuree n : l'effet peut \xEAtre accumul\xE9 : chaque fois qu'on applique \xE0 nouveau l'effet avec une dur\xE9e donn\xE9e, on ajoute cette dur\xE9e \xE0 la dur\xE9e courante de l'effet sur la cible. On ne peut cumuler ainsi que n instances de l'effet.
    • +
    • --valeur n : pour certains effet, permet de sp\xE9cifier une valeur qui remplace la valeur par d\xE9faut de l'effet.
    • +
    • --optionEffet opt arg1 arg2 ... : sp\xE9cifie une option \xE0 l'effet. L'option opt doit \xEAtre donn\xE9e sans le -- et sera pass\xE9e telle quelle \xE0 l'effet, par exemple pour les d\xE9g\xE2ts p\xE9riodiques. Si on a besoin de plusieurs options, il faut utiliser plusieurs fois --optionEffet.
    • +
    • --secret : le r\xE9sultat de l'effet est chuchot\xE9 au joueur qui lance la commande.
    • +
    • --fx effet : affiche l'effet sp\xE9cial entre le lanceur et ses cibles. Il est possible d'utiliser un effet que vous avez d\xE9fini vous-m\xEAme en utilisant l'option --fx custom nom, o\xF9 nom est le nom de votre effet.
    • +
    • --targetFx effet : affiche l'effet sp\xE9cial sur toutes les cibles (l'effet ne doit pas \xEAtre directionnel).
    • --son son : joue le son (normalement compatible avec Roll20AM)
    • --image img : affiche l'image dans le texte d'activation de l'effet.
    • -
    • --tokenSide n : utilisable seulement pour les tokens à plusieurs faces. Dans ce cas, va changer la face du token en n (à noter que les faces sont numérotées à partir de 0). Quand l'effet se termine, le token retrouve la face qu'il avait au moment où on avait appliqué l'effet.
    • -
    • --type : il est possible d'associer un type à l'effet. L'utilisation la plus courante est le type poison ou maladie, qui vont permettre de tenir compte des bonus ou immunités contre les effets de ce type.
    • -
    • --montreActions : affiche les actions du tours de la cible après avoir appliqué l'effet. Utile si les actions du tours dépendent de cet effet, pour afficher une liste à jour.
    • -
    • --degainer L : le lanceur dégaine l'arme de label L.
    • +
    • --tokenSide n : utilisable seulement pour les tokens \xE0 plusieurs faces. Dans ce cas, va changer la face du token en n (\xE0 noter que les faces sont num\xE9rot\xE9es \xE0 partir de 0). Quand l'effet se termine, le token retrouve la face qu'il avait au moment o\xF9 on avait appliqu\xE9 l'effet.
    • +
    • --type : il est possible d'associer un type \xE0 l'effet. L'utilisation la plus courante est le type poison ou maladie, qui vont permettre de tenir compte des bonus ou immunit\xE9s contre les effets de ce type.
    • +
    • --montreActions : affiche les actions du tours de la cible apr\xE8s avoir appliqu\xE9 l'effet. Utile si les actions du tours d\xE9pendent de cet effet, pour afficher une liste \xE0 jour.
    • +
    • --degainer L : le lanceur d\xE9gaine l'arme de label L.
    -

    !cof-boire-alcool et !cof-desaouler permettent de faire varier le niveau d'ébriété. Par exemple, pour tester si le niveau d'ébriété augmente après avoir bu un certain nombre de verres, on peut utiliser la macro !cof-boire-alcool --save CON [[10+?{Nombre de verres}]]. +

    !cof-boire-alcool et !cof-desaouler permettent de faire varier le niveau d'\xE9bri\xE9t\xE9. Par exemple, pour tester si le niveau d'\xE9bri\xE9t\xE9 augmente apr\xE8s avoir bu un certain nombre de verres, on peut utiliser la macro !cof-boire-alcool --save CON [[10+?{Nombre de verres}]].

    -

    Effets retardés

    +

    Effets retard\xE9s

    -

    On peut utiliser l'effet temporaire générique messageRetarde(nom) pour programmer un message qui sera affiché après un certain nombre de tours. Au bout de ce nombre de tours, le nom est affiché, ainsi que le texte de valeur (avec --valeur si besoin). La syntaxe est !cof-effet-temp messageRetarde(nom) duree --valeur message. Si vous avez besoin d'un message qui contienne des espaces, remplacez les espaces par des _.

    -

    On peut aussi déclencher un effet après un certain nombre de tour avec l'effet temporaire générique effetRetarde(effet). Après la durée de l'effet retardé, si effet est un état, la cible est mise dans cet état, si c'est un effet temporaire, on lui applique cet effet pour une durée de 1 tour, ou si un argument --valeur a été donné, il sera utilisé comme durée. Enfin si ce n'est ni l'un ni l'autre, un attribut avec le nom effet sera créé, de valeur courante true, ou bien si un argument --valeur a été donné, cette valeur sera utilisée comme valeur courante de l'attribut effet.

    +

    On peut utiliser l'effet temporaire g\xE9n\xE9rique messageRetarde(nom) pour programmer un message qui sera affich\xE9 apr\xE8s un certain nombre de tours. Au bout de ce nombre de tours, le nom est affich\xE9, ainsi que le texte de valeur (avec --valeur si besoin). La syntaxe est !cof-effet-temp messageRetarde(nom) duree --valeur message. Si vous avez besoin d'un message qui contienne des espaces, remplacez les espaces par des _.

    +

    On peut aussi d\xE9clencher un effet apr\xE8s un certain nombre de tour avec l'effet temporaire g\xE9n\xE9rique effetRetarde(effet). Apr\xE8s la dur\xE9e de l'effet retard\xE9, si effet est un \xE9tat, la cible est mise dans cet \xE9tat, si c'est un effet temporaire, on lui applique cet effet pour une dur\xE9e de 1 tour, ou si un argument --valeur a \xE9t\xE9 donn\xE9, il sera utilis\xE9 comme dur\xE9e. Enfin si ce n'est ni l'un ni l'autre, un attribut avec le nom effet sera cr\xE9\xE9, de valeur courante true, ou bien si un argument --valeur a \xE9t\xE9 donn\xE9, cette valeur sera utilis\xE9e comme valeur courante de l'attribut effet.

    -

    Prédicats : !cof-set-predicate

    +

    Pr\xE9dicats : !cof-set-predicate

    -

    Il est possible d'ajouter ou de retirer un prédicat avec la fonction !cof-set-predicate nom, optionellement suivi de true ou false.

    +

    Il est possible d'ajouter ou de retirer un pr\xE9dicat avec la fonction !cof-set-predicate nom, optionellement suivi de true ou false.

    Autres attributs : !cof-set-attribute

    - Il est possible de changer ou créer n'importe quel attribut avec la fonction !cof-set-attribute nom val. Optionellement, on peut spécifier en troisième argument une valeur maximale de l'attribut (comme dans !cof-set-attribute nom val max). Attention, ça peut interragir de façon imprévue avec le script ou la fiche, si on écrit dans un attribut utilisé par la fiche. + Il est possible de changer ou cr\xE9er n'importe quel attribut avec la fonction !cof-set-attribute nom val. Optionellement, on peut sp\xE9cifier en troisi\xE8me argument une valeur maximale de l'attribut (comme dans !cof-set-attribute nom val max). Attention, \xE7a peut interragir de fa\xE7on impr\xE9vue avec le script ou la fiche, si on \xE9crit dans un attribut utilis\xE9 par la fiche.

    2.5 Sorts

    -

    !cof-attaque-magique @{selected|token_id} @{target|token_id} : fait un jet d'attaque magique opposé entre le lanceur et sa cible, et dit juste si le sort est raté ou réussi. Options disponibles : --portee et --mana.

    -

    !cof-lancer-sort texte : le token sélectionné lance un sort sans support particulier du script (seul un whisper est envoyé au joueur et au MJ). Options disponibles : --manapour indiquer un coût en mana et --son pour jouer un son. Pour un sort sur plusieurs cibles, utiliser l'option --lanceur @{selected|token_id}.

    -

    !cof-peur difficulté durée : effet de peur (nécromant, dragon, etc). Tant que la peur est active, statut screaming. difficulté est la difficulté du jet de SAG.

    +

    !cof-attaque-magique @{selected|token_id} @{target|token_id} : fait un jet d'attaque magique oppos\xE9 entre le lanceur et sa cible, et dit juste si le sort est rat\xE9 ou r\xE9ussi. Options disponibles : --portee et --mana.

    +

    !cof-lancer-sort texte : le token s\xE9lectionn\xE9 lance un sort sans support particulier du script (seul un whisper est envoy\xE9 au joueur et au MJ). Options disponibles : --manapour indiquer un co\xFBt en mana et --son pour jouer un son. Pour un sort sur plusieurs cibles, utiliser l'option --lanceur @{selected|token_id}.

    +

    !cof-peur difficult\xE9 dur\xE9e : effet de peur (n\xE9cromant, dragon, etc). Tant que la peur est active, statut screaming. difficult\xE9 est la difficult\xE9 du jet de SAG.

    Options :
      -
    • --resisteAvecForce : on prend le max de FOR et SAG pour résister
    • -
    • --etourdi : la peur fait fuir ou rend étourdi
    • +
    • --resisteAvecForce : on prend le max de FOR et SAG pour r\xE9sister
    • +
    • --etourdi : la peur fait fuir ou rend \xE9tourdi
    • --ralenti : la peur ralenti
    • -
    • --secoue : la peur ne donne qu'un malus de -2 aux tests. Mais un autre effet de peur de même type fait fuir.
    • +
    • --paralyse : la peur paralyse
    • +
    • --secoue : la peur ne donne qu'un malus de -2 aux tests. Mais un autre effet de peur de m\xEAme type fait fuir.
    • --effroi : la peur est passive (pas un sort)
    • -
    • --portee n : limite la portée du sort à n metres.
    • -
    • --lanceur id : le lanceur de l'effet de peur (si il y en a un). Nécessaire pour la portée, par exemple.
    • -
    • --titre message : spécifie un titre pour la fenêtre affichant les jets de résistance à la peur.
    • -
    • --immuniseSiResiste nom : la personne qui résiste à cet effet de peur est ensuite immunisé pour la journée aux effets de peur ayant la même option (avec le même nom).
    • +
    • --portee n : limite la port\xE9e du sort \xE0 n metres.
    • +
    • --lanceur id : le lanceur de l'effet de peur (si il y en a un). N\xE9cessaire pour la port\xE9e, par exemple.
    • +
    • --titre message : sp\xE9cifie un titre pour la fen\xEAtre affichant les jets de r\xE9sistance \xE0 la peur.
    • +
    • --immuniseSiResiste nom : la personne qui r\xE9siste \xE0 cet effet de peur est ensuite immunis\xE9 pour la journ\xE9e aux effets de peur ayant la m\xEAme option (avec le m\xEAme nom).
    - Noter qu'un prédicat courage permet d'obtenir un bonus (égal à la valeur du prédicat) au jet pour résister à la peur. + Noter qu'un pr\xE9dicat courage permet d'obtenir un bonus (\xE9gal \xE0 la valeur du pr\xE9dicat) au jet pour r\xE9sister \xE0 la peur.

    2.6 Consommables !cof-consommables

    -

    Cette fonction affiche une liste de consommables, avec la possibilité de cliquer sur un élément de la liste pour le consommer (et activer son effet) ou l'échanger avec un autre personnage (via le symbole d'échange).

    -

    Pour cela, la fonction utilise la liste des consommables sur la fiche (onglet "Équipement"). Elle ne va afficher que les consommables qui ont un effet (décrit dans la ligne Effet sous le nom du consommable).

    +

    Cette fonction affiche une liste de consommables, avec la possibilit\xE9 de cliquer sur un \xE9l\xE9ment de la liste pour le consommer (et activer son effet) ou l'\xE9changer avec un autre personnage (via le symbole d'\xE9change).

    +

    Pour cela, la fonction utilise la liste des consommables sur la fiche (onglet "\xC9quipement"). Elle ne va afficher que les consommables qui ont un effet (d\xE9crit dans la ligne Effet sous le nom du consommable).

    Exemple d'une liste de consommable.
    - +

    Pour l'instant, seules les commandes !cof-effet-temp, !cof-effet-combat, !cof-effet, !cof-enduire-poison, !cof-attack, !cof-lancer-sort et !cof-soin diminuent correctement le nombre de consommables.

    Attention :

      -
    • Pour la commande !cof-attack, il est vivemement recommandé de ne pas utiliser de label, mais uniquement un nom et des options si vous voulez faciliter l'échange du consommable.
    • -
    • De manière générale, faites attention avec les références utilisé dans le consommable du personnage qui utilise le consommable.
      +
    • Pour la commande !cof-attack, il est vivemement recommand\xE9 de ne pas utiliser de label, mais uniquement un nom et des options si vous voulez faciliter l'\xE9change du consommable.
    • +
    • De mani\xE8re g\xE9n\xE9rale, faites attention avec les r\xE9f\xE9rences utilis\xE9 dans le consommable du personnage qui utilise le consommable.
    -

    L'échange via le symbole vous permettra de sélectionner un token destinataire qui recevra le consommable dans sa liste. Si le consommable existe déjà pour le destinataire, sa quantité sera augmenté de 1, sinon le consommable sera créé.

    +

    L'\xE9change via le symbole vous permettra de s\xE9lectionner un token destinataire qui recevra le consommable dans sa liste. Si le consommable existe d\xE9j\xE0 pour le destinataire, sa quantit\xE9 sera augment\xE9 de 1, sinon le consommable sera cr\xE9\xE9.

    -

    Cette fonction peut-être très utile pour que les PJ échangent entre eux un consommable, mais aussi pour faciliter la vente d'objet entre PNJ et PJ.

    -

    Pour cette dernière, il vous suffira de préparer un personnage avec un token qui contient, dans son équipement, les consommables à échanger/vendre.

    +

    Cette fonction peut-\xEAtre tr\xE8s utile pour que les PJ \xE9changent entre eux un consommable, mais aussi pour faciliter la vente d'objet entre PNJ et PJ.

    +

    Pour cette derni\xE8re, il vous suffira de pr\xE9parer un personnage avec un token qui contient, dans son \xE9quipement, les consommables \xE0 \xE9changer/vendre.

    -

    2.7 Déplacements

    +

    2.7 D\xE9placements

    Retrouver un personnage

    -

    Pour centrer la vue d'un joueur sur un token particulier, on peut utiliser !cof-centrer-sur-token suivi du nom du token. Généralement, c'est une bonne idée pour un joueur d'avoir une macro avec le nom de son token pour le retrouver facilement quand il arrive sur une nouvelle carte.

    +

    Pour centrer la vue d'un joueur sur un token particulier, on peut utiliser !cof-centrer-sur-token suivi du nom du token. G\xE9n\xE9ralement, c'est une bonne id\xE9e pour un joueur d'avoir une macro avec le nom de son token pour le retrouver facilement quand il arrive sur une nouvelle carte.

    -

    Personnages immobilisés

    +

    Personnages immobilis\xE9s

    -

    Le script bloque automatiquement personnages immobilisés (paralysé, étourdi, etc...). Pour permettre de déplacer ces personnages vous pouvez simplement enlever le blockage (click droit sur le token, propriétés avancées). Si vous souhaitez être le seul à pouvoir le bouger, sélectionner le (ou les) token et cliquer sur la macro Bouger. Cela crée un token non bloqué associé au personnage. Bien penser à supprimer ce token après utilisation.

    +

    Le script bloque automatiquement personnages immobilis\xE9s (paralys\xE9, \xE9tourdi, etc...). Pour permettre de d\xE9placer ces personnages vous pouvez simplement enlever le blockage (click droit sur le token, propri\xE9t\xE9s avanc\xE9es). Si vous souhaitez \xEAtre le seul \xE0 pouvoir le bouger, s\xE9lectionner le (ou les) token et cliquer sur la macro Bouger. Cela cr\xE9e un token non bloqu\xE9 associ\xE9 au personnage. Bien penser \xE0 supprimer ce token apr\xE8s utilisation.

    Il est possible de mettre le jeu en pause (les joueurs ne peuvent plus bouger leurs tokens) en utilisant la macro ⏸. La macro change alors de nom et devient ⏵, que vous pouvez utiliser pour enlever la pause.

    Escaliers

    -

    Pour gérer les escaliers sur les cartes, vous pouvez utiliser la méthode suivante, inspirée du script Teleport : placez dans le layer "GM Info Overlay", au niveau des escaliers, des tokens qui prennent exactement la place des escaliers. Nommez ces escaliers avec un nom, suivi d'une lettre majuscule. Par exemple EscalierA.

    -

    Chaque escalier de la même colonne doit avoir le même nom, et différer seulement par la lettre finale. Ensuite, si un ensemble de tokens est sur un escalier, utilisez !cof-escalier pour téléporter les tokens à l'emplacement de l'escalier suivant dans l'ordre des lettres. Si vous utilisez l'argument haut, alors les tokens n'iront pas plus loin que le dernier étage, et avec l'argument bas, il iront dans l'ordre inverse.

    -

    Dans l'exemple précédent, il serait téléporté à l'emplacement du token nommé EscalierB. Cela ne fonctionne que si les bouts de l'escalier sont sur la même carte. À vous de choisir sir vous préférez révéler cette fonctionalité à vos joueurs, ou si vous le faites vous-même.

    -

    La limite au nombre d'escaliers est de 12 étages, donc pas de lettre après L.

    -

    Il est possible d'avoir des escaliers qui mènent à d'autres cartes (ce qui fait alors changer la carte vue par le joueur). Il suffit que le nom de l'escalier commence par tmap_. Attention, à cause de limitations de Roll20, cela ne peut fonctionner que si l'image du token est dans une lirary personnelle d'un joueur : si elle vient du marketplace, il fait d'abord la copier dans sa library, puis utiliser l'image qui est dans la library pour le token.

    +

    Pour g\xE9rer les escaliers sur les cartes, vous pouvez utiliser la m\xE9thode suivante, inspir\xE9e du script Teleport : placez dans le layer "GM Info Overlay", au niveau des escaliers, des tokens qui prennent exactement la place des escaliers. Nommez ces escaliers avec un nom, suivi d'une lettre majuscule. Par exemple EscalierA.

    +

    Chaque escalier de la m\xEAme colonne doit avoir le m\xEAme nom, et diff\xE9rer seulement par la lettre finale. Ensuite, si un ensemble de tokens est sur un escalier, utilisez !cof-escalier pour t\xE9l\xE9porter les tokens \xE0 l'emplacement de l'escalier suivant dans l'ordre des lettres. Si vous utilisez l'argument haut, alors les tokens n'iront pas plus loin que le dernier \xE9tage, et avec l'argument bas, il iront dans l'ordre inverse.

    +

    Dans l'exemple pr\xE9c\xE9dent, il serait t\xE9l\xE9port\xE9 \xE0 l'emplacement du token nomm\xE9 EscalierB. Cela ne fonctionne que si les bouts de l'escalier sont sur la m\xEAme carte. \xC0 vous de choisir sir vous pr\xE9f\xE9rez r\xE9v\xE9ler cette fonctionalit\xE9 \xE0 vos joueurs, ou si vous le faites vous-m\xEAme.

    +

    La limite au nombre d'escaliers est de 12 \xE9tages, donc pas de lettre apr\xE8s L.

    +

    Il est possible d'avoir des escaliers qui m\xE8nent \xE0 d'autres cartes (ce qui fait alors changer la carte vue par le joueur). Il suffit que le nom de l'escalier commence par tmap_. Attention, \xE0 cause de limitations de Roll20, cela ne peut fonctionner que si l'image du token est dans une lirary personnelle d'un joueur : si elle vient du marketplace, il fait d'abord la copier dans sa library, puis utiliser l'image qui est dans la library pour le token.

    Montures

    -

    Pour qu'un personnage puisse monter sur une monture, il faut que cette monture soit associée à une fiche de personnage et qu'il possède un prédicat monture. La commande pour monter sur la monture est !cof-en-selle @{selected|token_id} @{target|token_id}, à lancer en sélectionnant le cavalier.

    -

    On peut ensuite bouger la monture, cela déplace le cavalier. Le mieux est de lancer la commander alors que le token du cavalier est sur le token de la monture. Si on déplace le cavalier, cela fait aussi bouger sa monture.

    +

    Pour qu'un personnage puisse monter sur une monture, il faut que cette monture soit associ\xE9e \xE0 une fiche de personnage et qu'il poss\xE8de un pr\xE9dicat monture. La commande pour monter sur la monture est !cof-en-selle @{selected|token_id} @{target|token_id}, \xE0 lancer en s\xE9lectionnant le cavalier.

    +

    On peut ensuite bouger la monture, cela d\xE9place le cavalier. Le mieux est de lancer la commander alors que le token du cavalier est sur le token de la monture. Si on d\xE9place le cavalier, cela fait aussi bouger sa monture.

    Suivre un autre personnages

    - Le principe est le suivant : on sélectionne un token, dans les abilities qui s'affichent en haut de la map, on clique sur Suivre, puis on sélectionne le token à suivre. À partir de ce moment, le script déplace le premier token à chaque fois qu'on déplace le second (en tenant compte des états qui empêchent le mouvement et des obstacles sur le layer de lumière, si ils doivent empêcher le mouvement). On peut aussi suivre un token qui en suit un autre. Et pour arrêter de suivre un token, il suffit de déplacer manuellement le premier token. + Le principe est le suivant : on s\xE9lectionne un token, dans les abilities qui s'affichent en haut de la map, on clique sur Suivre, puis on s\xE9lectionne le token \xE0 suivre. \xC0 partir de ce moment, le script d\xE9place le premier token \xE0 chaque fois qu'on d\xE9place le second (en tenant compte des \xE9tats qui emp\xEAchent le mouvement et des obstacles sur le layer de lumi\xE8re, si ils doivent emp\xEAcher le mouvement). On peut aussi suivre un token qui en suit un autre. Et pour arr\xEAter de suivre un token, il suffit de d\xE9placer manuellement le premier token. - Ça permet donc d'avoir un familier qui suit un personnage, ou bien de faire automatiquement bouger un groupe de perosnnage dont l'ordre de marche est déterminé. + Ça permet donc d'avoir un familier qui suit un personnage, ou bien de faire automatiquement bouger un groupe de perosnnage dont l'ordre de marche est d\xE9termin\xE9.
    -

    Déplacer un personnage sur plusieurs cartes

    +

    D\xE9placer un personnage sur plusieurs cartes

    -

    Il est possible de synchroniser des tokens de même nom (représentant le même personnage) sur plusieurs cartes. Ainsi, déplacer le token sur une carte déplace aussi les token sur les autres cartes. Cela peut servir par exemple si tous les joueurs ne doivent pas voir la même chose sur une carte : chaque joueur est alors sur la carte qui lui montre ce qu'il doit voir, et tous les tokens des joueurs sont synchronisés entre les cartes.

    -

    La commande pour activer la synchonisation d'un (ou plusieurs) tokens séléctionnés est !cof-multi-cartes. Pour mettre fin à la synchronisation, on peut sélectionner ces tokens et faire !cof-multi-cartes false. Enfin, cette même commande sans selectionner aucun token met fin à toutes les synchronisations.

    +

    Il est possible de synchroniser des tokens de m\xEAme nom (repr\xE9sentant le m\xEAme personnage) sur plusieurs cartes. Ainsi, d\xE9placer le token sur une carte d\xE9place aussi les token sur les autres cartes. Cela peut servir par exemple si tous les joueurs ne doivent pas voir la m\xEAme chose sur une carte : chaque joueur est alors sur la carte qui lui montre ce qu'il doit voir, et tous les tokens des joueurs sont synchronis\xE9s entre les cartes.

    +

    La commande pour activer la synchonisation d'un (ou plusieurs) tokens s\xE9l\xE9ctionn\xE9s est !cof-multi-cartes. Pour mettre fin \xE0 la synchronisation, on peut s\xE9lectionner ces tokens et faire !cof-multi-cartes false. Enfin, cette m\xEAme commande sans selectionner aucun token met fin \xE0 toutes les synchronisations.

    -

    2.8 Lumière

    +

    2.8 Lumi\xE8re

    -

    Pour faire de la lumière, on peut utiliser !cof-lumiere token_id portee. Cela va faire en sorte que le token fasse de la lumière jusqu'à portee mètres. Il est possible d'avoir plusieurs sources de lumière, et la commande est compatible avec la vision dans le noir. La commande admet un troisième argument qui est la distance à laquelle la lumière devient moins brillante, et un quatrième argument qui est le nom du type de lumière (par défaut, lumiere), utilisé quand on éteint les lumières.

    -

    Pour éteindre des lumières, utiliser !cof-eteindre-lumiere en sélectionnant le ou les tokens désirés. Il est possible de prendre un argument optionnel qui est le nom du groupe de lumières que l'on souhaite éteindre. Par exemple, on peut ainsi éteindre toutes les torches et laisser les effets de lumière magique actifs.

    -

    Pour les torches, le script propose d'automatiser la gestion en utilisant la commande !cof-torche token_id. Si le token tient une torche allumée, cela éteint la torche (et propose au MJ d'indiquer combien de temps la torche est restée allumée), et sinon, si le token possède des torches, cela allume une torche. Le nombre de torche et leur état est stocké dans un attribut torches, dont la valeur courante contient le nombre de torches dans l'inventaire, et la valeur max le temps restant pour la torche en cours d'utilisation (60 minutes pour une torche neuve). Si aucun attribut de ce nom n'existe, le script se contente d'allumer ou d'éteindre une torche, sans gérer leur nombre.

    -

    Pour les armes qui font de la lumière, on peut préciser un prédicat eclaire dans le champ de prédicats de l'arme. La valeur du prédicat doit être la distance à laquelle l'arme éclaire. On peut préciser dans un prédicat eclaireFaible (toujours dans le champ de l'arme) le début de la lumière faible, si besoin. Ça peut aussi être une façon de gérer les torches.

    -

    Quand les personnages sont dans le brouillard, je mets la carte sans lumière, et je sélectionne les tokens et lance la commande !cof-vision-nocturne 6 pour qu'ils voient à 6 m.

    +

    Pour faire de la lumi\xE8re, on peut utiliser !cof-lumiere token_id portee. Cela va faire en sorte que le token fasse de la lumi\xE8re jusqu'\xE0 portee m\xE8tres. Il est possible d'avoir plusieurs sources de lumi\xE8re, et la commande est compatible avec la vision dans le noir. La commande admet un troisi\xE8me argument qui est la distance \xE0 laquelle la lumi\xE8re devient moins brillante, et un quatri\xE8me argument qui est le nom du type de lumi\xE8re (par d\xE9faut, lumiere), utilis\xE9 quand on \xE9teint les lumi\xE8res.

    +

    Pour \xE9teindre des lumi\xE8res, utiliser !cof-eteindre-lumiere en s\xE9lectionnant le ou les tokens d\xE9sir\xE9s. Il est possible de prendre un argument optionnel qui est le nom du groupe de lumi\xE8res que l'on souhaite \xE9teindre. Par exemple, on peut ainsi \xE9teindre toutes les torches et laisser les effets de lumi\xE8re magique actifs.

    +

    Pour les torches, le script propose d'automatiser la gestion en utilisant la commande !cof-torche token_id. Si le token tient une torche allum\xE9e, cela \xE9teint la torche (et propose au MJ d'indiquer combien de temps la torche est rest\xE9e allum\xE9e), et sinon, si le token poss\xE8de des torches, cela allume une torche. Le nombre de torche et leur \xE9tat est stock\xE9 dans un attribut torches, dont la valeur courante contient le nombre de torches dans l'inventaire, et la valeur max le temps restant pour la torche en cours d'utilisation (60 minutes pour une torche neuve). Si aucun attribut de ce nom n'existe, le script se contente d'allumer ou d'\xE9teindre une torche, sans g\xE9rer leur nombre.

    +

    Pour les armes qui font de la lumi\xE8re, on peut pr\xE9ciser un pr\xE9dicat eclaire dans le champ de pr\xE9dicats de l'arme. La valeur du pr\xE9dicat doit \xEAtre la distance \xE0 laquelle l'arme \xE9claire. On peut pr\xE9ciser dans un pr\xE9dicat eclaireFaible (toujours dans le champ de l'arme) le d\xE9but de la lumi\xE8re faible, si besoin. Ça peut aussi \xEAtre une fa\xE7on de g\xE9rer les torches.

    +

    Quand les personnages sont dans le brouillard, je mets la carte sans lumi\xE8re, et je s\xE9lectionne les tokens et lance la commande !cof-vision-nocturne 6 pour qu'ils voient \xE0 6 m.

    -

    2.9 Jet de caractéristiques

    +

    2.9 Jet de caract\xE9ristiques

    -

    !cof-jet ?{Faire un jet de |Charisme, CHA|Constitution, CON|Dextérité, DEX|Force, FOR|Intelligence, INT|Sagesse, SAG} : fait un simple jet pour la caractérisique sélectionnée.

    -

    Il est aussi possible de donner en argument une difficulté au jet. Par exemple en faisant !cof-jet INT ?{difficulté}.

    -

    Si on ne donne aucun argument (en dehors des options), la commande demande de préciser la caractéristique à tester. Pour chaque caractéristique, le script va proposer d'utiliser une des compétences définies sur la fiche (liste sous les capacités). Si il existe un handout nommé Compétences, celui-ci sera aussi utilisé pour proposer pour chaque caractéristique un choix de compétences à tester. Le handout doit contenir dans ses notes des lignes commençant par une caractéristique (FOR, DEX, ...), suivi de :, puis des noms de compétences, séparés par des blancs, des retours à la ligne, des virgules ou des /.

    +

    !cof-jet ?{Faire un jet de |Charisme, CHA|Constitution, CON|Dext\xE9rit\xE9, DEX|Force, FOR|Intelligence, INT|Sagesse, SAG} : fait un simple jet pour la caract\xE9risique s\xE9lectionn\xE9e.

    +

    Il est aussi possible de donner en argument une difficult\xE9 au jet. Par exemple en faisant !cof-jet INT ?{difficult\xE9}.

    +

    Si on ne donne aucun argument (en dehors des options), la commande demande de pr\xE9ciser la caract\xE9ristique \xE0 tester. Pour chaque caract\xE9ristique, le script va proposer d'utiliser une des comp\xE9tences d\xE9finies sur la fiche (liste sous les capacit\xE9s). Si il existe un handout nomm\xE9 Comp\xE9tences, celui-ci sera aussi utilis\xE9 pour proposer pour chaque caract\xE9ristique un choix de comp\xE9tences \xE0 tester. Le handout doit contenir dans ses notes des lignes commen\xE7ant par une caract\xE9ristique (FOR, DEX, ...), suivi de :, puis des noms de comp\xE9tences, s\xE9par\xE9s par des blancs, des retours \xE0 la ligne, des virgules ou des /.

    La fonction accepte les arguments suivants:

      -
    • --bonus pour spécifier un bonus numérique au jet.
    • -
    • --attribut pour spécifier un attribut dont la valeur doit être ajoutée au jet. Il est possible de spécifier plusieurs attributs, comme par exemple --attribut perception --attribut vigilance pour un jet de vigilance.
    • -
    • --predicat pour spécifier un prédicat dont la valeur doit être ajoutée au jet. Il est possible de spécifier plusieurs pédicats.
    • -
    • --nom précise le nom du jet à afficher. De plus, cela va aussi faire rechercher une compétence de même nom (sans tenir compte des majuscules) pour une fiche de PJ et un attribut ou un prédicat pour une fiche de PNJ. Par exemple !cof-jet DEX --nom Discrétion va lancer un jet de DEX, qui sera affiché comme un jet de Discrétion, et qui va ajouter au jet le bonus d'une compétence discrétion ou d'un éventuel prédicat discrétion.
    • -
    • --secret : le jet n'est visible que par les personnes qui contrôlent le personnage, plus le MJ. Si la personne qui a lancé la commande est MJ, il sera le seul à voir le résultat.
    • -
    • --competences : si la commande n'a pas déjà d'option --nom, invite l'utilisateur à choisir une compétence parmis une liste correspondant à la caractéristique (incluant celles provenant du handout Compétences tel que défini plus haut).
    • -
    • --plageEchecCritique c : permet de considérer tout jet de dé inférieur ou égal à c comme un échec critique.
    • +
    • --bonus pour sp\xE9cifier un bonus num\xE9rique au jet.
    • +
    • --attribut pour sp\xE9cifier un attribut dont la valeur doit \xEAtre ajout\xE9e au jet. Il est possible de sp\xE9cifier plusieurs attributs, comme par exemple --attribut perception --attribut vigilance pour un jet de vigilance.
    • +
    • --predicat pour sp\xE9cifier un pr\xE9dicat dont la valeur doit \xEAtre ajout\xE9e au jet. Il est possible de sp\xE9cifier plusieurs p\xE9dicats.
    • +
    • --nom pr\xE9cise le nom du jet \xE0 afficher. De plus, cela va aussi faire rechercher une comp\xE9tence de m\xEAme nom (sans tenir compte des majuscules) pour une fiche de PJ et un attribut ou un pr\xE9dicat pour une fiche de PNJ. Par exemple !cof-jet DEX --nom Discr\xE9tion va lancer un jet de DEX, qui sera affich\xE9 comme un jet de Discr\xE9tion, et qui va ajouter au jet le bonus d'une comp\xE9tence discr\xE9tion ou d'un \xE9ventuel pr\xE9dicat discr\xE9tion.
    • +
    • --secret : le jet n'est visible que par les personnes qui contr\xF4lent le personnage, plus le MJ. Si la personne qui a lanc\xE9 la commande est MJ, il sera le seul \xE0 voir le r\xE9sultat.
    • +
    • --competences : si la commande n'a pas d\xE9j\xE0 d'option --nom, invite l'utilisateur \xE0 choisir une comp\xE9tence parmis une liste correspondant \xE0 la caract\xE9ristique (incluant celles provenant du handout Comp\xE9tences tel que d\xE9fini plus haut).
    • +
    • --plageEchecCritique c : permet de consid\xE9rer tout jet de d\xE9 inf\xE9rieur ou \xE9gal \xE0 c comme un \xE9chec critique.
    • +
    • --succes message : affiche message en cas de succ\xE8s au jet. N'a pas d'effet si la difficult\xE9 du jet n'est pas d\xE9finie.
    -

    Si le personnage possède un attribut numérique modificateurTests, ce modificateur sera pris en compte pour tous les tests.

    -

    Dans les options de jeu (affichés en utilisant !cof-options, dans le menu des options d'affichage, il est possible de choisir de ne faire afficher les résultats qu'au MJ, qui peut alors en cliquant sur un bouton le montrer aux joueurs (ou pas).

    +

    Si le personnage poss\xE8de un attribut num\xE9rique modificateurTests, ce modificateur sera pris en compte pour tous les tests.

    +

    Dans les options de jeu (affich\xE9s en utilisant !cof-options, dans le menu des options d'affichage, il est possible de choisir de ne faire afficher les r\xE9sultats qu'au MJ, qui peut alors en cliquant sur un bouton le montrer aux joueurs (ou pas).

    -

    2.10 Anonymat et fausses identités

    +

    2.10 Anonymat et fausses identit\xE9s

    -

    La fiche de personnage propose deux noms par personnage : le nom principal (appelé simplement "nom") et un alias. Le nom principal est celui visible dans la liste des personnages de l'interface Roll20. C'est aussi celui qui est montré quand on montre une fiche aux joueurs. La fiche propose de choisir le nom affiché lors des jets (champ "connu") : soit le nom principal, soit l'alias. Le script part toujours de l'hypothèse que c'est ce nom qui est connu des joueurs, et que le second est le "vrai" nom. Je laisse le choix au MJ de décider lequel est quoi, car les deux méthodes ont leurs avantages et leurs inconvénients : si on choisit d'avoir l'alias en nom caché, on peut montrer la fiche aux joueurs, sans dévoiler le vrai nom. En revanche, dans la liste des personnages, il peut être plus difficile de s'y retrouver, car le MJ ne verra pas le vrai nom. Si on choisit d'avoir le vrai nom caché, tout est bien clair pour le MJ, mais il doit faire attention à ne pas montrer la fiche aux joueurs.

    +

    La fiche de personnage propose deux noms par personnage : le nom principal (appel\xE9 simplement "nom") et un alias. Le nom principal est celui visible dans la liste des personnages de l'interface Roll20. C'est aussi celui qui est montr\xE9 quand on montre une fiche aux joueurs. La fiche propose de choisir le nom affich\xE9 lors des jets (champ "connu") : soit le nom principal, soit l'alias. Le script part toujours de l'hypoth\xE8se que c'est ce nom qui est connu des joueurs, et que le second est le "vrai" nom. Je laisse le choix au MJ de d\xE9cider lequel est quoi, car les deux m\xE9thodes ont leurs avantages et leurs inconv\xE9nients : si on choisit d'avoir l'alias en nom cach\xE9, on peut montrer la fiche aux joueurs, sans d\xE9voiler le vrai nom. En revanche, dans la liste des personnages, il peut \xEAtre plus difficile de s'y retrouver, car le MJ ne verra pas le vrai nom. Si on choisit d'avoir le vrai nom cach\xE9, tout est bien clair pour le MJ, mais il doit faire attention \xE0 ne pas montrer la fiche aux joueurs.

    Concernant les tokens, le script suppose que vous mettez en "connu" le nom visible par les joueurs.

    -

    Révéler le vrai nom d'un personnage

    +

    R\xE9v\xE9ler le vrai nom d'un personnage

    -

    Pour révéler le vrai nom d'un personnage au joueurs, vous pourrez utiliser !cof-reveler-nom. L'effet s'applique à tous les personnages sélectionnés (voir les méthodes de sélection). L'effet est le suivant :

    +

    Pour r\xE9v\xE9ler le vrai nom d'un personnage au joueurs, vous pourrez utiliser !cof-reveler-nom. L'effet s'applique \xE0 tous les personnages s\xE9lectionn\xE9s (voir les m\xE9thodes de s\xE9lection). L'effet est le suivant :

      -
    • Si le personnage était connu par son nom, et que l'alias était non vide, alors on copie l'alias à la place du nom, et on efface l'alias.
    • -
    • Si le personnage était connu par son alias, alors on le passe en connu par son nom et on efface l'alias.
    • -
    • Si on a fait un des deux changements ci-dessus, alors on change aussi les noms des tokens : si on a passé un nom en argument à !cof-reveler-nom, alors on utilise ce nom. Sinon, on utilise le nouveau nom public. Tous les tokens liés prennent ce nom, et tous les tokens non liés gardent leur numéro et changent juste la partie avant le numéro en ce nom. On n'applique cette transformation qu'aux tokens dont les noms n'ont pas été modifiés (par rapport au token par défaut défini sur la fiche).
    • -
    • Et on change aussi le nom du token par défaut.
    • +
    • Si le personnage \xE9tait connu par son nom, et que l'alias \xE9tait non vide, alors on copie l'alias \xE0 la place du nom, et on efface l'alias.
    • +
    • Si le personnage \xE9tait connu par son alias, alors on le passe en connu par son nom et on efface l'alias.
    • +
    • Si on a fait un des deux changements ci-dessus, alors on change aussi les noms des tokens : si on a pass\xE9 un nom en argument \xE0 !cof-reveler-nom, alors on utilise ce nom. Sinon, on utilise le nouveau nom public. Tous les tokens li\xE9s prennent ce nom, et tous les tokens non li\xE9s gardent leur num\xE9ro et changent juste la partie avant le num\xE9ro en ce nom. On n'applique cette transformation qu'aux tokens dont les noms n'ont pas \xE9t\xE9 modifi\xE9s (par rapport au token par d\xE9faut d\xE9fini sur la fiche).
    • +
    • Et on change aussi le nom du token par d\xE9faut.

    2.11 Autres aspects du jeu

    Annuler une action : !cof-undo

    -

    Fait partie des fonctions que je met en macro dans la barre du MJ, ça peut servir très souvent. Elle est d'ailleurs générée par la commande !cof-set-macros.

    +

    Fait partie des fonctions que je met en macro dans la barre du MJ, \xE7a peut servir tr\xE8s souvent. Elle est d'ailleurs g\xE9n\xE9r\xE9e par la commande !cof-set-macros.

    Chance

    -

    Le script essaie de détecter les cas où un point de chance peut être utile, et dans ce cas fournit un bouton (utilisable par les joueurs contrôlant le perosnnage ou le GM), permettant de dépenser un point de chance. Attention, pour l'instant, il n'est pas possible de faire juste un undo de la dépense de point de chnce. Le undo après la dépense de point de chance annule toute l'action. Il faut ensuite faire un undo par point de chance dépensé.

    +

    Le script essaie de d\xE9tecter les cas o\xF9 un point de chance peut \xEAtre utile, et dans ce cas fournit un bouton (utilisable par les joueurs contr\xF4lant le perosnnage ou le GM), permettant de d\xE9penser un point de chance. Attention, pour l'instant, il n'est pas possible de faire juste un undo de la d\xE9pense de point de chnce. Le undo apr\xE8s la d\xE9pense de point de chance annule toute l'action. Il faut ensuite faire un undo par point de chance d\xE9pens\xE9.

    Surprise : !cof-surprise ?difficulte

    -

    Fait un test de surprise sur tous les tokens sélectionné. Si la difficulté n'est pas présente, ils sont automatiquement surpris. Les valeurs des compétences vigilance et perception sont ajoutés au test de sagesse.

    -

    Si vous souhaitez préciser que la surprise est le fait d'un personnage ou effet non vivant (pour ne pas faire bénéficier du bonus de la capacité Radar mental), vous pouvez rajouter l'option --nonVivant.

    +

    Fait un test de surprise sur tous les tokens s\xE9lectionn\xE9. Si la difficult\xE9 n'est pas pr\xE9sente, ils sont automatiquement surpris. Les valeurs des comp\xE9tences vigilance et perception sont ajout\xE9s au test de sagesse.

    +

    Si vous souhaitez pr\xE9ciser que la surprise est le fait d'un personnage ou effet non vivant (pour ne pas faire b\xE9n\xE9ficier du bonus de la capacit\xE9 Radar mental), vous pouvez rajouter l'option --nonVivant.

    Gestion de la bourse : !cof-bourse

    -

    La gestion de la bourse peut se faire sans ouvrir la fiche à l'aide de la commande !cof-bourse. Si un seul token est sélectionné (quelle que soit la méthode de sélection), la commande affiche le montant de la bourse, avec la possibilité de modifier directement les nombres de pièces ou de dépenser ou gagner un certain nombre de pièces.

    -

    !cof-bourse depenser n permet de faire dépenser de l'argent aux tokens sélectionnés. On peut préciser le type de pièces (pc, pa, po ou pp) après le montant, par défaut le script utilise les pièces d'argent. De même, on peut utiliser !cof-bourse gagner n pour ajouter de l'argent.

    +

    La gestion de la bourse peut se faire sans ouvrir la fiche \xE0 l'aide de la commande !cof-bourse. Si un seul token est s\xE9lectionn\xE9 (quelle que soit la m\xE9thode de s\xE9lection), la commande affiche le montant de la bourse, avec la possibilit\xE9 de modifier directement les nombres de pi\xE8ces ou de d\xE9penser ou gagner un certain nombre de pi\xE8ces.

    +

    !cof-bourse depenser n permet de faire d\xE9penser de l'argent aux tokens s\xE9lectionn\xE9s. On peut pr\xE9ciser le type de pi\xE8ces (pc, pa, po ou pp) apr\xE8s le montant, par d\xE9faut le script utilise les pi\xE8ces d'argent. De m\xEAme, on peut utiliser !cof-bourse gagner n pour ajouter de l'argent.

    Jouer un son

    -

    Les fonctions d'attaque peuvent jouer un son (options commençant par --soundAttack). Une partie des actions admet aussi une option --son pour jouer un son. Finalement, il est aussi possible de simplement jouer un son en utilisant !cof-jouer-son son. Il est possible d'arrêter tous les sons avec la commande !cof-jouer-son, sans argument.

    +

    Les fonctions d'attaque peuvent jouer un son (options commen\xE7ant par --soundAttack). Une partie des actions admet aussi une option --son pour jouer un son. Finalement, il est aussi possible de simplement jouer un son en utilisant !cof-jouer-son son. Il est possible d'arr\xEAter tous les sons avec la commande !cof-jouer-son, sans argument.

    -

    Le script est compatible avec Roll20AM, et si ce script est installé, il fera appel à lui. Mais si il n'est pas installé (et seulement dans ce cas !), il va simplement utiliser les sons dans le jukebox.

    +

    Le script est compatible avec Roll20AM, et si ce script est install\xE9, il fera appel \xE0 lui. Mais si il n'est pas install\xE9 (et seulement dans ce cas !), il va simplement utiliser les sons dans le jukebox.

    Changer la taille d'une page : !cof-agrandir-page

    - !cof-agrandir-carte coef permet de multiplier par coef les dimensions de tout ce qui se trouve sur la carte et le layer de la lumière. Les tokens sont déplacés pour se retrouver à la même position relative sur la carte. Je l'utilise pour les cartes que je trouve trop petites pour des groupes de 5-6 joueurs. + !cof-agrandir-carte coef permet de multiplier par coef les dimensions de tout ce qui se trouve sur la carte et le layer de la lumi\xE8re. Les tokens sont d\xE9plac\xE9s pour se retrouver \xE0 la m\xEAme position relative sur la carte. Je l'utilise pour les cartes que je trouve trop petites pour des groupes de 5-6 joueurs.

    Retarder l'affichage de la mort

    -

    Pour retarder l'affichage de la mort d'un personnage, ajoutez à ce personnage un prédicat mortDemandeConfirmation. Ainsi, si le personnage meurt à la suite d'une attaque, les PVs finaux ne seront pas enlevés, et la croix rouge indiquant la mort ne sera pas dessinée. À la place, le MJ verra au bout de 2 secondes un bouton lui-demandant de confirmer la mort (par exemple le temps de décrire comment la mort advient).

    +

    Pour retarder l'affichage de la mort d'un personnage, ajoutez \xE0 ce personnage un pr\xE9dicat mortDemandeConfirmation. Ainsi, si le personnage meurt \xE0 la suite d'une attaque, les PVs finaux ne seront pas enlev\xE9s, et la croix rouge indiquant la mort ne sera pas dessin\xE9e. \xC0 la place, le MJ verra au bout de 2 secondes un bouton lui-demandant de confirmer la mort (par exemple le temps de d\xE9crire comment la mort advient).

    -

    3. Capacités par Classe

    +

    3. Capacit\xE9s par Classe

    Arquebusier

    Voie de l'artilleur

      -
    1. Mécanismes : ajouter les bonus sur la fiche
    2. -
    3. Tir de semonce : utiliser le modificateur semonce aux attaques. On laisse le MJ vérifier si la dernière attaque du personnage était bien un échec (devrait être facile à voir dans le chat). Le plus pratique pour l'utilisation avec differentes armes, est de créer une action Tir de barrage dans les actions du tour, avec comme code #Attaque -1 --semonce. -
    4. Tir de barrage : Utiliser l'option --tirDeBarrage. Ça multiplie les dégâts par 2, ignore la charge, et laisse un message demandant le undo si la cible décide de ne pas bouger.
    5. -
    6. Couleuvrine : ajouter une attaque à distance, avec dans les modificateurs, poudre, limiteParCombat (ou en ligne de commande, avec l'option --limiteParCombat)
    7. -
    8. Feu nourri : faire les attaques comme pour le tirde barrage. Le script ne va pas vérifier que les cibles ne sont pas trop loin les unes des autres.
    9. +
    10. M\xE9canismes : ajouter les bonus sur la fiche
    11. +
    12. Tir de semonce : utiliser le modificateur semonce aux attaques. On laisse le MJ v\xE9rifier si la derni\xE8re attaque du personnage \xE9tait bien un \xE9chec (devrait \xEAtre facile \xE0 voir dans le chat). Le plus pratique pour l'utilisation avec differentes armes, est de cr\xE9er une action Tir de barrage dans les actions du tour, avec comme code #Attaque -1 --semonce. +
    13. Tir de barrage : Utiliser l'option --tirDeBarrage. Ça multiplie les d\xE9g\xE2ts par 2, ignore la charge, et laisse un message demandant le undo si la cible d\xE9cide de ne pas bouger.
    14. +
    15. Couleuvrine : ajouter une attaque \xE0 distance, avec dans les modificateurs, poudre, limiteParCombat (ou en ligne de commande, avec l'option --limiteParCombat)
    16. +
    17. Feu nourri : faire les attaques comme pour le tirde barrage. Le script ne va pas v\xE9rifier que les cibles ne sont pas trop loin les unes des autres.

    Voie des explosifs

      -
    1. Chimiste : ajoutez un prédicat chimiste, ainsi que les compétences de chimie et alchimie sur la fiche. Si vous utilisez la capacité alternative Grenaille, vous pouvez soit gérer les charges de grenaille avec !cof-recharger L --grenaille, soit (si vous ne voulez pas faire gérer les charges) utiliser l'option --grenaille. Si vous utilisez la même attaque pour plusieurs armes et que seule une partie est chargée de grenaille, il faudra aussi utiliser cette option pour utiliser l'arme chargée de grenaille.
    2. -
    3. Démolition : pas de support particulier
    4. +
    5. Chimiste : ajoutez un pr\xE9dicat chimiste, ainsi que les comp\xE9tences de chimie et alchimie sur la fiche. Si vous utilisez la capacit\xE9 alternative Grenaille, vous pouvez soit g\xE9rer les charges de grenaille avec !cof-recharger L --grenaille, soit (si vous ne voulez pas faire g\xE9rer les charges) utiliser l'option --grenaille. Si vous utilisez la m\xEAme attaque pour plusieurs armes et que seule une partie est charg\xE9e de grenaille, il faudra aussi utiliser cette option pour utiliser l'arme charg\xE9e de grenaille.
    6. +
    7. D\xE9molition : pas de support particulier
    8. Poudre puissante : ajuster les attaques
    9. -
    10. Piège explosif :
    11. -
    12. Boulet explosif : ajouter une attaque de type Arme de jet, dégâts 5d6 de type contondant (ou feu ?), portée 20, modificateurs auto, options --disque 5 --psave DEX [[12+@{selected|DEX}]]
    13. +
    14. Pi\xE8ge explosif :
    15. +
    16. Boulet explosif : ajouter une attaque de type Arme de jet, d\xE9g\xE2ts 5d6 de type contondant (ou feu ?), port\xE9e 20, modificateurs auto, options --disque 5 --psave DEX [[12+@{selected|DEX}]]

    Voie du champ de bataille

      -
    1. Action concertée : utiliser !cof-echange-init @{selected|token_id} @{target|token_id} nn peut valoir 0, 1 ou 2 selon le rang dans la voie.
    2. -
    3. À couvert : !cof-a-couvert @{selected|token_id} @{target|token_id} le target est l'allié qui se déplace avec l'arquebusier. Se sélectionner soi-même si pas d'allié.
    4. -
    5. Combattant aguerri : se reporter à la capacité choisie
    6. -
    7. Combat de masse : pas de support particulier, effectuer les actions supplémentaires en fonction des situations.
    8. -
    9. Constitution héroïque : reporter le bonus sur la fiche
    10. +
    11. Action concert\xE9e : utiliser !cof-echange-init @{selected|token_id} @{target|token_id} n o\xF9 n peut valoir 0, 1 ou 2 selon le rang dans la voie.
    12. +
    13. \xC0 couvert : !cof-a-couvert @{selected|token_id} @{target|token_id} le target est l'alli\xE9 qui se d\xE9place avec l'arquebusier. Se s\xE9lectionner soi-m\xEAme si pas d'alli\xE9.
    14. +
    15. Combattant aguerri : se reporter \xE0 la capacit\xE9 choisie
    16. +
    17. Combat de masse : pas de support particulier, effectuer les actions suppl\xE9mentaires en fonction des situations.
    18. +
    19. Constitution h\xE9ro\xEFque : reporter le bonus sur la fiche

    Voie du Pistolero

    1. - Plus vite que son ombre : ajouter un prédicat plusViteQueSonOmbre. On peut associer un nombre à ce prédicat pour modifier le bonus à l'initiative, ou bien lui donner la valeur arbalete pour activer le bonus sur les arbalètes au lieu des armes à poudre. + Plus vite que son ombre : ajouter un pr\xE9dicat plusViteQueSonOmbre. On peut associer un nombre \xE0 ce pr\xE9dicat pour modifier le bonus \xE0 l'initiative, ou bien lui donner la valeur arbalete pour activer le bonus sur les arbal\xE8tes au lieu des armes \xE0 poudre.
    2. Cadence de tir : pas de support
    3. -
    4. Tir double : utiliser l'option --tirDouble si deux tirs sur une même cible. Si les deux armes sont différentes, rajouter le label de la deuxième arme après l'option (si le label est l2, cela donne --tirDouble l2).
    5. -
    6. As de la gâchette : utiliser l'option --asDeLaGachette pour les attaques avec des armes à poudre ou des arbalètes.
    7. -
    8. Dextérité héroïque : reporter le bonus sur la fiche
    9. +
    10. Tir double : utiliser l'option --tirDouble si deux tirs sur une m\xEAme cible. Si les deux armes sont diff\xE9rentes, rajouter le label de la deuxi\xE8me arme apr\xE8s l'option (si le label est l2, cela donne --tirDouble l2).
    11. +
    12. As de la g\xE2chette : utiliser l'option --asDeLaGachette pour les attaques avec des armes \xE0 poudre ou des arbal\xE8tes.
    13. +
    14. Dext\xE9rit\xE9 h\xE9ro\xEFque : reporter le bonus sur la fiche
    -

    Voie de la précision

    +

    Voie de la pr\xE9cision

      -
    1. Joli coup ! : ajouter un prédicat joliCoup sur la fiche.
    2. -
    3. Tir précis : ajouter un prédicat tirPrecis, valeur 1 ou 2 (le bonus apporté par la capacité)
    4. -
    5. Défaut dans la cuirasse : utiliser !cof-defaut-dans-la-cuirasse @{selected|token_id} @{target|token_id}
    6. -
    7. Tir parabolique : ajouter un prédicat tirParabolique. Surtout ne pas changer la portée des armes, pour que le script gère correctement les distances entre portéex2 et portéex3.
    8. -
    9. Tir mortel : Ajouter ?{Tir mortel ?|Oui, --avecd12crit --plus 2d6|Non,} aux attaques à distance du personnage
    10. +
    11. Joli coup ! : ajouter un pr\xE9dicat joliCoup sur la fiche.
    12. +
    13. Tir pr\xE9cis : ajouter un pr\xE9dicat tirPrecis, valeur 1 ou 2 (le bonus apport\xE9 par la capacit\xE9)
    14. +
    15. D\xE9faut dans la cuirasse : utiliser !cof-defaut-dans-la-cuirasse @{selected|token_id} @{target|token_id}
    16. +
    17. Tir parabolique : ajouter un pr\xE9dicat tirParabolique. Surtout ne pas changer la port\xE9e des armes, pour que le script g\xE8re correctement les distances entre port\xE9ex2 et port\xE9ex3.
    18. +
    19. Tir mortel : Ajouter ?{Tir mortel ?|Oui, --avecd12crit --plus 2d6|Non,} aux attaques \xE0 distance du personnage

    Barbare

    Voie de la brute

      -
    1. Argument de taille : ajouter le bonus de PV sur la fiche. Ajouter un prédicat argumentDeTaille. Le script devrait automatiquement tenir compte de cette capacité pour les tests de négociation, persuasion et intimidation. Pour s'assurer que la bonne compétence est utilisée, vous pouvez ajouter ces noms au handout de compétence (voir la partie sur les jet de caractéristiques, le handout Compétences) ou sur les fiches de personnages.
    2. -
    3. Tour de force : ajouter un prédicat tourDeForce. Le script ajoutera systématique un bouton lors de tous les tests de FOR du personnage. Au MJ de décider s'il peut être utilisé ou non.
    4. +
    5. Argument de taille : ajouter le bonus de PV sur la fiche. Ajouter un pr\xE9dicat argumentDeTaille. Le script devrait automatiquement tenir compte de cette capacit\xE9 pour les tests de n\xE9gociation, persuasion et intimidation. Pour s'assurer que la bonne comp\xE9tence est utilis\xE9e, vous pouvez ajouter ces noms au handout de comp\xE9tence (voir la partie sur les jet de caract\xE9ristiques, le handout Comp\xE9tences) ou sur les fiches de personnages.
    6. +
    7. Tour de force : ajouter un pr\xE9dicat tourDeForce. Le script ajoutera syst\xE9matique un bouton lors de tous les tests de FOR du personnage. Au MJ de d\xE9cider s'il peut \xEAtre utilis\xE9 ou non.
    8. Attaque brutale : faire l'attaque avec les options --bonusAttaque -2 --plus 1d6
    9. -
    10. Briseur d'os : ajouter un prédicat briseurDOs. Cela va automatiquement affecter les chances de coups critique au contact.
    11. -
    12. Force héroïque : reporter sur la fiche.
    13. +
    14. Briseur d'os : ajouter un pr\xE9dicat briseurDOs. Cela va automatiquement affecter les chances de coups critique au contact.
    15. +
    16. Force h\xE9ro\xEFque : reporter sur la fiche.

    Voie du pagne

      -
    1. Vigueur : ajouter les compétences avec leurs bonus sur la fiche
    2. -
    3. Peau de pierre : ajouter un prédicat peauDePierre. La nouvelle DEF sera calculée automatiquement.
    4. +
    5. Vigueur : ajouter les comp\xE9tences avec leurs bonus sur la fiche
    6. +
    7. Peau de pierre : ajouter un pr\xE9dicat peauDePierre. La nouvelle DEF sera calcul\xE9e automatiquement.
    8. Tatouages : ajouter le bonus choisi sur la fiche
    9. Peau d'acier : ajouter dans la partie RD de la fiche, 3/1
    10. -
    11. Constitution héroïque : reporter les bonus sur la fiche
    12. +
    13. Constitution h\xE9ro\xEFque : reporter les bonus sur la fiche

    Voie du pourfendeur

      -
    1. Réflexes félins : ajouter un prédicat reflexesFelins, avec comme valeur le bonus aux saves et à l'initiative.
    2. -
    3. Charge : faire une attaque avec les options --bonusAttaque 2 --plus 1d6. Pour gérer plusieurs armes, vous pouvez utiliser la commande #Attaque -1.
    4. -
    5. Enchaînement : ajouter un prédicat enchainement.
    6. -
    7. Déchaînement d'acier : !cof-attack-line @{selected|token_id} --distanceMax 10. L'attaque va être faite avec l'arme en main, mais on peut spécifier un label d'attaque (avant les options) et toutes les options supportées par !cof-attack.
    8. +
    9. R\xE9flexes f\xE9lins : ajouter un pr\xE9dicat reflexesFelins, avec comme valeur le bonus aux saves et \xE0 l'initiative.
    10. +
    11. Charge : faire une attaque avec les options --bonusAttaque 2 --plus 1d6. Pour g\xE9rer plusieurs armes, vous pouvez utiliser la commande #Attaque -1.
    12. +
    13. Encha\xEEnement : ajouter un pr\xE9dicat enchainement.
    14. +
    15. D\xE9cha\xEEnement d'acier : !cof-attack-line @{selected|token_id} --distanceMax 10. L'attaque va \xEAtre faite avec l'arme en main, mais on peut sp\xE9cifier un label d'attaque (avant les options) et toutes les options support\xE9es par !cof-attack.
    16. Attaque tourbillon : Faite une action avec le code !cof-explosion -1 --auto --disque 5 --saufAllies --limiteParCombat 1 tourbillon.

    Voie du primitif

      -
    1. Proche de la nature : ajouter le rang à une compétence perception
    2. -
    3. Armure de vent : Ajouter un prédicat armureDeVent avec comme valeur le rang dans la voie du primitif. Cela augmente la DEF, mais seulement lorsque le barbare ne porte pas d'armure (ne se voit pas sur le total de DEF de la fiche)
    4. -
    5. Vigilance : ajouter 5 à une compétence vigilance et ajouter un prédicat immuniteAuxSournoises
    6. -
    7. Résistance à la magie : ajouter un prédicat resistanceALaMagieBarbare.
    8. -
    9. Vitalité débordante : faire une ability de type token action, avec le code !cof-soin ?{Nombre d'heures écoulées}d6 --message guérit à une vitesse surnaturelle
    10. +
    11. Proche de la nature : ajouter le rang \xE0 une comp\xE9tence perception
    12. +
    13. Armure de vent : Ajouter un pr\xE9dicat armureDeVent avec comme valeur le rang dans la voie du primitif. Cela augmente la DEF, mais seulement lorsque le barbare ne porte pas d'armure (ne se voit pas sur le total de DEF de la fiche)
    14. +
    15. Vigilance : ajouter 5 \xE0 une comp\xE9tence vigilance et ajouter un pr\xE9dicat immuniteAuxSournoises
    16. +
    17. R\xE9sistance \xE0 la magie : ajouter un pr\xE9dicat resistanceALaMagieBarbare.
    18. +
    19. Vitalit\xE9 d\xE9bordante : faire une ability de type token action, avec le code !cof-soin ?{Nombre d'heures \xE9coul\xE9es}d6 --message gu\xE9rit \xE0 une vitesse surnaturelle

    Voie de la rage

    1. Cri de guerre : !cof-effet-combat criDeGuerre
    2. -
    3. Défier la mort : ajouter un prédicat defierLaMort.
    4. -
    5. Rage du berserk : utiliser !cof-rage-du-berserk, à la fois pour entrer en rage et pour tenter d'en sortir avant la fin du combat.
    6. -
    7. Même pas mal : ajouter un prédicat memePasMal. Le joueur doit lui-même activer la rage ou le furie si il souhaite en profiter.
    8. -
    9. Furie du berserk : utiliser !cof-rage-du-berserk --furie pour entrer en rage et pour tenter d'en sortir avant la fin du combat. Pour sortir de la rage, l'option --furie peut être omise.
    10. +
    11. D\xE9fier la mort : ajouter un pr\xE9dicat defierLaMort.
    12. +
    13. Rage du berserk : utiliser !cof-rage-du-berserk, \xE0 la fois pour entrer en rage et pour tenter d'en sortir avant la fin du combat.
    14. +
    15. M\xEAme pas mal : ajouter un pr\xE9dicat memePasMal. Le joueur doit lui-m\xEAme activer la rage ou le furie si il souhaite en profiter.
    16. +
    17. Furie du berserk : utiliser !cof-rage-du-berserk --furie pour entrer en rage et pour tenter d'en sortir avant la fin du combat. Pour sortir de la rage, l'option --furie peut \xEAtre omise.
    - Note: en option, il est possible de diviser par 2 la pénalité de défense infligée par la Rage ou la Furie en ajoutant un prédicat rageDuBerserkAmelioree au personnage (par exemple pour la ceinture d'Anathazerïn p. 341) + Note: en option, il est possible de diviser par 2 la p\xE9nalit\xE9 de d\xE9fense inflig\xE9e par la Rage ou la Furie en ajoutant un pr\xE9dicat rageDuBerserkAmelioree au personnage (par exemple pour la ceinture d'Anathazer\xEFn p. 341)

    Barde

    Voie de l'escrime

      -
    1. Précision : simplement utiliser le bon score sur la fiche.
    2. -
    3. Intelligence du combat : ajouter un prédicat intelligenceDuCombat.
    4. -
    5. Feinte : faire une attaque avec l'option --feinte pour profiter des effets de feinte au tour suivant. Par défaut, le bonus à l'attaque suivante est de +5 (règles de base), mais vous pouvez spécifier un bonus différent (par exemple 10 pour les règles de la boîte d'initiation) avec un prédicat bonusFeinte (la valeur du prédicat remplace le bonus de +5 par défaut). Il est aussi possible de changer le nombre de dés de dégât bonus en utilisant un prédicatnbDesFeinte.
    6. -
    7. Attaque flamboyante : faire une attaque avec le modificateur attaqueFlamboyante. Le plus pratique pour l'utilisation avec différentes armes, est d'ajouter à la liste des actions du tour une action de titre Attaque flamboyante et de code #Attaque -1 --attaqueFlamboyante. Attention, afin de garder un intérêt à la feinte quand on dispose de cette attaque, j'ai choisi de rajouter encore le mod. de charisme aux DM en cas d'attaque flamboyante suivant une feinte réussie. Si cela ne vous convient pas, vous pouvez à la place de cette option ajouter --bonusAttaque [[@{selected|CHA}]] --plus [[@{selected|CHA}]].
    8. -
    9. Botte mortelle : ajoutez un prédicat botteMortelle.
    10. +
    11. Pr\xE9cision : simplement utiliser le bon score sur la fiche.
    12. +
    13. Intelligence du combat : ajouter un pr\xE9dicat intelligenceDuCombat.
    14. +
    15. Feinte : faire une attaque avec l'option --feinte pour profiter des effets de feinte au tour suivant. Par d\xE9faut, le bonus \xE0 l'attaque suivante est de +5 (r\xE8gles de base), mais vous pouvez sp\xE9cifier un bonus diff\xE9rent (par exemple 10 pour les r\xE8gles de la bo\xEEte d'initiation) avec un pr\xE9dicat bonusFeinte (la valeur du pr\xE9dicat remplace le bonus de +5 par d\xE9faut). Il est aussi possible de changer le nombre de d\xE9s de d\xE9g\xE2t bonus en utilisant un pr\xE9dicatnbDesFeinte.
    16. +
    17. Attaque flamboyante : faire une attaque avec le modificateur attaqueFlamboyante. Le plus pratique pour l'utilisation avec diff\xE9rentes armes, est d'ajouter \xE0 la liste des actions du tour une action de titre Attaque flamboyante et de code #Attaque -1 --attaqueFlamboyante. Attention, afin de garder un int\xE9r\xEAt \xE0 la feinte quand on dispose de cette attaque, j'ai choisi de rajouter encore le mod. de charisme aux DM en cas d'attaque flamboyante suivant une feinte r\xE9ussie. Si cela ne vous convient pas, vous pouvez \xE0 la place de cette option ajouter --bonusAttaque [[@{selected|CHA}]] --plus [[@{selected|CHA}]].
    18. +
    19. Botte mortelle : ajoutez un pr\xE9dicat botteMortelle.

    Voie du musicien

      -
    1. Chant des héros : !cof-effet-temp chantDesHeros [[5+@{selected|CHA}]] --allies. Il faut avoir défini une équipe avec le barde.
    2. +
    3. Chant des h\xE9ros : !cof-effet-temp chantDesHeros [[5+@{selected|CHA}]] --allies. Il faut avoir d\xE9fini une \xE9quipe avec le barde.
    4. Attaque sonore :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, DM 1d6+CHA, de portée 10, type Sortilège, dégâts soniques, options --mana 0 --cone --fx breath-smoke.
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, DM 1d6+CHA, de port\xE9e 10, type Sortil\xE8ge, d\xE9g\xE2ts soniques, options --mana 0 --cone --fx breath-smoke.
      • Objet de sort : #Attaque Attaque sonore --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|CHA}]] --portee 10 --sortilege --sonique --cone --fx breath-smoke
    5. -
    6. Zone de silence : !cof-effet-temp zoneDeSilence [[1d6+@{selected|CHA}]] --lanceur @{selected|token_id} --portee 35 --disque @{target|token_id} 3 --mana 1. Le script ne gère pas le moment où les cibles sortent de la zone. Si cela arrive, le MJ doit enlever à la main l'attribut zoneDeSilence créé par le script pour le personnage concerné.
    7. -
    8. Danse irrésisitible : +
    9. Zone de silence : !cof-effet-temp zoneDeSilence [[1d6+@{selected|CHA}]] --lanceur @{selected|token_id} --portee 35 --disque @{target|token_id} 3 --mana 1. Le script ne g\xE8re pas le moment o\xF9 les cibles sortent de la zone. Si cela arrive, le MJ doit enlever \xE0 la main l'attribut zoneDeSilence cr\xE9\xE9 par le script pour le personnage concern\xE9.
    10. +
    11. Danse irr\xE9sisitible :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateur pasDeDmg, options --mana 2 --effet danseIrresistible [[1d4+@{selected|CHA]].
      • -
      • Objet de sort : #Attaque Danse irrésisitible --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet danseIrresistible [[1d4+@{selected|CHA]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateur pasDeDmg, options --mana 2 --effet danseIrresistible [[1d4+@{selected|CHA]].
      • +
      • Objet de sort : #Attaque Danse irr\xE9sisitible --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet danseIrresistible [[1d4+@{selected|CHA]]
    12. -
    13. Musique fascinante : !cof-lancer-sort joue une musique fascinante qui contrôle toutes les créatures de son choix de moins de [[5+@{selected|CHA}]] PV --mana 3
    14. +
    15. Musique fascinante : !cof-lancer-sort joue une musique fascinante qui contr\xF4le toutes les cr\xE9atures de son choix de moins de [[5+@{selected|CHA}]] PV --mana 3

    Voie du saltimbanque

      -
    1. Acrobate : ajouter les compétences sur la fiche
    2. -
    3. Grâce féline : ajouter un prédicat graceFeline. Cela va affecter l'initiative et la DEF, mais sans se voir sur la fiche.
    4. +
    5. Acrobate : ajouter les comp\xE9tences sur la fiche
    6. +
    7. Gr\xE2ce f\xE9line : ajouter un pr\xE9dicat graceFeline. Cela va affecter l'initiative et la DEF, mais sans se voir sur la fiche.
    8. Lanceur de couteau : faire normalement l'attaque.
    9. -
    10. Esquive acrobatique : ajouter un prédicat esquiveAcrobatique.
    11. -
    12. Liberté d'action : ajouter un prédicat liberteDAction.
    13. +
    14. Esquive acrobatique : ajouter un pr\xE9dicat esquiveAcrobatique.
    15. +
    16. Libert\xE9 d'action : ajouter un pr\xE9dicat liberteDAction.
    -

    Voie de la séduction

    +

    Voie de la s\xE9duction

      -
    1. Charmant : ajouter les compétences sur la fiche
    2. -
    3. Dentelles et rapière : Ajouter un prédicat dentellesEtRapiere avec comme valeur le rang dans la voie de la séduction. Cela augmente la DEF, mais seulement lorsque le barde ne porte pas d'armure et seulement contre les attaques au contact. (ne se voit pas sur le total de DEF de la fiche)
    4. -
    5. Arme secrète : !cof-arme-secrete @{selected|token_id} @{target|token_id}
    6. +
    7. Charmant : ajouter les comp\xE9tences sur la fiche
    8. +
    9. Dentelles et rapi\xE8re : Ajouter un pr\xE9dicat dentellesEtRapiere avec comme valeur le rang dans la voie de la s\xE9duction. Cela augmente la DEF, mais seulement lorsque le barde ne porte pas d'armure et seulement contre les attaques au contact. (ne se voit pas sur le total de DEF de la fiche)
    10. +
    11. Arme secr\xE8te : !cof-arme-secrete @{selected|token_id} @{target|token_id}
    12. Suggestion :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg, options --mana 2 --difficultePVmax --attaqueMentale --if touche --message la cible doit faire l'action suggérée --endif.
      • -
      • Objet de sort : #Attaque Suggestion --toucher [[@{selected|ATKMAG}]] --portee 20 --pasDeDmg --difficultePVmax --sortilege --attaqueMentale --if touche --message la cible doit faire l'action suggérée --endif
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg, options --mana 2 --difficultePVmax --attaqueMentale --if touche --message la cible doit faire l'action sugg\xE9r\xE9e --endif.
      • +
      • Objet de sort : #Attaque Suggestion --toucher [[@{selected|ATKMAG}]] --portee 20 --pasDeDmg --difficultePVmax --sortilege --attaqueMentale --if touche --message la cible doit faire l'action sugg\xE9r\xE9e --endif
    13. -
    14. Charisme héroïque : Reporter le bonus sur la fiche.
    15. +
    16. Charisme h\xE9ro\xEFque : Reporter le bonus sur la fiche.

    Voie du vagabond

      -
    1. Rumeurs et légendes : ajouter les compétences sur la fiche
    2. -
    3. Compréhension des langues : !cof-lancer-sort lance un sort de compréhension des langues. --messageMJ la compréhension des langues va durer [[1d6+@{selected|CHA}]] minutes --mana 0
    4. -
    5. Débrouillard : pas de support particulier. Ajouter le bonus aux compétences que vous souhaitez noter.
    6. -
    7. Déguisement :!cof-lancer-sort lance un sort de déguisement --mana 2
    8. -
    9. Touche à tout : se reporter aux capacités choisies
    10. +
    11. Rumeurs et l\xE9gendes : ajouter les comp\xE9tences sur la fiche
    12. +
    13. Compr\xE9hension des langues : !cof-lancer-sort lance un sort de compr\xE9hension des langues. --messageMJ la compr\xE9hension des langues va durer [[1d6+@{selected|CHA}]] minutes --mana 0
    14. +
    15. D\xE9brouillard : pas de support particulier. Ajouter le bonus aux comp\xE9tences que vous souhaitez noter.
    16. +
    17. D\xE9guisement :!cof-lancer-sort lance un sort de d\xE9guisement --mana 2
    18. +
    19. Touche \xE0 tout : se reporter aux capacit\xE9s choisies

    Chevalier

    Voie du cavalier

      -
    1. Fidèle monture : Faire un personnage pour la monture, avec un prédicat monture. Pour monter sur la monture, on peut utiliser une ability de type token action, avec !cof-en-selle @{selected|token_id} nom_de_la_monture. Pour en descendre, il suffit de cliquer à nouveau sur le bouton de l'ability. Si vous souhaitez éviter que la monture apparaisse dans le turn tracker, vous pouvez ajouter un prédicat aucuneActionCombat à la monture.
    2. -
    3. Cavalier émérite : Ajouter au chevalier un prédicat cavalierEmerite:2. Pour la défense de la monture, ajouter à cellle-ci un prédicat defDeriveeDe de valeur le nom du chevalier (exactement tel qu'il apparaît sur la fiche, il est possible que cela demande d'utiliser la syntaxe avec ::).
    4. -
    5. Monture magique : pour les soins automatiques de la nuit, ajouter un prédicat montureMagique.
    6. +
    7. Fid\xE8le monture : Faire un personnage pour la monture, avec un pr\xE9dicat monture. Pour monter sur la monture, on peut utiliser une ability de type token action, avec !cof-en-selle @{selected|token_id} nom_de_la_monture. Pour en descendre, il suffit de cliquer \xE0 nouveau sur le bouton de l'ability. Si vous souhaitez \xE9viter que la monture apparaisse dans le turn tracker, vous pouvez ajouter un pr\xE9dicat aucuneActionCombat \xE0 la monture.
    8. +
    9. Cavalier \xE9m\xE9rite : Ajouter au chevalier un pr\xE9dicat cavalierEmerite:2. Pour la d\xE9fense de la monture, ajouter \xE0 cellle-ci un pr\xE9dicat defDeriveeDe de valeur le nom du chevalier (exactement tel qu'il appara\xEEt sur la fiche, il est possible que cela demande d'utiliser la syntaxe avec ::).
    10. +
    11. Monture magique : pour les soins automatiques de la nuit, ajouter un pr\xE9dicat montureMagique.
    12. - Charge : pas de support pour le déplacement, mais + Charge : pas de support pour le d\xE9placement, mais
      • Pour l'attaque : utiliser --m2d20 --plus 1d6
      • -
      • Pour les créatures sur la trajectoire, utiliser !cof-jet FOR 18, et en cas de succès, infliger les DM.
      • +
      • Pour les cr\xE9atures sur la trajectoire, utiliser !cof-jet FOR 18, et en cas de succ\xE8s, infliger les DM.
    13. -
    14. Monture fantastique : Faire un personnage pour la monture, avec un prédicat monture.
    15. +
    16. Monture fantastique : Faire un personnage pour la monture, avec un pr\xE9dicat monture.

    Voie de la guerre

      @@ -1155,38 +1158,38 @@

      Voie de la guerre

    1. Encaisser un coup :
      • utiliser !cof-effet-temp encaisserUnCoup 1 pour se mettre en position
      • -
      • Le script proposera un bouton à activer en cas d'attaque réussie alors que le chevalier est en position.
      • +
      • Le script proposera un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le chevalier est en position.
    2. -
    3. Coup de bouclier : faire une attaque de bouclier, de type Arme gauche, avec le modificateur avecd12crit. Pour que cette attaque soit proposée dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un prédicat attaqueAuBouclier de valeur le label de l'attaque.
    4. +
    5. Coup de bouclier : faire une attaque de bouclier, de type Arme gauche, avec le modificateur avecd12crit. Pour que cette attaque soit propos\xE9e dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un pr\xE9dicat attaqueAuBouclier de valeur le label de l'attaque.
    6. Frappe lourde : faire l'attaque avec les options --avecd12crit --plus 2d6 --ignoreMoitieRD --seulementContact
    7. -
    8. Force héroïque : reporter les bonus sur la fiche
    9. +
    10. Force h\xE9ro\xEFque : reporter les bonus sur la fiche
    -

    Voie du héro

    +

    Voie du h\xE9ro

      -
    1. Ignorer la douleur : Ajouter un prédicat ignorerLaDouleur. Normalement, le script affiche un bouton quand cela est utilisable, mais on peut aussi le déclencher avec !cof-ignorer-la-douleur juste après le coup.
    2. -
    3. Piqures d'insectes : ajouter un prédicat piquresDInsectes, avec comme valeur le rang dans la voie.
    4. -
    5. Laissez-le-moi ! : Ajouter un prédicat laissezLeMoi. Le bonus sera accordé contre tous les tokens ayant le statut de chef (donnés avec !cof-set-state chef true, ou alors simplement en activant le marker sur le token).
    6. -
    7. Seul contre tous : Utiliser !cof-effet-temp seulContreTous 1 pour se mettre en position. Les actions affichées en cas de riposte seront normalement une attaque avec l'arme en main si il y en a, plus les attaques naturelles cochées sur la liste d'attaque. Si ça ne convient pas, vous pouvez écrire une liste d'actions nomméeRipostes (voir les actions du tour).
    8. -
    9. Charisme héroïque : reporter sur la fiche.
    10. +
    11. Ignorer la douleur : Ajouter un pr\xE9dicat ignorerLaDouleur. Normalement, le script affiche un bouton quand cela est utilisable, mais on peut aussi le d\xE9clencher avec !cof-ignorer-la-douleur juste apr\xE8s le coup.
    12. +
    13. Piqures d'insectes : ajouter un pr\xE9dicat piquresDInsectes, avec comme valeur le rang dans la voie.
    14. +
    15. Laissez-le-moi ! : Ajouter un pr\xE9dicat laissezLeMoi. Le bonus sera accord\xE9 contre tous les tokens ayant le statut de chef (donn\xE9s avec !cof-set-state chef true, ou alors simplement en activant le marker sur le token).
    16. +
    17. Seul contre tous : Utiliser !cof-effet-temp seulContreTous 1 pour se mettre en position. Les actions affich\xE9es en cas de riposte seront normalement une attaque avec l'arme en main si il y en a, plus les attaques naturelles coch\xE9es sur la liste d'attaque. Si \xE7a ne convient pas, vous pouvez \xE9crire une liste d'actions nomm\xE9eRipostes (voir les actions du tour).
    18. +
    19. Charisme h\xE9ro\xEFque : reporter sur la fiche.

    Voie du meneur d'hommes

      -
    1. Sans peur : Ajouter un prédicat sansPeur, utilisé quand on essaiera de faire peur à un allié.
    2. -
    3. Intercepter : Ajouter un prédicat intercepter, et un autre voieDuMeneurDHomme de valeur le rang dans la voie, s'il est différent de 2.
    4. -
    5. Exemplaire : !cof-exemplaire, juste après l'attaque ratée.
    6. +
    7. Sans peur : Ajouter un pr\xE9dicat sansPeur, utilis\xE9 quand on essaiera de faire peur \xE0 un alli\xE9.
    8. +
    9. Intercepter : Ajouter un pr\xE9dicat intercepter, et un autre voieDuMeneurDHomme de valeur le rang dans la voie, s'il est diff\xE9rent de 2.
    10. +
    11. Exemplaire : !cof-exemplaire, juste apr\xE8s l'attaque rat\xE9e.
    12. Ordre de bataille : pas de support
    13. Charge fantastique : !cof-charge-fantastique @{selected|token_id} --alliesEnVue --self --limiteParCombat 1

    Voie de la noblesse

      -
    1. Éduqué : pas de support particulier, juste reporter les bonus sur la fiche.
    2. -
    3. Autorité naturelle : simplement reporter sur la fiche les bonus d'init et de DEF, et ajouter la capacité intimider.
    4. -
    5. Écuyer : +
    6. \xC9duqu\xE9 : pas de support particulier, juste reporter les bonus sur la fiche.
    7. +
    8. Autorit\xE9 naturelle : simplement reporter sur la fiche les bonus d'init et de DEF, et ajouter la capacit\xE9 intimider.
    9. +
    10. \xC9cuyer :
        -
      • Pour le bonus au critique, ajouter un prédicat ecuyer.
      • -
      • Pour les soins de nuit, ajouter à l'écuyer un prédicat ecuyerDe, avec comme valeur le nom du chevalier (attention à utiliser la syntaxe avec :: si ce nom contient des espaces). L'écuyer pourra soigner chaque nuit le chevalier et certains alliés, mais pour qu'il soigne les alliés, il ne faut pas oublier de le mettre dans la liste de l'équipe du chevalier.
      • -
      • Si on souhaite que l'écuyer puisse soigner gratuitement la monture, il faut aussi que celle-ci ait un prédicat montureDe, avec comme valeur le nom du chevalier.
      • +
      • Pour le bonus au critique, ajouter un pr\xE9dicat ecuyer.
      • +
      • Pour les soins de nuit, ajouter \xE0 l'\xE9cuyer un pr\xE9dicat ecuyerDe, avec comme valeur le nom du chevalier (attention \xE0 utiliser la syntaxe avec :: si ce nom contient des espaces). L'\xE9cuyer pourra soigner chaque nuit le chevalier et certains alli\xE9s, mais pour qu'il soigne les alli\xE9s, il ne faut pas oublier de le mettre dans la liste de l'\xE9quipe du chevalier.
      • +
      • Si on souhaite que l'\xE9cuyer puisse soigner gratuitement la monture, il faut aussi que celle-ci ait un pr\xE9dicat montureDe, avec comme valeur le nom du chevalier.
    @@ -1196,52 +1199,52 @@

    Druide

    Voie des animaux

    1. Langage des animaux : pas de support particulier
    2. -
    3. Nuée d'insectes : Pas de support particulier pour les DM de zone qui détruisent la nuée (enlever l'attribut nueeDInsecte sur la cible dans ce cas). +
    4. Nu\xE9e d'insectes : Pas de support particulier pour les DM de zone qui d\xE9truisent la nu\xE9e (enlever l'attribut nueeDInsecte sur la cible dans ce cas).
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateur pasDeDmg, options --mana 0 --effet nueeDInsectes [[5+@{selected|SAG}]].
      • -
      • Objet de sort : #Attaque Nuée d'insectes --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet nueeDInsectes [[5+@{selected|SAG}]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateur pasDeDmg, options --mana 0 --effet nueeDInsectes [[5+@{selected|SAG}]].
      • +
      • Objet de sort : #Attaque Nu\xE9e d'insectes --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet nueeDInsectes [[5+@{selected|SAG}]]
    5. -
    6. Le guetteur : Si elle n'est pas déjà présente dans votre handout de compétences, ajouter au druide une compétence perception (valeur 0 pour le moment). Créer un personnage et un token pour l'oiseau. Ajouter au druide un prédicat guetteur de valeur le nom exact de l'oiseau (sur la fiche, attention à utiliser la symtaxe avec :: si le nom comporte des espaces). Ajouter de même un prédicat PVPartagesAvec de valeur le nom de l'oiseau. Ajouter aussi à l'oiseau un prédicat PVPartagesAvec de valeur le nom du druide. Pour le faire agir en même temps que le druide, ajoutez aussi à l'oiseau un prédicat initiativeDeriveeDe de valeur le nom du druide. Pour l'attaque, ajouter sur la fiche une attaque de contact faisant 1d4 DM, avec dans les options --attaqueMagiqueDe nom de personnage du druide. Si vous souhaitez que le guetteur rentre en combat en même temps que le druide, ajoutez au druide un prédicat nommé entrerEnCombatAvec, de valeur le nom du token de l'oiseau.
    7. -
    8. Masque du prédateur : !cof-effet-temp masqueDuPredateur [[5+@{selected|SAG}]] --mana 2
    9. +
    10. Le guetteur : Si elle n'est pas d\xE9j\xE0 pr\xE9sente dans votre handout de comp\xE9tences, ajouter au druide une comp\xE9tence perception (valeur 0 pour le moment). Cr\xE9er un personnage et un token pour l'oiseau. Ajouter au druide un pr\xE9dicat guetteur de valeur le nom exact de l'oiseau (sur la fiche, attention \xE0 utiliser la symtaxe avec :: si le nom comporte des espaces). Ajouter de m\xEAme un pr\xE9dicat PVPartagesAvec de valeur le nom de l'oiseau. Ajouter aussi \xE0 l'oiseau un pr\xE9dicat PVPartagesAvec de valeur le nom du druide. Pour le faire agir en m\xEAme temps que le druide, ajoutez aussi \xE0 l'oiseau un pr\xE9dicat initiativeDeriveeDe de valeur le nom du druide. Pour l'attaque, ajouter sur la fiche une attaque de contact faisant 1d4 DM, avec dans les options --attaqueMagiqueDe nom de personnage du druide. Si vous souhaitez que le guetteur rentre en combat en m\xEAme temps que le druide, ajoutez au druide un pr\xE9dicat nomm\xE9 entrerEnCombatAvec, de valeur le nom du token de l'oiseau.
    11. +
    12. Masque du pr\xE9dateur : !cof-effet-temp masqueDuPredateur [[5+@{selected|SAG}]] --mana 2
    13. Forme animale : pas d'autre support que !cof-lancer-sort se transforme en ?{Transformation en ?} --mana 3

    Voie du fauve

      -
    1. Vitesse du félin : ajouter un prédicat vitesseDuFelin, de valeur le rang dans la voie. Pensez à ajouter des compétences de saut, escalade et course sur la fiche (sans les bonus !) s'ils ne sont pas déjà présent dans votre handout de compétences.
    2. -
    3. Panthère : ajouter un personnage pour la panthère, qui sera contrôlé par le joueur. Si vous souhaitez que la panthère rentre en combat à chaque fois que le druide entre en combat, ajoutez au druide un prédicat nommé entrerEnCombatAvec, de valeur le nom du token de la panthère (il peut y avoir plusieurs prédicats avec ce nom).
    4. -
    5. Attaque bondissante : faire l'attaque avec les options --bonusAttaque 5 --plus 1d6. Les conditions d'utilisation sont à vérifier par le MJ.
    6. -
    7. Grand félin : ajuster la fiche de la panthère, et pour le soin, utiliser !cof-soin @{selected|token_id} nom_familier ?{Montant des soins} --transfer.
    8. -
    9. Les sept vies du chat : pas de support particulier, la commande Undo peut être utilisée pour annuler l'action qui a mené le Druide à 0 PV.
    10. +
    11. Vitesse du f\xE9lin : ajouter un pr\xE9dicat vitesseDuFelin, de valeur le rang dans la voie. Pensez \xE0 ajouter des comp\xE9tences de saut, escalade et course sur la fiche (sans les bonus !) s'ils ne sont pas d\xE9j\xE0 pr\xE9sent dans votre handout de comp\xE9tences.
    12. +
    13. Panth\xE8re : ajouter un personnage pour la panth\xE8re, qui sera contr\xF4l\xE9 par le joueur. Si vous souhaitez que la panth\xE8re rentre en combat \xE0 chaque fois que le druide entre en combat, ajoutez au druide un pr\xE9dicat nomm\xE9 entrerEnCombatAvec, de valeur le nom du token de la panth\xE8re (il peut y avoir plusieurs pr\xE9dicats avec ce nom).
    14. +
    15. Attaque bondissante : faire l'attaque avec les options --bonusAttaque 5 --plus 1d6. Les conditions d'utilisation sont \xE0 v\xE9rifier par le MJ.
    16. +
    17. Grand f\xE9lin : ajuster la fiche de la panth\xE8re, et pour le soin, utiliser !cof-soin @{selected|token_id} nom_familier ?{Montant des soins} --transfer.
    18. +
    19. Les sept vies du chat : pas de support particulier, la commande Undo peut \xEAtre utilis\xE9e pour annuler l'action qui a men\xE9 le Druide \xE0 0 PV.

    Voie de la nature

      -
    1. Maître de la survie : Ajouter +2 par rang à une compétence vigilance
    2. -
    3. Marche sylvestre : ajouter un prédicat marcheSylvestre. Pour indiquer un terrain difficile, on peut utiliser les objets graphiques sur le layer des cartes (map en anglais). Pour cela, éditer l'objet, et ajouter dans les notes pour MJ une ligne terrainDifficile. Tout le dessin est considéré comme un terrain difficile. On peut restreindre la partie considérée comme difficile à un disque en écrivant terrainDifficile: disque nn est le diamètre du disque en pixels. À noter que la zone d'une prison végétale est considérée difficile par le script. Le druide est considéré en terrain difficile si vous le mettez dans l'état conditionsHostiles (pour des valeurs inférieures à 5). Alternativement, si vous n'avez pas ajouté le type de terrain vous pouvez taper !cof-effet marcheSylvestre oui quand le druide entre dans un terrain que vous considérez difficile. Dans ce cas, faire !cof-effet marcheSylvestre non quand il sort de cette zone.
    4. -
    5. Résistant : ajouter dans la RD sur la fiche, nature:v, avec comme valeur v la RD (donc deux fois le rang dans la voie). Cette RD s'applique à toute attaque ou dommages avec l'option --nature ou --naturel. Il s'applique aussi à toute attaque venant d'un personnage avec un prédicat animal, ou insecte ou bien avec un profil animal ou insecte, ou avec une race reconnue comme étant un animal ou un insecte. Dans ce cas, si on souhaite qu'une attaque d'une telle créature ne soit pas considérée comme naturelle, on peut utiliser l'option --artificiel à l'attaque.
    6. -
    7. Bâton de druide : Simplement créer l'attaque correspondante et permettre les deux attaques en action limitée.
    8. -
    9. Constitution héroïque : reporter sur la fiche
    10. +
    11. Ma\xEEtre de la survie : Ajouter +2 par rang \xE0 une comp\xE9tence vigilance
    12. +
    13. Marche sylvestre : ajouter un pr\xE9dicat marcheSylvestre. Pour indiquer un terrain difficile, on peut utiliser les objets graphiques sur le layer des cartes (map en anglais). Pour cela, \xE9diter l'objet, et ajouter dans les notes pour MJ une ligne terrainDifficile. Tout le dessin est consid\xE9r\xE9 comme un terrain difficile. On peut restreindre la partie consid\xE9r\xE9e comme difficile \xE0 un disque en \xE9crivant terrainDifficile: disque n o\xF9 n est le diam\xE8tre du disque en pixels. \xC0 noter que la zone d'une prison v\xE9g\xE9tale est consid\xE9r\xE9e difficile par le script. Le druide est consid\xE9r\xE9 en terrain difficile si vous le mettez dans l'\xE9tat conditionsHostiles (pour des valeurs inf\xE9rieures \xE0 5). Alternativement, si vous n'avez pas ajout\xE9 le type de terrain vous pouvez taper !cof-effet marcheSylvestre oui quand le druide entre dans un terrain que vous consid\xE9rez difficile. Dans ce cas, faire !cof-effet marcheSylvestre non quand il sort de cette zone.
    14. +
    15. R\xE9sistant : ajouter dans la RD sur la fiche, nature:v, avec comme valeur v la RD (donc deux fois le rang dans la voie). Cette RD s'applique \xE0 toute attaque ou dommages avec l'option --nature ou --naturel. Il s'applique aussi \xE0 toute attaque venant d'un personnage avec un pr\xE9dicat animal, ou insecte ou bien avec un profil animal ou insecte, ou avec une race reconnue comme \xE9tant un animal ou un insecte. Dans ce cas, si on souhaite qu'une attaque d'une telle cr\xE9ature ne soit pas consid\xE9r\xE9e comme naturelle, on peut utiliser l'option --artificiel \xE0 l'attaque.
    16. +
    17. B\xE2ton de druide : Simplement cr\xE9er l'attaque correspondante et permettre les deux attaques en action limit\xE9e.
    18. +
    19. Constitution h\xE9ro\xEFque : reporter sur la fiche

    Voie du protecteur

      -
    1. Baies magiques : Pour simplement créer les baies, on peut utiliser !cof-creer-baies, avec éventuellement des arguments pour la dépense de mana. Si le sort ne demande pas de dépense et que le temps passé n'est pas important, il peut être plus simple de directement utiliser !cof-distribuer-baies avec option --allies --self ou --target pour créer et donner des baies (en ayant sélectionné le druide, le mieux est d'utiliser une ability). Pour consommer ensuite une baie, il faut utiliser !cof-consommables.
    2. -
    3. Forêt vivante : on peut mettre un effet (avec !cof-effet) foretVivanteEnnemie aux personnages affectés. Par exemple, si on veut donner l'effet aux personnages non alliés du druide, on peut faire !cof-effet foretVivanteEnnemie oui --disque @{selected|token_id} 2000 --saufAllies --mana 0. Attention, l'effet ne disparaît que si on fait un !cof-effet foretVivanteEnnemie non sur les personnages.
    4. -
    5. Régénération : !cof-effet-temp regeneration [[@{selected|niveau} + @{selected|SAG}]] --lanceur @{selected|token_id} --target @{target|token_id} --limiteCibleParJour 1 --portee 0 --mana 1.
    6. -
    7. Forme d'arbre : !cof-effet-temp formeDArbre [[5+@{selected|SAG}]] --mana 2. J'ai choisi de donner comme pouvoir supplémentaire à cette forme d'avoir ses propres PVs, et le druide récupère ses PVs originaux à la fin de l'effet. La transformation est annulée aussi si l'arbre perd tous ses PVs. Le nombre de PVs par défaut est de niveau x 5, mais il peut être modifié en ajoutant au argument --valeur pv. Pour augmenter un peu l'intérêt de ce sort, je lui fais aussi augmenter de 50% le bonus de peau d'écorce. Si vous utilisez les actions à afficher à chaque tour, vous pouvez aussi créer une liste d'actions nommée Forme d'arbre contenant les sorts et actions possibles en forme d'arbre. Si une telle liste existe, elle va toujours afficher au moins les actions défensive, d'attente et d'attaque sous forme d'arbre (pas besoin de créer une attaque dédiée sur la fiche). Il est possible de spécifier une image pour le token en forme d'arbre, en utilisant le valeur d'un prédicat tokenFormeDArbre.
    8. -
    9. Sagesse héroïque : reporter sur la fiche
    10. +
    11. Baies magiques : Pour simplement cr\xE9er les baies, on peut utiliser !cof-creer-baies, avec \xE9ventuellement des arguments pour la d\xE9pense de mana. Si le sort ne demande pas de d\xE9pense et que le temps pass\xE9 n'est pas important, il peut \xEAtre plus simple de directement utiliser !cof-distribuer-baies avec option --allies --self ou --target pour cr\xE9er et donner des baies (en ayant s\xE9lectionn\xE9 le druide, le mieux est d'utiliser une ability). Pour consommer ensuite une baie, il faut utiliser !cof-consommables.
    12. +
    13. For\xEAt vivante : on peut mettre un effet (avec !cof-effet) foretVivanteEnnemie aux personnages affect\xE9s. Par exemple, si on veut donner l'effet aux personnages non alli\xE9s du druide, on peut faire !cof-effet foretVivanteEnnemie oui --disque @{selected|token_id} 2000 --saufAllies --mana 0. Attention, l'effet ne dispara\xEEt que si on fait un !cof-effet foretVivanteEnnemie non sur les personnages.
    14. +
    15. R\xE9g\xE9n\xE9ration : !cof-effet-temp regeneration [[@{selected|niveau} + @{selected|SAG}]] --lanceur @{selected|token_id} --target @{target|token_id} --limiteCibleParJour 1 --portee 0 --mana 1.
    16. +
    17. Forme d'arbre : !cof-effet-temp formeDArbre [[5+@{selected|SAG}]] --mana 2. J'ai choisi de donner comme pouvoir suppl\xE9mentaire \xE0 cette forme d'avoir ses propres PVs, et le druide r\xE9cup\xE8re ses PVs originaux \xE0 la fin de l'effet. La transformation est annul\xE9e aussi si l'arbre perd tous ses PVs. Le nombre de PVs par d\xE9faut est de niveau x 5, mais il peut \xEAtre modifi\xE9 en ajoutant au argument --valeur pv. Pour augmenter un peu l'int\xE9r\xEAt de ce sort, je lui fais aussi augmenter de 50% le bonus de peau d'\xE9corce. Si vous utilisez les actions \xE0 afficher \xE0 chaque tour, vous pouvez aussi cr\xE9er une liste d'actions nomm\xE9e Forme d'arbre contenant les sorts et actions possibles en forme d'arbre. Si une telle liste existe, elle va toujours afficher au moins les actions d\xE9fensive, d'attente et d'attaque sous forme d'arbre (pas besoin de cr\xE9er une attaque d\xE9di\xE9e sur la fiche). Il est possible de sp\xE9cifier une image pour le token en forme d'arbre, en utilisant le valeur d'un pr\xE9dicat tokenFormeDArbre.
    18. +
    19. Sagesse h\xE9ro\xEFque : reporter sur la fiche
    -

    Voie des végétaux

    +

    Voie des v\xE9g\xE9taux

      -
    1. Peau d'écorce : !cof-effet-temp peauDEcorce [[5+@{selected|SAG}]] --mana 0. Par défaut, utilise la valeur d'un prédicat voieDesVegetaux (qui devrait avoir comme valeur le rang dans la voie). Il est possible de choisir une autre valeur en utilisant l'option --valeur, et si aucune des deux méthodes n'est utilisée, le bonus de DEF est de 1.
    2. -
    3. Prison végétale : !cof-effet-temp prisonVegetale [[5+@{selected|SAG}]] --saveActifParTour FOR [[10+@{selected|SAG}]] --lanceur @{selected|token_id} --disque @{target|token_id} 5 20 --saufAllies --mana 0.
    4. -
    5. Animation d'un arbre : !cof-animer-arbre @{selected|token_id} @{target|token_id} --portee 0 --mana 1. Cela implique d'avoir un token représentant l'arbre sur la carte. Ce que je fais, c'est de passer un token d'arbre du layer map au layer tokens, puis je laisse le joueur faire le sort. Si c'est trop compliqué, vous pouvez aussi préparer un personnage arbre, avec les caractéristiques décrites, et le faire arriver sur la carte à la main (ne pas oublier sa RD 10/feu_hache, dans ce cas).
    6. +
    7. Peau d'\xE9corce : !cof-effet-temp peauDEcorce [[5+@{selected|SAG}]] --mana 0. Par d\xE9faut, utilise la valeur d'un pr\xE9dicat voieDesVegetaux (qui devrait avoir comme valeur le rang dans la voie). Il est possible de choisir une autre valeur en utilisant l'option --valeur, et si aucune des deux m\xE9thodes n'est utilis\xE9e, le bonus de DEF est de 1.
    8. +
    9. Prison v\xE9g\xE9tale : !cof-effet-temp prisonVegetale [[5+@{selected|SAG}]] --saveActifParTour FOR [[10+@{selected|SAG}]] --lanceur @{selected|token_id} --disque @{target|token_id} 5 20 --saufAllies --mana 0.
    10. +
    11. Animation d'un arbre : !cof-animer-arbre @{selected|token_id} @{target|token_id} --portee 0 --mana 1. Cela implique d'avoir un token repr\xE9sentant l'arbre sur la carte. Ce que je fais, c'est de passer un token d'arbre du layer map au layer tokens, puis je laisse le joueur faire le sort. Si c'est trop compliqu\xE9, vous pouvez aussi pr\xE9parer un personnage arbre, avec les caract\xE9ristiques d\xE9crites, et le faire arriver sur la carte \xE0 la main (ne pas oublier sa RD 10/feu_hache, dans ce cas).
    12. Gland de pouvoir :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateur pasDeDmg, options --mana 2 --effet statueDeBois [[2d6+@{selected|SAG}]] --valeur 10 10. À noter qu'un prédicat immunite_petrification permet d'être immunisé à cet effet.
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateur pasDeDmg, options --mana 2 --effet statueDeBois [[2d6+@{selected|SAG}]] --valeur 10 10. \xC0 noter qu'un pr\xE9dicat immunite_petrification permet d'\xEAtre immunis\xE9 \xE0 cet effet.
      • Objet de sort : #Attaque Gland de pouvoir --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --effet statueDeBois [[2d6+@{selected|SAG}]] --valeur 10 10
    13. -
    14. Porte végétale : Pas de support au niveau du script, à part !cof-lancer-sort lance un sort de porte végétale --mana 3.
    15. +
    16. Porte v\xE9g\xE9tale : Pas de support au niveau du script, \xE0 part !cof-lancer-sort lance un sort de porte v\xE9g\xE9tale --mana 3.

    Ensorceleur

    @@ -1252,225 +1255,225 @@

    Voie de l'air

  • Sous tension :
    1. !cof-effet-temp sousTension [[5+@{selected|CHA}]] --mana 0 pour lancer le sort et mettre l'ensorceleur sous tension
    2. -
    3. Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+CHA, portée 10, type Sortilège, dégâts électriques, options --si etat sousTension --fx beam-holy.
    4. -
    5. Pour les objets de sorts, on peut mettre l'attaque directement sous la forme #Attaque Décharge électrique --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|CHA}]] --electrique --portee 10 --sortilege --si etat sousTension --fx beam-holy
    6. +
    7. Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+CHA, port\xE9e 10, type Sortil\xE8ge, d\xE9g\xE2ts \xE9lectriques, options --si etat sousTension --fx beam-holy.
    8. +
    9. Pour les objets de sorts, on peut mettre l'attaque directement sous la forme #Attaque D\xE9charge \xE9lectrique --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|CHA}]] --electrique --portee 10 --sortilege --si etat sousTension --fx beam-holy
  • - Note : Il est possible de spécifier une autre valeur pour les DM automatiques quand le lanceur est touché en contact, en rajoutant --valeur X à la première ability. + Note : Il est possible de sp\xE9cifier une autre valeur pour les DM automatiques quand le lanceur est touch\xE9 en contact, en rajoutant --valeur X \xE0 la premi\xE8re ability. -
  • Télékinésie : Pas de support autre que !cof-lancer-sort lance un sort de télékinésie --mana 1
  • +
  • T\xE9l\xE9kin\xE9sie : Pas de support autre que !cof-lancer-sort lance un sort de t\xE9l\xE9kin\xE9sie --mana 1
  • Foudre :
      -
    • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, 4d6+CHA, portée 10, type Sortilège, options --mana 2 --psave DEX [[12+@{selected|DEX}]] --ligne --fx beam-holy.
    • +
    • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, 4d6+CHA, port\xE9e 10, type Sortil\xE8ge, options --mana 2 --psave DEX [[12+@{selected|DEX}]] --ligne --fx beam-holy.
    • Objet de sort : #Attaque Foudre --toucher [[@{selected|ATKMAG}]] --dm 4d6+[[@{selected|CHA}]] --portee 10 --sortilege --psave DEX [[12+@{selected|DEX}]] --ligne --fx beam-holy
  • -
  • Forme éthérée : !cof-effet-temp intangible [[5 + @{selected|CHA}]] --mana 3. Pour implémentaer des variantes, il existe aussi un effet intangibleInvisible qui cumule les états intangible et invisible, et l'option --puissant donne la possibilité au personnage de passer entre l'état tangible et intangible à chaque tour, tant que dure l'effet.
  • +
  • Forme \xE9th\xE9r\xE9e : !cof-effet-temp intangible [[5 + @{selected|CHA}]] --mana 3. Pour impl\xE9mentaer des variantes, il existe aussi un effet intangibleInvisible qui cumule les \xE9tats intangible et invisible, et l'option --puissant donne la possibilit\xE9 au personnage de passer entre l'\xE9tat tangible et intangible \xE0 chaque tour, tant que dure l'effet.
  • Voie de la divination

      -
    1. 6eme sens : ajouter le bonus en DEF divers et initiative diver, ajouter une compétence vigilance, de valeur 2*rang (le bonus aux jet de surprise).
    2. -
    3. Détection de l'invisible : !cof-effet-temp detectionDeLInvisible [[5+@{selected|CHA}]] --mana 0.
    4. -
    5. Clairvoyance : !cof-lancer-sort peut voir et entendre à distance --mana 1
    6. -
    7. Prescience : ajouter un prédicat prescience (on peut y associer un nombre pour avoir plus d'une prescience par tour). Si le personnage était sur la carte au moment de lancer le combat, il se verra proposer un bouton pour utiliser sa prescience à la fin de chaque tour. Attention, en l'état, il est impossible d'annuler l'utilisation de ce bouton. De plus, ce bouton ne fera rien si le script a été interrompu depuis le début du tour (interruption de la partie, redémarrage du script, etc...).
    8. +
    9. 6eme sens : ajouter le bonus en DEF divers et initiative diver, ajouter une comp\xE9tence vigilance, de valeur 2*rang (le bonus aux jet de surprise).
    10. +
    11. D\xE9tection de l'invisible : !cof-effet-temp detectionDeLInvisible [[5+@{selected|CHA}]] --mana 0.
    12. +
    13. Clairvoyance : !cof-lancer-sort peut voir et entendre \xE0 distance --mana 1
    14. +
    15. Prescience : ajouter un pr\xE9dicat prescience (on peut y associer un nombre pour avoir plus d'une prescience par tour). Si le personnage \xE9tait sur la carte au moment de lancer le combat, il se verra proposer un bouton pour utiliser sa prescience \xE0 la fin de chaque tour. Attention, en l'\xE9tat, il est impossible d'annuler l'utilisation de ce bouton. De plus, ce bouton ne fera rien si le script a \xE9t\xE9 interrompu depuis le d\xE9but du tour (interruption de la partie, red\xE9marrage du script, etc...).
    16. Hyperconscience : reporter sur la fiche.
    -

    Voie de l'envoûteur

    +

    Voie de l'envo\xFBteur

    1. Injonction : utiliser !cof-injonction @{selected|token_id} @{target|token_id} --portee 20 --mana 0
    2. -
    3. Sommeil : !cof-sommeil @{selected|token_id} --disque @{target|token_id} 5 20 --mana 0. Pour sélectionner le centre de la zone, on peut utiliser un personnage fictif (avec un token représentant une cible, par exemple) ayant 0 de max de PV.
    4. +
    5. Sommeil : !cof-sommeil @{selected|token_id} --disque @{target|token_id} 5 20 --mana 0. Pour s\xE9lectionner le centre de la zone, on peut utiliser un personnage fictif (avec un token repr\xE9sentant une cible, par exemple) ayant 0 de max de PV.
    6. Confusion:
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg options --mana 1 --attaqueMentale --effet confusion [[3+@{selected|CHA}]] --saveParTour SAG [[10+@{selected|CHA}]].
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg options --mana 1 --attaqueMentale --effet confusion [[3+@{selected|CHA}]] --saveParTour SAG [[10+@{selected|CHA}]].
      • Objet de sort : #Attaque Confusion --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --attaqueMentale --effet confusion [[3+@{selected|CHA}]] --saveParTour SAG [[10+@{selected|CHA}]]
    7. -
    8. Amitié: +
    9. Amiti\xE9:
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg options --mana 2 --attaqueMentale --difficultePVmax --effet charme --save SAG [[12+@{selected|CHA}]] --saveParJour SAG [[12+@{selected|CHA}]].
      • -
      • Objet de sort : #Attaque Amitié --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --attaqueMentale --difficultePVmax --effet charme --save SAG [[12+@{selected|CHA}]] --saveParJour SAG [[12+@{selected|CHA}]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg options --mana 2 --attaqueMentale --difficultePVmax --effet charme --save SAG [[12+@{selected|CHA}]] --saveParJour SAG [[12+@{selected|CHA}]].
      • +
      • Objet de sort : #Attaque Amiti\xE9 --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --attaqueMentale --difficultePVmax --effet charme --save SAG [[12+@{selected|CHA}]] --saveParJour SAG [[12+@{selected|CHA}]]
    10. Domination : utiliser !cof-attaque-magique @{selected|token_id} @{target|token_id} --portee 20 --attaqueMentale

    Voie des illusions

      -
    1. Image décalée : !cof-effet-temp imageDecalee [[5+@{selected|CHA}]] --mana 0.
    2. +
    3. Image d\xE9cal\xE9e : !cof-effet-temp imageDecalee [[5+@{selected|CHA}]] --mana 0.
    4. Mirage : pas de support autre que !cof-lancer-sort lance un sort de mirage ([[5+@{selected|CHA}]] minutes) --mana 0
    5. Imitation : pas de support autre que !cof-lancer-sort lance un sort d'imitation ([[5+@{selected|CHA}]] minutes) --mana 1
    6. -
    7. Dédoublement : +
    8. D\xE9doublement :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg options --mana 2 --effet dedoublement [[5+@{selected|CHA}]].
      • -
      • Objet de sort : #Attaque Dédoublement --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet dedoublement [[5+@{selected|CHA}]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg options --mana 2 --effet dedoublement [[5+@{selected|CHA}]].
      • +
      • Objet de sort : #Attaque D\xE9doublement --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet dedoublement [[5+@{selected|CHA}]]
    9. -
    10. Tueur fantasmagorique : !cof-tueur-fantasmagorique @{selected|token_id} @{target|token_id} --portee 20 --mana 3. Attention, j'en ai fait une interprétation un peu personnelle : au lieu de ne pas pouvoir toucher les cibles de niveau supérieur au lanceur, les cible de niveau supérieur gagnent un bonus de 5 par niveau au dessus de celui du lanceur pour résister au tueur fantasmagorique. Et ceux de niveau inférieur un malus de 1 par niveau de différence. Si cette interprétation ne vous convient pas, n'hésitez pas à me demander des changements.
    11. +
    12. Tueur fantasmagorique : !cof-tueur-fantasmagorique @{selected|token_id} @{target|token_id} --portee 20 --mana 3. Attention, j'en ai fait une interpr\xE9tation un peu personnelle : au lieu de ne pas pouvoir toucher les cibles de niveau sup\xE9rieur au lanceur, les cible de niveau sup\xE9rieur gagnent un bonus de 5 par niveau au dessus de celui du lanceur pour r\xE9sister au tueur fantasmagorique. Et ceux de niveau inf\xE9rieur un malus de 1 par niveau de diff\xE9rence. Si cette interpr\xE9tation ne vous convient pas, n'h\xE9sitez pas \xE0 me demander des changements.

    Voie de l'invocation

      -
    1. Familier : créer un personnage (de type PNJ) pour le familier, controlé par le joueur et avec un token lié ayant la capacité de voir. +
    2. Familier : cr\xE9er un personnage (de type PNJ) pour le familier, control\xE9 par le joueur et avec un token li\xE9 ayant la capacit\xE9 de voir.
        -
      • Pour le bonus en initiative, ajouter un prédicat familier au personnage, avec comme valeur le nom du compagnon (doit être exactement le même que celui du token du compagnon). Cela automatise l'initiative quand le familier est présent.
      • -
      • Pour les points de vie partagés avec le familier, il faut mettre un prédicat PVPartagesAvec de valeur le nom du familier (celui de la fiche, pas forcément le même que le token) pour le personnage, et un prédicat similaire chez le familier, de valeur le nom du personnage. Le partage de PVs ne fonctionne pas avec des mooks, et il ne fait pas le partage de dégâts temporaires. En revanche, le script devrait gérer correctement les dégâts de zone.
      • -
      • Pour la défense du familier, lui ajouter un prédicat defDeriveeDe, de valeur le nom du personnage (nom complet sur la fiche, attention à bien utiliser la syntaxe avec :: si ce nom contient des espaces ou autres caractères spéciaux).
      • -
      • L'initiative ne devrait pas être très utile, mais si besoin, ajoutez un prédicat initiativeDeriveeDe de valeur le nom du personnage. En fait, pour les familiers normaux, je préfères même qu'ils n'apparaissent pas sur le turn tracker, et je leur met donc un prédicat aucuneActionCombat.
      • +
      • Pour le bonus en initiative, ajouter un pr\xE9dicat familier au personnage, avec comme valeur le nom du compagnon (doit \xEAtre exactement le m\xEAme que celui du token du compagnon). Cela automatise l'initiative quand le familier est pr\xE9sent.
      • +
      • Pour les points de vie partag\xE9s avec le familier, il faut mettre un pr\xE9dicat PVPartagesAvec de valeur le nom du familier (celui de la fiche, pas forc\xE9ment le m\xEAme que le token) pour le personnage, et un pr\xE9dicat similaire chez le familier, de valeur le nom du personnage. Le partage de PVs ne fonctionne pas avec des mooks, et il ne fait pas le partage de d\xE9g\xE2ts temporaires. En revanche, le script devrait g\xE9rer correctement les d\xE9g\xE2ts de zone.
      • +
      • Pour la d\xE9fense du familier, lui ajouter un pr\xE9dicat defDeriveeDe, de valeur le nom du personnage (nom complet sur la fiche, attention \xE0 bien utiliser la syntaxe avec :: si ce nom contient des espaces ou autres caract\xE8res sp\xE9ciaux).
      • +
      • L'initiative ne devrait pas \xEAtre tr\xE8s utile, mais si besoin, ajoutez un pr\xE9dicat initiativeDeriveeDe de valeur le nom du personnage. En fait, pour les familiers normaux, je pr\xE9f\xE8res m\xEAme qu'ils n'apparaissent pas sur le turn tracker, et je leur met donc un pr\xE9dicat aucuneActionCombat.
    3. -
    4. Serviteur invisible : pas de support autre que !cof-lancer-sort crée une force invisible pour ([[5+@{selected|CHA}]] minutes) --mana 0
    5. -
    6. Mur de force : !cof-mur-de-force ?{Spherique?|Oui,&#32;|Non,mur} --mana 1. Cela affiche une image d'un champ de force, mais seulement si il est sphérique. Il est possible de ne pas afficher d'image avec la commande !cof-mur-de-force noImage. Il est possible d'utiliser une autre image que l'image par défaut en utilisant la commande !cof-mur-de-force pathpath est l'adresse url d'une image de la librairie Roll20 qui représente un mur de force sphérique. On peut aussi changer l'image par défaut dans les options de jeu.
    7. -
    8. Épée dansante : +
    9. Serviteur invisible : pas de support autre que !cof-lancer-sort cr\xE9e une force invisible pour ([[5+@{selected|CHA}]] minutes) --mana 0
    10. +
    11. Mur de force : !cof-mur-de-force ?{Spherique?|Oui,&#32;|Non,mur} --mana 1. Cela affiche une image d'un champ de force, mais seulement si il est sph\xE9rique. Il est possible de ne pas afficher d'image avec la commande !cof-mur-de-force noImage. Il est possible d'utiliser une autre image que l'image par d\xE9faut en utilisant la commande !cof-mur-de-force path o\xF9 path est l'adresse url d'une image de la librairie Roll20 qui repr\xE9sente un mur de force sph\xE9rique. On peut aussi changer l'image par d\xE9faut dans les options de jeu.
    12. +
    13. \xC9p\xE9e dansante :
      • !cof-effet-temp epeeDansante [[5+@{selected|CHA}]] --mana 2 pour lancer le sort
      • -
      • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+CHA, portée 20, type Sortilège, dégâts magiques, options --si etat epeeDansante --ignoreObstacles.
      • -
      • Pour les objets de sort, on peut utiliser une action #Attaque Épée dansante --toucher [[@{selected|ATKMAG}]] --dm 1d8+[[@{selected|CHA}]] --magique --portee 20 --sortilege --si etat epeeDansante --ignoreObstacles
      • +
      • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+CHA, port\xE9e 20, type Sortil\xE8ge, d\xE9g\xE2ts magiques, options --si etat epeeDansante --ignoreObstacles.
      • +
      • Pour les objets de sort, on peut utiliser une action #Attaque \xC9p\xE9e dansante --toucher [[@{selected|ATKMAG}]] --dm 1d8+[[@{selected|CHA}]] --magique --portee 20 --sortilege --si etat epeeDansante --ignoreObstacles
      - Pour une rapière dansante, il existe aussi un effet temporaire rapiereDansante. + Pour une rapi\xE8re dansante, il existe aussi un effet temporaire rapiereDansante.
    14. -
    15. Charisme héroïque : reporter sur la fiche
    16. +
    17. Charisme h\xE9ro\xEFque : reporter sur la fiche

    Forgesort

    Voie des artefacts

      -
    1. Bâton de mage : simplement adapter l'attaque, avec aussi le modificateur magique. Pour l'éclair d'énergie, ajoutez dans les options ?{Attaque|Normale,--magieRapide 2|Éclair d'énergie (L),--eclairDEnergie}. Si vous autorisez les règles de mana pour cette attaque, remplacez par ?{Attaque|Normale,&#32;|Éclair d'énergie (L),--eclairDEnergie|Éclair d'énergie rapide, --eclairDEnergie --magieRapide|Éclair d'énergie puissant (L), --eclairDEnergie --tempeteDeMana 1}.
    2. -
    3. Blocage : pas de support autre que !cof-lancer-sort scelle une porte ou un coffre (+5 solidité & RD) pour [[@{selected|INT}]] minutes --mana 0
    4. +
    5. B\xE2ton de mage : simplement adapter l'attaque, avec aussi le modificateur magique. Pour l'\xE9clair d'\xE9nergie, ajoutez dans les options ?{Attaque|Normale,--magieRapide 2|\xC9clair d'\xE9nergie (L),--eclairDEnergie}. Si vous autorisez les r\xE8gles de mana pour cette attaque, remplacez par ?{Attaque|Normale,&#32;|\xC9clair d'\xE9nergie (L),--eclairDEnergie|\xC9clair d'\xE9nergie rapide, --eclairDEnergie --magieRapide|\xC9clair d'\xE9nergie puissant (L), --eclairDEnergie --tempeteDeMana 1}.
    6. +
    7. Blocage : pas de support autre que !cof-lancer-sort scelle une porte ou un coffre (+5 solidit\xE9 & RD) pour [[@{selected|INT}]] minutes --mana 0
    8. Sac sans fond : pas de support particulier
    9. -
    10. Frappe des arcanes : le plus simple est d'utiliser la même ligne d'attaque (disons que son label est E) que pour l'attaque d'énergie (mais si besoin, rien n'empêche d'en utiliser une autre). La commande sera alors !cof-explosion E --auto --magique --sortilege --portee 10 --etat renverse --save FOR [[10+@{selected|INT}]].
    11. +
    12. Frappe des arcanes : le plus simple est d'utiliser la m\xEAme ligne d'attaque (disons que son label est E) que pour l'attaque d'\xE9nergie (mais si besoin, rien n'emp\xEAche d'en utiliser une autre). La commande sera alors !cof-explosion E --auto --magique --sortilege --portee 10 --etat renverse --save FOR [[10+@{selected|INT}]].
    13. Artefact majeur : pas de support particulier
    -

    Voie des élixirs

    -

    Pour créer ou juste voir ses élixirs, utiliser la commande !cof-elixirs. Pour cela, il faut aussi un prédicat voieDesElixirs avec comme valeur le rang dans la voie. Noter que la commande !cof-elixirs affiche une liste d'élixirs, et que pour effectivement créer un élixir, il faut cliquer sur le bouton correspondant dans cette liste. Le script propose les élixirs par défaut du jeu, mais vous pouvez modifier cette liste : pour changer un élixir de rang k (k<4), ajouter un attribut de nom Elixir k, de valeur courante le nom et de valeur maximale l'effet.

    +

    Voie des \xE9lixirs

    +

    Pour cr\xE9er ou juste voir ses \xE9lixirs, utiliser la commande !cof-elixirs. Pour cela, il faut aussi un pr\xE9dicat voieDesElixirs avec comme valeur le rang dans la voie. Noter que la commande !cof-elixirs affiche une liste d'\xE9lixirs, et que pour effectivement cr\xE9er un \xE9lixir, il faut cliquer sur le bouton correspondant dans cette liste. Le script propose les \xE9lixirs par d\xE9faut du jeu, mais vous pouvez modifier cette liste : pour changer un \xE9lixir de rang k (k<4), ajouter un attribut de nom Elixir k, de valeur courante le nom et de valeur maximale l'effet.

      -
    1. Fortifiant : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables. Si vous souhaitez avoir une potion de fortifiant indépendament de cette Voie (par exemple achetée dans une échope), vous pouvez ajouter un consommable avec l'effet !cof-fortifiant n, où n est le rang dans la Voie du forgesort qui a créé la potion.
    2. -
    3. Feu grégeois : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
    4. -
    5. Élixir de guérison : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
    6. -
    7. Potion magique : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
    8. -
    9. Élixirs magiques : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
    10. +
    11. Fortifiant : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables. Si vous souhaitez avoir une potion de fortifiant ind\xE9pendament de cette Voie (par exemple achet\xE9e dans une \xE9chope), vous pouvez ajouter un consommable avec l'effet !cof-fortifiant n, o\xF9 n est le rang dans la Voie du forgesort qui a cr\xE9\xE9 la potion.
    12. +
    13. Feu gr\xE9geois : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
    14. +
    15. \xC9lixir de gu\xE9rison : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
    16. +
    17. Potion magique : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
    18. +
    19. \xC9lixirs magiques : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
    -

    Voie du métal

    +

    Voie du m\xE9tal

      -
    1. Forgeron : Il faut un prédicat voieDuMetal pour connaître le rang (ou utiliser l'option --valeur). Lancer le sort avec !cof-effet-temp forgeron(L) [[5+@{selected|INT}]]L est le label d'une attaque. Ensuite, chaque fois que cette attaque sera utilisée, les dégâts seront ajoutés. Limitations : si deux attaques utilisent la même arme, il faut faire deux fois l'action, une pour chaque attaque.
    2. -
    3. Métal brûlant : +
    4. Forgeron : Il faut un pr\xE9dicat voieDuMetal pour conna\xEEtre le rang (ou utiliser l'option --valeur). Lancer le sort avec !cof-effet-temp forgeron(L) [[5+@{selected|INT}]] o\xF9 L est le label d'une attaque. Ensuite, chaque fois que cette attaque sera utilis\xE9e, les d\xE9g\xE2ts seront ajout\xE9s. Limitations : si deux attaques utilisent la m\xEAme arme, il faut faire deux fois l'action, une pour chaque attaque.
    5. +
    6. M\xE9tal br\xFBlant :
        -
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg options --mana 0 --effet ?{Chauffer|une arme,armeBrulante|une armure,armureBrulante} [[5+@{selected|INT}]].
      • -
      • Objet de sort : #Attaque Métal brûlant --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet ?{Chauffer|une arme,armeBrulante|une armure,armureBrulante} [[5+@{selected|INT}]]
      • +
      • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg options --mana 0 --effet ?{Chauffer|une arme,armeBrulante|une armure,armureBrulante} [[5+@{selected|INT}]].
      • +
      • Objet de sort : #Attaque M\xE9tal br\xFBlant --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet ?{Chauffer|une arme,armeBrulante|une armure,armureBrulante} [[5+@{selected|INT}]]
      - Pour mettre fin à l'effet (si la cible lâche son arme ou enlève son armure), vous pouvez utiliser la macro !cof-effet-temp ?{Se débarrasser d'une |arme,armeBrulante|armure,armureBrulante} 0 + Pour mettre fin \xE0 l'effet (si la cible l\xE2che son arme ou enl\xE8ve son armure), vous pouvez utiliser la macro !cof-effet-temp ?{Se d\xE9barrasser d'une |arme,armeBrulante|armure,armureBrulante} 0
    7. -
    8. Magnétisme : !cof-effet-temp magnetisme [[3+@{selected|INT}]] --mana 1. L'effet n'est actif que contre les attaques ayant l'option --metal. Il est possible de changer le bonus de DEF apporté avec l'option --valeur.
    9. -
    10. Métal hurlant :
    11. +
    12. Magn\xE9tisme : !cof-effet-temp magnetisme [[3+@{selected|INT}]] --mana 1. L'effet n'est actif que contre les attaques ayant l'option --metal. Il est possible de changer le bonus de DEF apport\xE9 avec l'option --valeur.
    13. +
    14. M\xE9tal hurlant :
    15. Endurer : reporter les bonus sur la fiche

    Voie du golem

      -
    1. Grosse tête : Vous pouvez ajouter un prédicat grosseTete. Normalement, le bonus devrait dépendre des actions du forgesort. Si vous souhaitez le faire, vous pouvez ne pas mettre le prédicat, mais juste avant un jet de force pour lequel vous pensez que la grosse tête s'applique, faire !cof-set-predicate grosseTete true (en sélectionnant le token du forgesort), puis après le jet faire !cof-set-predicate grosseTete false. Si vous voulez l'ajout de grosse tête par défaut, vous pouvez aussi faire l'opération dans l'ordre inverse pour les jets pour lesquels vous pensez que le bonus ne peut pas s'appliquer.
    2. -
    3. Golem : ajouter un personnage et un token pour le golem (ne pas oublier le prédicat nonVivant pour le golem). Pour les réparations, utiliser !cof-soin @{selected|token_id} nom_du_golem rangd6+@{selected|INT}. Bien remplacer rang par le rang dans la voie, dans cette commande. Attention, le nom du golem est celui du token représentant le golem, et il ne doit pas contenir de blanc.
    4. -
    5. Protecteur : !cof-interposer permet de s'interposer à la place de la cible de la dernière attaque. (Attention, pas de undo pour cette action)
    6. -
    7. Golem supérieur : reporter les avantages sur la fiche du golem.
    8. -
    9. Intelligence héroïque : reporter sur la fiche
    10. +
    11. Grosse t\xEAte : Vous pouvez ajouter un pr\xE9dicat grosseTete. Normalement, le bonus devrait d\xE9pendre des actions du forgesort. Si vous souhaitez le faire, vous pouvez ne pas mettre le pr\xE9dicat, mais juste avant un jet de force pour lequel vous pensez que la grosse t\xEAte s'applique, faire !cof-set-predicate grosseTete true (en s\xE9lectionnant le token du forgesort), puis apr\xE8s le jet faire !cof-set-predicate grosseTete false. Si vous voulez l'ajout de grosse t\xEAte par d\xE9faut, vous pouvez aussi faire l'op\xE9ration dans l'ordre inverse pour les jets pour lesquels vous pensez que le bonus ne peut pas s'appliquer.
    12. +
    13. Golem : ajouter un personnage et un token pour le golem (ne pas oublier le pr\xE9dicat nonVivant pour le golem). Pour les r\xE9parations, utiliser !cof-soin @{selected|token_id} nom_du_golem rangd6+@{selected|INT}. Bien remplacer rang par le rang dans la voie, dans cette commande. Attention, le nom du golem est celui du token repr\xE9sentant le golem, et il ne doit pas contenir de blanc.
    14. +
    15. Protecteur : !cof-interposer permet de s'interposer \xE0 la place de la cible de la derni\xE8re attaque. (Attention, pas de undo pour cette action)
    16. +
    17. Golem sup\xE9rieur : reporter les avantages sur la fiche du golem.
    18. +
    19. Intelligence h\xE9ro\xEFque : reporter sur la fiche

    Voie des runes

    -

    Ajouter un prédicat voieDesRunes pour le personnage avec comme valeur le niveau dans la voie des Runes.

    +

    Ajouter un pr\xE9dicat voieDesRunes pour le personnage avec comme valeur le niveau dans la voie des Runes.

      -
    1. Runes de défense : Rien à faire, le prédicat voieDesRunes est pris en compte dans le calcule de la DEF.
    2. -
    3. Rune d'énergie : La fabrication des runes de combat est gérée par la commande !cof-runes (il est fortement conseillé de créer une ability pour le forgesort). Le script tente de détecter quand les runes peuvent être utilisées en combat et propose un bouton (à la manière des points de chance). Lors de chaque nuit (utilisation de la commande !cof-nouveau-jour) toutes les runes sont retirées, mais le script va suggérer des raccourcis au forgesort pour les restaurer facilement à tous les tokens présents sur la page des joueurs (par personnage, type de rune, et aussi un bouton "Tout renouveler"). Les points de mana sont automatiquement décomptés.
    4. -
    5. Rune de protection : cf. ci-dessus. Le script implémente par défaut un maximum de dommages absorbés par la rune équivalent au rang du forgesort dans la voie des Runes multiplié par 10. Il est possible de désactiver cette limitation via !cof-options.
    6. -
    7. Rune de puissance : cf. ci-dessus. Créer une rune de puissance vous demandera d'indiquer en plus le numéro de l'arme sur la fiche du propriétaire.
    8. -
    9. Rune de pouvoir : pas de support particulier, créer l'objet de pouvoir approprié.
    10. +
    11. Runes de d\xE9fense : Rien \xE0 faire, le pr\xE9dicat voieDesRunes est pris en compte dans le calcule de la DEF.
    12. +
    13. Rune d'\xE9nergie : La fabrication des runes de combat est g\xE9r\xE9e par la commande !cof-runes (il est fortement conseill\xE9 de cr\xE9er une ability pour le forgesort). Le script tente de d\xE9tecter quand les runes peuvent \xEAtre utilis\xE9es en combat et propose un bouton (\xE0 la mani\xE8re des points de chance). Lors de chaque nuit (utilisation de la commande !cof-nouveau-jour) toutes les runes sont retir\xE9es, mais le script va sugg\xE9rer des raccourcis au forgesort pour les restaurer facilement \xE0 tous les tokens pr\xE9sents sur la page des joueurs (par personnage, type de rune, et aussi un bouton "Tout renouveler"). Les points de mana sont automatiquement d\xE9compt\xE9s.
    14. +
    15. Rune de protection : cf. ci-dessus. Le script impl\xE9mente par d\xE9faut un maximum de dommages absorb\xE9s par la rune \xE9quivalent au rang du forgesort dans la voie des Runes multipli\xE9 par 10. Il est possible de d\xE9sactiver cette limitation via !cof-options.
    16. +
    17. Rune de puissance : cf. ci-dessus. Cr\xE9er une rune de puissance vous demandera d'indiquer en plus le num\xE9ro de l'arme sur la fiche du propri\xE9taire.
    18. +
    19. Rune de pouvoir : pas de support particulier, cr\xE9er l'objet de pouvoir appropri\xE9.

    Guerrier

    Voie du bouclier

      -
    1. Protéger un allié : !cof-proteger-un-allie @{selected|token_id} @{target|token_id}. Fonctionne aussi si on remplace le target par un nom de token. Le script ne vérifie pas que le guerrier ne change pas d'allié plus d'une fois par tour.
    2. +
    3. Prot\xE9ger un alli\xE9 : !cof-proteger-un-allie @{selected|token_id} @{target|token_id}. Fonctionne aussi si on remplace le target par un nom de token. Le script ne v\xE9rifie pas que le guerrier ne change pas d'alli\xE9 plus d'une fois par tour.
    4. Absorber un coup :
        -
      • utiliser !cof-effet-temp absorberUnCoup 1 pour se mettre en position. Attention, ça ne vérifie pas si le guerrier porte son bouclier.
      • -
      • le script propose un bouton à activer en cas d'attaque réussie alors que le guerrier est en position.
      • +
      • utiliser !cof-effet-temp absorberUnCoup 1 pour se mettre en position. Attention, \xE7a ne v\xE9rifie pas si le guerrier porte son bouclier.
      • +
      • le script propose un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le guerrier est en position.
    5. Absorber un sort :
        -
      • utiliser !cof-effet-temp absorberUnSort 1 pour se mettre en position. Attention, ça ne vérifie pas si le guerrier porte son bouclier.
      • -
      • le script propose un bouton à activer en cas d'attaque réussie alors que le guerrier est en position.
      • +
      • utiliser !cof-effet-temp absorberUnSort 1 pour se mettre en position. Attention, \xE7a ne v\xE9rifie pas si le guerrier porte son bouclier.
      • +
      • le script propose un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le guerrier est en position.
    6. -
    7. Armure lourde : Noter l'armure sur la feuille du personnage, et ajouter un prédicat armureLourdeGuerrier au personnage. L'annulation du critique ne se produira que si l'armure est portée et que la valeur totale du bonus de défense supérieure ou égale à 7 (le bonus de DEF d'une armure de plaques complète).
    8. +
    9. Armure lourde : Noter l'armure sur la feuille du personnage, et ajouter un pr\xE9dicat armureLourdeGuerrier au personnage. L'annulation du critique ne se produira que si l'armure est port\xE9e et que la valeur totale du bonus de d\xE9fense sup\xE9rieure ou \xE9gale \xE0 7 (le bonus de DEF d'une armure de plaques compl\xE8te).

    Voie du combat

      -
    1. Vivacité : simplement augmenter l'init sur la fiche.
    2. -
    3. Désarmer : !cof-desarmer @{selected|token_id} @{target|token_id}. On peut utiliser un troisième argument optionnel, qui est le label d'une arme par défaut, au cas où le guerrier n'aurait pas d'arme en main.
    4. -
    5. Double attaque : faire deux attaques, avec l'option supplémentaire --bonusAttaque -2.
    6. -
    7. Attaque circulaire : faire les attaques normalement, ce n'est pas considéré comme une aoe.
    8. +
    9. Vivacit\xE9 : simplement augmenter l'init sur la fiche.
    10. +
    11. D\xE9sarmer : !cof-desarmer @{selected|token_id} @{target|token_id}. On peut utiliser un troisi\xE8me argument optionnel, qui est le label d'une arme par d\xE9faut, au cas o\xF9 le guerrier n'aurait pas d'arme en main.
    12. +
    13. Double attaque : faire deux attaques, avec l'option suppl\xE9mentaire --bonusAttaque -2.
    14. +
    15. Attaque circulaire : faire les attaques normalement, ce n'est pas consid\xE9r\xE9 comme une aoe.
    16. Attaque puissante : #Attaque -1 --avecd12crit --plus 2d6 --seulementContact.
    -

    Voie du maître d'armes

    +

    Voie du ma\xEEtre d'armes

      -
    1. Arme de prédilection : il est possible de préciser une famille d'armes de prédilection (un peu plus large que dans les règles), parmis arc, arbalete, hache, epee, marteau, masse, epieu, poudre, baton et rapiere. Si cela vous convient, ajoutez un prédicat armeDePredilection de valeur une de ces familles. Sinon, simplement ajouter le bonus sur les attaques dans la fiche.
    2. -
    3. Science du critique : pour ne pas avoir à modifier les chances de critique pour toutes les attaques, utiliser un prédicat scienceDuCritique. Attention à ne pas faire ça ET modifier les chances de critiques de l'attaque, car ça s'additionne.
    4. -
    5. Spécialisation : reporter le bonus aux DM sur la fiche.
    6. +
    7. Arme de pr\xE9dilection : il est possible de pr\xE9ciser une famille d'armes de pr\xE9dilection (un peu plus large que dans les r\xE8gles), parmis arc, arbalete, hache, epee, marteau, masse, epieu, poudre, baton et rapiere. Si cela vous convient, ajoutez un pr\xE9dicat armeDePredilection de valeur une de ces familles. Sinon, simplement ajouter le bonus sur les attaques dans la fiche.
    8. +
    9. Science du critique : pour ne pas avoir \xE0 modifier les chances de critique pour toutes les attaques, utiliser un pr\xE9dicat scienceDuCritique. Attention \xE0 ne pas faire \xE7a ET modifier les chances de critiques de l'attaque, car \xE7a s'additionne.
    10. +
    11. Sp\xE9cialisation : reporter le bonus aux DM sur la fiche.
    12. Attaque parfaite : utiliser les options --m2d20 --plus 1d6.
    13. -
    14. Riposte : ajouter un prédicat riposteGuerrier. Les actions affichées en cas de riposte seront normalement une attaque avec l'arme en main, et les attaques naturelles cochées du personnage. Si cela ne convient pas, écrivez une liste d'actions nommée Ripostes.
    15. +
    16. Riposte : ajouter un pr\xE9dicat riposteGuerrier. Les actions affich\xE9es en cas de riposte seront normalement une attaque avec l'arme en main, et les attaques naturelles coch\xE9es du personnage. Si cela ne convient pas, \xE9crivez une liste d'actions nomm\xE9e Ripostes.
    -

    Voie de la résistance

    +

    Voie de la r\xE9sistance

    1. Robustesse : rajouter les PV sur la fiche.
    2. Armure naturelle : rajouter la DEF sur la fiche.
    3. -
    4. Second souffle : Ajouter un prédicat secondSouffle permet de faire apparaître un bouton pour utiliser le second souffle quand le guerrier a perdu des PVs en combat, limite le gain de PVs à ceux perdus dans le combat en cours, et utilise automatiquement la capacité en fin de combat si elle n'a pas été utilisée. Si cette automatisation ne vous convient pas, vous pouvez utiliser la commande !cof-soin @{selected|token_id} secondSouffle à la place. Enfin, on peut préciser une valeur pour ce prédicat, pour remplacer le niveau + CON (par exemple pour un PNJ).
    5. -
    6. Dur à cuire : rajouter un prédicat durACuire sur la fiche.
    7. -
    8. Constitution héroïque : reporter les bonus sur la fiche.
    9. +
    10. Second souffle : Ajouter un pr\xE9dicat secondSouffle permet de faire appara\xEEtre un bouton pour utiliser le second souffle quand le guerrier a perdu des PVs en combat, limite le gain de PVs \xE0 ceux perdus dans le combat en cours, et utilise automatiquement la capacit\xE9 en fin de combat si elle n'a pas \xE9t\xE9 utilis\xE9e. Si cette automatisation ne vous convient pas, vous pouvez utiliser la commande !cof-soin @{selected|token_id} secondSouffle \xE0 la place. Enfin, on peut pr\xE9ciser une valeur pour ce pr\xE9dicat, pour remplacer le niveau + CON (par exemple pour un PNJ).
    11. +
    12. Dur \xE0 cuire : rajouter un pr\xE9dicat durACuire sur la fiche.
    13. +
    14. Constitution h\xE9ro\xEFque : reporter les bonus sur la fiche.

    Voie du soldat

      -
    1. Posture de combat : !cof-posture-de-combat bonus attr1 attr2, où les deux attr peuvent être soit DEF soit ATT soit DM, et le bonus est retiré au premier attribut pour être ajouté au second. Le bonus peut être limité si le guerrier a un prédicat voieDuSoldat qui indique son rang dans la voie. Exemple d'utilisation : !cof-posture-de-combat ?{Bonus} ?{Baisser|Défense,DEF|Attaque,ATT|Dégâts,DM} ?{Augmenter|Défense,DEF|Attaque,ATT|Dégâts,DM}. Normalement, la règle fait décider de sa posture au guerrier à chaque tour, mais en pratique, il en change assez rarement. Une posture de combat reste donc active jusqu'à la fin du combat ou jusqu'à ce qu'on en change (elle est neutre si on a le même attribut à buffer et débuffer).
    2. -
    3. Combat en phalange : ajouter un prédicat combatEnPhalange. Les bonus seront ajoutés automatiquement en fonctions des alliés définis selon cette méthode.
    4. -
    5. Prouesse : ajouter un prédicat prouesse (on peut y associer un nombre, si on souhaite plus d'une utilisation par tour). Le script générera automatiquement les boutons Prouesse sur les test appropriés.
    6. -
    7. Dernier rempart : pas de support particulier, le MJ doit gérer les attaques supplémentaires.
    8. -
    9. Force héroïque : reporter sur la fiche.
    10. +
    11. Posture de combat : !cof-posture-de-combat bonus attr1 attr2, o\xF9 les deux attr peuvent \xEAtre soit DEF soit ATT soit DM, et le bonus est retir\xE9 au premier attribut pour \xEAtre ajout\xE9 au second. Le bonus peut \xEAtre limit\xE9 si le guerrier a un pr\xE9dicat voieDuSoldat qui indique son rang dans la voie. Exemple d'utilisation : !cof-posture-de-combat ?{Bonus} ?{Baisser|D\xE9fense,DEF|Attaque,ATT|D\xE9g\xE2ts,DM} ?{Augmenter|D\xE9fense,DEF|Attaque,ATT|D\xE9g\xE2ts,DM}. Normalement, la r\xE8gle fait d\xE9cider de sa posture au guerrier \xE0 chaque tour, mais en pratique, il en change assez rarement. Une posture de combat reste donc active jusqu'\xE0 la fin du combat ou jusqu'\xE0 ce qu'on en change (elle est neutre si on a le m\xEAme attribut \xE0 buffer et d\xE9buffer).
    12. +
    13. Combat en phalange : ajouter un pr\xE9dicat combatEnPhalange. Les bonus seront ajout\xE9s automatiquement en fonctions des alli\xE9s d\xE9finis selon cette m\xE9thode.
    14. +
    15. Prouesse : ajouter un pr\xE9dicat prouesse (on peut y associer un nombre, si on souhaite plus d'une utilisation par tour). Le script g\xE9n\xE9rera automatiquement les boutons Prouesse sur les test appropri\xE9s.
    16. +
    17. Dernier rempart : pas de support particulier, le MJ doit g\xE9rer les attaques suppl\xE9mentaires.
    18. +
    19. Force h\xE9ro\xEFque : reporter sur la fiche.

    Invocateur

    Voie de la conjuration

      -
    1. Conjuration de prédateur : !cof-conjuration-de-predateur --mana 0.
    2. -
    3. Conjuration renforcée : vous pouvez soit utiliser un prédicat voieDeLaConjuration, de valeur le rang dans la voie, soit ajouter ce rang en premier argument de !cof-conjuration-de-predateur.
    4. -
    5. Conjuration d'armée : !cof-conjuration-armee --limiteParJour 1 --mana 1. Le niveau de puissance de l'armée et déterminé par la valeur d'un prédicat voieDeLaConjuration, ou sinon par un argument optionnel qui donne les DMs infligés par l'armée (par exemple, !cof-conjuration-armee 2d6). L'armée va apparaître comme un token normal, mais avec une aura de 20m de coté qui représente la place qu'elle occupe. Pour les dégâts qu'elle inflige, utiliser son attaque sur toutes les cibles désignées par l'invocateur. Pour faire disparaître l'armée, il suffit de la tuer (par exemple en utilisant !cof-set-state mort true). Tous les personnages dans la zone de l'armée et qui ne sont pas alliés de l'invocateurs ont automatiquement une nouvelle action dans leur liste pour attaquer l'armée. Cette action leur permet aussi de bénéficier d'une division des DM par 2 lorsque l'armée les attaque.
    6. +
    7. Conjuration de pr\xE9dateur : !cof-conjuration-de-predateur --mana 0.
    8. +
    9. Conjuration renforc\xE9e : vous pouvez soit utiliser un pr\xE9dicat voieDeLaConjuration, de valeur le rang dans la voie, soit ajouter ce rang en premier argument de !cof-conjuration-de-predateur.
    10. +
    11. Conjuration d'arm\xE9e : !cof-conjuration-armee --limiteParJour 1 --mana 1. Le niveau de puissance de l'arm\xE9e et d\xE9termin\xE9 par la valeur d'un pr\xE9dicat voieDeLaConjuration, ou sinon par un argument optionnel qui donne les DMs inflig\xE9s par l'arm\xE9e (par exemple, !cof-conjuration-armee 2d6). L'arm\xE9e va appara\xEEtre comme un token normal, mais avec une aura de 20m de cot\xE9 qui repr\xE9sente la place qu'elle occupe. Pour les d\xE9g\xE2ts qu'elle inflige, utiliser son attaque sur toutes les cibles d\xE9sign\xE9es par l'invocateur. Pour faire dispara\xEEtre l'arm\xE9e, il suffit de la tuer (par exemple en utilisant !cof-set-state mort true). Tous les personnages dans la zone de l'arm\xE9e et qui ne sont pas alli\xE9s de l'invocateurs ont automatiquement une nouvelle action dans leur liste pour attaquer l'arm\xE9e. Cette action leur permet aussi de b\xE9n\xE9ficier d'une division des DM par 2 lorsque l'arm\xE9e les attaque.
    -

    Voie de l'entité

    +

    Voie de l'entit\xE9

      -
    1. Invocation d'une entité : ajouter la fiche correspondante.
    2. -
    3. Lien magique : pour l'instant, gérer à la main le transfert de dégâts.
    4. -
    5. Amélioration : ajuster la fiche de l'entité.
    6. +
    7. Invocation d'une entit\xE9 : ajouter la fiche correspondante.
    8. +
    9. Lien magique : pour l'instant, g\xE9rer \xE0 la main le transfert de d\xE9g\xE2ts.
    10. +
    11. Am\xE9lioration : ajuster la fiche de l'entit\xE9.

    Voie du familier

      -
    1. Familier : créer un token pour le familier, avec vue et controlé par le joueur. Le partage des PV n'est pas géré. Pour le bonus en initiative, ajouter un prédicat familier, avec comme valeur le nom du compagnon (doit être exactement le même que celui du token du compagnon). Cela automatise l'initiative quand le familier est présent.
    2. -
    3. Résistance : ajouter la valeur de RD sur la fiche du familier.
    4. -
    5. Sens développés : ajouter un prédicat perception de valeur 5 (ou augmenter ce prédicat, si il existe déjà), et ajouter un prédicat visionDansLeNoir de valeur 20 (40 si le personnage dispose déjà de la vision dans le noir).
    6. +
    7. Familier : cr\xE9er un token pour le familier, avec vue et control\xE9 par le joueur. Le partage des PV n'est pas g\xE9r\xE9. Pour le bonus en initiative, ajouter un pr\xE9dicat familier, avec comme valeur le nom du compagnon (doit \xEAtre exactement le m\xEAme que celui du token du compagnon). Cela automatise l'initiative quand le familier est pr\xE9sent.
    8. +
    9. R\xE9sistance : ajouter la valeur de RD sur la fiche du familier.
    10. +
    11. Sens d\xE9velopp\xE9s : ajouter un pr\xE9dicat perception de valeur 5 (ou augmenter ce pr\xE9dicat, si il existe d\xE9j\xE0), et ajouter un pr\xE9dicat visionDansLeNoir de valeur 20 (40 si le personnage dispose d\xE9j\xE0 de la vision dans le noir).

    Voie des mutations

    1. Mutation offensive :
      • !cof-effet-temp mutationOffensive [[5+@{selected|CHA}]] --mana 0 pour lancer le sort
      • -
      • Ajouter une attaque sur la fiche utilisant l'attaque au contact, dommages 1d6+FOR+3, type Naturel, dégâts magiques, options --si etat mutationOffensive
      • +
      • Ajouter une attaque sur la fiche utilisant l'attaque au contact, dommages 1d6+FOR+3, type Naturel, d\xE9g\xE2ts magiques, options --si etat mutationOffensive
      • Pour un objet de sort, vous pouvez utiliser une action avec le code #Attaque Mutation offensive --toucher [[@{selected|ATKCAC}]] --dm 1d6+[[3+@{selected|FOR}]] --magique --naturel --si etat mutationOffensive
    2. -
    3. Mutation protectrice : !cof-effet ?{Mutation protectrice|Cuirasse,mutationCuirasse|Écailles rouges,mutationEcaillesRouges|Fourrure violette,mutationFourrureViolette|Ouïes,mutationOuies|Sang noir,mutationSangNoir} true --classeEffet mutationProtectrice --mana 0. Pour la valeur de protection de la cuirasse, vous pouvez soit utiliser un prédicat voieDesMutations, de valeur le rang dans la voie, soit remplacer mutationCuirasse par mutationCuirasse --valeur rang. Pour enlever la mutation, le MJ peut ensuite simplement sélectionner le personnage et utiliser !cof-fin-classe-effet mutationProtectrice.
    4. -
    5. Surpuissance physique : !cof-effet ?{Surpuissance physique|Muscles hypertrophiés,mutationMusclesHypertrophies|Silhouette filiforme,mutationSilhouetteFiliforme|Silhouette massive,mutationSilhouetteMassive} true --classeEffet surpuissancePhysique --mana 1. Pour enlever la mutation, le MJ peut ensuite simplement sélectionner le personnage et utiliser !cof-fin-classe-effet surpuissancePhysique.
    6. -
    7. Adaptation motrice : pas d'autre support que !cof-lancer-sort --message se fait pousser ?{Adaptation motrice ?|Ailes|des ailes|Pattes demesurées,des pattes demesurées|Queue de poisson,une queue de poisson} --mana 2
    8. +
    9. Mutation protectrice : !cof-effet ?{Mutation protectrice|Cuirasse,mutationCuirasse|\xC9cailles rouges,mutationEcaillesRouges|Fourrure violette,mutationFourrureViolette|Ou\xEFes,mutationOuies|Sang noir,mutationSangNoir} true --classeEffet mutationProtectrice --mana 0. Pour la valeur de protection de la cuirasse, vous pouvez soit utiliser un pr\xE9dicat voieDesMutations, de valeur le rang dans la voie, soit remplacer mutationCuirasse par mutationCuirasse --valeur rang. Pour enlever la mutation, le MJ peut ensuite simplement s\xE9lectionner le personnage et utiliser !cof-fin-classe-effet mutationProtectrice.
    10. +
    11. Surpuissance physique : !cof-effet ?{Surpuissance physique|Muscles hypertrophi\xE9s,mutationMusclesHypertrophies|Silhouette filiforme,mutationSilhouetteFiliforme|Silhouette massive,mutationSilhouetteMassive} true --classeEffet surpuissancePhysique --mana 1. Pour enlever la mutation, le MJ peut ensuite simplement s\xE9lectionner le personnage et utiliser !cof-fin-classe-effet surpuissancePhysique.
    12. +
    13. Adaptation motrice : pas d'autre support que !cof-lancer-sort --message se fait pousser ?{Adaptation motrice ?|Ailes|des ailes|Pattes demesur\xE9es,des pattes demesur\xE9es|Queue de poisson,une queue de poisson} --mana 2

    Voie des portes

    1. Raccourci : pas de support autre que !cof-lancer-sort lance un sort de Raccourci --mana 0
    2. -
    3. Porte artificielle : pas de support autre que !cof-lancer-sort lance un sort de Porte artificielle --mana 0. Un jour, je compte lui faire créer une porte.
    4. +
    5. Porte artificielle : pas de support autre que !cof-lancer-sort lance un sort de Porte artificielle --mana 0. Un jour, je compte lui faire cr\xE9er une porte.
    6. Manoir d'outre-tombe : pas d'autre support que !cof-lancer-sort enchante une porte --mana 1
    7. Enkystement lointain : !cof-enkystement-lointain @{selected|token_id} @{target|token_id} --portee 20 --mana 2 --limiteParCombat 1 enkystement.
    8. Porte dimensionnelle : pas de support pour l'instant.
    9. @@ -1480,14 +1483,14 @@

      Magicien

      Voie de la magie des arcanes

        -
      1. Agrandissement : !cof-effet-temp agrandissement [[5+@{selected|INT}]] --target @{target|token_id} --lanceur @{selected|token_id} --portee 0 --mana 0. Si vous souhaitez qu'une arme puisse être tenue à une main quand le personnage est agrandi, ajoutez à l'arme le prédicat armeDeGrand.
      2. -
      3. Forme gazeuse : !cof-effet-temp formeGazeuse [[1d4 + @{selected|INT}]] --mana 0. Au MJ de faire attention que sous cette forme, toutes les capacités sont interdites.
      4. -
      5. Hâte : !cof-effet-temp hate [[1d6+@{selected|INT}]] --mana 1, au MJ de gérer ensuite les actions possibles chaque tour.
      6. -
      7. Téléportation : Pas de support autre que !cof-lancer-sort se téléporte (à [[@{selected|INTELLIGENCE}*10]] m maximum) --mana 2.
      8. -
      9. Désintégration : +
      10. Agrandissement : !cof-effet-temp agrandissement [[5+@{selected|INT}]] --target @{target|token_id} --lanceur @{selected|token_id} --portee 0 --mana 0. Si vous souhaitez qu'une arme puisse \xEAtre tenue \xE0 une main quand le personnage est agrandi, ajoutez \xE0 l'arme le pr\xE9dicat armeDeGrand.
      11. +
      12. Forme gazeuse : !cof-effet-temp formeGazeuse [[1d4 + @{selected|INT}]] --mana 0. Au MJ de faire attention que sous cette forme, toutes les capacit\xE9s sont interdites.
      13. +
      14. H\xE2te : !cof-effet-temp hate [[1d6+@{selected|INT}]] --mana 1, au MJ de g\xE9rer ensuite les actions possibles chaque tour.
      15. +
      16. T\xE9l\xE9portation : Pas de support autre que !cof-lancer-sort se t\xE9l\xE9porte (\xE0 [[@{selected|INTELLIGENCE}*10]] m maximum) --mana 2.
      17. +
      18. D\xE9sint\xE9gration :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 5D6+INT, portée 20, type Sortilège, dégâts magiques, options --mana 3.
        • -
        • Objet de sort : #Attaque Désintégration --toucher [[@{selected|ATKMAG}]] --dm 5d6+[[@{selected|INT}]] --magique --portee 20 --sortilege
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 5D6+INT, port\xE9e 20, type Sortil\xE8ge, d\xE9g\xE2ts magiques, options --mana 3.
        • +
        • Objet de sort : #Attaque D\xE9sint\xE9gration --toucher [[@{selected|ATKMAG}]] --dm 5d6+[[@{selected|INT}]] --magique --portee 20 --sortilege
      @@ -1495,518 +1498,519 @@

      Voie de la magie destructrice

      1. Projectile magique :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4, portée 50, type Sortilège, modificateurs auto dégâts magiques, options --mana 0 --fx beam-magic.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4, port\xE9e 50, type Sortil\xE8ge, modificateurs auto d\xE9g\xE2ts magiques, options --mana 0 --fx beam-magic.
        • Objet de sort : #Attaque Projectile Magique --auto --dm 1d4 --magique --portee 50 --sortilege --fx beam-magic
      2. Rayon affaiblissant :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateurs pasDeDmg dégâts magiques, options --mana 0 --effet rayonAffaiblissant [[1d6+@{selected|INT}]] --fx splatter-magic.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateurs pasDeDmg d\xE9g\xE2ts magiques, options --mana 0 --effet rayonAffaiblissant [[1d6+@{selected|INT}]] --fx splatter-magic.
        • Objet de sort : #Attaque Rayon affaiblissant --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --effet rayonAffaiblissant [[1d6+@{selected|INT}]] --fx splatter-magic
      3. -
      4. Flèche enflammée : +
      5. Fl\xE8che enflamm\xE9e :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, portée 30, type Sortilège, dégâts feu, options --mana 1 --fx beam-fire --feu --enflamme.
        • -
        • Objet de sort : #Attaque Flèche enflammée --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --feu --portee 30 --sortilege --fx beam-fire --enflamme
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, port\xE9e 30, type Sortil\xE8ge, d\xE9g\xE2ts feu, options --mana 1 --fx beam-fire --feu --enflamme.
        • +
        • Objet de sort : #Attaque Fl\xE8che enflamm\xE9e --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --feu --portee 30 --sortilege --fx beam-fire --enflamme
      6. Boule de feu :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 4d6+INT, portée 30, type Sortilège, dégâts feu, options --mana 2 --demiAuto --disque 6 --psave DEX [[10+@{selected|INT}]] --targetFx explode-fire.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 4d6+INT, port\xE9e 30, type Sortil\xE8ge, d\xE9g\xE2ts feu, options --mana 2 --demiAuto --disque 6 --psave DEX [[10+@{selected|INT}]] --targetFx explode-fire.
        • Objet de sort : #Attaque Boule de feu --toucher [[@{selected|ATKMAG}]] --dm 4d6+[[@{selected|INT}]] --feu --magique --portee 30 --sortilege --demiAuto --disque 6 --psave DEX [[10+@{selected|INT}]] --targetFx explode-fire
      7. -
      8. Rituel de puissance : faire l'appel aux attaques avec --avecd12crit --plus 2d6. On peut par exemple ajouter ceci dans les options des attaques lorsque le Rituel peut être utilisé :?{Rituel de puissance?|Non,&#32;|Oui,--avecd12crit --plus 2d6}
      9. +
      10. Rituel de puissance : faire l'appel aux attaques avec --avecd12crit --plus 2d6. On peut par exemple ajouter ceci dans les options des attaques lorsque le Rituel peut \xEAtre utilis\xE9 :?{Rituel de puissance?|Non,&#32;|Oui,--avecd12crit --plus 2d6}
      -

      Voie de la magie élémentaire

      +

      Voie de la magie \xE9l\xE9mentaire

      1. Asphyxie :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège,modificateurs pasDeDmg, options --mana 0 --effet asphyxie [[1+@{selected|INT}]].
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge,modificateurs pasDeDmg, options --mana 0 --effet asphyxie [[1+@{selected|INT}]].
        • Objet de sort : #Attaque Asphyxie --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --effet asphyxie [[1+@{selected|INT}]]
      2. -
      3. Protection contre les éléments : ajouter un prédicat voieDeLaMagieElementaire avec comme valeur le rang dans la voie. Pour lancer le sort, faire !cof-effet-temp protectionContreLesElements [[5+@{selected|INT}]] --mana 0. Notez que si vous utilisez une option --valeur à la place d'utiliser le prédicat, la RD sera cette valeur multipliée par 2.
      4. -
      5. Arme enflammée : Lancer le sort avec !cof-effet-temp armeEnflammee [[5+@{selected|INT}]] --lanceur @{selected|token_id} --target @{target|token_id} --portee 0 --mana 1. Il faut que la cible tienne une arme en main (voir !cof-degainer). Limitations : si deux attaques utilisent la même arme, il faut faire deux fois l'action, une pour chaque attaque. Si vous souhaitez faire le même effet mais avec des dégâts de froid, vous pouvez utiliser armeGlacee à la place.
      6. -
      7. Respiration aquatique : pas de support autre que !cof-lancer-sort lance un sort de respiration aquatique (durée 10 minutes, sur soi plus [[@{selected|INT}]] compagnons) --mana 2.
      8. -
      9. Peau de pierre : !cof-effet-temp peauDePierreMag [[5+@{selected|INT}]] --mana 3. Le script va appliquer une RD de [5+Mod. d'INT] en dernier lieu, et compter le maximum des 40 dégâts par défaut. Il est possible de changer la valeur de la RD et le nombre de points de dégâts absorbés en ajoutant l'option --valeur rd absorbe. À noter que le script rajoute +1 à la RD et +5 au total de dégâts absorbés en cas de magie puissante, ou par point de mana depensé en magie intense.
      10. +
      11. Protection contre les \xE9l\xE9ments : ajouter un pr\xE9dicat voieDeLaMagieElementaire avec comme valeur le rang dans la voie. Pour lancer le sort, faire !cof-effet-temp protectionContreLesElements [[5+@{selected|INT}]] --mana 0. Notez que si vous utilisez une option --valeur \xE0 la place d'utiliser le pr\xE9dicat, la RD sera cette valeur multipli\xE9e par 2.
      12. +
      13. Arme enflamm\xE9e : Lancer le sort avec !cof-effet-temp armeEnflammee [[5+@{selected|INT}]] --lanceur @{selected|token_id} --target @{target|token_id} --portee 0 --mana 1. Il faut que la cible tienne une arme en main (voir !cof-degainer). Limitations : si deux attaques utilisent la m\xEAme arme, il faut faire deux fois l'action, une pour chaque attaque. Si vous souhaitez faire le m\xEAme effet mais avec des d\xE9g\xE2ts de froid, vous pouvez utiliser armeGlacee \xE0 la place.
      14. +
      15. Respiration aquatique : pas de support autre que !cof-lancer-sort lance un sort de respiration aquatique (dur\xE9e 10 minutes, sur soi plus [[@{selected|INT}]] compagnons) --mana 2.
      16. +
      17. Peau de pierre : !cof-effet-temp peauDePierreMag [[5+@{selected|INT}]] --mana 3. Le script va appliquer une RD de [5+Mod. d'INT] en dernier lieu, et compter le maximum des 40 d\xE9g\xE2ts par d\xE9faut. Il est possible de changer la valeur de la RD et le nombre de points de d\xE9g\xE2ts absorb\xE9s en ajoutant l'option --valeur rd absorbe. \xC0 noter que le script rajoute +1 \xE0 la RD et +5 au total de d\xE9g\xE2ts absorb\xE9s en cas de magie puissante, ou par point de mana depens\xE9 en magie intense.

      Voie de la magie protectrice

      1. Armure du mage : !cof-effet-combat armureDuMage --mana 0.
      2. Chute ralentie : pas de support autre que !cof-lancer-sort lance un sort de Chute ralentie --mana 0
      3. Flou : !cof-effet-temp flou [[1d4+@{selected|INT}]] --mana 1.
      4. -
      5. Cercle de protection : Le script ne gère pas le cercle en lui-même, mais vous pouvez créer deux abilities. +
      6. Cercle de protection : Le script ne g\xE8re pas le cercle en lui-m\xEAme, mais vous pouvez cr\xE9er deux abilities.
        • !cof-effet-temp cercleDeProtection 100 --target @{target|token_id} --lanceur @{selected|token_id} --valeur @{selected|token_id} et cibler un personnage pour lui appliquer l'effet.
        • !cof-effet-temp cercleDeProtection fin --target @{target|token_id} --lanceur @{selected|token_id} pour supprimer l'effet sur un personnage.
        - Le script proposera alors automatiquement à ces personnages un bouton avec le nom du magicien si une cible protégée est ciblée par une attaque magique. Le jet d'attaque magique opposé sera automatisé. Si vous utilisez les options de mana, rajoutez --mana {Coût ?} à la première ability. Indiquer le coût au lancement, et 0 pour les autres applications. + Le script proposera alors automatiquement \xE0 ces personnages un bouton avec le nom du magicien si une cible prot\xE9g\xE9e est cibl\xE9e par une attaque magique. Le jet d'attaque magique oppos\xE9 sera automatis\xE9. Si vous utilisez les options de mana, rajoutez --mana {Co\xFBt ?} \xE0 la premi\xE8re ability. Indiquer le co\xFBt au lancement, et 0 pour les autres applications.
      7. -
      8. Arrêt du temps : pas de support autre que !cof-lancer-sort arrête le temps pour [[1d6+@{selected|INT}]] tours --mana 3
      9. +
      10. Arr\xEAt du temps : pas de support autre que !cof-lancer-sort arr\xEAte le temps pour [[1d6+@{selected|INT}]] tours --mana 3

      Voie de la magie universelle

        -
      1. Lumière : !cof-lumiere @{target|token_id} 20 --mana 0. On peut utiliser une cible qui ne soit qu'un personnage sans PV, et dans ce cas le token disparaît, et pour éteindre la lumière, le MJ doit supprimer le token dans le layer de l'éclairage dynamique. Si la cible est un personnage avec des PV, alors la lumière se déplacera avec lui, et pour éteindre la lumière, il faut séclectionner le ou les tokens et lancer !cof-eteindre-lumiere lumiere.
      2. -
      3. Détection de la magie : pas de support autre que !cof-lancer-sort lance un sort de Détection de la Magie --mana 0.
      4. -
      5. Invisibilité : utiliser !cof-set-state invisible true --message se rend invisible --messageMJ l'invisibilité va durer [[1d6+@{selected|INT}]] minutes --mana 1. Pour les ennemis, mettre dans le layer gm, pour les joueurs, ne pas les cibler. Reste le problème des AOE...
      6. +
      7. Lumi\xE8re : !cof-lumiere @{target|token_id} 20 --mana 0. On peut utiliser une cible qui ne soit qu'un personnage sans PV, et dans ce cas le token dispara\xEEt, et pour \xE9teindre la lumi\xE8re, le MJ doit supprimer le token dans le layer de l'\xE9clairage dynamique. Si la cible est un personnage avec des PV, alors la lumi\xE8re se d\xE9placera avec lui, et pour \xE9teindre la lumi\xE8re, il faut s\xE9clectionner le ou les tokens et lancer !cof-eteindre-lumiere lumiere.
      8. +
      9. D\xE9tection de la magie : pas de support autre que !cof-lancer-sort lance un sort de D\xE9tection de la Magie --mana 0.
      10. +
      11. Invisibilit\xE9 : utiliser !cof-set-state invisible true --message se rend invisible --messageMJ l'invisibilit\xE9 va durer [[1d6+@{selected|INT}]] minutes --mana 1. Pour les ennemis, mettre dans le layer gm, pour les joueurs, ne pas les cibler. Reste le probl\xE8me des AOE...
      12. Vol : pas de support autre que !cof-lancer-sort vole --messageMJ le vol va durer [[1d6+@{selected|INT}]] minutes --mana 2
      13. -
      14. Intelligence héroïque : reporter sur la fiche
      15. +
      16. Intelligence h\xE9ro\xEFque : reporter sur la fiche

      Moine

      -

      Voie de l’énergie vitale

      +

      Voie de l\x2019\xE9nergie vitale

        -
      1. Main d'énergie : utiliser l'attaque à mains nues avec l'option --mainsDEnergie. D'autre part, ajouter l'option --magique à toutes les attaques à mains nues.
      2. -
      3. Pression mortelle : utiliser l'option --pointsVitaux pour ne pas infliger immédiatement les dégâts, et l'option --pressionMortelle pour libérer les dégâts.
      4. -
      5. Invulnérable: utiliser un prédicat invulnerable
      6. -
      7. Projection du ki : ajouter simplement l'attaque sur la fiche, et utiliser le type d'attaque Sortilege et le type de dégâts magique.
      8. -
      9. Ascétisme : noter la constitution comme une caractéristique supérieure sur la fiche.
      10. +
      11. Main d'\xE9nergie : utiliser l'attaque \xE0 mains nues avec l'option --mainsDEnergie. D'autre part, ajouter l'option --magique \xE0 toutes les attaques \xE0 mains nues.
      12. +
      13. Pression mortelle : utiliser l'option --pointsVitaux pour ne pas infliger imm\xE9diatement les d\xE9g\xE2ts, et l'option --pressionMortelle pour lib\xE9rer les d\xE9g\xE2ts.
      14. +
      15. Invuln\xE9rable: utiliser un pr\xE9dicat invulnerable
      16. +
      17. Projection du ki : ajouter simplement l'attaque sur la fiche, et utiliser le type d'attaque Sortilege et le type de d\xE9g\xE2ts magique.
      18. +
      19. Asc\xE9tisme : noter la constitution comme une caract\xE9ristique sup\xE9rieure sur la fiche.
      -

      Voie de la maîtrise

      +

      Voie de la ma\xEEtrise

        -
      1. Esquive du singe : mettre à jour la défense sur la fiche, et ajouter une compétence acrobatie avec le bonus donné par la capacité.
      2. -
      3. Morsure du serpent : pour ne pas avoir à modifier les chances de critique pour toutes les attaques au contact, utiliser un prédicat morsureDuSerpent. Attention à ne pas faire ça ET modifier les chances de critiques de l'attaque, car ça s'additionne. (En revanche, pas de soucis avec la science du critique).
      4. -
      5. Griffes du tigre : rajouter l'option --explodeMax aux attaques à mains nues.
      6. -
      7. Fureur du dragon : Créer une action : !cof-explosion Fureur du dragon --auto --portee 0 --disque 1 --saufAllies --dm 2D6+[[@{selected|FOR}]] --etat renverse --save FOR 10 --limiteParCombat 1 fureurDuDragon
      8. +
      9. Esquive du singe : mettre \xE0 jour la d\xE9fense sur la fiche, et ajouter une comp\xE9tence acrobatie avec le bonus donn\xE9 par la capacit\xE9.
      10. +
      11. Morsure du serpent : pour ne pas avoir \xE0 modifier les chances de critique pour toutes les attaques au contact, utiliser un pr\xE9dicat morsureDuSerpent. Attention \xE0 ne pas faire \xE7a ET modifier les chances de critiques de l'attaque, car \xE7a s'additionne. (En revanche, pas de soucis avec la science du critique).
      12. +
      13. Griffes du tigre : rajouter l'option --explodeMax aux attaques \xE0 mains nues.
      14. +
      15. Fureur du dragon : Cr\xE9er une action : !cof-explosion Fureur du dragon --auto --portee 0 --disque 1 --saufAllies --dm 2D6+[[@{selected|FOR}]] --etat renverse --save FOR 10 --limiteParCombat 1 fureurDuDragon
      16. Moment de perfection : !cof-effet-temp momentDePerfection 1 --limiteParCombat 1
      -

      Voie de la méditation

      +

      Voie de la m\xE9ditation

        -
      1. Pacifisme : ajouter un prédicat pacifisme. Il est possible d'y associer une valeur pour appliquer un bonus à la défense différent de 5.
      2. -
      3. Transe de guérison : !cof-transe-guerison
      4. -
      5. Maîtrise du ki : adapter les valeurs de DEF et init
      6. +
      7. Pacifisme : ajouter un pr\xE9dicat pacifisme. Il est possible d'y associer une valeur pour appliquer un bonus \xE0 la d\xE9fense diff\xE9rent de 5.
      8. +
      9. Transe de gu\xE9rison : !cof-transe-guerison
      10. +
      11. Ma\xEEtrise du ki : adapter les valeurs de DEF et init
      12. Projection mentale : aucun support
      13. -
      14. Sagesse héroïque : reporter sur la fiche
      15. +
      16. Sagesse h\xE9ro\xEFque : reporter sur la fiche

      Voie du poing

        -
      1. Poings de fer : simplement enlever le --tempDmg et ajuster les dégâts
      2. -
      3. Parade de projectiles : ajouter un prédicat paradeDeProjectiles. Le script proposera automatiquement un bouton pour parer l'attaque dans les cas appropriés.
      4. +
      5. Poings de fer : simplement enlever le --tempDmg et ajuster les d\xE9g\xE2ts
      6. +
      7. Parade de projectiles : ajouter un pr\xE9dicat paradeDeProjectiles. Le script proposera automatiquement un bouton pour parer l'attaque dans les cas appropri\xE9s.
      8. Peau de fer : ajuster la DEF sur la fiche.
      9. -
      10. Déluge de coups : le MJ gère le nombre d'attaques. Pour les attaques au d12, utiliser l'option --avecd12.
      11. +
      12. D\xE9luge de coups : le MJ g\xE8re le nombre d'attaques. Pour les attaques au d12, utiliser l'option --avecd12.
      13. Puissance du ki : utiliser les options --avecd12crit --plus 2d6.

      Voie du vent

        -
      1. Pas du vent : un prédicat pasDuVent avec comme valeur le rang dans la voie permet d'augmenter automatiquement l'initiative. Pour le reste, il n'y a pas de support particulier.
      2. -
      3. Course du vent : géré par le MJ.
      4. +
      5. Pas du vent : un pr\xE9dicat pasDuVent avec comme valeur le rang dans la voie permet d'augmenter automatiquement l'initiative. Pour le reste, il n'y a pas de support particulier.
      6. +
      7. Course du vent : g\xE9r\xE9 par le MJ.
      8. Course des airs : pas de support.
      9. -
      10. Lévitation : pas de support.
      11. +
      12. L\xE9vitation : pas de support.
      13. Passe-muraille : pas de support.
      -

      Nécromancien

      +

      N\xE9cromancien

      -

      Voie du démon

      +

      Voie du d\xE9mon

        -
      1. Malédiction : +
      2. Mal\xE9diction :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg malediction, options --mana 0.
        • -
        • Objet de sort : #Attaque Malédiction --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --malediction
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg malediction, options --mana 0.
        • +
        • Objet de sort : #Attaque Mal\xE9diction --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --malediction
      3. Aspect de la succube :
        • !cof-effet-temp aspectDeLaSuccube [[5+@{selected|INT}]] --mana 0 pour lancer le sort
        • -
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4+CHA, portée 0, type Sortilège, dégâts de drain, options --si etat aspectDeLaSuccube.
        • +
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4+CHA, port\xE9e 0, type Sortil\xE8ge, d\xE9g\xE2ts de drain, options --si etat aspectDeLaSuccube.
        • Pour un objet de sort, le code sera #Attaque Attaque de la succube --toucher [[@{selected|ATKMAG}]] --dm 1d4+[[@{selected|CHA}]] --magique --portee 0 --sortilege --si etat aspectDeLaSuccube --drain
      4. -
      5. Pacte sanglant : créer un prédicat pacteSanglant de valeur 3 (rang 3) ou 5 (rang 5). Le script va automatiser l'ajout de boutons sur tous les tests a posteriori, y compris sur les attaques qui ciblent le personnage. Aux joueurs de s'accorder sur la nécessité d'une déclaration a priori nécessaire pour l'utilisation de la capacité.
      6. -
      7. Aspect du démon : +
      8. Pacte sanglant : cr\xE9er un pr\xE9dicat pacteSanglant de valeur 3 (rang 3) ou 5 (rang 5). Le script va automatiser l'ajout de boutons sur tous les tests a posteriori, y compris sur les attaques qui ciblent le personnage. Aux joueurs de s'accorder sur la n\xE9cessit\xE9 d'une d\xE9claration a priori n\xE9cessaire pour l'utilisation de la capacit\xE9.
      9. +
      10. Aspect du d\xE9mon :
        • !cof-effet-temp aspectDuDemon [[5+@{selected|INT}]] --mana 2 pour lancer le sort
        • -
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+4, portée 0, type Sortilège, dégâts magiques, options --si etat aspectDuDemon
        • -
        • Pour un objet de sort, l'attaque pourra avoir le code #Attaque Attaque du démon --toucher [[@{selected|ATKMAG}]] --dm 1d6+4 --magique --portee 0 --sortilege --si etat aspectDuDemon
        • +
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+4, port\xE9e 0, type Sortil\xE8ge, d\xE9g\xE2ts magiques, options --si etat aspectDuDemon
        • +
        • Pour un objet de sort, l'attaque pourra avoir le code #Attaque Attaque du d\xE9mon --toucher [[@{selected|ATKMAG}]] --dm 1d6+4 --magique --portee 0 --sortilege --si etat aspectDuDemon
      11. -
      12. Invocation d'un démon : !cof-invoquer-demon @{selected|token_id} --mana 3
      13. +
      14. Invocation d'un d\xE9mon : !cof-invoquer-demon @{selected|token_id} --mana 3

      Voie de la mort

        -
      1. Siphon des âmes : ajouter un prédicat siphonDesAmes. Par défaut, si il y a plusieurs personnages avec ce pouvoir, tous vont siphoner les âmes sans interaction. Mais il est possible de déclarer un ordre de priorité, telle que si les personnages de plus haute priorité ont siphoné tous les points de vie qu'ils pouvaient, il ne reste rien à siphoner pour les autre. Pour se faire, utilisez un prédicat siphonDesAmesPrioritaire avec la valeur numérique de la priorité (0 par défaut, plus la valeur est grande, plus le personnage est prioritaire).
      2. +
      3. Siphon des \xE2mes : ajouter un pr\xE9dicat siphonDesAmes. Par d\xE9faut, si il y a plusieurs personnages avec ce pouvoir, tous vont siphoner les \xE2mes sans interaction. Mais il est possible de d\xE9clarer un ordre de priorit\xE9, telle que si les personnages de plus haute priorit\xE9 ont siphon\xE9 tous les points de vie qu'ils pouvaient, il ne reste rien \xE0 siphoner pour les autre. Pour se faire, utilisez un pr\xE9dicat siphonDesAmesPrioritaire avec la valeur num\xE9rique de la priorit\xE9 (0 par d\xE9faut, plus la valeur est grande, plus le personnage est prioritaire).
      4. Masque mortuaire : !cof-effet-temp masqueMortuaire [[5+@{selected|INT}]] --mana 0
      5. Baiser du vampire :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+INT, portée 50, type Sortilège, dégâts de drain, options --mana 1 --seulementVivant.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+INT, port\xE9e 50, type Sortil\xE8ge, d\xE9g\xE2ts de drain, options --mana 1 --seulementVivant.
        • Objet de sort : #Attaque Baiser du vampire --toucher [[@{selected|ATKMAG}]] --dm 1d8+[[@{selected|INT}]] --portee 50 --sortilege --drain --seulementVivant
      6. Briser les coeurs :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 5d6+INT, portée 20, type Sortilège, modificateurs seulementVivant necromancie, options --mana 2 --psave CON [[10+@{selected|INT}]] tempete 2.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 5d6+INT, port\xE9e 20, type Sortil\xE8ge, modificateurs seulementVivant necromancie, options --mana 2 --psave CON [[10+@{selected|INT}]] tempete 2.
        • Objet de sort : #Attaque Briser les coeurs --toucher [[@{selected|ATKMAG}]] --dm 5d6+[[@{selected|INT}]] --portee 20 --sortilege --psave CON [[10+@{selected|INT}]] tempete 2 --seulementVivant --necromancie
        - À noter que la partie tempete 2 implémente une chose qui n'est pas dans les règles, à savoir augmenter la difficulté du test de constitution de 2 par point de mana investi en tempête de mana intense. Je trouvais en effet que sans cet ajout, à mana égale, le sort était moins intéressant que le baiser du vampire. Il reste moins fort et plus situationnel que la désintégration du magicien (à mana égale), même avec ce changement. + \xC0 noter que la partie tempete 2 impl\xE9mente une chose qui n'est pas dans les r\xE8gles, \xE0 savoir augmenter la difficult\xE9 du test de constitution de 2 par point de mana investi en temp\xEAte de mana intense. Je trouvais en effet que sans cet ajout, \xE0 mana \xE9gale, le sort \xE9tait moins int\xE9ressant que le baiser du vampire. Il reste moins fort et plus situationnel que la d\xE9sint\xE9gration du magicien (\xE0 mana \xE9gale), m\xEAme avec ce changement.
      7. Mot de mort :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateurs pasDeDmg necromancie difficultePV, options --mana 3 --etat mort --save CON [[10+@{selected|INT}]] tempete 2.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateurs pasDeDmg necromancie difficultePV, options --mana 3 --etat mort --save CON [[10+@{selected|INT}]] tempete 2.
        • Objet de sort : #Attaque Mot de mort --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --necromancie --difficultePV --etat mort --save CON [[10+@{selected|INT}]] tempete 2
        - Comme pour Briser les coeurs, je pense qu'on peut augmenter la difficulté du jet de résistance avec la puissance de la tempête de mana. + Comme pour Briser les coeurs, je pense qu'on peut augmenter la difficult\xE9 du jet de r\xE9sistance avec la puissance de la temp\xEAte de mana.

      Voie de l'outre-tombe

      1. Peur :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg, options --mana 0 --peur [[10+@{selected|INT}]] [[1d4+r]]r est le rang dans la voie
        • -
        • Objet de sort : #Attaque Peur --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --peur [[10+@{selected|INT}]] [[1d4+r]]r est le niveau de l'objet
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg, options --mana 0 --peur [[10+@{selected|INT}]] [[1d4+r]]o\xF9 r est le rang dans la voie
        • +
        • Objet de sort : #Attaque Peur --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --peur [[10+@{selected|INT}]] [[1d4+r]]o\xF9 r est le niveau de l'objet
      2. -
      3. Animation d'un mort-vivant : !cof-animer-mort @{selected|token_id} --mana 0. Cela met directement le nécromant et le zombie en combat. Les Zombies perdent automatiquement 1 PV tous les 6 rounds. Lorsqu'ils atteignent 0 PV (quelle qu'en soit la raison) ou à la fin du combat, ils sont automatiquement détruits et supprimés. Si le lanceur a un prédicat voieOutreTombe, le script gère le maximum de zombies qu'il peut invoquer. Mana, consommables et limites sont gérées, mais pas Tempête de Mana.
      4. -
      5. Putréfaction : +
      6. Animation d'un mort-vivant : !cof-animer-mort @{selected|token_id} --mana 0. Cela met directement le n\xE9cromant et le zombie en combat. Les Zombies perdent automatiquement 1 PV tous les 6 rounds. Lorsqu'ils atteignent 0 PV (quelle qu'en soit la raison) ou \xE0 la fin du combat, ils sont automatiquement d\xE9truits et supprim\xE9s. Si le lanceur a un pr\xE9dicat voieOutreTombe, le script g\xE8re le maximum de zombies qu'il peut invoquer. Mana, consommables et limites sont g\xE9r\xE9es, mais pas Temp\xEAte de Mana.
      7. +
      8. Putr\xE9faction :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, portée 10, type Sortilège, modificateurs necromancie, options --mana 1 --effet putrefactionOutreTombe --save CON [[12+@{selected|INT}]]
        • -
        • Objet de sort : #Attaque Putréfaction --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --portee 10 --sortilege --necromancie --effet putrefactionOutreTombe --save CON [[12+@{selected|INT}]]
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, port\xE9e 10, type Sortil\xE8ge, modificateurs necromancie, options --mana 1 --effet putrefactionOutreTombe --save CON [[12+@{selected|INT}]]
        • +
        • Objet de sort : #Attaque Putr\xE9faction --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --portee 10 --sortilege --necromancie --effet putrefactionOutreTombe --save CON [[12+@{selected|INT}]]
      9. Ensevelissement :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg necromancie, options --mana 2 --etat enseveli FORDEX [[13+@{selected|INT}]]
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg necromancie, options --mana 2 --etat enseveli FORDEX [[13+@{selected|INT}]]
        • Objet de sort : #Attaque Ensevelissement --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --necromancie --etat enseveli FORDEX [[13+@{selected|INT}]]
        - Les dégâts sont infligés au début de chaque tour, et la cible recevra à son initiative un bouton lui permettant d'effectuer le jet pour sortir. Elle pourra également ajouter un bonus manuel au jet, en fonction des actions réalisées pour l'aider à sortir. + Les d\xE9g\xE2ts sont inflig\xE9s au d\xE9but de chaque tour, et la cible recevra \xE0 son initiative un bouton lui permettant d'effectuer le jet pour sortir. Elle pourra \xE9galement ajouter un bonus manuel au jet, en fonction des actions r\xE9alis\xE9es pour l'aider \xE0 sortir.
      10. -
      11. Armée des morts : !cof-effet-temp armeeDesMorts @{selected|niveau} --limiteParJour 1 --mana 3. La zone couverte est symbolisée par l'activation d'une aura sur le token du lanceur. Le script utilisera pour cela l'aura 2 du token, donc attention si vous l'utilisez déjà sur le token du lanceur, elle sera écrasée. Toute cible (le script ignore les alliés du lanceur) qui s'active dans une zone couverte par une armée recevra dans ses actions un bouton spécial pour se défendre. Les dégâts sont infligés automatiquement en début de tour. En option, le script support l'argument --puissant des règles de Mana de base, qui doublent la surface couverte (rayon 28m). Il est aussi possible d'utiliser l'option de Tempête de Mana ; la surface couverte sera multipliée par le nombre de PM investis en Magie Intense. Les adversaires avec un prédicat volant ne seront pas affectés.
      12. +
      13. Arm\xE9e des morts : !cof-effet-temp armeeDesMorts @{selected|niveau} --limiteParJour 1 --mana 3. La zone couverte est symbolis\xE9e par l'activation d'une aura sur le token du lanceur. Le script utilisera pour cela l'aura 2 du token, donc attention si vous l'utilisez d\xE9j\xE0 sur le token du lanceur, elle sera \xE9cras\xE9e. Toute cible (le script ignore les alli\xE9s du lanceur) qui s'active dans une zone couverte par une arm\xE9e recevra dans ses actions un bouton sp\xE9cial pour se d\xE9fendre. Les d\xE9g\xE2ts sont inflig\xE9s automatiquement en d\xE9but de tour. En option, le script support l'argument --puissant des r\xE8gles de Mana de base, qui doublent la surface couverte (rayon 28m). Il est aussi possible d'utiliser l'option de Temp\xEAte de Mana ; la surface couverte sera multipli\xE9e par le nombre de PM investis en Magie Intense. Les adversaires avec un pr\xE9dicat volant ne seront pas affect\xE9s.

      Voie du sang

      1. Saignements :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateurs pasDeDmg necromancie, options --mana 0 --effet saignementsSang rang, où rang est le rang dans la Voie
        • -
        • Objet de sort : #Attaque Saignements --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --necromancie --effet saignementsSang rang, où rang est le niveau de l'objet
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateurs pasDeDmg necromancie, options --mana 0 --effet saignementsSang rang, o\xF9 rang est le rang dans la Voie
        • +
        • Objet de sort : #Attaque Saignements --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --necromancie --effet saignementsSang rang, o\xF9 rang est le niveau de l'objet
        - Si vous souhaitez que le saignement ne puisse pas être appliqué à certains personnages (comme des golems ou des squelettes), vous pouvez leur ajouter un prédicat immuniteSaignement. + Si vous souhaitez que le saignement ne puisse pas \xEAtre appliqu\xE9 \xE0 certains personnages (comme des golems ou des squelettes), vous pouvez leur ajouter un pr\xE9dicat immuniteSaignement.
      2. Sang mordant : !cof-effet-temp sangMordant [[5+@{selected|INT}]] --mana 0.
      3. -
      4. Exsangue : ajouter un prédicat exsangue.
      5. -
      6. Hémorragie : +
      7. Exsangue : ajouter un pr\xE9dicat exsangue.
      8. +
      9. H\xE9morragie :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 10, type Sortilège, modificateurs pasDeDmg necromancie, options --mana 2 --effet hemorragie [[5+@{selected|INT}]]
        • -
        • Objet de sort : #Attaque Hémorragie --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --necromancie --effet hemorragie [[5+@{selected|INT}]]
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 10, type Sortil\xE8ge, modificateurs pasDeDmg necromancie, options --mana 2 --effet hemorragie [[5+@{selected|INT}]]
        • +
        • Objet de sort : #Attaque H\xE9morragie --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 10 --sortilege --necromancie --effet hemorragie [[5+@{selected|INT}]]
      10. Lien de sang :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, portée 20, type Sortilège, modificateurs pasDeDmg necromancie, options --mana 3 --effet lienDeSang [[5+@{selected|INT}]]
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg necromancie, options --mana 3 --effet lienDeSang [[5+@{selected|INT}]]
        • Objet de sort : #Attaque Lien de sang --toucher [[@{selected|ATKMAG}]] --pasDeDmg --portee 20 --sortilege --necromancie --effet lienDeSang [[5+@{selected|INT}]]
        Pas de support pour le lancement de sort sans ligne de vue.

      Voie de la sombre magie

      -

      Ajouter sur la fiche une compétence Occultisme avec en bonus 2 fois le rang dans cette voie.

      +

      Ajouter sur la fiche une comp\xE9tence Occultisme avec en bonus 2 fois le rang dans cette voie.

        -
      1. Ténèbres : !cof-tenebres @{selected|token_id} @{target|token_id} --mana 0. La commande pose un token transparent avec une aura noire visible par les joueurs pour visualiser la zone, et une petite aura jaune visible uniquement par le MJ (pour sélectionner le token si nécessaire). Tous les tokens présents dans la zone au lancement du sort sont automatiquement aveuglés. Au MJ ensuite d'enlever l'état aveuglé quand les cibles sortent de la zone. A la fin de la durée du sort, ou à la fin du combat, la zone et les états aveuglés restant disparaissent automatiquement. Il est aussi possible de changer les valeurs par défaut du sort (portée 20m, rayon 5m) avec les options --portee X et --rayon X. En règle custom, l'option puissant permet de doubler la superficie couverte (le script calcule le rayon approprié si custom).
      2. -
      3. Pattes d'araignées : !cof-lancer-sort peut se déplacer sur les murs pendants [[5+@{selected|INT}]] tours --mana 0
      4. -
      5. Strangulation : Le script va vérifier que la cible est bien vivante, en se basant sur la race, et sinon sur la présence éventuelle d'un prédicat nonVivant. +
      6. T\xE9n\xE8bres : !cof-tenebres @{selected|token_id} @{target|token_id} --mana 0. La commande pose un token transparent avec une aura noire visible par les joueurs pour visualiser la zone, et une petite aura jaune visible uniquement par le MJ (pour s\xE9lectionner le token si n\xE9cessaire). Tous les tokens pr\xE9sents dans la zone au lancement du sort sont automatiquement aveugl\xE9s. Au MJ ensuite d'enlever l'\xE9tat aveugl\xE9 quand les cibles sortent de la zone. A la fin de la dur\xE9e du sort, ou \xE0 la fin du combat, la zone et les \xE9tats aveugl\xE9s restant disparaissent automatiquement. Il est aussi possible de changer les valeurs par d\xE9faut du sort (port\xE9e 20m, rayon 5m) avec les options --portee X et --rayon X. En r\xE8gle custom, l'option puissant permet de doubler la superficie couverte (le script calcule le rayon appropri\xE9 si custom).
      7. +
      8. Pattes d'araign\xE9es : !cof-lancer-sort peut se d\xE9placer sur les murs pendants [[5+@{selected|INT}]] tours --mana 0
      9. +
      10. Strangulation : Le script va v\xE9rifier que la cible est bien vivante, en se basant sur la race, et sinon sur la pr\xE9sence \xE9ventuelle d'un pr\xE9dicat nonVivant.
          -
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, portée 20, type Sortilège, dégâts magiques, modificateurs necromancie, options --mana 1 --effet strangulation rang
        • +
        • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, port\xE9e 20, type Sortil\xE8ge, d\xE9g\xE2ts magiques, modificateurs necromancie, options --mana 1 --effet strangulation rang
        • !cof-strangulation @{selected|token_id} @{target|token_id} pour maintenir la strangulation
        • Pour un objet de sort, le code de l'attaque sera #Attaque Strangulation --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|INT}]] --magique --portee 20 --sortilege --effet strangulation rang
      11. -
      12. Ombre mortelle : !cof-ombre-mortelle @{selected|token_id} @{target|token_id} [[3+@{selected|INT}]] --portee 20 --mana 2 va créer un double de la cible, (à condition de disposer de 2 points de mana) et ajouter ce double à l'initiative. Au MJ ensuite de la faire attaquer à son tour (pas d'aoe, juste attaquer le token dont elle est l'ombre). Le token disparaît lorsque le nombre de tours est écoulé. Il est possible de choisir l'image utilisée pour représenter l'ombre en passant l'url de l'image avec l'option --image.
      13. -
      14. Intelligence héroïque : utiliser la fiche
      15. +
      16. Ombre mortelle : !cof-ombre-mortelle @{selected|token_id} @{target|token_id} [[3+@{selected|INT}]] --portee 20 --mana 2 va cr\xE9er un double de la cible, (\xE0 condition de disposer de 2 points de mana) et ajouter ce double \xE0 l'initiative. Au MJ ensuite de la faire attaquer \xE0 son tour (pas d'aoe, juste attaquer le token dont elle est l'ombre). Le token dispara\xEEt lorsque le nombre de tours est \xE9coul\xE9. Il est possible de choisir l'image utilis\xE9e pour repr\xE9senter l'ombre en passant l'url de l'image avec l'option --image.
      17. +
      18. Intelligence h\xE9ro\xEFque : utiliser la fiche
      -

      Prêtre

      +

      Pr\xEAtre

      Voie de la foi

        -
      1. Parole divine : ajouter une compétence convaincre, de valeur 2 fois le rang dans la voie, et ajouter cette compétence dans la liste.
      2. +
      3. Parole divine : ajouter une comp\xE9tence convaincre, de valeur 2 fois le rang dans la voie, et ajouter cette comp\xE9tence dans la liste.
      4. Arme d'argent :
          -
        • Pour attaquer avec l'arme d'argent, faire l'attaque avec les DM appropriés, les modificateurs armeDArgent, magique et l'option --si etat armeDArgent.
        • -
        • !cof-effet-combat armeDArgent --mana 0 pour lancer le sort. Vous pouvez ajouter l'option --degainer L (où L est le label de l'attaque avec l'arme d'argent) si vous souhaitez que le prêtre puisse prendre l'arme en main dans le même tour.
        • +
        • Pour attaquer avec l'arme d'argent, faire l'attaque avec les DM appropri\xE9s, les modificateurs armeDArgent, magique et l'option --si etat armeDArgent.
        • +
        • !cof-effet-combat armeDArgent --mana 0 pour lancer le sort. Vous pouvez ajouter l'option --degainer L (o\xF9 L est le label de l'attaque avec l'arme d'argent) si vous souhaitez que le pr\xEAtre puisse prendre l'arme en main dans le m\xEAme tour.
      5. -
      6. Ailes célestes : !cof-effet-temp ailesCelestes [[5+@{selected|SAG}]] --mana 1.
      7. +
      8. Ailes c\xE9lestes : !cof-effet-temp ailesCelestes [[5+@{selected|SAG}]] --mana 1.
      9. Foudres divines :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+SAG, portée 10, type Sortilège, dégâts électrique, modificateur saufAllies, option --mana 2. Décochez cette attaque, car elle sera appelée de manière spéciale : si le label de ce sort est L, il ne vous reste plus qu'à faire une action avec !cof-explosion L.
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+SAG, port\xE9e 10, type Sortil\xE8ge, d\xE9g\xE2ts \xE9lectrique, modificateur saufAllies, option --mana 2. D\xE9cochez cette attaque, car elle sera appel\xE9e de mani\xE8re sp\xE9ciale : si le label de ce sort est L, il ne vous reste plus qu'\xE0 faire une action avec !cof-explosion L.
        • Objet de sort : !cof-explosion Foudres divines --toucher [[@{selected|ATKMAG}]] --dm 1d6+[[@{selected|SAG}]] --electrique --sortilege --portee 10 --saufAllies
      10. -
      11. Charisme héroïque : reporter les bonus sur la fiche
      12. +
      13. Charisme h\xE9ro\xEFque : reporter les bonus sur la fiche

      Voie de la guerre sainte

        -
      1. Arme bénie : utiliser les modificateurs reroll1, beni et magique à l'attaque
      2. -
      3. Bouclier de la foi : ajuster le bonus de DEF du bouclier
      4. +
      5. Arme b\xE9nie : utiliser les modificateurs reroll1, beni et magique \xE0 l'attaque
      6. +
      7. Bouclier de la foi : ajouter un pr\xE9dicat bouclierDeLaFoi, de valeur le bonus en DEF. Ce bonus sera automatiquement ajout\xE9 quand le pr\xEAtre porte son bouclier.
      8. Marteau sprirituel :
          -
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+SAG, portée 30, type Sortilège, options --mana 1
        • +
        • Sort : Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d8+SAG, port\xE9e 30, type Sortil\xE8ge, options --mana 1
        • Objet de sort : #Attaque Marteau sprirituel --toucher [[@{selected|ATKMAG}]] --dm 1d8+[[@{selected|SAG}]] --portee 30 --sortilege
      9. -
      10. Châtiment divin : Ajoutez dans la actions du tour une action nommée Châtiment divin, de code #Attaque -1 --bonusAttaque [[@{selected|SAG}]] --plus [[@{selected|SAG}]].
      11. +
      12. Ch\xE2timent divin : Ajoutez dans la actions du tour une action nomm\xE9e Ch\xE2timent divin, de code #Attaque -1 --bonusAttaque [[@{selected|SAG}]] --plus [[@{selected|SAG}]].
      13. Mot de pouvoir : !cof-effet-temp etourdi 1 --lanceur @{selected|token_id} --enVue --saufAllies --message @{selected|token_name} prononce un mot avec la voix de son dieu --mana 3
      -

      Voie de la prière

      +

      Voie de la pri\xE8re

        -
      1. Bénédiction : !cof-effet-temp benediction [[3+@{selected|SAG}]] --alliesEnVue --self --mana 0. Il faut avoir défini une équipe avec le prêtre.
      2. -
      3. Destruction des morts-vivants : !cof-destruction-des-morts-vivants 2d6 --mana 0. Au rang 4 dans la voie, ajuster les dégâts. Notez que le script considère comme mort-vivant tout personnage avec le champ race à squelette, zombie, momie, goule,vampire ou mort-vivant, ou alors qui possède un prédicat mortVivant. Pour éviter la répétition abusive du sort, vous pouvez augmenter la difficulté à chaque fois que le sort est réussi pendant un même combat, avec l'option --malusRepetition m. Un mort-vivant ayant le prédicat immunite_destruction ne sera pas affecté par ce sort.
      4. +
      5. B\xE9n\xE9diction : !cof-effet-temp benediction [[3+@{selected|SAG}]] --alliesEnVue --self --mana 0. Il faut avoir d\xE9fini une \xE9quipe avec le pr\xEAtre.
      6. +
      7. Destruction des morts-vivants : !cof-destruction-des-morts-vivants 2d6 --mana 0. Au rang 4 dans la voie, ajuster les d\xE9g\xE2ts. Notez que le script consid\xE8re comme mort-vivant tout personnage avec le champ race \xE0 squelette, zombie, momie, goule,vampire ou mort-vivant, ou alors qui poss\xE8de un pr\xE9dicat mortVivant. Pour \xE9viter la r\xE9p\xE9tition abusive du sort, vous pouvez augmenter la difficult\xE9 \xE0 chaque fois que le sort est r\xE9ussi pendant un m\xEAme combat, avec l'option --malusRepetition m. Un mort-vivant ayant le pr\xE9dicat immunite_destruction ne sera pas affect\xE9 par ce sort.
      8. Sanctuaire : !cof-effet-temp sanctuaire [[5+@{selected|SAG}]] --mana 1.
      9. -
      10. Intervention Divine : ajouter au personnage un prédicat interventionDivine. Ensuite, utiliser !cof-intervention-divine ?{Type ?|rate|touche} juste après l'attaque en sélectionnant le token du Prêtre pour modifier le résultat selon le choix. Il est très pratique de mettre cette commande dans une Ability à afficher en Token Action. Ne supporte que le jet de touche de la dernière attaque effectuée.
      11. -
      12. Sagesse héroïque : Reporter les bonus sur la fiche.
      13. +
      14. Intervention Divine : ajouter au personnage un pr\xE9dicat interventionDivine. Ensuite, utiliser !cof-intervention-divine ?{Type ?|rate|touche} juste apr\xE8s l'attaque en s\xE9lectionnant le token du Pr\xEAtre pour modifier le r\xE9sultat selon le choix. Il est tr\xE8s pratique de mettre cette commande dans une Ability \xE0 afficher en Token Action. Ne supporte que le jet de touche de la derni\xE8re attaque effectu\xE9e.
      15. +
      16. Sagesse h\xE9ro\xEFque : Reporter les bonus sur la fiche.

      Voie des soins

      -

      Ajouter un prédicat voieDesSoins avec comme valeur le rang dans la voie.

      +

      Ajouter un pr\xE9dicat voieDesSoins avec comme valeur le rang dans la voie.

        -
      1. Soins légers : !cof-soin @{selected|token_id} @{target|token_id} leger --mana 0. Vous pouvez rajouter un petit effet visuel, par exemple avec --targetFx bubbling-holy. À titre personnel, j'ajoute --depasseLimite 1 pour permettre de lancer plus de sorts de soins léger en une journée (mais avec une augmentation cumulative du coût en mana de 1 à chaque dépassement).
      2. -
      3. Soins modérés : !cof-soin @{selected|token_id} @{target|token_id} modere --mana 0.
      4. -
      5. Soins de groupe : !cof-soin @{selected|token_id} groupe --mana 1 (ne pas oublier de définir des alliés). Attention, toutefois, le sort ne va pas automatiquement soigner les personnages notés comme morts, ce qui est le cas général si ils sont tombés à 0 PV. Si certains alliés notés morts ne sont pas vraiment morts, mais juste inconscient, il faudra que le MJ fasse la mise à jour de l'état et des PV lui-même.
      6. -
      7. Guérison : !cof-guerison @{selected|token_id} @{target|token_id} --portee 0 --limiteParJour 1 --mana 2. Pour l'instant ça ne fait que remettre les points de vie au maximum.
      8. +
      9. Soins l\xE9gers : !cof-soin @{selected|token_id} @{target|token_id} leger --mana 0. Vous pouvez rajouter un petit effet visuel, par exemple avec --targetFx bubbling-holy. \xC0 titre personnel, j'ajoute --depasseLimite 1 pour permettre de lancer plus de sorts de soins l\xE9ger en une journ\xE9e (mais avec une augmentation cumulative du co\xFBt en mana de 1 \xE0 chaque d\xE9passement).
      10. +
      11. Soins mod\xE9r\xE9s : !cof-soin @{selected|token_id} @{target|token_id} modere --mana 0.
      12. +
      13. Soins de groupe : !cof-soin @{selected|token_id} groupe --mana 1 (ne pas oublier de d\xE9finir des alli\xE9s). Attention, toutefois, le sort ne va pas automatiquement soigner les personnages not\xE9s comme morts, ce qui est le cas g\xE9n\xE9ral si ils sont tomb\xE9s \xE0 0 PV. Si certains alli\xE9s not\xE9s morts ne sont pas vraiment morts, mais juste inconscient, il faudra que le MJ fasse la mise \xE0 jour de l'\xE9tat et des PV lui-m\xEAme.
      14. +
      15. Gu\xE9rison : !cof-guerison @{selected|token_id} @{target|token_id} --portee 0 --limiteParJour 1 --mana 2. Pour l'instant \xE7a ne fait que remettre les points de vie au maximum.
      16. +
      17. Rappel \xE0 la vie : pas de suport, simplement faire !cof-lancer-sort Rappel \xE0 la vie --mana 3 --limiteParJour 1 rappelALaVie.
      -

      Voie de la spiritualité

      +

      Voie de la spiritualit\xE9

        -
      1. Vêtements sacrés : Ajouter un prédicat vetementsSacres avec comme valeur le rang dans la voie de la spiritualité. Cela augmente la DEF, mais seulement lorsque le prêtre ne porte pas d'armure (ne se voit pas sur le total de DEF de la fiche)
      2. -
      3. Protection contre le mal : !cof-effet-combat protectionContreLeMal --lanceur @{selected|token_id} --target @{target|token_id} --portee 0 --mana 0. Donne le bonus contre toute créature dont l'attribut race est squelette, zombie, démon, élémentaire, ou bien qui possède un prédicat mauvais.
      4. -
      5. Délivrance : !cof-delivrance @{selected|token_id} @{target|token_id} --portee 0 --mana 1
      6. -
      7. Marche des plans : !cof-lancer-sort marche entre les plans (il peut se déplacer de [[(3+@{selected|SAG})*10]] km) --mana 2.
      8. -
      9. Messie : pas d'autre support que !cof-lancer-sort entre directement en contact avec son dieu pour réaliser un miracle --mana 3
      10. +
      11. V\xEAtements sacr\xE9s : Ajouter un pr\xE9dicat vetementsSacres avec comme valeur le rang dans la voie de la spiritualit\xE9. Cela augmente la DEF, mais seulement lorsque le pr\xEAtre ne porte pas d'armure (ne se voit pas sur le total de DEF de la fiche)
      12. +
      13. Protection contre le mal : !cof-effet-combat protectionContreLeMal --lanceur @{selected|token_id} --target @{target|token_id} --portee 0 --mana 0. Donne le bonus contre toute cr\xE9ature dont l'attribut race est squelette, zombie, d\xE9mon, \xE9l\xE9mentaire, ou bien qui poss\xE8de un pr\xE9dicat mauvais.
      14. +
      15. D\xE9livrance : !cof-delivrance @{selected|token_id} @{target|token_id} --portee 0 --mana 1
      16. +
      17. Marche des plans : !cof-lancer-sort marche entre les plans (il peut se d\xE9placer de [[(3+@{selected|SAG})*10]] km) --mana 2.
      18. +
      19. Messie : pas d'autre support que !cof-lancer-sort entre directement en contact avec son dieu pour r\xE9aliser un miracle --mana 3

      Psionique

      Voie de l'attaque mentale

        -
      1. Attaque mentale : faire 2 attaques, une pour les DMs létaux, avec les options --sortilege --attaqueMentale --mana 0 et l'autre avec l'option supplémentaire --tempDmg (et en ajustant les DM).
      2. -
      3. Bouclier psi : ajouter un prédicat bouclierPsi.
      4. -
      5. Attaque étourdissante : faire une attaque mentale, avec les options --avecd12 --if moins niveau --if etatCible bouclierPsi --effet etourdi 1 --save CHA [[8+@{selected|CHA}]] --else --effet etourdi 1 --endif --endif --mana 1.
      6. +
      7. Attaque mentale : faire 2 attaques, une pour les DMs l\xE9taux, avec les options --sortilege --attaqueMentale --mana 0 et l'autre avec l'option suppl\xE9mentaire --tempDmg (et en ajustant les DM).
      8. +
      9. Bouclier psi : ajouter un pr\xE9dicat bouclierPsi.
      10. +
      11. Attaque \xE9tourdissante : faire une attaque mentale, avec les options --avecd12 --if moins niveau --if etatCible bouclierPsi --effet etourdi 1 --save CHA [[8+@{selected|CHA}]] --else --effet etourdi 1 --endif --endif --mana 1.
      12. Vague psionique : faire les attaques mentales sur toutes les cibles. En cas d'utilisation avec la Mana, le plus simple est de faire deux ability :
          -
        • !cof-lancer-sort lance une vague psychique --mana 2 qui lance le sort (pratique pour y mettre votre dépense de Mana unique)
        • -
        • Une ability qui permet de faire une attaque mentale (sans dépense de Mana)
        • +
        • !cof-lancer-sort lance une vague psychique --mana 2 qui lance le sort (pratique pour y mettre votre d\xE9pense de Mana unique)
        • +
        • Une ability qui permet de faire une attaque mentale (sans d\xE9pense de Mana)
      13. -
      14. Ego héroïque : reporter les bonus sur la fiche
      15. +
      16. Ego h\xE9ro\xEFque : reporter les bonus sur la fiche
      -

      Voie du contrôle corporel

      +

      Voie du contr\xF4le corporel

        -
      1. Proprioception : ajouter les PVs sur la fiche, et ajouter un prédicat proprioception.
      2. -
      3. Transe de régénération : ajoutez une ability !cof-soin @{selected|token_id} 1d6+[[@{selected|niveau} + @{selected|CHA}]] --limiteParJour rang --mana 0 --message entre en transe de régénération pour [[2d6]] tours.
      4. -
      5. Contrôle du métabolisme : ajouter un prédicat controleDuMetabolisme. Ne pas modifier l'initiative, le bonus de charisme sera pris en compte par le script.
      6. -
      7. Contrôle sanguin : ajouter un prédicat controleSanguin. Le script immunise aux poison, aux effets saignements automatisés, et divise par deux les dommages des attaques avec --vampirise.
      8. +
      9. Proprioception : ajouter les PVs sur la fiche, et ajouter un pr\xE9dicat proprioception.
      10. +
      11. Transe de r\xE9g\xE9n\xE9ration : ajoutez une ability !cof-soin @{selected|token_id} 1d6+[[@{selected|niveau} + @{selected|CHA}]] --limiteParJour rang --mana 0 --message entre en transe de r\xE9g\xE9n\xE9ration pour [[2d6]] tours.
      12. +
      13. Contr\xF4le du m\xE9tabolisme : ajouter un pr\xE9dicat controleDuMetabolisme. Ne pas modifier l'initiative, le bonus de charisme sera pris en compte par le script.
      14. +
      15. Contr\xF4le sanguin : ajouter un pr\xE9dicat controleSanguin. Le script immunise aux poison, aux effets saignements automatis\xE9s, et divise par deux les dommages des attaques avec --vampirise.

      Voie de l'empathie

        -
      1. Perception extra-sensorielle : ajuster l'initiative et ajouter le bonus à une compétence perception (pour les jets).
      2. -
      3. Défense intuitive : ajouter un prédicat defenseIntuitive. Ne pas modifier la DEF sur la fiche, la sagesse sera automatiquement prise en compte.
      4. -
      5. Perception du passé : !cof-lancer-sort tente de percevoir le passé --mana 1 pour lancer le sort. On peut faire le jet en utilisant !cof-jet SAG 15.
      6. -
      7. Vision lointaine : pas de support autre que !cof-lancer-sort projette son esprit à grande distance --mana 2. Utiliser !cof-jet SAG pour les jets de sagesse.
      8. -
      9. Perception héroïque : reporter les bonus sur la fiche
      10. +
      11. Perception extra-sensorielle : ajuster l'initiative et ajouter le bonus \xE0 une comp\xE9tence perception (pour les jets).
      12. +
      13. D\xE9fense intuitive : ajouter un pr\xE9dicat defenseIntuitive. Ne pas modifier la DEF sur la fiche, la sagesse sera automatiquement prise en compte.
      14. +
      15. Perception du pass\xE9 : !cof-lancer-sort tente de percevoir le pass\xE9 --mana 1 pour lancer le sort. On peut faire le jet en utilisant !cof-jet SAG 15.
      16. +
      17. Vision lointaine : pas de support autre que !cof-lancer-sort projette son esprit \xE0 grande distance --mana 2. Utiliser !cof-jet SAG pour les jets de sagesse.
      18. +
      19. Perception h\xE9ro\xEFque : reporter les bonus sur la fiche
      -

      Voie de la télékinésie

      +

      Voie de la t\xE9l\xE9kin\xE9sie

        -
      1. Manipulation à distance : pour les attaques à distance, le plus simple est d'utiliser une autre attaque en utilisant le score d'attaque magique et le bon modificateur de DMs.
      2. -
      3. Champ de protection : pour l'effet de base, si vous suivez les règles, ajustez simplement la DEF sur la fiche. Si vous préférez en faire un sort, vous pouvez utiliser la commande !cof-effet-temp champDeProtection [[5+@{selected|CHA}]]. La valeur par défaut est celle d'un prédicat voieDeLaTelekinesie, et pour utiliser une autre valeur, on peut utiliser l'option --valeur. Pour le champ à distance, faire !cof-effet-temp champDeProtection 1 --lanceur @{selected|token_id} --portee 10 --valeur n --target @{target|token_id}.
      4. +
      5. Manipulation \xE0 distance : pour les attaques \xE0 distance, le plus simple est d'utiliser une autre attaque en utilisant le score d'attaque magique et le bon modificateur de DMs.
      6. +
      7. Champ de protection : pour l'effet de base, si vous suivez les r\xE8gles, ajustez simplement la DEF sur la fiche. Si vous pr\xE9f\xE9rez en faire un sort, vous pouvez utiliser la commande !cof-effet-temp champDeProtection [[5+@{selected|CHA}]]. La valeur par d\xE9faut est celle d'un pr\xE9dicat voieDeLaTelekinesie, et pour utiliser une autre valeur, on peut utiliser l'option --valeur. Pour le champ \xE0 distance, faire !cof-effet-temp champDeProtection 1 --lanceur @{selected|token_id} --portee 10 --valeur n --target @{target|token_id}.
      8. Onde de choc :
          -
        • Sort : Ajouter une attaque sur la fiche dommages 1d8+CHA, portée 0, type Sortilège, modificateurs auto, options --mana 1 --disque ?{Portée (max 10) ?|10} --etat renverse --save FOR [[10+@{selected|CHA}]] --targetFx explode-magic. Décochez cette attaque, et appelez la dans une action qui fait !cof-explosion li est le label de l'attaque.
        • -
        • Objet de sort : !cof-explosion Onde de choc --auto --dm 1d8+[[@{selected|SAG}]] --portee 0 --sortilege --disque ?{Portée (max 10) ?|10} --etat renverse --save FOR [[10+@{selected|CHA}]] --targetFx explode-magic
        • +
        • Sort : Ajouter une attaque sur la fiche dommages 1d8+CHA, port\xE9e 0, type Sortil\xE8ge, modificateurs auto, options --mana 1 --disque ?{Port\xE9e (max 10) ?|10} --etat renverse --save FOR [[10+@{selected|CHA}]] --targetFx explode-magic. D\xE9cochez cette attaque, et appelez la dans une action qui fait !cof-explosion l o\xF9 i est le label de l'attaque.
        • +
        • Objet de sort : !cof-explosion Onde de choc --auto --dm 1d8+[[@{selected|SAG}]] --portee 0 --sortilege --disque ?{Port\xE9e (max 10) ?|10} --etat renverse --save FOR [[10+@{selected|CHA}]] --targetFx explode-magic
      9. -
      10. Combat kinétique : créer un prédicat combatKinetique. Cela appliquera automatiquement la RD dans tous les cas où le personnage est attaqué par un adversaire et qu'il est conscient. Pour l'augmentation des dommages, reporter sur les attaques sur la fiche.
      11. -
      12. Psychoportation : !cof-lancer-sort s'élève dans les airs pendant [[5+@{selected|INT}]] tours --mana 3. Passer la FOR en caractéristique supérieure via la fiche.
      13. +
      14. Combat kin\xE9tique : cr\xE9er un pr\xE9dicat combatKinetique. Cela appliquera automatiquement la RD dans tous les cas o\xF9 le personnage est attaqu\xE9 par un adversaire et qu'il est conscient. Pour l'augmentation des dommages, reporter sur les attaques sur la fiche.
      15. +
      16. Psychoportation : !cof-lancer-sort s'\xE9l\xE8ve dans les airs pendant [[5+@{selected|INT}]] tours --mana 3. Passer la FOR en caract\xE9ristique sup\xE9rieure via la fiche.
      -

      Voie de la télépathie

      +

      Voie de la t\xE9l\xE9pathie

        -
      1. Télépathie : pas de support autre que !cof-lancer-sort communique par télépathie pendant [[5+@{selected|SAG}]] tours --mana 0
      2. -
      3. Radar mental : ajouter un prédicat radarMental, de valeur le bonus procuré par le radar mental (2 fois le rang dans la voie). En cas de surprise provoquée par quelque chose de non-vivant penser à utiliser l'option --nonVivant dans !cof-surprise.
      4. -
      5. Suggestion : utiliser !cof-attaque-magique-contre-pv @{selected|token_id} @{target|token_id} --limiteParJour 1 suggestion --mana 1 (attention, ça ne teste pas si la cible a un niveau inférieur au psionique, ni si la cible est pensante).
      6. -
      7. Lire les pensées: faire une attaque de type sortilège, portée 10 m, avec l'option --difficulteCarac SAG --if touche --message lit les pensées de @{target|token_name} pendant [[1d6+@{selected|SAG}]] tours --endif.
      8. -
      9. Domination psy : faire une attaque de type sortilège, portée 20 m, avec les modificateurs dominationPsy, attaqueMentale et pasDeDmg.
      10. +
      11. T\xE9l\xE9pathie : pas de support autre que !cof-lancer-sort communique par t\xE9l\xE9pathie pendant [[5+@{selected|SAG}]] tours --mana 0
      12. +
      13. Radar mental : ajouter un pr\xE9dicat radarMental, de valeur le bonus procur\xE9 par le radar mental (2 fois le rang dans la voie). En cas de surprise provoqu\xE9e par quelque chose de non-vivant penser \xE0 utiliser l'option --nonVivant dans !cof-surprise.
      14. +
      15. Suggestion : Ajouter une attaque sur la fiche utilisant l'attaque magique, port\xE9e 20, type Sortil\xE8ge, modificateurs pasDeDmg, difficultePVmax, attaqueMentale, options --si moins niveau --if touche --message la cible doit faire l'action sugg\xE9r\xE9e --endif.
      16. +
      17. Lire les pens\xE9es: faire une attaque de type sortil\xE8ge, port\xE9e 10 m, avec l'option --difficulteCarac SAG --if touche --message lit les pens\xE9es de @{target|token_name} pendant [[1d6+@{selected|SAG}]] tours --endif.
      18. +
      19. Domination psy : faire une attaque de type sortil\xE8ge, port\xE9e 20 m, avec les modificateurs dominationPsy, attaqueMentale et pasDeDmg.
      -

      Rôdeur

      +

      R\xF4deur

      Voie de l'archer

        -
      1. Sens affutés : Créez un prédicat sensAffutes. Cela va ajuster l'initiative (ne se voit pas sur la fiche), ainsi que les dégâts des arcs (attention à ne pas en plus le rajouter sur la fiche !). Ajoutez ensuite le bonus aux compétences perception et vigilance (ou créez-les).
      2. +
      3. Sens affut\xE9s : Cr\xE9ez un pr\xE9dicat sensAffutes. Cela va ajuster l'initiative (ne se voit pas sur la fiche), ainsi que les d\xE9g\xE2ts des arcs (attention \xE0 ne pas en plus le rajouter sur la fiche !). Ajoutez ensuite le bonus aux comp\xE9tences perception et vigilance (ou cr\xE9ez-les).
      4. Tir aveugle : utiliser une attaque avec l'option --tirAveugle.
      5. Tir rapide : faire simplement deux attaques dans le tour
      6. -
      7. Flèche de mort : faire l'attaque avec les options --m2d20 --incrDmgCoef
      8. +
      9. Fl\xE8che de mort : faire l'attaque avec les options --m2d20 --incrDmgCoef
      10. Dans le mille : faire l'attaque avec les options --avecd12crit --plus 2d6

      Voie du compagnon animal

        -
      1. Odorat : ajouter une compétence pistage, de valeur 5 (ou augmentée de 5)
      2. -
      3. Surveillance : ajouter un prédicat surveillance, avec comme valeur le nom du compagnon (doit être exactement le même que celui du token du compagnon). Cela automatise l'initiative et le bonus aux jets de surprise, le reste se gère manuellement
      4. -
      5. Combat : ajouter le loup sous contrôle du joueur. Si vous souhaitez que le loup rentre en combat à chaque fois que le rôdeur entre en combat, ajoutez au rôdeur un prédicat nommé entrerEnCombatAvec, de valeur le nom du token du loup.
      6. +
      7. Odorat : ajouter une comp\xE9tence pistage, de valeur 5 (ou augment\xE9e de 5)
      8. +
      9. Surveillance : ajouter un pr\xE9dicat surveillance, avec comme valeur le nom du compagnon (doit \xEAtre exactement le m\xEAme que celui du token du compagnon). Cela automatise l'initiative et le bonus aux jets de surprise, le reste se g\xE8re manuellement
      10. +
      11. Combat : ajouter le loup sous contr\xF4le du joueur. Si vous souhaitez que le loup rentre en combat \xE0 chaque fois que le r\xF4deur entre en combat, ajoutez au r\xF4deur un pr\xE9dicat nomm\xE9 entrerEnCombatAvec, de valeur le nom du token du loup.
      12. Empathie animale : pour soigner, utiliser !cof-soin @{selected|token_id} nom_familier ?{Montant des soins} --transfer
      13. -
      14. Animal fabuleux : ajuster les caractéristiques du loup
      15. +
      16. Animal fabuleux : ajuster les caract\xE9ristiques du loup

      Voie de l'escarmouche

        -
      1. Chasseur émérite : ajouter un prédicat chasseurEmerite. Puis, si dans le profil (attribut profil) de la cible, il y a animal (ou si la cible a un prédicat animal), le bonus s'applique. Ajouter aussi le bonus à une compétence pistage.
      2. -
      3. Traquenard : ajouter un prédicat traquenard, puis option --traquenard pour l'attaque. Pour une utilisation pratique, le mieux est de faire une attaque d'arme en main avec l'option : #Attaque -1 --traquenard.
      4. -
      5. Attaque éclair : --plus [[@{selected|DEX}]] --bonusAttaque [[@{selected|DEX}]]
      6. -
      7. Repli : simplement faire un jet en utilisant par exemple !cof-jet DEX 10, et décrire le résultat.
      8. -
      9. Dextérité héroïque : reporter sur la fiche.
      10. +
      11. Chasseur \xE9m\xE9rite : ajouter un pr\xE9dicat chasseurEmerite. Puis, si dans le profil (attribut profil) de la cible, il y a animal (ou si la cible a un pr\xE9dicat animal), le bonus s'applique. Ajouter aussi le bonus \xE0 une comp\xE9tence pistage.
      12. +
      13. Traquenard : ajouter un pr\xE9dicat traquenard, puis option --traquenard pour l'attaque. Pour une utilisation pratique, le mieux est de faire une attaque d'arme en main avec l'option : #Attaque -1 --traquenard.
      14. +
      15. Attaque \xE9clair : --plus [[@{selected|DEX}]] --bonusAttaque [[@{selected|DEX}]]
      16. +
      17. Repli : simplement faire un jet en utilisant par exemple !cof-jet DEX 10, et d\xE9crire le r\xE9sultat.
      18. +
      19. Dext\xE9rit\xE9 h\xE9ro\xEFque : reporter sur la fiche.

      Voie de la survie

        -
      1. Endurant : ajouter une compétence survie, de caractéristique CON, avec le bonus 2xrang dans la Voie.
      2. -
      3. Nature nourricière : pour la recherche d'herbes, ajouter un prédicat voieDeLaSurvie avec comme valeur le rang du personnage dans la voie. On peut utiliser !cof-nature-nourriciere pour lancer la recherche. Cela crée automatiquement les doses de plantes médicinales dans les consommables du personnage. Ces doses sont supprimées toutes les nuits. Pour les besoins d'un personnage, j'ai aussi donné la possibilité de trouver des baies magiques à la place des herbes médicinales. Pour cela, il faut un prédicat natureNourriciereBaies.
      4. -
      5. Grand pas : ajouter les compétences natation et escalade, de valeur 5.
      6. -
      7. Increvable : ajouter un prédicat increvable.
      8. -
      9. Constitution héroïque : reporter les bonus sur la fiche
      10. +
      11. Endurant : ajouter une comp\xE9tence survie, de caract\xE9ristique CON, avec le bonus 2xrang dans la Voie.
      12. +
      13. Nature nourrici\xE8re : pour la recherche d'herbes, ajouter un pr\xE9dicat voieDeLaSurvie avec comme valeur le rang du personnage dans la voie. On peut utiliser !cof-nature-nourriciere pour lancer la recherche. Cela cr\xE9e automatiquement les doses de plantes m\xE9dicinales dans les consommables du personnage. Ces doses sont supprim\xE9es toutes les nuits. Pour les besoins d'un personnage, j'ai aussi donn\xE9 la possibilit\xE9 de trouver des baies magiques \xE0 la place des herbes m\xE9dicinales. Pour cela, il faut un pr\xE9dicat natureNourriciereBaies.
      14. +
      15. Grand pas : ajouter les comp\xE9tences natation et escalade, de valeur 5.
      16. +
      17. Increvable : ajouter un pr\xE9dicat increvable.
      18. +
      19. Constitution h\xE9ro\xEFque : reporter les bonus sur la fiche

      Voie du traqueur

        -
      1. Pas de loup : ajouter le bonus à une compétence discrétion.
      2. -
      3. Ennemi juré : ajouter un prédicat ennemiJure avec comme valeur la race des ennemis. Cette race doit se retrouver dans le champ race de l'ennemi. Le script reconnait aussi le type mort-vivant (tout en minuscules) et dans ce cas va déterminer si la cible est un mort-vivant (prédicat mortVivant ou race reconnue comme mort-vivant), ainsi que le type géant (pour les géants, ogres, trolls, etc.) et le type gobelin.
      4. +
      5. Pas de loup : ajouter le bonus \xE0 une comp\xE9tence discr\xE9tion.
      6. +
      7. Ennemi jur\xE9 : ajouter un pr\xE9dicat ennemiJure avec comme valeur la race des ennemis. Cette race doit se retrouver dans le champ race de l'ennemi. Le script reconnait aussi le type mort-vivant (tout en minuscules) et dans ce cas va d\xE9terminer si la cible est un mort-vivant (pr\xE9dicat mortVivant ou race reconnue comme mort-vivant), ainsi que le type g\xE9ant (pour les g\xE9ants, ogres, trolls, etc.) et le type gobelin.
      8. Embuscade : en cas d'attaque sur les ennemis, les mettre tous surpris avec la commande !cof-set-state surpris true
      9. -
      10. Second ennemi juré : on peut renseigner une seconde race dans un nouveau prédicat ennemiJure, ou alors le rajouter au prédicat ennemiJure précédant, en la séparant de la première par une virgule (exemple : ennemiJure:: orque, araignée, sans rien ensuite sur la ligne)
      11. -
      12. Perception héroïque : reporter les bonus sur la fiche
      13. +
      14. Second ennemi jur\xE9 : on peut renseigner une seconde race dans un nouveau pr\xE9dicat ennemiJure, ou alors le rajouter au pr\xE9dicat ennemiJure pr\xE9c\xE9dant, en la s\xE9parant de la premi\xE8re par une virgule (exemple : ennemiJure:: orque, araign\xE9e, sans rien ensuite sur la ligne)
      15. +
      16. Perception h\xE9ro\xEFque : reporter les bonus sur la fiche
      -

      Samouraï

      +

      Samoura\xEF

      Voie de l'arc et du cheval

        -
      1. Monture loyale : ajouter un prédicat montureLoyale. Pour la monture, il faut faire un personnage avec un prédicat monture. Pour monter sur la monture, utiliser !cof-en-selle @{selected|token_id} nom_de_la_monture, et pour en descendre, il suffit de faire la même commande (utiliser une ability "token action" rend cela assez facile à l'usage).
      2. +
      3. Monture loyale : ajouter un pr\xE9dicat montureLoyale. Pour la monture, il faut faire un personnage avec un pr\xE9dicat monture. Pour monter sur la monture, utiliser !cof-en-selle @{selected|token_id} nom_de_la_monture, et pour en descendre, il suffit de faire la m\xEAme commande (utiliser une ability "token action" rend cela assez facile \xE0 l'usage).
      4. Tir en mouvement : pas de support particulier.
      5. -
      6. Tir fatal : ajouter un prédicat tirFatal. Pour tenir compte du bonus supplémentaire avec le rang dans la voie, ajouter un prédicat voieDeLArcEtDuCheval de valeur le rang atteint dans cette voie. Si vous souhaitez que cette capacité s'applique à une autre classe d'arme que les arcs, vous pouvez associer ce nom au prédicat tirfatal (attention, sans accent). Par exemple, pour les arbalètes, tirFatal:arbalete.
      7. +
      8. Tir fatal : ajouter un pr\xE9dicat tirFatal. Pour tenir compte du bonus suppl\xE9mentaire avec le rang dans la voie, ajouter un pr\xE9dicat voieDeLArcEtDuCheval de valeur le rang atteint dans cette voie. Si vous souhaitez que cette capacit\xE9 s'applique \xE0 une autre classe d'arme que les arcs, vous pouvez associer ce nom au pr\xE9dicat tirfatal (attention, sans accent). Par exemple, pour les arbal\xE8tes, tirFatal:arbalete.

      Voie du dirigeant

        -
      1. Éduqué : simplement noter les bonus et compétences sur la fiche.
      2. -
      3. Homme de cour : ajouter une compétence étiquette, de valeur 5.
      4. -
      5. Lame de lignée : pas de support particulier pour l'arme, mais quand le samouraï perd l'arme, vous pouvez utiliser la commande !cof-effet lameDeLigneePerdue true (avec le samouraï sélectionné). Quand il la retrouve, utilisez !cof-effet lameDeLigneePerdue false.
      6. +
      7. \xC9duqu\xE9 : simplement noter les bonus et comp\xE9tences sur la fiche.
      8. +
      9. Homme de cour : ajouter une comp\xE9tence \xE9tiquette, de valeur 5.
      10. +
      11. Lame de lign\xE9e : pas de support particulier pour l'arme, mais quand le samoura\xEF perd l'arme, vous pouvez utiliser la commande !cof-effet lameDeLigneePerdue true (avec le samoura\xEF s\xE9lectionn\xE9). Quand il la retrouve, utilisez !cof-effet lameDeLigneePerdue false.

      Voie de l'honneur

        -
      1. Chef né : ajouter un prédicat immunite_peur, et des compétences pour l'intimidation et commander.
      2. -
      3. Défi : !cof-defi-samourai @{selected|token_id} @{target|token_id} bonus. Le bonus en argument est optionnel. S'il n'est pas présent, le script utilise la valeur d'un prédicat voieDeLHonneur.
      4. +
      5. Chef n\xE9 : ajouter un pr\xE9dicat immunite_peur, et des comp\xE9tences pour l'intimidation et commander.
      6. +
      7. D\xE9fi : !cof-defi-samourai @{selected|token_id} @{target|token_id} bonus. Le bonus en argument est optionnel. S'il n'est pas pr\xE9sent, le script utilise la valeur d'un pr\xE9dicat voieDeLHonneur.
      8. Honorable : pas de support particulier.

      Voie du ki

        -
      1. Esprit vide : ajouter un prédicat espritVide. Si vous voulez un boonus différent (par exemple à partir du rang 4 dans la voie), associez les bonus au prédicat.
      2. -
      3. Main vide : faire l'attaque à mains nues correspondant à la capacité.
      4. -
      5. Kiai : ajouter un prédicat kiai, de valeur 1. Au rang 5, mettre cette valeur à 2, le script se charge d'attendre 1d6 tours avant de proposer le deuxième kiai.
      6. -
      7. Course mortelle : !cof-attack-line @{selected|token_id} --distanceMax 10. L'attaque va être faite avec l'arme en main, mais on peut spécifier un label d'attaque (avant les options) et toutes les options supportées par !cof-attack.
      8. +
      9. Esprit vide : ajouter un pr\xE9dicat espritVide. Si vous voulez un boonus diff\xE9rent (par exemple \xE0 partir du rang 4 dans la voie), associez les bonus au pr\xE9dicat.
      10. +
      11. Main vide : faire l'attaque \xE0 mains nues correspondant \xE0 la capacit\xE9.
      12. +
      13. Kiai : ajouter un pr\xE9dicat kiai, de valeur 1. Au rang 5, mettre cette valeur \xE0 2, le script se charge d'attendre 1d6 tours avant de proposer le deuxi\xE8me kiai.
      14. +
      15. Course mortelle : !cof-attack-line @{selected|token_id} --distanceMax 10. L'attaque va \xEAtre faite avec l'arme en main, mais on peut sp\xE9cifier un label d'attaque (avant les options) et toutes les options support\xE9es par !cof-attack.
      16. Puissance du ki : #Attaque -1 --avecd12crit --plus 2d6 --seulementContact.

      Voie du sabre

        -
      1. Technique du sabre : ajouter un prédicat techniqueDuSabre, de valeur le rang dans la Voie.
      2. -
      3. Frappe du vide : ajouter un prédicat frappeDuVide.
      4. -
      5. Lames Jumelles : faire les attaques avec le modificateur lamesJumelles permet de prendre en compte la force courante de l'attaquant pour les malus éventuels à l'attaque. Comme le samouraï va par défaut commencer le combat les mains vides, et qu'avec cette capacité il voudra certainement dégainer à la fois le katana et le wakizachi, on peut utiliser un prédicat pour lui faciliter la tâche : si le label du katana est 5 et celui du wakizachi par exemple 3, ajouter un prédicat actionDegainer1:5-3 (de cette façon, le fait de dégainer le katana et le wakizachi sera en tête de liste).
      6. +
      7. Technique du sabre : ajouter un pr\xE9dicat techniqueDuSabre, de valeur le rang dans la Voie.
      8. +
      9. Frappe du vide : ajouter un pr\xE9dicat frappeDuVide.
      10. +
      11. Lames Jumelles : faire les attaques avec le modificateur lamesJumelles permet de prendre en compte la force courante de l'attaquant pour les malus \xE9ventuels \xE0 l'attaque. Comme le samoura\xEF va par d\xE9faut commencer le combat les mains vides, et qu'avec cette capacit\xE9 il voudra certainement d\xE9gainer \xE0 la fois le katana et le wakizachi, on peut utiliser un pr\xE9dicat pour lui faciliter la t\xE2che : si le label du katana est 5 et celui du wakizachi par exemple 3, ajouter un pr\xE9dicat actionDegainer1:5-3 (de cette fa\xE7on, le fait de d\xE9gainer le katana et le wakizachi sera en t\xEAte de liste).

      Voleur

      Voie de l'assassin

        -
      1. Discrétion : ajouter une compétence discrétion sur la fiche, avec le bon bonus.
      2. -
      3. Attaque sournoise : Ajouter un prédicat attaqueSournoise, de valeur le nombre de dés de l'attaque sournoise. Ensuite, faire des versions des attaques avec --sournoise. Au MJ de vérifier que les conditions de l'attaque sournoise sont remplies. Le plus pratique pour l'utilisation avec différentes armes, est d'ajouter à la liste des actions du tour une action de titre Attaque sournoise et de code #Attaque -1 --sournoise.
      4. -
      5. Ombre mouvante : utiliser la commande !cof-ombre-mouvante --fx burst-smoke (la partie --fx burst-smoke peut être omise ou changée, bien sûr). Le script ne gère pas encore l'attaque sournoise qui peut suivre, au MJ de surveiller l'initiative du voleur par rapport à sa cible.
      6. -
      7. Surprise : ajouter un prédicat immunite_surpris. Pour le reste, à gérer par le MJ.
      8. -
      9. Ouverture mortelle : ajouter les options --ouvertureMortelle --limiteParCombat 1 ouvertureMortelle --sournoise. Selon les indications de Kegron, ne mettre la partie --sournoise que si les conditions s'y prêtent (dans le dos, surprise, acrobatie, etc).
      10. +
      11. Discr\xE9tion : ajouter une comp\xE9tence discr\xE9tion sur la fiche, avec le bon bonus.
      12. +
      13. Attaque sournoise : Ajouter un pr\xE9dicat attaqueSournoise, de valeur le nombre de d\xE9s de l'attaque sournoise. Ensuite, faire des versions des attaques avec --sournoise. Au MJ de v\xE9rifier que les conditions de l'attaque sournoise sont remplies. Le plus pratique pour l'utilisation avec diff\xE9rentes armes, est d'ajouter \xE0 la liste des actions du tour une action de titre Attaque sournoise et de code #Attaque -1 --sournoise.
      14. +
      15. Ombre mouvante : utiliser la commande !cof-ombre-mouvante --fx burst-smoke (la partie --fx burst-smoke peut \xEAtre omise ou chang\xE9e, bien s\xFBr). Le script ne g\xE8re pas encore l'attaque sournoise qui peut suivre, au MJ de surveiller l'initiative du voleur par rapport \xE0 sa cible.
      16. +
      17. Surprise : ajouter un pr\xE9dicat immunite_surpris. Pour le reste, \xE0 g\xE9rer par le MJ.
      18. +
      19. Ouverture mortelle : ajouter les options --ouvertureMortelle --limiteParCombat 1 ouvertureMortelle --sournoise. Selon les indications de Kegron, ne mettre la partie --sournoise que si les conditions s'y pr\xEAtent (dans le dos, surprise, acrobatie, etc).

      Voie de l'aventurier

        -
      1. Sprint : Pour vérifier que ce n'est bien utilisé qu'une fois par combat, on pourra utiliser !cof-lancer-sort pousse un sprint --limiteParCombat 1 sprint.
      2. -
      3. Provocation : !cof-provocation @{selected|token_id} @{target|token_id}. Au joueur ensuite de faire son attaque gratuite si la provocation est réussie et que l'adversaire l'attaque.
      4. -
      5. Grâce féline : ajouter un prédicat graceFeline. Cela va affecter l'initiative et la DEF, mais sans se voir sur la fiche. Pour les tests de déplacement, ajouter un prédicat graceFelineVoleur (penser à proposer l'utilisation de compétences, en ajoutant les compétences course, saut, acrobatie et escalade au voleur ou sur le handout de compétences).
      6. +
      7. Sprint : Pour v\xE9rifier que ce n'est bien utilis\xE9 qu'une fois par combat, on pourra utiliser !cof-lancer-sort pousse un sprint --limiteParCombat 1 sprint.
      8. +
      9. Provocation : !cof-provocation @{selected|token_id} @{target|token_id}. Au joueur ensuite de faire son attaque gratuite si la provocation est r\xE9ussie et que l'adversaire l'attaque.
      10. +
      11. Gr\xE2ce f\xE9line : ajouter un pr\xE9dicat graceFeline. Cela va affecter l'initiative et la DEF, mais sans se voir sur la fiche. Pour les tests de d\xE9placement, ajouter un pr\xE9dicat graceFelineVoleur (penser \xE0 proposer l'utilisation de comp\xE9tences, en ajoutant les comp\xE9tences course, saut, acrobatie et escalade au voleur ou sur le handout de comp\xE9tences).
      -

      Voie du déplacement

      +

      Voie du d\xE9placement

        -
      1. Esquive : Ajouter un prédicat esquiveVoleur, de valeur le rang dans la voie. Ne pas modifier la DEF sur la fiche, le script fera les ajustements (et montrera le total avec !cof-statut).
      2. +
      3. Esquive : Ajouter un pr\xE9dicat esquiveVoleur, de valeur le rang dans la voie. Ne pas modifier la DEF sur la fiche, le script fera les ajustements (et montrera le total avec !cof-statut).
      4. Chute : pas de support particulier.
      5. -
      6. Acrobaties : faire !cof-jet DEX 15 --nom acrobatie pour le jet de dextérité, le reste est géré par le MJ. Il est possible d'automatiser quand le personnage décide de faire une attaque quel que soit le résultat du jet d'acrobatie grace à la commande #Attaque -1 --attaqueAcrobatique.
      7. -
      8. Esquive de la magie : ajouter un prédicat esquiveDeLaMagie.
      9. -
      10. Dextérité héroïque : ajouter les bonus sur la fiche
      11. +
      12. Acrobaties : faire !cof-jet DEX 15 --nom acrobatie pour le jet de dext\xE9rit\xE9, le reste est g\xE9r\xE9 par le MJ. Il est possible d'automatiser quand le personnage d\xE9cide de faire une attaque quel que soit le r\xE9sultat du jet d'acrobatie grace \xE0 la commande #Attaque -1 --attaqueAcrobatique.
      13. +
      14. Esquive de la magie : ajouter un pr\xE9dicat esquiveDeLaMagie.
      15. +
      16. Dext\xE9rit\xE9 h\xE9ro\xEFque : ajouter les bonus sur la fiche

      Voie du roublard

        -
      1. Doigts agiles : utiliser des compétences sur la fiche de personnage
      2. -
      3. Détecter les pièges : faire le jet avec !cof-jet INT ?{Piège normal?|Oui,10|Magique,15} --secret
      4. -
      5. Croc-en-jambe : ajouter un prédicat crocEnJambe. Pour distinguer les adversaires quadrupèdes qui ne seraient pas connues du script, lui ajouter un prédicat quadrupede. Les adversaires avec un prédicat volant ne seront pas affectés.
      6. +
      7. Doigts agiles : utiliser des comp\xE9tences sur la fiche de personnage
      8. +
      9. D\xE9tecter les pi\xE8ges : faire le jet avec !cof-jet INT ?{Pi\xE8ge normal?|Oui,10|Magique,15} --secret
      10. +
      11. Croc-en-jambe : ajouter un pr\xE9dicat crocEnJambe. Pour distinguer les adversaires quadrup\xE8des qui ne seraient pas connues du script, lui ajouter un pr\xE9dicat quadrupede. Les adversaires avec un pr\xE9dicat volant ne seront pas affect\xE9s.
      12. Attaque paralysante : lancer une des attaques de contact du voleur en rajoutant les options --limiteParCombat 1 attaqueParalysante --pasDeDmg --effet paralysieRoublard [[1d4]].
      13. -
      14. Attaque en traître : Ajouter un prédicat attaqueEnTraitre. Les actions affichées en cas d'attaque en traître seront par défaut une attaque avec l'arme en main et les attaques naturelles de la fiche cochées. Si cela ne convient pas, vous pouvez créer une liste d'actions nommée Attaques en traitre contenant les attaques possibles pour l'attaque en traître.
      15. +
      16. Attaque en tra\xEEtre : Ajouter un pr\xE9dicat attaqueEnTraitre. Les actions affich\xE9es en cas d'attaque en tra\xEEtre seront par d\xE9faut une attaque avec l'arme en main et les attaques naturelles de la fiche coch\xE9es. Si cela ne convient pas, vous pouvez cr\xE9er une liste d'actions nomm\xE9e Attaques en traitre contenant les attaques possibles pour l'attaque en tra\xEEtre.

      Voie du spadassin

      1. Attaque en finesse : faire les modifications sur la fiche
      2. -
      3. Esquive fatale : Ajouter un prédicat esquiveFatale (on peut y associer un nombre pour permettre plus d'une utilisation par combat). En combat, si la situation s'y prête, un bouton permettre d'utiliser l'esquive. Ne pas oublier de définir les alliés du voleur pour que la vérification des cibles soit correcte.
      4. -
      5. Frappe chirurgicale : ajouter un prédicat frappeChirurgicale.
      6. -
      7. Ambidextrie : pas géré par le script.
      8. -
      9. Botte secrète : ajouter un prédicat botteSecrete. Ne pas oublier le prédicat attaqueSournoise qui doit être associé au nombre de dés des attaques sournoises du voleur.
      10. +
      11. Esquive fatale : Ajouter un pr\xE9dicat esquiveFatale (on peut y associer un nombre pour permettre plus d'une utilisation par combat). En combat, si la situation s'y pr\xEAte, un bouton permettre d'utiliser l'esquive. Ne pas oublier de d\xE9finir les alli\xE9s du voleur pour que la v\xE9rification des cibles soit correcte.
      12. +
      13. Frappe chirurgicale : ajouter un pr\xE9dicat frappeChirurgicale.
      14. +
      15. Ambidextrie : pas g\xE9r\xE9 par le script.
      16. +
      17. Botte secr\xE8te : ajouter un pr\xE9dicat botteSecrete. Ne pas oublier le pr\xE9dicat attaqueSournoise qui doit \xEAtre associ\xE9 au nombre de d\xE9s des attaques sournoises du voleur.
    -

    4. Autres capacités

    +

    4. Autres capacit\xE9s

    -

    4.1 Voies et capacités raciales

    +

    4.1 Voies et capacit\xE9s raciales

    - Quelques capacités communes à plusieurs races : + Quelques capacit\xE9s communes \xE0 plusieurs races :
      -
    • Vision dans le noir : ajoutez un prédicat visionDansLeNoir de valeur le nombre de metres à laquelle le personnage peut voir dans le noir. Le script va adapter la vison dans le noir à l'unité de mesure utilisée sur la page où le token du personnage est créé.
    • +
    • Vision dans le noir : ajoutez un pr\xE9dicat visionDansLeNoir de valeur le nombre de metres \xE0 laquelle le personnage peut voir dans le noir. Le script va adapter la vison dans le noir \xE0 l'unit\xE9 de mesure utilis\xE9e sur la page o\xF9 le token du personnage est cr\xE9\xE9.
    -

    Âme forgée

    -

    Pour les capacités raciales, un prédicat vieArtificielle permet de diviser tous les soins par 2. Pour la résistance aux effets de drains, au feu et au froid, ajouter dans la RD sur la fiche drain:5, feu:5, froid:5. Pour l'immunité aux poisons et maladies, utiliser un prédicat creatureArtificielle. Enfin pour le saignement, ajouter un prédicat immuniteSaignement.

    +

    \xC2me forg\xE9e

    +

    Pour les capacit\xE9s raciales, un pr\xE9dicat vieArtificielle permet de diviser tous les soins par 2. Pour la r\xE9sistance aux effets de drains, au feu et au froid, ajouter dans la RD sur la fiche drain:5, feu:5, froid:5. Pour l'immunit\xE9 aux poisons et maladies, utiliser un pr\xE9dicat creatureArtificielle. Enfin pour le saignement, ajouter un pr\xE9dicat immuniteSaignement.

      -
    1. Main lourde : ajuster les DM, et enlever l'option --tempDmg pour l'attaque à mains nues.
    2. +
    3. Main lourde : ajuster les DM, et enlever l'option --tempDmg pour l'attaque \xE0 mains nues.

    Demi-ogre

    • Vision dans le noir.
    • -
    • Énorme : pas de support, ajuster les attaques
    • -
    • Grande taille : quand le demi-ogre rentre dans une construction de taille humaine, utiliser !cof-effet constructionTailleHumaine true. À la sortie du bâtiment, !cof-effet constructionTailleHumaine false. Pour les espaces exigus, de même avec l'effet espaceExigu.
    • -
    • Réaction violente : en cas de provocation, exécuter !cof-effet-temp reactionViolente [[1d6]] --save SAG 10. On peut par exemple mettre ce code en ability liée au token. Au MJ et au joueur de gérer les actions qui s'ensuivent. Le script propose une action à l'ogre pour prendre sur lui à chaque tour.
    • +
    • \xC9norme : pas de support, ajuster les attaques
    • +
    • Grande taille : quand le demi-ogre rentre dans une construction de taille humaine, utiliser !cof-effet constructionTailleHumaine true. \xC0 la sortie du b\xE2timent, !cof-effet constructionTailleHumaine false. Pour les espaces exigus, de m\xEAme avec l'effet espaceExigu.
    • +
    • R\xE9action violente : en cas de provocation, ex\xE9cuter !cof-effet-temp reactionViolente [[1d6]] --save SAG 10. On peut par exemple mettre ce code en ability li\xE9e au token. Au MJ et au joueur de g\xE9rer les actions qui s'ensuivent. Le script propose une action \xE0 l'ogre pour prendre sur lui \xE0 chaque tour.
      -
    1. Sang-froid : ajouter un prédicat sangFroid. Modifier la commande pour les provocations en !cof-effet-temp reactionViolente [[1d4]] --save SAG 5.
    2. -
    3. Violence ciblée : ajouter un prédicat violenceCiblee.
    4. +
    5. Sang-froid : ajouter un pr\xE9dicat sangFroid. Modifier la commande pour les provocations en !cof-effet-temp reactionViolente [[1d4]] --save SAG 5.
    6. +
    7. Violence cibl\xE9e : ajouter un pr\xE9dicat violenceCiblee.

    Demi-orque

    Vision dans le noir.
    1. Force de la nature : ajouter les bonus sur la fiche
    2. -
    3. Talent pour la violence : voir les capacités choisies
    4. +
    5. Talent pour la violence : voir les capacit\xE9s choisies
    6. Critique brutal : pour l'instant, ajouter le modificateur incrCritCoef pour toutes les attaques au contact.
    7. Attaque sanglante : faire une attaque (ou liste d'attaques) avec les options --effet blessureQuiSaigne --saveParTour CON [[12 + @{selected|FOR}]]
    8. -
    9. Colosse : augmenter les caractéristiques sur la fiche.
    10. +
    11. Colosse : augmenter les caract\xE9ristiques sur la fiche.

    Elfe sylvain

      -
    1. Grâce elfique : simplement reporter sur la fiche
    2. -
    3. Enfant de la forêt : voir les capacités choisies
    4. -
    5. Archer émérite : ajuster les chances de critique sur les attaques à l'arc
    6. -
    7. Flèche sanglante : faire une attaque (ou liste d'attaques) avec les options --effet blessureQuiSaigne --saveParTour CON [[12 + @{selected|DEX}]]
    8. -
    9. Supériorité elfique : augmenter les caractéristiques sur la fiche.
    10. +
    11. Gr\xE2ce elfique : simplement reporter sur la fiche
    12. +
    13. Enfant de la for\xEAt : voir les capacit\xE9s choisies
    14. +
    15. Archer \xE9m\xE9rite : ajuster les chances de critique sur les attaques \xE0 l'arc
    16. +
    17. Fl\xE8che sanglante : faire une attaque (ou liste d'attaques) avec les options --effet blessureQuiSaigne --saveParTour CON [[12 + @{selected|DEX}]]
    18. +
    19. Sup\xE9riorit\xE9 elfique : augmenter les caract\xE9ristiques sur la fiche.
    -

    Fée et lutin

    +

    F\xE9e et lutin

    • Vision dans le noir.
    • -
    • Tout petit : ajouter un prédicat toutPetit qui va automatiquement ajuster la défense et les jets de discrétion.
    • -
    • Vol et Téléportation : pas de support.
    • -
    • Trop petit : ajouter un prédicat tropPetit. Cela va aussi changer les dégâts de base des armes (il vaut mieux laisser les vrais DM pour que la capacité Grande taille fonctionne).
    • +
    • Tout petit : ajouter un pr\xE9dicat toutPetit qui va automatiquement ajuster la d\xE9fense et les jets de discr\xE9tion.
    • +
    • Vol et T\xE9l\xE9portation : pas de support.
    • +
    • Trop petit : ajouter un pr\xE9dicat tropPetit. Cela va aussi changer les d\xE9g\xE2ts de base des armes (il vaut mieux laisser les vrais DM pour que la capacit\xE9 Grande taille fonctionne).
    1. Langage des animaux : aucun support
    2. -
    3. Invisibilité : !cof-set-state invisible true --message se rend invisible --messageMJ l'invisibilité va durer [[1d6+@{selected|INT}]] minutes --limiteParJour rr est le rang dans la Voie.
    4. -
    5. Monture féérique : ajouter un ersonnage pour la monture. Ajoutez-lui le prédicat monture. Pour monter sur la monture, utiliser !cof-en-selle @{selected|token_id} nom_de_la_monture, et pour en descendre, il suffit de faire la même commande (utiliser une ability "token action" rend cela assez facile à l'usage). Si vous souhaitez que la monture rentre en combat à chaque fois que l'être féérique entre en combat, ajoutez à l'être féérique un prédicat nommé entrerEnCombatAvec, de valeur le nom du token de la monture (pensez à utiliser la syntaxe avec :: si ce nom contient des caractères spéciaux).
    6. -
    7. Grande taille : !cof-effet grandeTaille oui --lanceur @{selected|token_id} --limiteParJour 3 --messageMJ La taille humaine durera [[1d6+@{selected|CHA}]] minutes. Le script ne gère pas les durées en minutes, le MJ devra penser à supprimer l'effet, par exemple depuis le statut (!cof-statut).
    8. +
    9. Invisibilit\xE9 : !cof-set-state invisible true --message se rend invisible --messageMJ l'invisibilit\xE9 va durer [[1d6+@{selected|INT}]] minutes --limiteParJour r o\xF9 r est le rang dans la Voie.
    10. +
    11. Monture f\xE9\xE9rique : ajouter un ersonnage pour la monture. Ajoutez-lui le pr\xE9dicat monture. Pour monter sur la monture, utiliser !cof-en-selle @{selected|token_id} nom_de_la_monture, et pour en descendre, il suffit de faire la m\xEAme commande (utiliser une ability "token action" rend cela assez facile \xE0 l'usage). Si vous souhaitez que la monture rentre en combat \xE0 chaque fois que l'\xEAtre f\xE9\xE9rique entre en combat, ajoutez \xE0 l'\xEAtre f\xE9\xE9rique un pr\xE9dicat nomm\xE9 entrerEnCombatAvec, de valeur le nom du token de la monture (pensez \xE0 utiliser la syntaxe avec :: si ce nom contient des caract\xE8res sp\xE9ciaux).
    12. +
    13. Grande taille : !cof-effet grandeTaille oui --lanceur @{selected|token_id} --limiteParJour 3 --messageMJ La taille humaine durera [[1d6+@{selected|CHA}]] minutes. Le script ne g\xE8re pas les dur\xE9es en minutes, le MJ devra penser \xE0 supprimer l'effet, par exemple depuis le statut (!cof-statut).
    -

    Félis

    +

    F\xE9lis

      -
    1. Âme féline : ajouter un prédicat ameFeline, de valeur le rang dans la voie. Pensez à ajouter des compétences pour le mouvement sur la fiche si ils ne sont pas déjà présent dans votre handout de compétences.
    2. +
    3. \xC2me f\xE9line : ajouter un pr\xE9dicat ameFeline, de valeur le rang dans la voie. Pensez \xE0 ajouter des comp\xE9tences pour le mouvement sur la fiche si ils ne sont pas d\xE9j\xE0 pr\xE9sent dans votre handout de comp\xE9tences.
    4. Armes naturelles :
        -
      • Créez une attaque "Griffes et crocs" naturelle de contact avec en DM 1d6 + Mod de FOR et les options --si etat armesNaturelles --message Attaque de ses griffes et crocs !.
      • +
      • Cr\xE9ez une attaque "Griffes et crocs" naturelle de contact avec en DM 1d6 + Mod de FOR et les options --si etat armesNaturelles --message Attaque de ses griffes et crocs !.
      • Pour faire sortir les griffes, dans l'onglet script, ajouter une action "Sortir/rentrer les griffes" faisant !cof-effet armesNaturelles.
    5. @@ -2014,49 +2018,49 @@

      Félis

      Gnome

      1. Petit pote : ajouter le bonus de CHA sur la fiche
      2. -
      3. Don occulte : se reporter aux capacités choisies.
      4. -
      5. Insignifiant : ajouter un prédicat insignifiant. +
      6. Don occulte : se reporter aux capacit\xE9s choisies.
      7. +
      8. Insignifiant : ajouter un pr\xE9dicat insignifiant.

      Halfelin

      -

      Petite taille : ajouter le bonus de DEF sur la ficher, et ajouter 2 à une compétence discrétion.

      +

      Petite taille : ajouter le bonus de DEF sur la ficher, et ajouter 2 \xE0 une comp\xE9tence discr\xE9tion.

        -
      1. Petit veinard : ajouter un prédicat petitVeinard (on peut y associer un nombre si on veut plus d'une utilisation par combat). Le script ne va automatiser que les relancer de dés d'attaque ou de jets de caractéristiques (et encore, pas tous). Il propose d'utiliser la chance à chaque attaque, même réussie, mais dans ce cas, c'est au joueur de relancer le dé concerné, et au MJ d'en appliquer les conséquences.
      2. -
      3. Résistance légendaire : ajouter le bonus en CON sur la fiche, et ajouter un prédicat DEF_magie avec comme valeur 5.
      4. +
      5. Petit veinard : ajouter un pr\xE9dicat petitVeinard (on peut y associer un nombre si on veut plus d'une utilisation par combat). Le script ne va automatiser que les relancer de d\xE9s d'attaque ou de jets de caract\xE9ristiques (et encore, pas tous). Il propose d'utiliser la chance \xE0 chaque attaque, m\xEAme r\xE9ussie, mais dans ce cas, c'est au joueur de relancer le d\xE9 concern\xE9, et au MJ d'en appliquer les cons\xE9quences.
      6. +
      7. R\xE9sistance l\xE9gendaire : ajouter le bonus en CON sur la fiche, et ajouter un pr\xE9dicat DEF_magie avec comme valeur 5.

      Haut elfe

        -
      1. Grâce elfique : ajouter les bonus sur la fiche
      2. -
      3. Talent pour la magie : voir les capacités choisies
      4. -
      5. Force d'âme : ajouter des prédicat immunite_peur et immunite_endormi. Ajouter aussi des prédicats DEF_magie et bonusSagesseMagie de valeur 5.
      6. +
      7. Gr\xE2ce elfique : ajouter les bonus sur la fiche
      8. +
      9. Talent pour la magie : voir les capacit\xE9s choisies
      10. +
      11. Force d'\xE2me : ajouter des pr\xE9dicat immunite_peur et immunite_endormi. Ajouter aussi des pr\xE9dicats DEF_magie et bonusSagesseMagie de valeur 5.

      Humain

      -

      Instinct de survie : créer un prédicat instinctDeSurvieHumain.

      +

      Instinct de survie : cr\xE9er un pr\xE9dicat instinctDeSurvieHumain.

        -
      1. Adaptable : ajouter un prédicat adaptable, de valeur le bonus en cas de test raté. Le script ne va appliquer le bonus que pour les tests avec difficulté identifiée. Le MJ devra l'appliquer dans les cas ratés par le script.
      2. -
      3. Loup parmi les loups : ajouter un prédicat loupParmiLesLoups avec comme valeur 1 ou 2 selon le rang dans la voie. Une créature sera considérée comme humanoïde si elle a un prédicat humanoide, ou si sa race est reconnue comme humanoïde.
      4. -
      5. Versatile : se reporter à la capacité choisie.
      6. -
      7. Increvable : ajouter un prédicat increvableHumain.
      8. +
      9. Adaptable : ajouter un pr\xE9dicat adaptable, de valeur le bonus en cas de test rat\xE9. Le script ne va appliquer le bonus que pour les tests avec difficult\xE9 identifi\xE9e. Le MJ devra l'appliquer dans les cas rat\xE9s par le script.
      10. +
      11. Loup parmi les loups : ajouter un pr\xE9dicat loupParmiLesLoups avec comme valeur 1 ou 2 selon le rang dans la voie. Une cr\xE9ature sera consid\xE9r\xE9e comme humano\xEFde si elle a un pr\xE9dicat humanoide, ou si sa race est reconnue comme humano\xEFde.
      12. +
      13. Versatile : se reporter \xE0 la capacit\xE9 choisie.
      14. +
      15. Increvable : ajouter un pr\xE9dicat increvableHumain.

      Drakonide

        -
      1. Souffle : ajouter une attaque naturelle cochée, faisant des dégâts du type du drakonide, de portée 10 m, avec comme option --cone 30 --psave DEX 12 --tempsRecharge rechargeSouffle [[1d4]].
      2. -
      3. Intimidant : ajouter la compétence intimidation sur la fiche, avec un bonus de +5.
      4. -
      5. Écailles robustes : ajouter le bonus sur la fiche.
      6. -
      7. Fureur drakonide : ajouter un prédicat fureurDrakonide.
      8. -
      9. Héritage draconique : ajuster les caractéristiques sur la fiche.
      10. +
      11. Souffle : ajouter une attaque naturelle coch\xE9e, faisant des d\xE9g\xE2ts du type du drakonide, de port\xE9e 10 m, avec comme option --cone 30 --psave DEX 12 --tempsRecharge rechargeSouffle [[1d4]].
      12. +
      13. Intimidant : ajouter la comp\xE9tence intimidation sur la fiche, avec un bonus de +5.
      14. +
      15. \xC9cailles robustes : ajouter le bonus sur la fiche.
      16. +
      17. Fureur drakonide : ajouter un pr\xE9dicat fureurDrakonide.
      18. +
      19. H\xE9ritage draconique : ajuster les caract\xE9ristiques sur la fiche.

      Lutin

      - Voir les fées. + Voir les f\xE9es.

      Minotaure

      • Vision dans le noir.
      • Coup de corne : ajouter simplement l'attaque.
      • -
      • Sens de l'orientation : utiliser une compétence/
      • -
      • Grande taille : quand le minotaure rentre dans une construction de taille humaine, utiliser !cof-effet constructionTailleHumaine true. À la sortie du bâtiment, !cof-effet constructionTailleHumaine false. Pour les espaces exigus, de même avec l'effet espaceExigu. Si on veut un seul bouton, enlever simplement l'argument true.
      • +
      • Sens de l'orientation : utiliser une comp\xE9tence/
      • +
      • Grande taille : quand le minotaure rentre dans une construction de taille humaine, utiliser !cof-effet constructionTailleHumaine true. \xC0 la sortie du b\xE2timent, !cof-effet constructionTailleHumaine false. Pour les espaces exigus, de m\xEAme avec l'effet espaceExigu. Si on veut un seul bouton, enlever simplement l'argument true.
        -
      1. Charge : #Attaque -1 --bonusAttaque 2 --plus 1d6. Le déplacement n'est pas encore géré. Modifier les bonus si le minotaure possède la capacité Charge du barbare.
      2. -
      3. Frénésie : On peut faire passer en frénésie avec la commande !cof-effet-temp frenesieMinotaure [[1d6]]. Quand j'aurai le temps, il devrait être possible de faire apparaître un bouton quand le minotaure est blessé.
      4. +
      5. Charge : #Attaque -1 --bonusAttaque 2 --plus 1d6. Le d\xE9placement n'est pas encore g\xE9r\xE9. Modifier les bonus si le minotaure poss\xE8de la capacit\xE9 Charge du barbare.
      6. +
      7. Fr\xE9n\xE9sie : On peut faire passer en fr\xE9n\xE9sie avec la commande !cof-effet-temp frenesieMinotaure [[1d6]]. Quand j'aurai le temps, il devrait \xEAtre possible de faire appara\xEEtre un bouton quand le minotaure est bless\xE9.
      8. Orientation infaillible : pas de support particulier.
      9. Encorner : pas de support particulier.
      10. Colosse : reporter sur la fiche.
      11. @@ -2066,137 +2070,137 @@

        Nain

      12. Vision dans le noir.
        1. -
        2. Résistance : ajouter les bonus sur la fiche
        3. +
        4. R\xE9sistance : ajouter les bonus sur la fiche
        5. Solide comme un roc : ajouter le texte 2/1 dans la RD sur la fiche.
        6. -
        7. Haches et marteaux : ajouter un prédicat hachesEtMarteaux. Ne pas oublier de mettre le modificateur hache ou marteau pour les attaques qui sont concernées.
        8. +
        9. Haches et marteaux : ajouter un pr\xE9dicat hachesEtMarteaux. Ne pas oublier de mettre le modificateur hache ou marteau pour les attaques qui sont concern\xE9es.

        Tieflin

        • Vision dans le noir.
        • -
        • Résistance aux éléments : ajouter dans la RD sur la fiche feu:5, electrique:5, froid:5
        • +
        • R\xE9sistance aux \xE9l\xE9ments : ajouter dans la RD sur la fiche feu:5, electrique:5, froid:5
          -
        1. Se faire discret : ajouter les jets sur la fiche, ou bien des compétences mentir et deguisement de valeur 5, à utiliser avec !cof-jet.
        2. +
        3. Se faire discret : ajouter les jets sur la fiche, ou bien des comp\xE9tences mentir et deguisement de valeur 5, \xE0 utiliser avec !cof-jet.
    -

    4.2 Voies de prestige et capacités épiques

    +

    4.2 Voies de prestige et capacit\xE9s \xE9piques

    -

    Voie d'Arwendée

    +

    Voie d'Arwend\xE9e

      -
    1. Sens affutés : Créez un prédicat sensAffutes. Cela va ajuster l'initiative (ne se voit pas sur la fiche), ainsi que les dégâts des arcs. Ajoutez ensuite le bonus aux compétences perception et vigilance (ou créez-les).
    2. -
    3. Arc de maître : Créez un prédicat arcDeMaitre pour automatiquement augmenter la portée des arcs de 20 m.
    4. +
    5. Sens affut\xE9s : Cr\xE9ez un pr\xE9dicat sensAffutes. Cela va ajuster l'initiative (ne se voit pas sur la fiche), ainsi que les d\xE9g\xE2ts des arcs. Ajoutez ensuite le bonus aux comp\xE9tences perception et vigilance (ou cr\xE9ez-les).
    6. +
    7. Arc de ma\xEEtre : Cr\xE9ez un pr\xE9dicat arcDeMaitre pour automatiquement augmenter la port\xE9e des arcs de 20 m.
    8. Carquois magique : !cof-effet-temp carquoisMagique [[5+@{selected|SAG}]] --valeur ?{Type de DM?|feu|froid|foudre} --mana 1.
    9. -
    10. Protection contre les projectiles : Créez un prédicat protectionContreLesProjectiles de valeur 10. Puis, pour lancer le sort, utilisez !cof-effet-temp protectionContreLesProjectiles [[6*(5+@{selected|SAG})]] --lanceur @{selected|token_id} --target @{target|token_id} --mana 2.
    11. -
    12. Pluie de flèches : lancer l'attaque avec les options --limiteParCombat 1 pluieDeFleches --disque 5 --toucheDoubleDmg --mana 3.
    13. +
    14. Protection contre les projectiles : Cr\xE9ez un pr\xE9dicat protectionContreLesProjectiles de valeur 10. Puis, pour lancer le sort, utilisez !cof-effet-temp protectionContreLesProjectiles [[6*(5+@{selected|SAG})]] --lanceur @{selected|token_id} --target @{target|token_id} --mana 2.
    15. +
    16. Pluie de fl\xE8ches : lancer l'attaque avec les options --limiteParCombat 1 pluieDeFleches --disque 5 --toucheDoubleDmg --mana 3.

    Voie de l'archange

      -
    1. Forme d'ange : !cof-effet-temp formeDAnge [[5+@{selected|SAG}]] --mana 0. Le MJ devra gérer l'aspect en vol.
    2. -
    3. Soins améliorés : utiliser un prédicat voieDeLArchange avec comme valeur le rang dans la voie.
    4. -
    5. Épée céleste : rien à faire si le prédicat voieDeLArchange a la bonne valeur. Si le personnage n'a pas déjà la capacité Arme d'argent, ajouter une attaque pour cette arme, avec le modificateur armeDArgent et l'option --si etat armeDArgent.
    6. +
    7. Forme d'ange : !cof-effet-temp formeDAnge [[5+@{selected|SAG}]] --mana 0. Le MJ devra g\xE9rer l'aspect en vol.
    8. +
    9. Soins am\xE9lior\xE9s : utiliser un pr\xE9dicat voieDeLArchange avec comme valeur le rang dans la voie.
    10. +
    11. \xC9p\xE9e c\xE9leste : rien \xE0 faire si le pr\xE9dicat voieDeLArchange a la bonne valeur. Si le personnage n'a pas d\xE9j\xE0 la capacit\xE9 Arme d'argent, ajouter une attaque pour cette arme, avec le modificateur armeDArgent et l'option --si etat armeDArgent.

    Voie de l'archer arcanique

      -
    1. Flèche magique : vous pouvez ajouter une munition de type flèche, avec les modificateurs magique, reroll1.
    2. -
    3. Flèche tueuse : ajouter une munition dédiée, avec les modificateurs magique, reroll1 et les options --bonusAttaque 3 --plus rd6. Au Mj et au joueur de vérifier que cette flèche n'est utilisée que contre la bonne cible...
    4. -
    5. Flèche intangible : ajouter une action avec le code #Attaque -1 --difficulteCarac DEX --ignoreObstacles. Attention, pour l'instant le script ne vérifie pas que l'arme utilisée est bien un arc.
    6. -
    7. Flèches vivantes : ajoutez aux munitions du rang 1 et 2 l'option --if deAttaque 15 --plus 2d6 --message la flèche prend vie au contact du sang --endif.
    8. -
    9. Flèche chercheuse : faire une action avec le code #Attaque -1 --plus 2d6 --portee 1000 --limiteParJour 1 flecheChercheuse.
    10. +
    11. Fl\xE8che magique : vous pouvez ajouter une munition de type fl\xE8che, avec les modificateurs magique, reroll1.
    12. +
    13. Fl\xE8che tueuse : ajouter une munition d\xE9di\xE9e, avec les modificateurs magique, reroll1 et les options --bonusAttaque 3 --plus rd6. Au Mj et au joueur de v\xE9rifier que cette fl\xE8che n'est utilis\xE9e que contre la bonne cible...
    14. +
    15. Fl\xE8che intangible : ajouter une action avec le code #Attaque -1 --difficulteCarac DEX --ignoreObstacles. Attention, pour l'instant le script ne v\xE9rifie pas que l'arme utilis\xE9e est bien un arc.
    16. +
    17. Fl\xE8ches vivantes : ajoutez aux munitions du rang 1 et 2 l'option --if deAttaque 15 --plus 2d6 --message la fl\xE8che prend vie au contact du sang --endif.
    18. +
    19. Fl\xE8che chercheuse : faire une action avec le code #Attaque -1 --plus 2d6 --portee 1000 --limiteParJour 1 flecheChercheuse.

    Voie de l'expert

    - Reporter les bonus sur la fiche et créer les compétences adéquates. + Reporter les bonus sur la fiche et cr\xE9er les comp\xE9tences ad\xE9quates.

    Voie de l'expert du combat

      -
    1. Expertise du combat : créer un prédicat expertDuCombat avec comme valeur le rang dans la voie. La commande !cof-statut donne un état des lieux des dés dépensés pendant le combat/le tour. Les dés ne sont actifs qu'en combat et sont réinitialisés à l'utilisation de !cof-fin-combat. L'implémentation part du principe que l'augmentation de la DEF doit être décidée avant le jet de dommages, comme une esquive acrobatique par exemple.
    2. +
    3. Expertise du combat : cr\xE9er un pr\xE9dicat expertDuCombat avec comme valeur le rang dans la voie. La commande !cof-statut donne un \xE9tat des lieux des d\xE9s d\xE9pens\xE9s pendant le combat/le tour. Les d\xE9s ne sont actifs qu'en combat et sont r\xE9initialis\xE9s \xE0 l'utilisation de !cof-fin-combat. L'impl\xE9mentation part du principe que l'augmentation de la DEF doit \xEAtre d\xE9cid\xE9e avant le jet de dommages, comme une esquive acrobatique par exemple.
    4. Bousculer : !cof-expert-combat-bousculer @{selected|token_id} @{target|token_id}
    5. -
    6. Expertise supérieure : il suffit de mettre à jour la valeur du prédicat expertDuCombat ; le script automatise la mise à jour des limites et la possibilité d'augmenter les DM.
    7. -
    8. Déplacement tactique : pas de support spécifique pour le déplacement, mais on peut prévoir une action !cof-expert-combat pour le personnage, qui ne fera qu'une dépense simple de dé d'expertise.
    9. -
    10. Expertise majeure : les limites de dés par tour sont automatiques avec la bonne valeur du prédicat expertDuCombat. Pour l'instant le cumul de dés sur le même jet n'est pas supporté.
    11. +
    12. Expertise sup\xE9rieure : il suffit de mettre \xE0 jour la valeur du pr\xE9dicat expertDuCombat ; le script automatise la mise \xE0 jour des limites et la possibilit\xE9 d'augmenter les DM.
    13. +
    14. D\xE9placement tactique : pas de support sp\xE9cifique pour le d\xE9placement, mais on peut pr\xE9voir une action !cof-expert-combat pour le personnage, qui ne fera qu'une d\xE9pense simple de d\xE9 d'expertise.
    15. +
    16. Expertise majeure : les limites de d\xE9s par tour sont automatiques avec la bonne valeur du pr\xE9dicat expertDuCombat. Pour l'instant le cumul de d\xE9s sur le m\xEAme jet n'est pas support\xE9.

    Voie de l'homme du peuple

    - Reporter les bonus sur la fiche et créer les compétences adéquates. + Reporter les bonus sur la fiche et cr\xE9er les comp\xE9tences ad\xE9quates.

    Voie de la fusion lycanthropique

      -
    1. Lycanthropie : !cof-effet-temp lycanthropie [[5*@{selected|SAG}]]. Si vous souhaitez un changement d'image du token, utilisez un token à plusieurs faces. Dans la liste des faces, en partant de 0, on note n le numéro de la face qui contient l'image de loup-garou. Ajoutez alors --tokenSide n à la commande. Par exemple, si la première face est l'image normale du personnage, et la seconde face celle d'un loup-garou, on pourra utiliser !cof-effet-temp lycanthropie [[5*@{selected|SAG}]] --tokenSide 1.
    2. -
    3. Éventration : ajouter un prédicat lycanthropeEventre.
    4. +
    5. Lycanthropie : !cof-effet-temp lycanthropie [[5*@{selected|SAG}]]. Si vous souhaitez un changement d'image du token, utilisez un token \xE0 plusieurs faces. Dans la liste des faces, en partant de 0, on note n le num\xE9ro de la face qui contient l'image de loup-garou. Ajoutez alors --tokenSide n \xE0 la commande. Par exemple, si la premi\xE8re face est l'image normale du personnage, et la seconde face celle d'un loup-garou, on pourra utiliser !cof-effet-temp lycanthropie [[5*@{selected|SAG}]] --tokenSide 1.
    6. +
    7. \xC9ventration : ajouter un pr\xE9dicat lycanthropeEventre.

    Voie de Morn

      -
    1. Secrets de l'au-delà : !cof-effet-temp secretsDeLAuDela 1 --mana 0
    2. +
    3. Secrets de l'au-del\xE0 : !cof-effet-temp secretsDeLAuDela 1 --mana 0
    4. Souffle de vie : !cof-soin @{selected|token_id} @{target|token_id} souffleDeVie --mana 0
    5. -
    6. Souffle de mort : faire une attaque magique, de portée 20 m (la portée par défaut pour les sorts, mais rien n'est spécifié dans le texte), de dégâts 2d8+INT. Ajoutez auto dans les modificateurs. Pour les options, --disque 10 souffleDeMort --effet souffleDeMort 1 --save CON 10 --mana 1.
    7. +
    8. Souffle de mort : faire une attaque magique, de port\xE9e 20 m (la port\xE9e par d\xE9faut pour les sorts, mais rien n'est sp\xE9cifi\xE9 dans le texte), de d\xE9g\xE2ts 2d8+INT. Ajoutez auto dans les modificateurs. Pour les options, --disque 10 souffleDeMort --effet souffleDeMort 1 --save CON 10 --mana 1.
    -

    Voie de Prestige spécialisée

    +

    Voie de Prestige sp\xE9cialis\xE9e

      -
    1. Expertise : ajouter un prédicat expertiseSpecialisee, de valeur soit une caractéristique, soit une compétence, soit un mot-clé pour une capacité. Pour l'instant, ne sont implémentés que la rage du berserk (rageDuBerserk) et la furie du berserk (furieDuBerserk).
    2. +
    3. Expertise : ajouter un pr\xE9dicat expertiseSpecialisee, de valeur soit une caract\xE9ristique, soit une comp\xE9tence, soit un mot-cl\xE9 pour une capacit\xE9. Pour l'instant, ne sont impl\xE9ment\xE9s que la rage du berserk (rageDuBerserk) et la furie du berserk (furieDuBerserk).
    -

    Voie de Périndé

    +

    Voie de P\xE9rind\xE9

    1. Soutient
    2. -
    3. Présence réconfortante
    4. +
    5. Pr\xE9sence r\xE9confortante
    6. Prendre sur soit
    7. -
    8. Défendre les siens
    9. -
    10. Don de soi : !cof-soin @{selected|token_id} ?{Nombre de dés?|1|2|3|4|5}d6 --allies 10 --sacrifierPV --mana 3
    11. +
    12. D\xE9fendre les siens
    13. +
    14. Don de soi : !cof-soin @{selected|token_id} ?{Nombre de d\xE9s?|1|2|3|4|5}d6 --allies 10 --sacrifierPV --mana 3
    -

    Voie des armes à deux mains

    +

    Voie des armes \xE0 deux mains

      -
    1. Allonge : reporter le bonus d'attaque sur la fiche. Par facilité, j'ai considéré que le bonus d'Init était permanent et nous l'avons reporté sur la fiche.
    2. -
    3. Gros Monstre, grosse arme : ajouter un prédicat grosMonstreGrosseArme.
    4. -
    5. Tenir à distance (L) : !cof-effet-temp tenirADistance 1.
    6. -
    7. Attaque à outrance : !cof-attaque-a-outrance ?{Attaque à outrance ?|Non,0|-2 DEF / +1D6 DM,2}. Par facilité, cette "posture de combat" perdure jusqu'à la fin du combat ou jusqu'à ce que le guerrier en change. Au rang 5, on pourra utiliser !cof-attaque-a-outrance ?{Attaque à outrance ?|Non,0|-2 DEF/+1D6 DM,2|-5 DEF/+2D6 DM,5}
    8. -
    9. Critique destructeur : ajouter --plusCrit 2d6 aux attaques d'armes à 2 mains
    10. +
    11. Allonge : reporter le bonus d'attaque sur la fiche. Par facilit\xE9, j'ai consid\xE9r\xE9 que le bonus d'Init \xE9tait permanent et nous l'avons report\xE9 sur la fiche.
    12. +
    13. Gros Monstre, grosse arme : ajouter un pr\xE9dicat grosMonstreGrosseArme.
    14. +
    15. Tenir \xE0 distance (L) : !cof-effet-temp tenirADistance 1.
    16. +
    17. Attaque \xE0 outrance : !cof-attaque-a-outrance ?{Attaque \xE0 outrance ?|Non,0|-2 DEF / +1D6 DM,2}. Par facilit\xE9, cette "posture de combat" perdure jusqu'\xE0 la fin du combat ou jusqu'\xE0 ce que le guerrier en change. Au rang 5, on pourra utiliser !cof-attaque-a-outrance ?{Attaque \xE0 outrance ?|Non,0|-2 DEF/+1D6 DM,2|-5 DEF/+2D6 DM,5}
    18. +
    19. Critique destructeur : ajouter --plusCrit 2d6 aux attaques d'armes \xE0 2 mains

    Voie des vermines

      -
    1. Nuée de criquets : ajouter une attaque magique, de portée 20 m, type Sortilege, modificateur pasDeDmg et options --effet nueeDeCriquets [[5+@{selected|SAG}]]. Pas de support particulier pour les DM de zone qui détruisent la nuée (enlever l'attribut nueeDeCriquets sur la cible dans ce cas).
    2. +
    3. Nu\xE9e de criquets : ajouter une attaque magique, de port\xE9e 20 m, type Sortilege, modificateur pasDeDmg et options --effet nueeDeCriquets [[5+@{selected|SAG}]]. Pas de support particulier pour les DM de zone qui d\xE9truisent la nu\xE9e (enlever l'attribut nueeDeCriquets sur la cible dans ce cas).

    Voie du chasseur de corruption

    -

    Pour savoir si une cible est corrompue, le script va utiliser un prédicat corrompu qu'il appartient au MJ d'ajouter pour les créatures selon ses critères.

    +

    Pour savoir si une cible est corrompue, le script va utiliser un pr\xE9dicat corrompu qu'il appartient au MJ d'ajouter pour les cr\xE9atures selon ses crit\xE8res.

    1. Sentir la corruption : !cof-sentir-la-corruption @{selected|token_id} @{target|token_id}.
    2. -
    3. Combattre la corruption : ajouter un prédicat combattreLaCorruption. Y associer la valeur 2 au rang 4 dans la voie.
    4. -
    5. Chasseur de sorcière : ajouter un prédicat chasseurDeSorciere. Pour reconnaître les nécromanciens et autres prêtres maléfiques, il faut aussi leur ajouter un prédicat necromancien.
    6. -
    7. Frappe préventive : pas de support du script.
    8. +
    9. Combattre la corruption : ajouter un pr\xE9dicat combattreLaCorruption. Y associer la valeur 2 au rang 4 dans la voie.
    10. +
    11. Chasseur de sorci\xE8re : ajouter un pr\xE9dicat chasseurDeSorciere. Pour reconna\xEEtre les n\xE9cromanciens et autres pr\xEAtres mal\xE9fiques, il faut aussi leur ajouter un pr\xE9dicat necromancien.
    12. +
    13. Frappe pr\xE9ventive : pas de support du script.

    Voie du chevalier dragon

      -
    1. Ordre du chevalier dragon : créer les compétences Persuasion et Intimidation avec les bonus de base de +5. Ajouter un prédicat ordreDuChevalierDragon. Quand le personnage est monté, le script rajoutera automatiquement un bonus de +5 via !cof-jet
    2. -
    3. Épée de feu : !cof-effet-temp armeEnflammee [[5+@{selected|CHA}]] --lanceur @{selected|token_id} --target @{selected|token_id}. Ne se cumule pas avec l'Arme enflammée du Magicien.
    4. -
    5. Résistance au feu : rajouter feu:5 (ou 10 au rang 5) dans la partie RD de la fiche
    6. +
    7. Ordre du chevalier dragon : cr\xE9er les comp\xE9tences Persuasion et Intimidation avec les bonus de base de +5. Ajouter un pr\xE9dicat ordreDuChevalierDragon. Quand le personnage est mont\xE9, le script rajoutera automatiquement un bonus de +5 via !cof-jet
    8. +
    9. \xC9p\xE9e de feu : !cof-effet-temp armeEnflammee [[5+@{selected|CHA}]] --lanceur @{selected|token_id} --target @{selected|token_id}. Ne se cumule pas avec l'Arme enflamm\xE9e du Magicien.
    10. +
    11. R\xE9sistance au feu : rajouter feu:5 (ou 10 au rang 5) dans la partie RD de la fiche
    12. Monture puissante : modifier la fiche du Drake
    13. -
    14. Souffle enflammé : ajouter une attaque au dragon, même jet pour touche, dm 2d6, portée 40, arme naturelle qui inflige des dégâts de feu, avec comme options --disque 3 --dmSiRate 1d6 --dmCible 4d6
    15. +
    16. Souffle enflamm\xE9 : ajouter une attaque au dragon, m\xEAme jet pour touche, dm 2d6, port\xE9e 40, arme naturelle qui inflige des d\xE9g\xE2ts de feu, avec comme options --disque 3 --dmSiRate 1d6 --dmCible 4d6
    -

    Voie du combat à deux armes

    +

    Voie du combat \xE0 deux armes

      -
    1. Combat à deux armes amélioré : mettre une des attaques de type arme gauche, et y ajouter le modificateur avecd12crit. Pas encore de support pour la capacité avancée : dans ce cas, ajoutez le +1 dans la barre 3 du token ou sur les attaques.
    2. -
    3. Parade croisée : !cof-effet-temp paradeCroisee 1 --valeur rang --montreActionsrang est le rang dans la Voie.
    4. +
    5. Combat \xE0 deux armes am\xE9lior\xE9 : mettre une des attaques de type arme gauche, et y ajouter le modificateur avecd12crit. Pas encore de support pour la capacit\xE9 avanc\xE9e : dans ce cas, ajoutez le +1 dans la barre 3 du token ou sur les attaques.
    6. +
    7. Parade crois\xE9e : !cof-effet-temp paradeCroisee 1 --valeur rang --montreActions o\xF9 rang est le rang dans la Voie.

    Voie du danseur de guerre

      -
    1. Pirouettes : on peut rajouter les bonus sur la fiche, ou bien ajouter un prédicat pirouettes, de valeur le bonus en défense (qui ne s'applique que si le malus d'armure est inférieur à 4).
    2. -
    3. Vent des lames : pas de support du script, simplement ajouter les attaques adaptées sur la fiche
    4. +
    5. Pirouettes : on peut rajouter les bonus sur la fiche, ou bien ajouter un pr\xE9dicat pirouettes, de valeur le bonus en d\xE9fense (qui ne s'applique que si le malus d'armure est inf\xE9rieur \xE0 4).
    6. +
    7. Vent des lames : pas de support du script, simplement ajouter les attaques adapt\xE9es sur la fiche
    8. Attaque en mouvement : pas de support du script.
    9. -
    10. Danse des lames : !cof-effet-combat danseDesLames. Pour l'attaque gratuite supplémentaire, on peut faire #Attaque -1 --si etat danseDesLames --avecd12crit.
    11. +
    12. Danse des lames : !cof-effet-combat danseDesLames. Pour l'attaque gratuite suppl\xE9mentaire, on peut faire #Attaque -1 --si etat danseDesLames --avecd12crit.

    Voie du familier fantastique

      -
    1. Familier fantastique : créer un personnage (de type PNJ) pour le familier, controlé par le joueur et avec un token lié ayant la capacité de voir. +
    2. Familier fantastique : cr\xE9er un personnage (de type PNJ) pour le familier, control\xE9 par le joueur et avec un token li\xE9 ayant la capacit\xE9 de voir.
        -
      • Pour le bonus en initiative, ajouter au personnage un prédicat familier de valeur le nom du compagnon (doit être exactement le même que celui du token du compagnon). Cela automatise l'initiative quand le familier est présent.
      • -
      • Pour les points de vie partagés avec le familier, il faut mettre un prédicat PVPartagesAvec de valeur le nom du familier (celui de la fiche, pas forcément le même que le token) pour le personnage, et un prédicat similaire chez le familier, de valeur le nom du personnage. Le partage de PVs ne fonctionne pas avec des mooks, et il ne fait pas le partage de dégâts temporaires. En revanche, le script devrait gérer correctement les dégâts de zone.
      • -
      • Pour la défense du familier, ajouter lui un prédicat defDeriveeDe, de valeur le nom du personnage (nom complet sur la fiche, attention à bien utiliser la syntaxe avec :: si ce nom contient des espaces ou d'autres caractères spéciaux).
      • -
      • Pour l'initiative, ajoutez un prédicat initiativeDeriveeDe de valeur le nom du personnage.
      • +
      • Pour le bonus en initiative, ajouter au personnage un pr\xE9dicat familier de valeur le nom du compagnon (doit \xEAtre exactement le m\xEAme que celui du token du compagnon). Cela automatise l'initiative quand le familier est pr\xE9sent.
      • +
      • Pour les points de vie partag\xE9s avec le familier, il faut mettre un pr\xE9dicat PVPartagesAvec de valeur le nom du familier (celui de la fiche, pas forc\xE9ment le m\xEAme que le token) pour le personnage, et un pr\xE9dicat similaire chez le familier, de valeur le nom du personnage. Le partage de PVs ne fonctionne pas avec des mooks, et il ne fait pas le partage de d\xE9g\xE2ts temporaires. En revanche, le script devrait g\xE9rer correctement les d\xE9g\xE2ts de zone.
      • +
      • Pour la d\xE9fense du familier, ajouter lui un pr\xE9dicat defDeriveeDe, de valeur le nom du personnage (nom complet sur la fiche, attention \xE0 bien utiliser la syntaxe avec :: si ce nom contient des espaces ou d'autres caract\xE8res sp\xE9ciaux).
      • +
      • Pour l'initiative, ajoutez un pr\xE9dicat initiativeDeriveeDe de valeur le nom du personnage.
    3. Pouvoir mineur :
        -
      • Minimoi (Égocentrisme) : Téléportation, pas de support.
      • +
      • Minimoi (\xC9gocentrisme) : T\xE9l\xE9portation, pas de support.
    4. Canalisation : Lancer l'attaque avec l'option --canaliseParFamilier.
    5. -
    6. Pouvoir supérieur : +
    7. Pouvoir sup\xE9rieur :
        -
      • Minimoi (Clone) : à faire.
      • +
      • Minimoi (Clone) : \xE0 faire.
    @@ -2204,324 +2208,326 @@

    Voie du gel

    1. -
    2. Cône de froid : faire une attaque portee 20m, dégâts 2d6+INT de froid, avec comme modificateur auto et comme options --cone 30 --fx breath-frost --ifSaveFails CON 13 --effet ralenti 1 --else --diviseDmg 2 --endif. Pour un objet de sort : !cof-attack @{selected|token_id} @{target|token_id} Cône de froid --sortilege --auto --dm 2d6+[[@{selected|INT}]] --froid --portee 20 --cone 30 --fx breath-frost --ifSaveFails CON 13 --effet ralentiTemp 1 --else --diviseDmg 2 --endif
    3. -
    4. Présence glaciale : !cof-effet presenceGlaciale oui. Utiliser !cof-effet presenceGlaciale non pour mettre fin à l'effet. On peut préciser un bonus de DEF et des dégâts différents avec l'option --valeur. Ainsi, la version grimoire sera !cof-effet presenceGlaciale oui --valeur 3 1d4.
    5. +
    6. C\xF4ne de froid : faire une attaque portee 20m, d\xE9g\xE2ts 2d6+INT de froid, avec comme modificateur auto et comme options --cone 30 --fx breath-frost --ifSaveFails CON 13 --effet ralenti 1 --else --diviseDmg 2 --endif. Pour un objet de sort : !cof-attack @{selected|token_id} @{target|token_id} C\xF4ne de froid --sortilege --auto --dm 2d6+[[@{selected|INT}]] --froid --portee 20 --cone 30 --fx breath-frost --ifSaveFails CON 13 --effet ralentiTemp 1 --else --diviseDmg 2 --endif
    7. +
    8. Pr\xE9sence glaciale : !cof-effet presenceGlaciale oui. Utiliser !cof-effet presenceGlaciale non pour mettre fin \xE0 l'effet. On peut pr\xE9ciser un bonus de DEF et des d\xE9g\xE2ts diff\xE9rents avec l'option --valeur. Ainsi, la version grimoire sera !cof-effet presenceGlaciale oui --valeur 3 1d4.
    -

    Voie du guérisseur

    +

    Voie du gu\xE9risseur

      -
    1. Premiers soins : ajouter un prédicat voieDuGuerisseur de valeur le rang dans cette voie pour le bonus aux soins de la Voie des soins. Pour le sort, faire !cof-soin @{selected|token_id} @{target|token_id} premiersSoins --mana 0.
    2. -
    3. Immunité : utilisez !cof-immunite-guerisseur [[1d6+@{selected|SAG}]] --mana 0 --target @{target|token_id} dans les actions du tour. Si utilisé directement dans le chat, ajoutez --lanceur @{selected|token_id}.
    4. +
    5. Premiers soins : ajouter un pr\xE9dicat voieDuGuerisseur de valeur le rang dans cette voie pour le bonus aux soins de la Voie des soins. Pour le sort, faire !cof-soin @{selected|token_id} @{target|token_id} premiersSoins --mana 0.
    6. +
    7. Immunit\xE9 : utilisez !cof-immunite-guerisseur [[1d6+@{selected|SAG}]] --mana 0 --target @{target|token_id} dans les actions du tour. Si utilis\xE9 directement dans le chat, ajoutez --lanceur @{selected|token_id}.
    8. Soins rapides : pas de support au niveau du script.
    9. -
    10. Zone de vie : !cof-zone-de-vie [[1d6+@{selected|SAG}]] --mana 1 --limiteParJour 3 --lanceur @{selected|token_id}. Cela devrait respecter le sort, sauf pour le moment où le soin prend effet : c'est au début de chaque tour du prêtre.
    11. +
    12. Zone de vie : !cof-zone-de-vie [[1d6+@{selected|SAG}]] --mana 1 --limiteParJour 3 --lanceur @{selected|token_id}. Cela devrait respecter le sort, sauf pour le moment o\xF9 le soin prend effet : c'est au d\xE9but de chaque tour du pr\xEAtre.

    Voie du guerrier-mage

    -

    Penser à utiliser l'option --magieEnArmure pour le lancement des sorts affectés.

    +

    Penser \xE0 utiliser l'option --magieEnArmure pour le lancement des sorts affect\xE9s.

      -
    1. Magie en armure : Ajouter un prédicat magieEnArmure de valeur la DEF totale à partir de laquelle le personnage peut lancer des sorts. Comme la fiche ne contient pas l'information de la DEF normale (sans magie) de l'armure portée, le script utilise la moyenne de la DEF et du malus d'armure. En ajoutant un prédicat magieEnArmureFacilitee, le script diminue aussi la difficulté des jets d'INT pour les armures avec une DEF trop grande de la valeur du prédicat de magie en armure.
    2. -
    3. Rituel Assuré : !cof-effet-temp rituelAssure 2 --mana 0. Le script ne permet pas de préciser le sort, le premier qui sera lancé après le rituel assuré bénéficiera de l'effet.
    4. -
    5. MagieDeCombat : Ajouter un prédicat magieDeCombat.
    6. +
    7. Magie en armure : Ajouter un pr\xE9dicat magieEnArmure de valeur la DEF totale \xE0 partir de laquelle le personnage peut lancer des sorts. Comme la fiche ne contient pas l'information de la DEF normale (sans magie) de l'armure port\xE9e, le script utilise la moyenne de la DEF et du malus d'armure. En ajoutant un pr\xE9dicat magieEnArmureFacilitee, le script diminue aussi la difficult\xE9 des jets d'INT pour les armures avec une DEF trop grande de la valeur du pr\xE9dicat de magie en armure.
    8. +
    9. Rituel Assur\xE9 : !cof-effet-temp rituelAssure 2 --mana 0. Le script ne permet pas de pr\xE9ciser le sort, le premier qui sera lanc\xE9 apr\xE8s le rituel assur\xE9 b\xE9n\xE9ficiera de l'effet.
    10. +
    11. MagieDeCombat : Ajouter un pr\xE9dicat magieDeCombat.
    12. Frappe des arcanes : faire une attaque avec l'option --frappeDesArcanes, par exemple dans une action dont le code serait #Attaque -1 --frappeDesArcanes.
    13. +
    14. Expertise du combat : aucun support du script.
    -

    Voie du héro

    +

    Voie du h\xE9ro

      -
    1. Destin héroïque : ajouter le bonus au bonus de points de chances sur la fiche (utiliser la roue crantée à droite de la section CHANCE de la fiche).
    2. -
    3. Ténacité : ajouter un prédicat tenacite.
    4. +
    5. Destin h\xE9ro\xEFque : ajouter le bonus au bonus de points de chances sur la fiche (utiliser la roue crant\xE9e \xE0 droite de la section CHANCE de la fiche).
    6. +
    7. T\xE9nacit\xE9 : ajouter un pr\xE9dicat tenacite.
    8. Homme de la situation : pas de support.
    9. -
    10. Meneur d'hommes : Ajouter une action : !cof-set-attribute meneurDHommesCible @{selected|token_id} --target @{target|token_id}. Le personnage peut utiliser cette action pour désigner sa cible. Tous les alliés du personnage recevront automatiquement les bonus sur le reste du combat.
    11. +
    12. Meneur d'hommes : Ajouter une action : !cof-set-attribute meneurDHommesCible @{selected|token_id} --target @{target|token_id}. Le personnage peut utiliser cette action pour d\xE9signer sa cible. Tous les alli\xE9s du personnage recevront automatiquement les bonus sur le reste du combat.
    -

    Voie du maître des poisons

    +

    Voie du ma\xEEtre des poisons

    Rappel : pour appliquer un poison, utiliser !cof-enduire-poison -1 type force save.
      -
    1. Connaissance du poison : ajouter un prédicat connaissanceDuPoison pour éviter le test d'INT quand le voleur applique du poison.
    2. -
    3. Poison rapide : faire les applications à la main (!cof-enduire-poison L rapide 2d6 12).
    4. -
    5. Poison affaiblissant : faire les applications à la main (!cof-enduire-poison L affaiblissant 0 15).
    6. +
    7. Connaissance du poison : ajouter un pr\xE9dicat connaissanceDuPoison pour \xE9viter le test d'INT quand le voleur applique du poison.
    8. +
    9. Poison rapide : faire les applications \xE0 la main (!cof-enduire-poison L rapide 2d6 12).
    10. +
    11. Poison affaiblissant : faire les applications \xE0 la main (!cof-enduire-poison L affaiblissant 0 15).

    Voie du messager

    1. Muet comme une tombe : pas de support pour l'instant.
    2. -
    3. Jusqu'à bon port : ajouter les compétences correspondantes sur la fiche.
    4. -
    5. Conducteur de diligence : ajouter les compétences, et en cas de combat depuis une diligence, utiliser la barre 3 pour le bonus à l'attaque.
    6. +
    7. Jusqu'\xE0 bon port : ajouter les comp\xE9tences correspondantes sur la fiche.
    8. +
    9. Conducteur de diligence : ajouter les comp\xE9tences, et en cas de combat depuis une diligence, utiliser la barre 3 pour le bonus \xE0 l'attaque.
    10. Sens du devoir : Activer avec !cof-effet sensDuDevoir true. On peut enlever cet effet depuis le statut, au changement de jour, ou avec la commande !cof-effet sensDuDevoir false.
    11. Attaque en mouvement : pas de support pour l'instant.

    Voie du pacte vampirique

      -
    1. Blessure sanglante : ajuter un prédicat blessureSanglante.
    2. -
    3. Sang puissant : ajouter un prédicat immuniteSaignement et un prédicat immuniteAbsorptionVampire.
    4. -
    5. Drain de sang : ajouter un prédicat drainDeSang.
    6. -
    7. Flot de sang : associer la valeur 2 au prédicat blessureSanglante.
    8. -
    9. Énergie impie : ajouter un prédicat energieImpie.
    10. +
    11. Blessure sanglante : ajuter un pr\xE9dicat blessureSanglante.
    12. +
    13. Sang puissant : ajouter un pr\xE9dicat immuniteSaignement et un pr\xE9dicat immuniteAbsorptionVampire.
    14. +
    15. Drain de sang : ajouter un pr\xE9dicat drainDeSang.
    16. +
    17. Flot de sang : associer la valeur 2 au pr\xE9dicat blessureSanglante.
    18. +
    19. \xC9nergie impie : ajouter un pr\xE9dicat energieImpie.

    Voie du porteur de bouclier

      -
    1. Expertise du bouclier : reporter le bonus sur la fiche dans le bonus de DEF conféré par le bouclier.
    2. -
    3. Progresser à couvert : !cof-effet-temp progresserACouvert 1 --lanceur @{selected|token_id} --target @{target|token_id} --self --portee 1. A utiliser pour cibler un allié à portée si nécessaire. Au MJ de vérifier qu'elle reste bien près du chevalier pour profiter du bonus.
    4. -
    5. Attaque au bouclier : Ajouter une arme avec son Bouclier en "Arme gauche" sur la fiche du personnage. Dans les modificateurs de l'arme, ajoutez avecd12crit. Pour que cette attaque soit proposée dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un prédicat attaqueAuBouclier de valeur le label de l'attaque.
    6. -
    7. Dévier les coups : Ajouter un prédicat devierLesCoups (on peut y associer un nombre, si on souhaite plus d'une utlisation par tour). Le script ajoute automatiquement un bouton sur les attaques sur lesquelles cette capacité peut-être utilisée.
    8. -
    9. Parade au bouclier : Ajouter un prédicat paradeAuBouclier. Sur l'ability Coup de bouclier créé pour le rang 3, ajouter --attaqueBouclierRenverse --decrLimitePredicatParTour paradeAuBouclier. Le script ajoute automatiquement un bouton sur les attaques sur lesquelles cette capacité peut-être utilisée. Si le personnage possède un bouclier en arme gauche, le script utilisera le bonus éventuel de l'arme en question sur le jet opposé.
    10. +
    11. Expertise du bouclier : reporter le bonus sur la fiche dans le bonus de DEF conf\xE9r\xE9 par le bouclier.
    12. +
    13. Progresser \xE0 couvert : !cof-effet-temp progresserACouvert 1 --lanceur @{selected|token_id} --target @{target|token_id} --self --portee 1. A utiliser pour cibler un alli\xE9 \xE0 port\xE9e si n\xE9cessaire. Au MJ de v\xE9rifier qu'elle reste bien pr\xE8s du chevalier pour profiter du bonus.
    14. +
    15. Attaque au bouclier : Ajouter une arme avec son Bouclier en "Arme gauche" sur la fiche du personnage. Dans les modificateurs de l'arme, ajoutez avecd12crit. Pour que cette attaque soit propos\xE9e dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un pr\xE9dicat attaqueAuBouclier de valeur le label de l'attaque.
    16. +
    17. D\xE9vier les coups : Ajouter un pr\xE9dicat devierLesCoups (on peut y associer un nombre, si on souhaite plus d'une utlisation par tour). Le script ajoute automatiquement un bouton sur les attaques sur lesquelles cette capacit\xE9 peut-\xEAtre utilis\xE9e.
    18. +
    19. Parade au bouclier : Ajouter un pr\xE9dicat paradeAuBouclier. Sur l'ability Coup de bouclier cr\xE9\xE9 pour le rang 3, ajouter --attaqueBouclierRenverse --decrLimitePredicatParTour paradeAuBouclier. Le script ajoute automatiquement un bouton sur les attaques sur lesquelles cette capacit\xE9 peut-\xEAtre utilis\xE9e. Si le personnage poss\xE8de un bouclier en arme gauche, le script utilisera le bonus \xE9ventuel de l'arme en question sur le jet oppos\xE9.
    -

    Voie du tueur de géant

    +

    Voie du tueur de g\xE9ant

      -
    1. Réduire la distance : ajouter un prédicat reduireLaDistance.
    2. -
    3. Ventre mou : ajouter un prédicat ventreMou. Cela va diminuer la RD fixe de 3 maximum pour une créature grande, 6 maximum pour une créature énorme et 10 maximum pour une créature colossale.
    4. -
    5. Bûcheron : ajouter un prédicat bucheron.
    6. +
    7. R\xE9duire la distance : ajouter un pr\xE9dicat reduireLaDistance.
    8. +
    9. Ventre mou : ajouter un pr\xE9dicat ventreMou. Cela va diminuer la RD fixe de 3 maximum pour une cr\xE9ature grande, 6 maximum pour une cr\xE9ature \xE9norme et 10 maximum pour une cr\xE9ature colossale.
    10. +
    11. B\xFBcheron : ajouter un pr\xE9dicat bucheron.
    -

    Capacités épiques

    +

    Capacit\xE9s \xE9piques

      -
    • Libérateur de Dorn : ajouter un prédicat liberateurDeDorn.
    • -
    • Libérateur de Kerserac : ajouter un prédicat liberateurDeKerserac.
    • -
    • Libérateur d'Anathazerïn : ajouter un prédicat liberateurDAnathazerin. La capacité donne le bonus de +2 quel que soit le poison.
    • -
    • Lien épique: ajouter pour chaque personnage un prédicat lienEpique, qui contiennent la même chose dans le champ courant (pensez à un nom d'équipe, par exemple).
    • -
    • Vitalité épique : ajouter un prédicat vitaliteEpique. Pas de support pour le coup mortel ou la régénération horaire. Attention, si vous utlisez !cof-soin pour cette régénération, les soins seront aussi doublés.
    • +
    • Lib\xE9rateur de Dorn : ajouter un pr\xE9dicat liberateurDeDorn.
    • +
    • Lib\xE9rateur de Kerserac : ajouter un pr\xE9dicat liberateurDeKerserac.
    • +
    • Lib\xE9rateur d'Anathazer\xEFn : ajouter un pr\xE9dicat liberateurDAnathazerin. La capacit\xE9 donne le bonus de +2 quel que soit le poison.
    • +
    • Lien \xE9pique: ajouter pour chaque personnage un pr\xE9dicat lienEpique, qui contiennent la m\xEAme chose dans le champ courant (pensez \xE0 un nom d'\xE9quipe, par exemple).
    • +
    • Vitalit\xE9 \xE9pique : ajouter un pr\xE9dicat vitaliteEpique. Pas de support pour le coup mortel ou la r\xE9g\xE9n\xE9ration horaire. Attention, si vous utlisez !cof-soin pour cette r\xE9g\xE9n\xE9ration, les soins seront aussi doubl\xE9s.
    -

    4.3 Voies de créatures

    +

    4.3 Voies de cr\xE9atures

    Voie du champion

    1. Imparable:
        -
      • Utiliser l'option --m2d20 pour l'action limitée.
      • -
      • Pour l'effet permanent, utiliser un prédicat champion
      • +
      • Utiliser l'option --m2d20 pour l'action limit\xE9e.
      • +
      • Pour l'effet permanent, utiliser un pr\xE9dicat champion
    2. -
    3. Riposte : Ajouter un prédicat riposte. Les actions affichées en cas de riposte seront normalement une attaque avec l'arme en main si il y en a, plus les attaques naturelles cochées sur la liste d'attaque. Si ça ne convient pas, vous pouvez écrire une liste d'actions nomméeRipostes (voir les actions du tour).
    4. -
    5. Hausser le ton : ajouter un prédicat hausserLeTon.
    6. +
    7. Riposte : Ajouter un pr\xE9dicat riposte. Les actions affich\xE9es en cas de riposte seront normalement une attaque avec l'arme en main si il y en a, plus les attaques naturelles coch\xE9es sur la liste d'attaque. Si \xE7a ne convient pas, vous pouvez \xE9crire une liste d'actions nomm\xE9eRipostes (voir les actions du tour).
    8. +
    9. Hausser le ton : ajouter un pr\xE9dicat hausserLeTon.
    -

    Voie du chef d'armée

    +

    Voie du chef d'arm\xE9e

      -
    1. Sergent : ne pas oublier l'action de plus donnée à un allié par tour. Utiliser un prédicat sergent (pour l'attaque ignorée par combat)
    2. -
    3. Capitaine : pour désigner le capitaine d'un ensemble de tokens sélectionné (quelle que soit la méthode), on peut utiliser !cof-capitaine @{selected|token_id} 2, en ajoutant les options de sélection (comme --target @{target|token_id}). Au lieu de sélectionner une cible, on peut utiliser le nom d'un token. Si le capitaine fait parti de la sélection, il sera automatiquement exclu (on ne peut être son propre capitaine). Si à la place de 2, le deuxième argument est 0, cela enlève le capitaine. L'attribut généré est lié à un personnage, pas un token spécifique, il suffit donc de cibler un token représentant un personnage pour affecter tous les tokens qui représentent ce personnage. Pas de support particulier pour l'attaque supplémentaire en cas d'action limitée.
    4. -
    5. Commandant : il faut ajouter un prédicat commandant. La méthode pour désigner les personnages sous les ordres du commandant est la même que pour le capitaine : !cof-capitaine @{selected|token_id} 3 (notez que la valeur est 3 pour le commandant, et 2 pour le capitaine).
    6. +
    7. Sergent : ne pas oublier l'action de plus donn\xE9e \xE0 un alli\xE9 par tour. Utiliser un pr\xE9dicat sergent (pour l'attaque ignor\xE9e par combat)
    8. +
    9. Capitaine : pour d\xE9signer le capitaine d'un ensemble de tokens s\xE9lectionn\xE9 (quelle que soit la m\xE9thode), on peut utiliser !cof-capitaine @{selected|token_id} 2, en ajoutant les options de s\xE9lection (comme --target @{target|token_id}). Au lieu de s\xE9lectionner une cible, on peut utiliser le nom d'un token. Si le capitaine fait parti de la s\xE9lection, il sera automatiquement exclu (on ne peut \xEAtre son propre capitaine). Si \xE0 la place de 2, le deuxi\xE8me argument est 0, cela enl\xE8ve le capitaine. L'attribut g\xE9n\xE9r\xE9 est li\xE9 \xE0 un personnage, pas un token sp\xE9cifique, il suffit donc de cibler un token repr\xE9sentant un personnage pour affecter tous les tokens qui repr\xE9sentent ce personnage. Pas de support particulier pour l'attaque suppl\xE9mentaire en cas d'action limit\xE9e.
    10. +
    11. Commandant : il faut ajouter un pr\xE9dicat commandant. La m\xE9thode pour d\xE9signer les personnages sous les ordres du commandant est la m\xEAme que pour le capitaine : !cof-capitaine @{selected|token_id} 3 (notez que la valeur est 3 pour le commandant, et 2 pour le capitaine).

    Voie du cogneur

    1. Charge : Faire l'attaque avec les arguments --m2d20 --pietine.
    2. -
    3. Enrager : ajouter un prédicat peutEnrager.
    4. +
    5. Enrager : ajouter un pr\xE9dicat peutEnrager.
    6. Percuter : Remplacer --pietine par --percute dans l'attaque de Charge.

    Voie du colosse

      -
    1. Fauchage : ajouter la RD, et ajouter un prédicat fauchage, qui va faire automatiquement le renversement si le dé d'attaque est entre 15 et 20. Il est possible de changer ce seuil associant au prédicat la valeur à laquelle le dé d'attaque provoque le renversement (15 par défaut). Par défaut, le fauchage est impossible si la taille du défenseur est supérieure ou égale à celle de l'attaquant. Vous pouvez spécifier un seuil de taille maximale dans un prédicat tailleFauchage (5 = grand, 6 énorme et 7 colossal).
    2. +
    3. Fauchage : ajouter la RD, et ajouter un pr\xE9dicat fauchage, qui va faire automatiquement le renversement si le d\xE9 d'attaque est entre 15 et 20. Il est possible de changer ce seuil associant au pr\xE9dicat la valeur \xE0 laquelle le d\xE9 d'attaque provoque le renversement (15 par d\xE9faut). Par d\xE9faut, le fauchage est impossible si la taille du d\xE9fenseur est sup\xE9rieure ou \xE9gale \xE0 celle de l'attaquant. Vous pouvez sp\xE9cifier un seuil de taille maximale dans un pr\xE9dicat tailleFauchage (5 = grand, 6 \xE9norme et 7 colossal).
    4. Balayage : faire une version de l'attaque avec --target @{target|Cible 2|token_id}
    5. -
    6. Projection : ajouter un prédicat projection.
    7. +
    8. Projection : ajouter un pr\xE9dicat projection.
    -

    Voie des créatures élémentaires

    -

    Ajouter un prédicat immunite_type, où type est le type de la créature élémentaire (feu, acide, froid, ...)

    +

    Voie des cr\xE9atures \xE9l\xE9mentaires

    +

    Ajouter un pr\xE9dicat immunite_type, o\xF9 type est le type de la cr\xE9ature \xE9l\xE9mentaire (feu, acide, froid, ...)

      -
    1. Souffle : faire une attaque avec le bon nombre de d6 en DM, du type voulu, de portée la portée du souffle, à utiliser avec les modificateurs auto cone et les options --tempsRecharge rechargeSouffle [[1d4]] --psave DEX 13. Ne pas oublier la possibilité d'utiliser un token cible temporaire pour le cone.
    2. -
    3. Corps élémentaire : ajouter un prédicat corpsElementaire, de valeur l'élément (feu, froid,...). Cela va automatiquement ajouter les dégâts aux attaques de contact, et faire des dégâts à ceux qui l'attaquent au contact. Cela va aussi faire apparaître dans les actions du tour une action de régéneration, que le MJ peut utiliser chaque tour, à lui de voir si les conditions s'y prêtent (source élémentaire proche). Pas de support générique pour les victimes saisies ou agripper, à gérer au cas par cas.
    4. -
    5. Explosion finale : ajouter un prédicat explosionFinale de valeur le label de l'attaque d'explosion. Cette attaque ne doit contenir aucune demande de valeur (de type ?{Munitions}). Par exemple, pour une explosion finale qui fait 3d6 DM à tout le monde dans les 10 m et qui permettrait de diviser les dégâts par 2 par un test de DEX difficulte 13 (18 si au contact) : on crée une attaque Explosion, de dégâts 3d6 du type voulu, de portée 10, de modificateur auto et avec l'option --psave DEX 13 contact 18. Pour changer les dégâts du corps élémentaire, on peut utiliser un prédicat nbCorpsElementaire de valeur le nombre de d6 à utiliser (2 normalement pour cette capacité).
    6. +
    7. Souffle : faire une attaque avec le bon nombre de d6 en DM, du type voulu, de port\xE9e la port\xE9e du souffle, \xE0 utiliser avec les modificateurs auto cone et les options --tempsRecharge rechargeSouffle [[1d4]] --psave DEX 13. Ne pas oublier la possibilit\xE9 d'utiliser un token cible temporaire pour le cone.
    8. +
    9. Corps \xE9l\xE9mentaire : ajouter un pr\xE9dicat corpsElementaire, de valeur l'\xE9l\xE9ment (feu, froid,...). Cela va automatiquement ajouter les d\xE9g\xE2ts aux attaques de contact, et faire des d\xE9g\xE2ts \xE0 ceux qui l'attaquent au contact. Cela va aussi faire appara\xEEtre dans les actions du tour une action de r\xE9g\xE9neration, que le MJ peut utiliser chaque tour, \xE0 lui de voir si les conditions s'y pr\xEAtent (source \xE9l\xE9mentaire proche). Pas de support g\xE9n\xE9rique pour les victimes saisies ou agripp\xE9es, \xE0 g\xE9rer au cas par cas.
    10. +
    11. Explosion finale : ajouter un pr\xE9dicat explosionFinale de valeur le label de l'attaque d'explosion. Cette attaque ne doit contenir aucune demande de valeur (de type ?{Munitions}). Par exemple, pour une explosion finale qui fait 3d6 DM \xE0 tout le monde dans les 10 m et qui permettrait de diviser les d\xE9g\xE2ts par 2 par un test de DEX difficulte 13 (18 si au contact) : on cr\xE9e une attaque Explosion, de d\xE9g\xE2ts 3d6 du type voulu, de port\xE9e 10, de modificateur auto et avec l'option --psave DEX 13 contact 18. Pour changer les d\xE9g\xE2ts du corps \xE9l\xE9mentaire, on peut utiliser un pr\xE9dicat nbCorpsElementaire de valeur le nombre de d6 \xE0 utiliser (2 normalement pour cette capacit\xE9).
    -

    Voie des créatures magique

    +

    Voie des cr\xE9atures magique

      -
    1. Réduction des DM : Ajouter la RD sur la fiche 5/genre, où genre peut être magique ou un des types d'attaque (feu, acide, poison, etc...).
    2. -
    3. Vitalité surnaturelle : ajouter un prédicat vitaliteSurnaturelle, de valeur le nombre de PV régénéré par tour. Si la régénération doit continuer même à la mort du personnage, ajoutez un + à la fin de la valeur. Si un type de dégât empêche la régénération, faites suivre la valeur de régénération d'un / suivi du type (attention, ça ne peut pas être le type drain). Si plusieurs types de dégâts, les séparer par une virgule (et dans ce cas, penser à utiliser la syntaxe avec ::. Par exemple, un troll aura un prédicat vitaliteSurnaturelle:: 5+ / feu, acide, en faisant attention à ne rien mettre ensuite sur la même ligne. Si vous voulez réinitialiser les dégâts qui ne peuvent pas se régénérer sur un personnage, vous pouvez utiliser des soins normaux (!cof-soin), et si vous avez augmenté à la main les PVs, vous pouvez effacer les attributs DMSuivistype qui ont été créés par le script. Pour empêcher la régénération même mort, le mieux est d'enlever le token de la page (ou de le mettre en token générique).
    4. +
    5. R\xE9duction des DM : Ajouter la RD sur la fiche 5/genre, o\xF9 genre peut \xEAtre magique ou un des types d'attaque (feu, acide, poison, etc...).
    6. +
    7. Vitalit\xE9 surnaturelle : ajouter un pr\xE9dicat vitaliteSurnaturelle, de valeur le nombre de PV r\xE9g\xE9n\xE9r\xE9 par tour. Si la r\xE9g\xE9n\xE9ration doit continuer m\xEAme \xE0 la mort du personnage, ajoutez un + \xE0 la fin de la valeur. Si un type de d\xE9g\xE2t emp\xEAche la r\xE9g\xE9n\xE9ration, faites suivre la valeur de r\xE9g\xE9n\xE9ration d'un / suivi du type (attention, \xE7a ne peut pas \xEAtre le type drain). Si plusieurs types de d\xE9g\xE2ts, les s\xE9parer par une virgule (et dans ce cas, penser \xE0 utiliser la syntaxe avec ::. Par exemple, un troll aura un pr\xE9dicat vitaliteSurnaturelle:: 5+ / feu, acide, en faisant attention \xE0 ne rien mettre ensuite sur la m\xEAme ligne. Si vous voulez r\xE9initialiser les d\xE9g\xE2ts qui ne peuvent pas se r\xE9g\xE9n\xE9rer sur un personnage, vous pouvez utiliser des soins normaux (!cof-soin), et si vous avez augment\xE9 \xE0 la main les PVs, vous pouvez effacer les attributs DMSuivistype qui ont \xE9t\xE9 cr\xE9\xE9s par le script. Pour emp\xEAcher la r\xE9g\xE9n\xE9ration m\xEAme mort, le mieux est d'enlever le token de la page (ou de le mettre en token g\xE9n\xE9rique).
    -

    Voie des créatures volantes

    -

    On peut mettre un prédicat volant pour immuniser la créature à certains effets qui ne peuvent affecter que des créatures terrestres, comme l'armée des morts ou le croc-en-jambe.

    +

    Voie des cr\xE9atures volantes

    +

    On peut mettre un pr\xE9dicat volant pour immuniser la cr\xE9ature \xE0 certains effets qui ne peuvent affecter que des cr\xE9atures terrestres, comme l'arm\xE9e des morts ou le croc-en-jambe.

      -
    1. Vol rapide : simplement faire une variante de l'attaque avec les options --bonusAttaque 5 --plus 1d6 à utiliser le premier tour de combat si a créature est en vol et attaque une créature au sol. Ne pas oublier l'action de mouvement supplémentaire en vol.
    2. -
    3. Agripper : ajouter un prédicat agripper (ne fera agripper que sur les attaques de contact).
    4. +
    5. Vol rapide : simplement faire une variante de l'attaque avec les options --bonusAttaque 5 --plus 1d6 \xE0 utiliser le premier tour de combat si a cr\xE9ature est en vol et attaque une cr\xE9ature au sol. Ne pas oublier l'action de mouvement suppl\xE9mentaire en vol.
    6. +
    7. Agripper : ajouter un pr\xE9dicat agripper (ne fera agripper que sur les attaques de contact).

    Voie de la magie de combat

    1. Attaque magique : simplement une attaque, avec les options --sortilege --magique --fx beam-magic. Pour la version de zone, utiliser les options --disque 5 --auto --psave DEX 10.
    2. Armure magique : utiliser !cof-effet-combat armureMagique
    -

    Voie de la magie de guérison

    +

    Voie de la magie de gu\xE9rison

    1. Soigner : !cof-soin @{selected|token_id} @{target|target1|token_id} [[ceil(@{target|target1|PV|max}/2)]] --limiteCibleParJour 1
    2. -
    3. Guérir : !cof-guerir @{selected|token_id} @{target|token_id} --portee 0
    4. +
    5. Gu\xE9rir : !cof-guerir @{selected|token_id} @{target|token_id} --portee 0
    -

    Voie de la magie maléfique

    +

    Voie de la magie mal\xE9fique

    1. Vampirisation :
        -
      • Ajouter une attaque magique avec les DMs de vampirisation, faisant des dégâts de type drain. (En objet, on utilisera les options --sortilege et --drain).
      • -
      • Ajouter un prédicat siphonDesAmes, de valeur de NC de la créature (ou sans valeur, si le NC est 0). Si vous voulez que ce siphon empêche un autre siphon des âmes, rajoutez un prédicat siphonDesAmesPrioritaire de valeur un nombre positif et supérieur à ceux sur lequel il est prioritaire.
      • +
      • Ajouter une attaque magique avec les DMs de vampirisation, faisant des d\xE9g\xE2ts de type drain. (En objet, on utilisera les options --sortilege et --drain).
      • +
      • Ajouter un pr\xE9dicat siphonDesAmes, de valeur de NC de la cr\xE9ature (ou sans valeur, si le NC est 0). Si vous voulez que ce siphon emp\xEAche un autre siphon des \xE2mes, rajoutez un pr\xE9dicat siphonDesAmesPrioritaire de valeur un nombre positif et sup\xE9rieur \xE0 ceux sur lequel il est prioritaire.
    2. -
    3. Animer un cadavre : !cof-animer-cadavre @{selected|token_id} @{target|token_id}. Au cas où vous auriez besoin d'enlever l'état de cadavre, il suffit d'enlever l'attribut nommé cadavreAnime.
    4. +
    5. Animer un cadavre : !cof-animer-cadavre @{selected|token_id} @{target|token_id}. Au cas o\xF9 vous auriez besoin d'enlever l'\xE9tat de cadavre, il suffit d'enlever l'attribut nomm\xE9 cadavreAnime.
    6. Injonction Mortelle : !cof-injonction-mortelle @{selected|token_id} @{target|token_id}

    Voie de la meute

      -
    1. Intergeanchables : Utiliser un prédicat interchangeable, avec comme valeur le nombre d'opposants à partir duquel les cibles peuvent être interverties. Par défaut, cela va donner un bonus de +2 en DEF et +3 an attaque. Pour retrouver la valeur normale de +5 en DEF, utilisez !cof-options.
    2. -
    3. Attaque en traître : Au MJ de décider si une attaque est en traître ou pas. Pour une attaque en traître, rajouter les arguments --sournoise 2 --bonusAttaque 5.
    4. +
    5. Intergeanchables : Utiliser un pr\xE9dicat interchangeable, avec comme valeur le nombre d'opposants \xE0 partir duquel les cibles peuvent \xEAtre interverties. Par d\xE9faut, cela va donner un bonus de +2 en DEF et +3 an attaque. Pour retrouver la valeur normale de +5 en DEF, utilisez !cof-options.
    6. +
    7. Attaque en tra\xEEtre : Au MJ de d\xE9cider si une attaque est en tra\xEEtre ou pas. Pour une attaque en tra\xEEtre, rajouter les arguments --sournoise 2 --bonusAttaque 5.
    -

    Voie du PNJ récurrent

    +

    Voie du PNJ r\xE9current

      -
    1. Instinct de survie : ajouter un prédicat instinctDeSurvie avec comme valeur le nombre de PV en-dessous duquel le PNJ gagne un bonus de DEF. les autres effets sont à faire par le MJ.
    2. -
    3. Chair à canon : ajouter un prédicat chairACanon. Ajouter ensuite à tous ses sous-fifres un prédicat chairACanonDe de valeur le nom exact du token du PNJ. On peut y mettre plusieurs noms séparés par des virgules. Attention, dans ce cas (et aussi si le nom de token contient des espaces ou virgules, etc) pensez à utiliser :: au lieu de : pour le prédicat.
    4. +
    5. Instinct de survie : ajouter un pr\xE9dicat instinctDeSurvie avec comme valeur le nombre de PV en-dessous duquel le PNJ gagne un bonus de DEF. les autres effets sont \xE0 faire par le MJ.
    6. +
    7. Chair \xE0 canon : ajouter un pr\xE9dicat chairACanon. Ajouter ensuite \xE0 tous ses sous-fifres un pr\xE9dicat chairACanonDe de valeur le nom exact du token du PNJ. On peut y mettre plusieurs noms s\xE9par\xE9s par des virgules. Attention, dans ce cas (et aussi si le nom de token contient des espaces ou virgules, etc) pensez \xE0 utiliser :: au lieu de : pour le pr\xE9dicat.
    -

    Voie du prédateur

    +

    Voie du pr\xE9dateur

      -
    1. Embuscade : Sélectionner les ennemis du prédateurs, et utiliser !cof-surprise. Par exemple, contre une équipe de joueurs dans le handout Equipe joueurs (cf la méthode de sélection de groupes), on pourra utiliser l'ability !cof-surprise [[15 + @{selected|DEX}]] --equipe joueurs. Pour les bonus en discrétion et init, reporter sur la fiche (et à un prédicat discrétion), pour l'attaque en embuscade sur une cible surprise, rajouter à une attaque les options --sournoise 1 --if moins FOR --etat renverse --endif.
    2. -
    3. Dévorer : ajouter un prédicat devorer.
    4. -
    5. Gober : ajouter un prédicat gober. Le script ne vérifie pas que le personnage fait son jet de force avant d'attaquer (mais il propose un bouton pour le faire), ni que l'arme utilisée n'est pas plus grande qu'une dague.
    6. +
    7. Embuscade : S\xE9lectionner les ennemis du pr\xE9dateurs, et utiliser !cof-surprise. Par exemple, contre une \xE9quipe de joueurs dans le handout Equipe joueurs (cf la m\xE9thode de s\xE9lection de groupes), on pourra utiliser l'ability !cof-surprise [[15 + @{selected|DEX}]] --equipe joueurs. Pour les bonus en discr\xE9tion et init, reporter sur la fiche (et \xE0 un pr\xE9dicat discr\xE9tion), pour l'attaque en embuscade sur une cible surprise, rajouter \xE0 une attaque les options --sournoise 1 --if moins FOR --etat renverse --endif.
    8. +
    9. D\xE9vorer : ajouter un pr\xE9dicat devorer.
    10. +
    11. Gober : ajouter un pr\xE9dicat gober. Le script ne v\xE9rifie pas que le personnage fait son jet de force avant d'attaquer (mais il propose un bouton pour le faire), ni que l'arme utilis\xE9e n'est pas plus grande qu'une dague.

    Voie du tueur

      -
    1. Attaque mortelle : donner la possibilité de faire une attaque avec les options --bonusAttaque 5 --sournoise rang*2. Rajouter un prédicat discrétion avec comme valeur 5.
    2. -
    3. Disparition : donner la possibilité de faire une attaque avec les options --disparition rang*2.
    4. -
    5. Assassinat : rajouter --if etatCible surpris --etat mort --save CON 15 --endif à l'Attaque mortelle.
    6. +
    7. Attaque mortelle : donner la possibilit\xE9 de faire une attaque avec les options --bonusAttaque 5 --sournoise rang*2. Rajouter un pr\xE9dicat discr\xE9tion avec comme valeur 5.
    8. +
    9. Disparition : donner la possibilit\xE9 de faire une attaque avec les options --disparition rang*2.
    10. +
    11. Assassinat : rajouter --if etatCible surpris --etat mort --save CON 15 --endif \xE0 l'Attaque mortelle.

    4.4 Autres sorts

    Sorts qui ne sont pas dans des voies, mais peuvent venir du grimoire (dans le compagnon) ou d'effets de parchemins.
      -
    • Animation des objets : !cof-animation-des-objets @{selected|token_id} ?{Taille d'objet|tabouret ou coffret,1|chaise ou coffre,2|meuble bas ou table,4|grande table,7|grosse armoire,10} On peut ajouter un troisième argument, @{target|token_id} pour animer un token d'objet sur la carte.
    • -
    • Armure d'eau : !cof-effet-combat armureDEau. Le script automatise l'immunité aux étreintes (pas aux enveloppements) et à la capacité Agripper des créatures volantes.
    • -
    • Choc : Faire une attaque de portée 20 m, de type Sortilège, DM contondants, portée 20 m, et avec les options --etat renverse --save FOR 10.
    • +
    • Animation des objets : !cof-animation-des-objets @{selected|token_id} ?{Taille d'objet|tabouret ou coffret,1|chaise ou coffre,2|meuble bas ou table,4|grande table,7|grosse armoire,10} On peut ajouter un troisi\xE8me argument, @{target|token_id} pour animer un token d'objet sur la carte.
    • +
    • Armure d'eau : !cof-effet-combat armureDEau. Le script automatise l'immunit\xE9 aux \xE9treintes (pas aux enveloppements) et \xE0 la capacit\xE9 Agripper des cr\xE9atures volantes.
    • +
    • Choc : Faire une attaque de port\xE9e 20 m, de type Sortil\xE8ge, DM contondants, port\xE9e 20 m, et avec les options --etat renverse --save FOR 10.
    • Coup au but : !cof-effet-temp bonusAttaqueTemp 1 --valeur 10 --lanceur @{selected|token_id} --portee 10 --mana 0 --target @{target|token_id}.
    • -
    • Force de géant : !cof-effet-temp forceDeGeant 10. Le bonus est de 2 par défaut, mais peut être modifié en utilisant l'option --valeur.
    • -
    • Mur de vent : !cof-mur-de-force vent. Par défaut, la durée sera de 5+mod. d'INT, mais on peut donner une autre valeur en argument, après vent. On peut aussi changer le rayon du mur en utilisant --portee. Cela ne gère ni les immunités, ni le jet de force pour passer le mur.
    • -
    • Nuée de scorpions : ajouter une attaque magique, de portée 20 m, type Sortilège, modificateur --pasDeDmg et option --effet nueeDeScorpions 10. Pas de support particulier pour les DM de zone qui détruisent la nuée (enlever l'attribut nueeDeScorpions sur la cible dans ce cas).
    • -
    • Résistance à la magie : pour l'augmentation de la DEF contre la magie, utiliser un prédicat DEF_magie et pour le bonus aux tests, resistanceALaMagie
    • +
    • Force de g\xE9ant : !cof-effet-temp forceDeGeant 10. Le bonus est de 2 par d\xE9faut, mais peut \xEAtre modifi\xE9 en utilisant l'option --valeur.
    • +
    • Mur de vent : !cof-mur-de-force vent. Par d\xE9faut, la dur\xE9e sera de 5+mod. d'INT, mais on peut donner une autre valeur en argument, apr\xE8s vent. On peut aussi changer le rayon du mur en utilisant --portee. Cela ne g\xE8re ni les immunit\xE9s, ni le jet de force pour passer le mur.
    • +
    • Nu\xE9e de scorpions : ajouter une attaque magique, de port\xE9e 20 m, type Sortil\xE8ge, modificateur --pasDeDmg et option --effet nueeDeScorpions 10. Pas de support particulier pour les DM de zone qui d\xE9truisent la nu\xE9e (enlever l'attribut nueeDeScorpions sur la cible dans ce cas).
    • +
    • R\xE9sistance \xE0 la magie : pour l'augmentation de la DEF contre la magie, utiliser un pr\xE9dicat DEF_magie et pour le bonus aux tests, resistanceALaMagie
    • Simulacre de vie : !cof-set-attribute PVTemporaires [[1d10 + @{selected|niveau}]] --message simulacre de vie
    • -
    • Sixième sens : !cof-effet sixiemeSens true. Pour mettre fin à l'effet du sort (qui a une durée en heures), on peut effacer l'attribut sixiemeSens, ou mieux encore, sélectionner le token et faire !cof-effet sixiemeSens false.
    • +
    • Sixi\xE8me sens : !cof-effet sixiemeSens true. Pour mettre fin \xE0 l'effet du sort (qui a une dur\xE9e en heures), on peut effacer l'attribut sixiemeSens, ou mieux encore, s\xE9lectionner le token et faire !cof-effet sixiemeSens false.
    • Toiles : !cof-effet-temp toiles [[5+@{selected|SAG}]] --saveActifParTour FOR [[10+@{selected|SAG}]] --lanceur @{selected|token_id} --disque @{target|token_id} 5 20 --saufAllies --mana 0.
    -

    4.5 Capacités diverses

    +

    4.5 Capacit\xE9s diverses

      -
    • Absorption d'énergie (spectres et vampires) : ajouter un prédicat absorptionEnergie de valeur la valeur du soin accordé à l'attaquant à chaque fois qu'il endommage une cible (5 par défaut, si vous ne mettez aucune valeur). Pour l'absorption des vampires, ajouter un prédicat vampire.
    • -
    • Action libre : ajouter un prédicat actionLibre.
    • -
    • Agripper (démon dans Noirbois) : !cof-agripper-de-demon @{selected|token_id} @{target|token_id}
    • -
    • Apparition : un prédicat apparition immunise à tous les DMs, sauf ceux de canalisation (voir plus bas), ou les attaques avec l'option energiePositive.
    • -
    • Armes de l'été (Les seigneurs de l'hiver) : pour le bonus défensif contre le seigneur de l'hivers, ajoutez sur les arme un prédicat armeDeLEte et sur la créature qui attaque (a priori seulement le seigneur de l'hiver) le prédicat creatureDeLHiver. Pour la Flamme de l'été, on peut rajouter dans les options --if predicatCible CreatureDeLHiver --incrDmgCoef 3 --incrCritCoef 3 --else --plus 1d6 --feu --enflamme --endif, et pour la Lance de l'aubre, --if predicatCible CreatureDeLHiver --incrDmgCoef 1 --incrCritCoef 1 --else --plus 1d6 --feu --enflamme --endif
    • -
    • Attaque en meute : ajouter un prédicat attaqueEnMeute de valeur le bonus d'attaque (2 pour un gobelin). Cela confère le bonus pour toutes les attaques de personnages avec ce prédicat suivant une effectuée par un autre personnage avec ce prédicat, jusqu'au prochain tour de ce personnage. Ainsi, si 2 créatures continuent d'attaquer la même cible, elles bénéficieront du bonus tout le temps, sauf la toute première attaque.
    • -
    • Attaque violente (Invicible) : ajouter un prédicat attaqueViolente.
    • -
    • Auras : pour les capacités qui font un effet permanent à une certaine portée, comme l'aura glaciale des spectres, utiliser un attribut nommé aura, de valeur courante la portée en mètres de l'aura, et de valeur maximale l'effet à appliquer. Si cet effet contient la chaîne de caractère $TOKEN, cette chaîne sera remplacée par le nom du token à l'origine de l'aura. Pour un exemple d'utilisation, voyez la ligne Aura glaciale en dessous.
    • -
    • Aura glaciale : ajouter un attribut aura, de valeur courante 5, et de valeur maximale !cof-effet-temp ralenti [[1d6]] --save CON 12 --magique --seulementVivant --message une aura de froid intense émane de $TOKEN.
    • -
    • Baroud d'honneur : ajouter un prédicat baroudHonneur (Quand le personnage arrive à 0 PV, il ne meurt pas jusqu'à sa prochaine attaque, qui se fait avec un bonus de +5)
    • -
    • Bâton des runes mortes : ajoutez dans les prédicats de l'arme le prédicat batonDesRunesMortes. Dans la fiche de Swarathnak, ajoutez le prédicat ennemiDuBatonDesRunesMortes.
    • -
    • Bonus à l'attaque magique : utiliser un prédicat bonusAttaqueMagique de valeur le bonus permet d'ajouter ce bonus aux attaques magiques. Utile en particulier en prédicat d'arme.
    • -
    • Boutefeu (Invincible) : utilisez un prédicat boutefeu. -
    • Canalisation : !cof-canaliser typetype peut être positif ou négatif, selon le type d'énergie canalisée. Il faut au moins soit une option --soin expr ou --dm expr (il est possible d'avoir les deux), pour exprimer le montant des soins ou des dégâts. Si vous souhaitez avoir un certain nombre de dégâts par point de mana dépensé, vous pouvez utiliser un prédicat deCanalisation contenant l'expression des dégâts (ou soins) par point de mana, et utiliser la syntaxe --soin n pm.
    • -
    • Châtiment du mâle : utiliser un prédicat chatimentDuMale.
    • -
    • Cibles multiples (nuées) : ajouter un prédicat ciblesMultiples.
    • +
    • Absorption d'\xE9nergie (spectres et vampires) : ajouter un pr\xE9dicat absorptionEnergie de valeur la valeur du soin accord\xE9 \xE0 l'attaquant \xE0 chaque fois qu'il endommage une cible (5 par d\xE9faut, si vous ne mettez aucune valeur). Pour l'absorption des vampires, ajouter un pr\xE9dicat vampire.
    • +
    • Action libre : ajouter un pr\xE9dicat actionLibre.
    • +
    • Agripper (d\xE9mon dans Noirbois) : !cof-agripper-de-demon @{selected|token_id} @{target|token_id}
    • +
    • Apparition : un pr\xE9dicat apparition immunise \xE0 tous les DMs, sauf ceux de canalisation (voir plus bas), ou les attaques avec l'option energiePositive.
    • +
    • Armes de l'\xE9t\xE9 (Les seigneurs de l'hiver) : pour le bonus d\xE9fensif contre le seigneur de l'hivers, ajoutez sur les arme un pr\xE9dicat armeDeLEte et sur la cr\xE9ature qui attaque (a priori seulement le seigneur de l'hiver) le pr\xE9dicat creatureDeLHiver. Pour la Flamme de l'\xE9t\xE9, on peut rajouter dans les options --if predicatCible CreatureDeLHiver --incrDmgCoef 3 --incrCritCoef 3 --else --plus 1d6 --feu --enflamme --endif, et pour la Lance de l'aubre, --if predicatCible CreatureDeLHiver --incrDmgCoef 1 --incrCritCoef 1 --else --plus 1d6 --feu --enflamme --endif
    • +
    • Attaque en meute : ajouter un pr\xE9dicat attaqueEnMeute de valeur le bonus d'attaque (2 pour un gobelin). Cela conf\xE8re le bonus pour toutes les attaques de personnages avec ce pr\xE9dicat suivant une effectu\xE9e par un autre personnage avec ce pr\xE9dicat, jusqu'au prochain tour de ce personnage. Ainsi, si 2 cr\xE9atures continuent d'attaquer la m\xEAme cible, elles b\xE9n\xE9ficieront du bonus tout le temps, sauf la toute premi\xE8re attaque.
    • +
    • Attaque violente (Invicible) : ajouter un pr\xE9dicat attaqueViolente.
    • +
    • Auras : pour les capacit\xE9s qui font un effet permanent \xE0 une certaine port\xE9e, comme l'aura glaciale des spectres, utiliser un attribut nomm\xE9 aura, de valeur courante la port\xE9e en m\xE8tres de l'aura, et de valeur maximale l'effet \xE0 appliquer. Si cet effet contient la cha\xEEne de caract\xE8re $TOKEN, cette cha\xEEne sera remplac\xE9e par le nom du token \xE0 l'origine de l'aura. Pour un exemple d'utilisation, voyez la ligne Aura glaciale en dessous.
    • +
    • Aura glaciale : ajouter un attribut aura, de valeur courante 5, et de valeur maximale !cof-effet-temp ralenti [[1d6]] --save CON 12 --magique --seulementVivant --message une aura de froid intense \xE9mane de $TOKEN.
    • +
    • Aura de profanation : ajouter un pr\xE9dicat auraDeProfanation.
    • +
    • Baroud d'honneur : ajouter un pr\xE9dicat baroudHonneur (Quand le personnage arrive \xE0 0 PV, il ne meurt pas jusqu'\xE0 sa prochaine attaque, qui se fait avec un bonus de +5)
    • +
    • B\xE2ton des runes mortes (Invincible) : ajoutez dans les pr\xE9dicats de l'arme le pr\xE9dicat batonDesRunesMortes. Dans la fiche de Swarathnak, ajoutez le pr\xE9dicat ennemiDuBatonDesRunesMortes.
    • +
    • Bonus \xE0 l'attaque magique : utiliser un pr\xE9dicat bonusAttaqueMagique de valeur le bonus permet d'ajouter ce bonus aux attaques magiques. Utile en particulier en pr\xE9dicat d'arme.
    • +
    • Boutefeu (Invincible) : utilisez un pr\xE9dicat boutefeu. +
    • Canalisation : !cof-canaliser type o\xF9 type peut \xEAtre positif ou n\xE9gatif, selon le type d'\xE9nergie canalis\xE9e. Il faut au moins soit une option --soin expr ou --dm expr (il est possible d'avoir les deux), pour exprimer le montant des soins ou des d\xE9g\xE2ts. Si vous souhaitez avoir un certain nombre de d\xE9g\xE2ts par point de mana d\xE9pens\xE9, vous pouvez utiliser un pr\xE9dicat deCanalisation contenant l'expression des d\xE9g\xE2ts (ou soins) par point de mana, et utiliser la syntaxe --soin n pm.
    • +
    • Ch\xE2timent du m\xE2le : utiliser un pr\xE9dicat chatimentDuMale.
    • +
    • Cibles multiples (nu\xE9es) : ajouter un pr\xE9dicat ciblesMultiples.
    • Clignotement : !cof-effet-temp clignotement [[1d6+2]].
    • -
    • Créature non-vivante : ajouter un prédicat nonVivant.
    • -
    • Créature végétative : ajouter un prédicat vegetatif.
    • -
    • Cyclone (pour les élementaires) : !cof-effet-temp cyclone [[1d4+1]] --limiteParCombat 1. Cela va proposer une attaque Traverser dans les actions de l'élémentaire, qui ne peut fonctionner que si le personnage a au moins une attaque sur sa fiche. Par défaut, l'attaque utilisée en traversant est l'attaque de label 1, mais on peut préciser un autre label en utilisant l'option --valeur.
    • -
    • Dégâts si touché au contact (élémentaire de feu,...) : ajouter un prédicat nommé dmSiToucheContact, de valeur les dégâts, suivis de -- et du type si besoin. Par exemple, pour un élémentaire de feu, le prédicat dmSiToucheContact:: 1d6 --feu, en fin de ligne (rien ne doit suivre sur cette ligne).
    • -
    • Drain de force (pour la campagne Invincible) : ajouter un prédicat auraDrainDeForce
    • -
    • Écraser (pour la campagne Invincible) : ajouter un prédicat ecraser de valeur le label de l'attaque utilisée pour écraser.
    • -
    • Effroi (dragons) : !cof-peur [[10+@{selected|FOR}]] 1d4 --effroi --ralenti --disque @{selected|token_id} 50 à utiliser au premier tour de jeu.
    • -
    • Énergie de la mort (pour la campagne Vengeance) : ajouter un prédicat energieDeLaMort. Le MJ devra être attentif au message indiquant le retour à la vie, car c'est lui qui devra enlever l'état mort et ajuster les PVs.
    • -
    • Enveloppement (cube gélatineux) : ajouter l'option --enveloppe, puis quand le bouton apparaît si l'attaque réussit, cliquer dessus. En cas d'enveloppement, la cible ne peut plus bouger et se déplace avec le cube (déplacer le cube met la cible dans le cube), et au tour du cube, il faut presser les boutons de dégâts pour les infliger aux cibles enveloppées.
    • -
    • Étreinte (serpents) : ajouter l'option --etreinte difficulte, puis quand le bouton apparaît si l'attaque réussit, cliquer dessus. En cas d'étreinte réussie, la cible ne peut plus bouger et se déplace avec le serpent, et au tour du serpent, il faut presser les boutons de dégâts pour les infliger aux cibles étreintes.
    • -
    • Étreinte (scorpions) : ajouter l'option --etreinteScorpion. Le script prend le parti de ne pas étourdir la cible, mais le -5 en DEF, le jet de FOR et les dégâts sont automatisés. La cible est libérée automatiquement à la mort du scorpion.
    • -
    • Étreinte avec immolation (démon gardien) : pour l'attaque limitée qui immole, ajouter l'option --etreinteImmole. Cette attaque réussira automatiquement contre une cible qui est déjà étreinte.
    • -
    • Faucheuse de géants: ajouter le modifcateur tueurDeGrands aux attaques.
    • -
    • Fièvre du chêne : pour ajouter encore une RD de 5 contre le feu, ajouter un prédicat fievreChene.
    • -
    • Fiévreux : !cof-effet fievreux donne -2 en attaque, au dégâts et aux tests.
    • -
    • Foudres du temps : !cof-effet-chaque-d20 foudresDuTemps permet d'activer les foudres du temps. On peut donner un argument pour remplacer la valeur par défaut (13) par un autre jet de dés. Un deuxième argument permet de faire sortir la foudre pour tout jet entre les deux valeurs. Par exemple !cof-effet-chaque-d20 foudresDuTemps 13 14 fait venir la foudre pour tout jet de 13 ou 14. Si votre jeu contient un son (ou playlist) nommé Foudre (avec la majuscule), le son sera joué à chaque fois que la foudre frappera. Finalement, !cof-effet-chaque-d20 foudresDuTemps fin met fin aux foudres du temps.
    • -
    • Frénésie : Ajouter un prédicat frenesie avec comme valeur le nombre de PV en-dessous duquel la créature devient frénétique (+2 aus jets d'attaque).
    • -
    • Hors de portée : ajouter un prédicat horsDePortee
    • -
    • Huile de fort assaut : !cof-effet-temp dmgArme(L) 10 --valeur 1d6L est le label de l'arme qu'on veut enduire d'huile de fort assaut.
    • -
    • Hurlement : Pour les chiens infernaux, !cof-peur [[10+?{Nombre de chiens?}]] 2d4 --titre Hurlement --immuniseSiResiste hurlement --disque 50 --saufAllies, et pour les fantômes, !cof-peur 12 1d6 --titre Hurlement terrible --immuniseSiResiste hurlement --disque 10 --saufAllies.
    • -
    • Illusion : Pour les illusions qui disparaissent et réapparaissent un peu plus loin quand on essaie de les toucher, ajouter un prédicat estUneIllusion.
    • -
    • Immunité aux armes : ajouter un prédicat immuniteAuxArmes. À noter qu'il est possible de spécifier le niveau de magie d'une attaque en donnant un argument à l'option --magique. Ainsi une arme de niveau magique 3 aura en argument --magique 3.
    • -
    • Immunité aux attaques non magiques : ajouter un prédicat immunite_nonMagique
    • -
    • Immunité aux critiques : ajouter un prédicat immuniteAuxCritiques.
    • -
    • Indéracinable : ajouter un prédicat inderacinable.
    • -
    • Insensible : ajouter un prédicat insensibleAffaibli.
    • -
    • Intangible (à la Pathfinder 1) : ajouter un un prédicat creatureIntangible pour l'immunité aux armes non-magiques et la division des autres dégâts.
    • -
    • Invisible : passer le personnage invisible (!cof-set-state invisible true, ou mettre directment le statut sur le token). Si il peut rester invisible en combat, lui ajouter un prédicat invisibleEnCombat. Si il est attaqué autrement qu'avec tir en aveugle par quelqu'un qui ne voit pas l'invisble (à vous de montrer au moins temporairement le token), un malus de +5 en DEF au contact et +10 à distance sera appliqué, de même que le bonus de +5 en attaque contre ceux qui ne voient pas l'invisible. Le script suppose toujours qu'un personnage qui dispose de tir aveugle utilise sa capacité contre les cibles invisibles: à vous de vérifier qu'il ne cumule pas ça avec une capacité limitée.
    • -
    • Langage sombre : en plus de comprendre les elfes noirs, j'ai décidé d'octroyer un bonus de +1 en DEF et +1 aux DM contre les elfes noirs, bonus justifié par la meilleure compréhension de leur culture et de leurs tactiques. Pour cela, j'utiliser un prédicat langageSombreHetre.
    • -
    • Message en cas de coup critique reçu : on peut utiliser un prédicat messageSiCritique avec en valeur un message à afficher en cas d'echec critique subit. Pensez à bien utiliser la syntaxe avec ::.
    • +
    • Cr\xE9ature non-vivante : ajouter un pr\xE9dicat nonVivant.
    • +
    • Cr\xE9ature v\xE9g\xE9tative : ajouter un pr\xE9dicat vegetatif.
    • +
    • Cyclone (pour les \xE9lementaires) : !cof-effet-temp cyclone [[1d4+1]] --limiteParCombat 1. Cela va proposer une attaque Traverser dans les actions de l'\xE9l\xE9mentaire, qui ne peut fonctionner que si le personnage a au moins une attaque sur sa fiche. Par d\xE9faut, l'attaque utilis\xE9e en traversant est l'attaque de label 1, mais on peut pr\xE9ciser un autre label en utilisant l'option --valeur.
    • +
    • D\xE9g\xE2ts si touch\xE9 au contact (\xE9l\xE9mentaire de feu,...) : ajouter un pr\xE9dicat nomm\xE9 dmSiToucheContact, de valeur les d\xE9g\xE2ts, suivis de -- et du type si besoin. Par exemple, pour un \xE9l\xE9mentaire de feu, le pr\xE9dicat dmSiToucheContact:: 1d6 --feu, en fin de ligne (rien ne doit suivre sur cette ligne).
    • +
    • Drain de force (pour la campagne Invincible) : ajouter un pr\xE9dicat auraDrainDeForce
    • +
    • \xC9craser (pour la campagne Invincible) : ajouter un pr\xE9dicat ecraser de valeur le label de l'attaque utilis\xE9e pour \xE9craser.
    • +
    • Effroi (dragons) : !cof-peur [[10+@{selected|FOR}]] 1d4 --effroi --ralenti --disque @{selected|token_id} 50 \xE0 utiliser au premier tour de jeu.
    • +
    • \xC9nergie de la mort (pour la campagne Vengeance) : ajouter un pr\xE9dicat energieDeLaMort. Le MJ devra \xEAtre attentif au message indiquant le retour \xE0 la vie, car c'est lui qui devra enlever l'\xE9tat mort et ajuster les PVs.
    • +
    • Enveloppement (cube g\xE9latineux) : ajouter l'option --enveloppe, puis quand le bouton appara\xEEt si l'attaque r\xE9ussit, cliquer dessus. En cas d'enveloppement, la cible ne peut plus bouger et se d\xE9place avec le cube (d\xE9placer le cube met la cible dans le cube), et au tour du cube, il faut presser les boutons de d\xE9g\xE2ts pour les infliger aux cibles envelopp\xE9es.
    • +
    • \xC9treinte (serpents) : ajouter l'option --etreinte difficulte, puis quand le bouton appara\xEEt si l'attaque r\xE9ussit, cliquer dessus. En cas d'\xE9treinte r\xE9ussie, la cible ne peut plus bouger et se d\xE9place avec le serpent, et au tour du serpent, il faut presser les boutons de d\xE9g\xE2ts pour les infliger aux cibles \xE9treintes.
    • +
    • \xC9treinte (scorpions) : ajouter l'option --etreinteScorpion. Le script prend le parti de ne pas \xE9tourdir la cible, mais le -5 en DEF, le jet de FOR et les d\xE9g\xE2ts sont automatis\xE9s. La cible est lib\xE9r\xE9e automatiquement \xE0 la mort du scorpion.
    • +
    • \xC9treinte avec immolation (d\xE9mon gardien) : pour l'attaque limit\xE9e qui immole, ajouter l'option --etreinteImmole. Cette attaque r\xE9ussira automatiquement contre une cible qui est d\xE9j\xE0 \xE9treinte.
    • +
    • Faucheuse de g\xE9ants: ajouter le modifcateur tueurDeGrands aux attaques.
    • +
    • Fi\xE8vre du ch\xEAne : pour ajouter encore une RD de 5 contre le feu, ajouter un pr\xE9dicat fievreChene.
    • +
    • Fi\xE9vreux : !cof-effet fievreux donne -2 en attaque, au d\xE9g\xE2ts et aux tests.
    • +
    • Foudres du temps : !cof-effet-chaque-d20 foudresDuTemps permet d'activer les foudres du temps. On peut donner un argument pour remplacer la valeur par d\xE9faut (13) par un autre jet de d\xE9s. Un deuxi\xE8me argument permet de faire sortir la foudre pour tout jet entre les deux valeurs. Par exemple !cof-effet-chaque-d20 foudresDuTemps 13 14 fait venir la foudre pour tout jet de 13 ou 14. Si votre jeu contient un son (ou playlist) nomm\xE9 Foudre (avec la majuscule), le son sera jou\xE9 \xE0 chaque fois que la foudre frappera. Finalement, !cof-effet-chaque-d20 foudresDuTemps fin met fin aux foudres du temps.
    • +
    • Fr\xE9n\xE9sie : Ajouter un pr\xE9dicat frenesie avec comme valeur le nombre de PV en-dessous duquel la cr\xE9ature devient fr\xE9n\xE9tique (+2 aus jets d'attaque).
    • +
    • Hors de port\xE9e : ajouter un pr\xE9dicat horsDePortee
    • +
    • Huile de fort assaut : !cof-effet-temp dmgArme(L) 10 --valeur 1d6 o\xF9 L est le label de l'arme qu'on veut enduire d'huile de fort assaut.
    • +
    • Hurlement : Pour les chiens infernaux, !cof-peur [[10+?{Nombre de chiens?}]] 2d4 --titre Hurlement --immuniseSiResiste hurlement --disque 50 --saufAllies, et pour les fant\xF4mes, !cof-peur 12 1d6 --titre Hurlement terrible --immuniseSiResiste hurlement --disque 10 --saufAllies.
    • +
    • Illusion : Pour les illusions qui disparaissent et r\xE9apparaissent un peu plus loin quand on essaie de les toucher, ajouter un pr\xE9dicat estUneIllusion.
    • +
    • Immunit\xE9 aux armes : ajouter un pr\xE9dicat immuniteAuxArmes. \xC0 noter qu'il est possible de sp\xE9cifier le niveau de magie d'une attaque en donnant un argument \xE0 l'option --magique. Ainsi une arme de niveau magique 3 aura en argument --magique 3.
    • +
    • Immunit\xE9 aux attaques non magiques : ajouter un pr\xE9dicat immunite_nonMagique
    • +
    • Immunit\xE9 aux critiques : ajouter un pr\xE9dicat immuniteAuxCritiques.
    • +
    • Ind\xE9racinable : ajouter un pr\xE9dicat inderacinable.
    • +
    • Insensible : ajouter un pr\xE9dicat insensibleAffaibli.
    • +
    • Intangible (\xE0 la Pathfinder 1) : ajouter un un pr\xE9dicat creatureIntangible pour l'immunit\xE9 aux armes non-magiques et la division des autres d\xE9g\xE2ts.
    • +
    • Invisible : passer le personnage invisible (!cof-set-state invisible true, ou mettre directment le statut sur le token). Si il peut rester invisible en combat, lui ajouter un pr\xE9dicat invisibleEnCombat. Si il est attaqu\xE9 autrement qu'avec tir en aveugle par quelqu'un qui ne voit pas l'invisble (\xE0 vous de montrer au moins temporairement le token), un malus de +5 en DEF au contact et +10 \xE0 distance sera appliqu\xE9, de m\xEAme que le bonus de +5 en attaque contre ceux qui ne voient pas l'invisible. Le script suppose toujours qu'un personnage qui dispose de tir aveugle utilise sa capacit\xE9 contre les cibles invisibles: \xE0 vous de v\xE9rifier qu'il ne cumule pas \xE7a avec une capacit\xE9 limit\xE9e.
    • +
    • Langage sombre : en plus de comprendre les elfes noirs, j'ai d\xE9cid\xE9 d'octroyer un bonus de +1 en DEF et +1 aux DM contre les elfes noirs, bonus justifi\xE9 par la meilleure compr\xE9hension de leur culture et de leurs tactiques. Pour cela, j'utiliser un pr\xE9dicat langageSombreHetre.
    • +
    • Message en cas de coup critique re\xE7u : on peut utiliser un pr\xE9dicat messageSiCritique avec en valeur un message \xE0 afficher en cas d'echec critique subit. Pensez \xE0 bien utiliser la syntaxe avec ::.
    • Mot de pouvoir qui immobilise : !cof-mot-de-pouvoir-immobilise --lanceur @{selected|token_id} --enVue --saufAllies
    • -
    • N'abandonne jamais : ajouter un prédicat nAbandonnejamais.
    • -
    • Noirbois : À l'entrée dans des ténèbres magiques, utiliser la commande !cof-tenebres-magiques. À la sortie ou la fin de ces ténèbres, faire !cof-tenebres-magiques fin. Pour allumer la fiole de lumière, sélectionner un token est faire !cof-fiole-de-lumiere dd est la distance à laquelle la fiole éclaire. On peut ajouter un troisième argument, qui est la distance à laquelle la lumière devient moins brillante (pas d'effet sur la mécanique de jeu). Pour éteindre la lumière, il faut mettre utiliser !cof-fiole-de-lumiere fin.
    • -
    • Noyade (plante carnivore) : il existe un effet de combat nommé noyade (pas de durée, il dure par défaut tout le combat) qui fait perdre 1d6 PV par tour, sauf à réussir un test de CON difficulté 15, et qui impose un malus de -3 aux attaques et aux DMs.
    • -
    • Ondes corruptrices (Anathazerïn) : Pour simplement le premier effet, faire !cof-effet ondesCorruptrices 2, puis pour augmeter l'effet !cof-effet ondesCorruptrices +2. L'effet peut être annulé avec !cof-effet ondesCorruptrices 0. Pour le porteur du bouclier de Grabuge, on peut mettre un prédicat porteurDuBouclierDeGrabuge.
    • -
    • Paralysie des goules : ajouter à l'attaque de morsure --effet paralyseGoule [[1d6]] --save CON 10.
    • -
    • Perte de substance (Invincible) : Ajouter pour tous les personnages concernés un prédicat perteDeSubstance. Le changement de jour va augmenter un compteur, à condition que les tokens des joueurs soient sur la page, et soit on ne sélectionne aucun token quand on lance la commande de changement de jour, soit on sélectionne au moins tous les tokens des joueurs. Le test de CHA n'est pas automatisé, mais le script en rappelle la difficulté. Pour les ancres, ajouter un prédicat ancreInvincible (par exemple dans les prédicats de l'arme). Pour la réduction des dégâts, ajouter au dragon un prédicat dragonInvincible. Pour les DM indirects, il faudra gérer à la main la réduction de DM.
    • -
    • Phylactère de canalisation : ajouter un prédicat phylacterePositif pour un phylactère de canalisation positive, ou phylactereNegatif pour un phylactère de canalisation négative. Associez à ce prédicat la valeur ajoutée pour chaque PM dépensé (nécessite l'utilisation du prédicat deCanalisation). Une valeur de 1d4 semble adaptée pour le phylactère de canalisation de Pathfinder 1.
    • -
    • Piqûres d'insectes : Rajouter un prédicat piquresDInsectes avec comme valeur la résistance aux dégâts à distance appropriée
    • +
    • N'abandonne jamais : ajouter un pr\xE9dicat nAbandonnejamais.
    • +
    • Noirbois : \xC0 l'entr\xE9e dans des t\xE9n\xE8bres magiques, utiliser la commande !cof-tenebres-magiques. \xC0 la sortie ou la fin de ces t\xE9n\xE8bres, faire !cof-tenebres-magiques fin. Pour allumer la fiole de lumi\xE8re, s\xE9lectionner un token est faire !cof-fiole-de-lumiere d o\xF9 d est la distance \xE0 laquelle la fiole \xE9claire. On peut ajouter un troisi\xE8me argument, qui est la distance \xE0 laquelle la lumi\xE8re devient moins brillante (pas d'effet sur la m\xE9canique de jeu). Pour \xE9teindre la lumi\xE8re, il faut mettre utiliser !cof-fiole-de-lumiere fin.
    • +
    • Noyade (plante carnivore) : il existe un effet de combat nomm\xE9 noyade (pas de dur\xE9e, il dure par d\xE9faut tout le combat) qui fait perdre 1d6 PV par tour, sauf \xE0 r\xE9ussir un test de CON difficult\xE9 15, et qui impose un malus de -3 aux attaques et aux DMs.
    • +
    • Ondes corruptrices (Anathazer\xEFn) : Pour simplement le premier effet, faire !cof-effet ondesCorruptrices 2, puis pour augmeter l'effet !cof-effet ondesCorruptrices +2. L'effet peut \xEAtre annul\xE9 avec !cof-effet ondesCorruptrices 0. Pour le porteur du bouclier de Grabuge, on peut mettre un pr\xE9dicat porteurDuBouclierDeGrabuge.
    • +
    • Paralysie des goules : ajouter \xE0 l'attaque de morsure --effet paralyseGoule [[1d6]] --save CON 10.
    • +
    • Perte de substance (Invincible) : Ajouter pour tous les personnages concern\xE9s un pr\xE9dicat perteDeSubstance. Le changement de jour va augmenter un compteur, \xE0 condition que les tokens des joueurs soient sur la page, et soit on ne s\xE9lectionne aucun token quand on lance la commande de changement de jour, soit on s\xE9lectionne au moins tous les tokens des joueurs. Le test de CHA n'est pas automatis\xE9, mais le script en rappelle la difficult\xE9. Pour les ancres, ajouter un pr\xE9dicat ancreInvincible (par exemple dans les pr\xE9dicats de l'arme). Pour la r\xE9duction des d\xE9g\xE2ts, ajouter au dragon un pr\xE9dicat dragonInvincible. Pour les DM indirects, il faudra g\xE9rer \xE0 la main la r\xE9duction de DM.
    • +
    • Phylact\xE8re de canalisation : ajouter un pr\xE9dicat phylacterePositif pour un phylact\xE8re de canalisation positive, ou phylactereNegatif pour un phylact\xE8re de canalisation n\xE9gative. Associez \xE0 ce pr\xE9dicat la valeur ajout\xE9e pour chaque PM d\xE9pens\xE9 (n\xE9cessite l'utilisation du pr\xE9dicat deCanalisation). Une valeur de 1d4 semble adapt\xE9e pour le phylact\xE8re de canalisation de Pathfinder 1.
    • +
    • Piq\xFBres d'insectes : Rajouter un pr\xE9dicat piquresDInsectes avec comme valeur la r\xE9sistance aux d\xE9g\xE2ts \xE0 distance appropri\xE9e
    • - Poison : pour enduire une arme de label L de poison, utiliser !cof-enduire-poison L type force save. Pour l'instant, type ne peut être que rapide ou affaiblissant. Pour un poison rapide, force est une expression pour les dégâts (typiquement, 2d6), pour un poison affaiblissant c'est une expression indiquant au bout de combien de tours le poison fait effet (si c'est 0, alors l'affaiblissement ne dure que pendant un combat, sinon c'est une durée en heures, à gérer par le MJ). save est la difficulté du jet de CON pour résister au poison. On peut rajouter deux arguments optionnels : + Poison : pour enduire une arme de label L de poison, utiliser !cof-enduire-poison L type force save. Pour l'instant, type ne peut \xEAtre que rapide ou affaiblissant. Pour un poison rapide, force est une expression pour les d\xE9g\xE2ts (typiquement, 2d6), pour un poison affaiblissant c'est une expression indiquant au bout de combien de tours le poison fait effet (si c'est 0, alors l'affaiblissement ne dure que pendant un combat, sinon c'est une dur\xE9e en heures, \xE0 g\xE9rer par le MJ). save est la difficult\xE9 du jet de CON pour r\xE9sister au poison. On peut rajouter deux arguments optionnels :
        -
      • --testINT n: fixe la difficulté du jet d'INT pour réussir à poser le poison. La difficulté par défaut est 14.
      • -
      • --dose nom: indique une ressource dans laquelle on puise pour enduire de poison. Il faudra que le personnage ait un attribut de nom dose_nom avec comme valeur le nombre de doses possédées.
      • +
      • --testINT n: fixe la difficult\xE9 du jet d'INT pour r\xE9ussir \xE0 poser le poison. La difficult\xE9 par d\xE9faut est 14.
      • +
      • --dose nom: indique une ressource dans laquelle on puise pour enduire de poison. Il faudra que le personnage ait un attribut de nom dose_nom avec comme valeur le nombre de doses poss\xE9d\xE9es.
      - Il est aussi possible d'enduire de poison des munitions. Pour ce faire, remplacer le label de l'attaque par munition_LL est le label de la munition. Le script suppose que toute munition lancée perd son poison. + Il est aussi possible d'enduire de poison des munitions. Pour ce faire, remplacer le label de l'attaque par munition_L o\xF9 L est le label de la munition. Le script suppose que toute munition lanc\xE9e perd son poison.

      Il existe les effets suivants pour simuler directement des poisons affaiblissants :

      • poisonAffaiblissant est un effet qui rend affaibli pendant tout un combat.
      • -
      • poisonAffaiblissantLong, le même effet mais sans limite de durée (à gérer par le MJ).
      • -
      • poisonAffaiblissantLatent est un effet à durée en tours. Quand l'effet prend fin, le personnage devient empoisonné et affaibli.
      • +
      • poisonAffaiblissantLong, le m\xEAme effet mais sans limite de dur\xE9e (\xE0 g\xE9rer par le MJ).
      • +
      • poisonAffaiblissantLatent est un effet \xE0 dur\xE9e en tours. Quand l'effet prend fin, le personnage devient empoisonn\xE9 et affaibli.
    • -
    • Potion de sang de l'Arbre-Coeur : !cof-effet sangDeLArbreCoeur true, à enlever quand les 24h sont passées.
    • -
    • Protection contre les souffles et dégâts de zone : ajouter un prédicat protectionDMZone. Pour une protection contre un seul élément (feu, froid, etc), ajouter _ et le nom de l'élément. Par exemple, contre le feu, on aura un prédicat protectionDMZone_feu. On peut aussi avoir une protection contre les souffles de dragons uniquement, mais qui annule les DM en cas de succès au test de DEX, avec le prédicat protectionSouffleDeDragon. On peut aussi donner une RD contre les souffles de dragons avec un prédicat numérique rdSouffleDeDragon.
    • -
    • Putréfaction : ajouter à l'attaque --effet putrefaction 5 --save CON 14 (pour les données des momies)
    • +
    • Potion de sang de l'Arbre-Coeur : !cof-effet sangDeLArbreCoeur true, \xE0 enlever quand les 24h sont pass\xE9es.
    • +
    • Protection contre les souffles et d\xE9g\xE2ts de zone : ajouter un pr\xE9dicat protectionDMZone. Pour une protection contre un seul \xE9l\xE9ment (feu, froid, etc), ajouter _ et le nom de l'\xE9l\xE9ment. Par exemple, contre le feu, on aura un pr\xE9dicat protectionDMZone_feu. On peut aussi avoir une protection contre les souffles de dragons uniquement, mais qui annule les DM en cas de succ\xE8s au test de DEX, avec le pr\xE9dicat protectionSouffleDeDragon. On peut aussi donner une RD contre les souffles de dragons avec un pr\xE9dicat num\xE9rique rdSouffleDeDragon.
    • +
    • Putr\xE9faction : ajouter \xE0 l'attaque --effet putrefaction 5 --save CON 14 (pour les donn\xE9es des momies)
    • Rage (pour la campagne Invincible) : pour entrer en rage, faire !cof-effet-combat rage. On peut par exemple mettre cette commande dans une ability.
    • -
    • Réaction allergique : il existe un effet reactionAllergique qui fait le malus en DEX et CHA et disparaît en cas de soin magique. Pour une attaque, on peut par exemple mettre --effet reactionAllergique --save CON 11.
    • -
    • Résistant (insectes) : ajouter un prédicat durACuire.
    • -
    • Regard pétrifiant : ajouter un prédicat regardPetrifiant. Comme il est difficile de savoir qui est affecté et quand, le prédicat génère juste une action pour la créature et le MJ doit décider à qui l'appliquer et quand. À noter qu'on peut associer une valeur au prédicat pour changer la difficulté de 16 par défaut (-4 quand un adversaire est conscient du pouvoir et évite de croiser le regard). Pour détourner le regard d'une cible, utiliser !cof-effet-combat detournerLeRegard. Pour fermer les yeux, !cof-effet-combat detournerLeRegard --valeur 5. Pour arrêter de détourner le regard !cof-effet-combat detournerLeRegard fin. Si vous souhaitez enlever un effet de pétrification, vous pouvez utiliser la commande !cof-effet petrifie false.
    • -
    • Saisir et broyer : ajouter un prédicat saisirEtBroyer
    • -
    • Sang de fer : ajouter un prédicat sangDeFerIf.
    • -
    • Sans esprit : ajouter un prédicat sansEsprit permet la réussite automatique des jets de résistance basés sur INT, SAG ou CHA.
    • -
    • Sphère de feu : !cof-sphere-de-feu.
    • -
    • Tremblements de terre : !cof-effet-chaque-d20 tremblementsDeTerre permet d'activer les tremblements de terre. On peut donner un argument pour remplacer la valeur par défaut (13) par un autre jet de dés. Un deuxième argument permet de faire trembler la terre pour tout jet entre les deux valeurs. Si votre jeu contient un son (ou playlist) nommé TremblementTerre (avec la majuscule), le son sera joué à chaque fois que la terre tremblera. Finalement, !cof-effet-chaque-d20 tremblementsDeTerre fin met fin aux tremblements de terre.
    • +
    • R\xE9action allergique : il existe un effet reactionAllergique qui fait le malus en DEX et CHA et dispara\xEEt en cas de soin magique. Pour une attaque, on peut par exemple mettre --effet reactionAllergique --save CON 11.
    • +
    • R\xE9sistant (insectes) : ajouter un pr\xE9dicat durACuire.
    • +
    • Regard p\xE9trifiant : ajouter un pr\xE9dicat regardPetrifiant. Comme il est difficile de savoir qui est affect\xE9 et quand, le pr\xE9dicat g\xE9n\xE8re juste une action pour la cr\xE9ature et le MJ doit d\xE9cider \xE0 qui l'appliquer et quand. \xC0 noter qu'on peut associer une valeur au pr\xE9dicat pour changer la difficult\xE9 de 16 par d\xE9faut (-4 quand un adversaire est conscient du pouvoir et \xE9vite de croiser le regard). Pour d\xE9tourner le regard d'une cible, utiliser !cof-effet-combat detournerLeRegard. Pour fermer les yeux, !cof-effet-combat detournerLeRegard --valeur 5. Pour arr\xEAter de d\xE9tourner le regard !cof-effet-combat detournerLeRegard fin. Si vous souhaitez enlever un effet de p\xE9trification, vous pouvez utiliser la commande !cof-effet petrifie false.
    • +
    • Saisir et broyer : ajouter un pr\xE9dicat saisirEtBroyer
    • +
    • Sang de fer : ajouter un pr\xE9dicat sangDeFerIf.
    • +
    • Sans esprit : ajouter un pr\xE9dicat sansEsprit permet la r\xE9ussite automatique des jets de r\xE9sistance bas\xE9s sur INT, SAG ou CHA.
    • +
    • Sph\xE8re de feu : !cof-sphere-de-feu.
    • +
    • Tremblements de terre : !cof-effet-chaque-d20 tremblementsDeTerre permet d'activer les tremblements de terre. On peut donner un argument pour remplacer la valeur par d\xE9faut (13) par un autre jet de d\xE9s. Un deuxi\xE8me argument permet de faire trembler la terre pour tout jet entre les deux valeurs. Si votre jeu contient un son (ou playlist) nomm\xE9 TremblementTerre (avec la majuscule), le son sera jou\xE9 \xE0 chaque fois que la terre tremblera. Finalement, !cof-effet-chaque-d20 tremblementsDeTerre fin met fin aux tremblements de terre.
    • Vision nocturne : on peut utiliser !cof-vision-nocturne 18 pour un effet de potion de vision nocturne. Attention, pour remettre la vision habituelle, il faut encore effacer le token et remettre le token du personnage depuis la fiche.
    • -
    • Vulnérabilité aux coups critiques : si la créature possède un prédicat vulnerableCritique, le script interprète la valeur de ce prédicat comme les chances (sur 100) qu'un coup critique tue directment la créature. Par exemple, la valeur sera de 25 pour un esprit du givre.
    • -
    • Vulnérabilité à un type de dégâts : ajouter un prédicat vulnerableA_type, pour augmenter de 50% les dégâts reçus de ce type.
    • +
    • Vuln\xE9rabilit\xE9 aux coups critiques : si la cr\xE9ature poss\xE8de un pr\xE9dicat vulnerableCritique, le script interpr\xE8te la valeur de ce pr\xE9dicat comme les chances (sur 100) qu'un coup critique tue directment la cr\xE9ature. Par exemple, la valeur sera de 25 pour un esprit du givre.
    • +
    • Vuln\xE9rabilit\xE9 \xE0 un type de d\xE9g\xE2ts : ajouter un pr\xE9dicat vulnerableA_type, pour augmenter de 50% les d\xE9g\xE2ts re\xE7us de ce type.

    5. Terres d'Arran

    -

    Le script determine s'il doit utiliser les règles par défaut des Terres d'Arran ou celles de COF générique en fonction des fiches de personnages présentes sur la partie. Pour que toutes vox fiches soient bien adaptées au setting des Terres d'Arran, assurez-vous de bien sélectionner ce setting dans les réglages du jeu (accessibles avant de lancer la partie "Options de jeu" ou "Game Settings".

    +

    Le script determine s'il doit utiliser les r\xE8gles par d\xE9faut des Terres d'Arran ou celles de COF g\xE9n\xE9rique en fonction des fiches de personnages pr\xE9sentes sur la partie. Pour que toutes vox fiches soient bien adapt\xE9es au setting des Terres d'Arran, assurez-vous de bien s\xE9lectionner ce setting dans les r\xE9glages du jeu (accessibles avant de lancer la partie "Options de jeu" ou "Game Settings".

    -

    Le fait d'être dans ce mode de règles change le calcul de l'initiative et des mods d'attaque.

    +

    Le fait d'\xEAtre dans ce mode de r\xE8gles change le calcul de l'initiative et des mods d'attaque.

    5.1 Les peuples d'Arran

    5.1.1 Elfes

    Voie du peuple des Elfes
      -
    1. Grâce Elfique : Ajouter le bonus au jets de charisme sur la fiche, et une compétence discrétion pour les déplacements silencieux.
    2. -
    3. Essence magique : ajouter un prédicat DEF_magie de valeur 2, et un prédicat resistanceALaMagie de valeur 2 aussi. Passer ces valeurs à 4 au rang 4 dans la voie.
    4. -
    5. Maîtrise des armes elfiques : Pas de support pour l'instant
    6. +
    7. Gr\xE2ce Elfique : Ajouter le bonus au jets de charisme sur la fiche, et une comp\xE9tence discr\xE9tion pour les d\xE9placements silencieux.
    8. +
    9. Essence magique : ajouter un pr\xE9dicat DEF_magie de valeur 2, et un pr\xE9dicat resistanceALaMagie de valeur 2 aussi. Passer ces valeurs \xE0 4 au rang 4 dans la voie.
    10. +
    11. Ma\xEEtrise des armes elfiques : Pas de support pour l'instant
    12. Empathie elfique : Pas de support
    13. -
    14. Immortalité :TODO
    15. +
    16. Immortalit\xE9 :TODO
    Voie culturelle des elfes blancs
      -
    1. Mémoire du monde : En Attente
    2. -
    3. Prédispositions magiques : En Attente
    4. -
    5. Lancier d’élite : En Attente
    6. -
    7. Blancheur immaculée : En Attente
    8. +
    9. M\xE9moire du monde : En Attente
    10. +
    11. Pr\xE9dispositions magiques : En Attente
    12. +
    13. Lancier d\x2019\xE9lite : En Attente
    14. +
    15. Blancheur immacul\xE9e : En Attente
    16. Parangon elfe blanc : En Attente
    Voie culturelle des elfes bleus
      -
    1. Équilibre parfait : Ajouter une compétence équilibre avec le bonus.
    2. -
    3. Natif d’Elsémur : voir la capacité choisie.
    4. +
    5. \xC9quilibre parfait : Ajouter une comp\xE9tence \xE9quilibre avec le bonus.
    6. +
    7. Natif d\x2019Els\xE9mur : voir la capacit\xE9 choisie.
    8. Imperturbable : En Attente
    9. -
    10. Les enseignements de l’eau : En Attente
    11. +
    12. Les enseignements de l\x2019eau : En Attente
    13. Parangon elfe bleu : En Attente
    Voie culturelle des elfes noirs
      -
    1. Artiste de l’ombre : En Attente
    2. +
    3. Artiste de l\x2019ombre : En Attente
    4. Apprenti de Slurce : En Attente
    5. -
    6. Armes secrètes : En Attente
    7. +
    8. Armes secr\xE8tes : En Attente
    9. Noir comme le sang : En Attente
    10. Parangon elfe noir : En Attente
    Voie culturelle des elfes sylvains
    1. Le chant de la Terre : En Attente
    2. -
    3. Enfant de la forêt : voir la capacité choisie
    4. -
    5. Archer émérite : ajuster les chances de critique pour les attaques utilisant les arcs.
    6. -
    7. Compagnon animal supérieur : En Attente
    8. +
    9. Enfant de la for\xEAt : voir la capacit\xE9 choisie
    10. +
    11. Archer \xE9m\xE9rite : ajuster les chances de critique pour les attaques utilisant les arcs.
    12. +
    13. Compagnon animal sup\xE9rieur : En Attente
    14. Parangon elfe vert : En Attente
    @@ -2529,21 +2535,21 @@

    5.1.2 Nains

    Voie du peuple des Nains
      -
    1. Résistance : En Attente
    2. +
    3. R\xE9sistance : En Attente
    4. Solide comme un roc : En Attente
    5. -
    6. Maîtrise des armes runiques : En Attente
    7. -
    8. Résistance à la magie : En Attente
    9. -
    10. Ténacité naine : En Attente
    11. +
    12. Ma\xEEtrise des armes runiques : En Attente
    13. +
    14. R\xE9sistance \xE0 la magie : En Attente
    15. +
    16. T\xE9nacit\xE9 naine : En Attente
    -
    Voie culturelle de l’ordre de la Forge
    +
    Voie culturelle de l\x2019ordre de la Forge
    1. Artisan de la forge : En Attente
    2. Forgeron runique : En Attente
    3. -
    4. Marteler le métal : En Attente
    5. -
    6. Runes de défense : En Attente
    7. -
    8. Maître artisan : En Attente
    9. +
    10. Marteler le m\xE9tal : En Attente
    11. +
    12. Runes de d\xE9fense : En Attente
    13. +
    14. Ma\xEEtre artisan : En Attente
    -
    Voie culturelle de l’ordre du Talion
    +
    Voie culturelle de l\x2019ordre du Talion
    1. Plein aux as : En Attente
    2. Le sens des affaires : En Attente
    3. @@ -2551,15 +2557,15 @@
      Voie culturelle de l’ordre du Talion
    4. La Loge noire : En Attente
    5. Seigneur du Talion : En Attente
    -
    Voie culturelle de l’ordre du Temple
    +
    Voie culturelle de l\x2019ordre du Temple
      -
    1. Grosse tête : En Attente
    2. +
    3. Grosse t\xEAte : En Attente
    4. Enseigne du Temple : En Attente
    5. -
    6. Invention étrange : En Attente
    7. -
    8. Rites funéraires (L) : En Attente
    9. -
    10. Maître du temple : En Attente
    11. +
    12. Invention \xE9trange : En Attente
    13. +
    14. Rites fun\xE9raires (L) : En Attente
    15. +
    16. Ma\xEEtre du temple : En Attente
    -
    Voie culturelle de l’ordre du Bouclier
    +
    Voie culturelle de l\x2019ordre du Bouclier
    1. Combat en phalange : En Attente
    2. Formation militaire : En Attente
    3. @@ -2567,13 +2573,13 @@
      Voie culturelle de l’ordre du Bouclier
    4. Fuite interdite : En Attente
    5. Veilleur du roi : En Attente
    -
    Voie culturelle de l’ordre des Errants
    +
    Voie culturelle de l\x2019ordre des Errants
    1. Moins que rien : En Attente
    2. -
    3. Passé révolu : En Attente
    4. +
    5. Pass\xE9 r\xE9volu : En Attente
    6. Paysan aguerri : En Attente
    7. -
    8. Solidarité des Errants : En Attente
    9. -
    10. Volonté héroïque : En Attente
    11. +
    12. Solidarit\xE9 des Errants : En Attente
    13. +
    14. Volont\xE9 h\xE9ro\xEFque : En Attente
    @@ -2585,7 +2591,7 @@
    Voie du peuple des Humains
  • Loup parmi les loups : En Attente
  • Enseignement exotique : En Attente
  • Versatile : En Attente
  • -
  • Dépassement : En Attente
  • +
  • D\xE9passement : En Attente
  • Voie culturelle des ruines nordiques
      @@ -2593,28 +2599,28 @@
      Voie culturelle des ruines nordiques
    1. Barbare : En Attente
    2. Expertise des haches : En Attente
    3. Homme des clans : En Attente
    4. -
    5. Conquéran: En Attente
    6. +
    7. Conqu\xE9ran: En Attente
    Voie culturelle du Mitan
      -
    1. Homme des cités : En Attente
    2. -
    3. Entre tradition et progrès : En Attente
    4. +
    5. Homme des cit\xE9s : En Attente
    6. +
    7. Entre tradition et progr\xE8s : En Attente
    8. Modernisme : En Attente
    9. Conspirateur : En Attente
    10. -
    11. Maître marchand : En Attente
    12. +
    13. Ma\xEEtre marchand : En Attente
    Voie culturelle des empires austraux
      -
    1. Érudition : En Attente
    2. -
    3. Études arcaniques : En Attente
    4. -
    5. Autorité culturelle : En Attente
    6. -
    7. Prédispositions arcaniques : En Attente
    8. +
    9. \xC9rudition : En Attente
    10. +
    11. \xC9tudes arcaniques : En Attente
    12. +
    13. Autorit\xE9 culturelle : En Attente
    14. +
    15. Pr\xE9dispositions arcaniques : En Attente
    16. Mage : En Attente
    Voie culturelle des Terres orientales
    1. Connaissances cosmopolites : En Attente
    2. -
    3. Rejeton de la cité des Sang-mêlés : En Attente
    4. +
    5. Rejeton de la cit\xE9 des Sang-m\xEAl\xE9s : En Attente
    6. Sentir la magie : En Attente
    7. Chevaucheur de dragons : En Attente
    8. Expert en filouterie : En Attente
    9. @@ -2624,16 +2630,16 @@

      5.1.3 Peaux Vertes

      Voie du peuple des Peaux Vertes
        -
      1. Pour l’honneur : En Attente
      2. -
      3. Frappe déloyale : En Attente
      4. -
      5. Maîtrise des armes sauvages : En Attente
      6. -
      7. Croyances païennes : En Attente
      8. -
      9. Héros tribal : En Attente
      10. +
      11. Pour l\x2019honneur : En Attente
      12. +
      13. Frappe d\xE9loyale : En Attente
      14. +
      15. Ma\xEEtrise des armes sauvages : En Attente
      16. +
      17. Croyances pa\xEFennes : En Attente
      18. +
      19. H\xE9ros tribal : En Attente
      Voie culturelle des Ogres
        -
      1. Énorme : En Attente
      2. +
      3. \xC9norme : En Attente
      4. Brute : En Attente
      5. Attaque massive (L) : En Attente
      6. Intuable : En Attente
      7. @@ -2662,80 +2668,80 @@

        5.2 Voies de la f

        Voie du bastion

          -
        1. Protéger un allié : !cof-proteger-un-allie @{selected|token_id} @{target|token_id}. Fonctionne aussi si on remplace le target par un nom de token. Le script ne vérifie pas que le combattant ne change pas d'allié plus d'une fois par tour. Pour la capacité avancée, ajouter un prédicat protegerUnAllieAvance.
        2. +
        3. Prot\xE9ger un alli\xE9 : !cof-proteger-un-allie @{selected|token_id} @{target|token_id}. Fonctionne aussi si on remplace le target par un nom de token. Le script ne v\xE9rifie pas que le combattant ne change pas d'alli\xE9 plus d'une fois par tour. Pour la capacit\xE9 avanc\xE9e, ajouter un pr\xE9dicat protegerUnAllieAvance.
        4. Absorber un coup (L) :
            -
          • utiliser !cof-effet-temp absorberUnCoup 1 pour se mettre en position. Attention, ça ne vérifie pas si le combattant porte son bouclier.
          • -
          • le script propose un bouton à activer en cas d'attaque réussie alors que le combattant est en position.
          • +
          • utiliser !cof-effet-temp absorberUnCoup 1 pour se mettre en position. Attention, \xE7a ne v\xE9rifie pas si le combattant porte son bouclier.
          • +
          • le script propose un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le combattant est en position.
        5. -
        6. Coup de bouclier : faire une attaque de bouclier, de type Arme gauche, avec le modificateur avecd12crit. Pour que cette attaque soit proposée dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un prédicat attaqueAuBouclier de valeur le label de l'attaque.
        7. +
        8. Coup de bouclier : faire une attaque de bouclier, de type Arme gauche, avec le modificateur avecd12crit. Pour que cette attaque soit propos\xE9e dans les listes d'action seulement quand le personnage porte son bouclier, ajouter un pr\xE9dicat attaqueAuBouclier de valeur le label de l'attaque.
        9. Absorber un sort (L) :
            -
          • utiliser !cof-effet-temp absorberUnSort 1 pour se mettre en position. Attention, ça ne vérifie pas si le combattant porte son bouclier.
          • -
          • le script propose un bouton à activer en cas d'attaque réussie alors que le combattant est en position.
          • +
          • utiliser !cof-effet-temp absorberUnSort 1 pour se mettre en position. Attention, \xE7a ne v\xE9rifie pas si le combattant porte son bouclier.
          • +
          • le script propose un bouton \xE0 activer en cas d'attaque r\xE9ussie alors que le combattant est en position.
        10. -
        11. Armure lourde : Noter l'armure sur la feuille du personnage, et ajouter un prédicat armureLourdeGuerrier au personnage. L'annulation du critique ne se produira que si l'armure est portée et que la valeur totale du bonus de défense supérieure ou égale à 7 (le bonus de DEF d'une armure de plaques complète).
        12. +
        13. Armure lourde : Noter l'armure sur la feuille du personnage, et ajouter un pr\xE9dicat armureLourdeGuerrier au personnage. L'annulation du critique ne se produira que si l'armure est port\xE9e et que la valeur totale du bonus de d\xE9fense sup\xE9rieure ou \xE9gale \xE0 7 (le bonus de DEF d'une armure de plaques compl\xE8te).

        Voie de la bravoure

        1. Robustesse : rajouter les PVs sur la fiche.
        2. Armure naturelle : rajouter la DEF sur la fiche
        3. -
        4. Prouesse : ajouter un prédicat prouesse (on peut y associer un nombre, si on souhaite plus d'une utilisation par tour). Le script générera automatiquement les boutons Prouesse sur les test appropriés.
        5. -
        6. Dernier rempart (L) : pas de support particulier, le MJ doit gérer les attaques supplémentaires.
        7. -
        8. Constitution héroïque : reporter les bonus sur la fiche.
        9. +
        10. Prouesse : ajouter un pr\xE9dicat prouesse (on peut y associer un nombre, si on souhaite plus d'une utilisation par tour). Le script g\xE9n\xE9rera automatiquement les boutons Prouesse sur les test appropri\xE9s.
        11. +
        12. Dernier rempart (L) : pas de support particulier, le MJ doit g\xE9rer les attaques suppl\xE9mentaires.
        13. +
        14. Constitution h\xE9ro\xEFque : reporter les bonus sur la fiche.
        -

        Voie du combat à deux armes

        +

        Voie du combat \xE0 deux armes

          -
        1. Combat à deux armes (L) : mettre une des attaques de type arme gauche, et y ajouter le modificateur avecd12crit. Pas encore de support pour la capacité avancée : dans ce cas, ajoutez le +1 dans la barre 3 du token ou sur les attaques.
        2. -
        3. Parade croisée (L) : !cof-effet-temp paradeCroisee 1 --valeur 2 --montreActions. Pour la capacité avancée, !cof-effet-temp paradeCroisee 1 --valeur 4 --montreActions.
        4. -
        5. Symétrie : En Attente
        6. +
        7. Combat \xE0 deux armes (L) : mettre une des attaques de type arme gauche, et y ajouter le modificateur avecd12crit. Pas encore de support pour la capacit\xE9 avanc\xE9e : dans ce cas, ajoutez le +1 dans la barre 3 du token ou sur les attaques.
        8. +
        9. Parade crois\xE9e (L) : !cof-effet-temp paradeCroisee 1 --valeur 2 --montreActions. Pour la capacit\xE9 avanc\xE9e, !cof-effet-temp paradeCroisee 1 --valeur 4 --montreActions.
        10. +
        11. Sym\xE9trie : En Attente
        12. Double peine : En Attente
        13. -
        14. Combat à deux armes parfait : En Attente
        15. +
        16. Combat \xE0 deux armes parfait : En Attente
        -

        Voie du combat monté

        +

        Voie du combat mont\xE9

          -
        1. Fidèle monture : Faire un personnage pour la monture, avec un prédicat monture. Pour monter sur la monture, on peut utiliser une ability de type token action, avec !cof-en-selle @{selected|token_id} nom_de_la_monture. Pour en descendre, il suffit de cliquer à nouveau sur le bouton de l'ability. Si vous souhaitez éviter que la monture apparaisse dans le turn tracker, vous pouvez ajouter un prédicat aucuneActionCombat à la monture.
        2. -
        3. Cavalier émérite : Ajouter au combattant un prédicat cavalierEmerite:2. Pour la défense de la monture, ajouter à cellle-ci un prédicat defDeriveeDe de valeur le nom du combattant (exactement tel qu'il apparaît sur la fiche, il est possible que cela demande d'utiliser la syntaxe avec ::). Attention, cela suppose que le combattant a une meilleure DEF que sa monture. Si ce n'est pas le cas, faire les ajustements sur la fiche du combattant.
        4. -
        5. Massacrer la piétaille : En Attente
        6. -
        7. Charge : pas de support pour le déplacement, mais +
        8. Fid\xE8le monture : Faire un personnage pour la monture, avec un pr\xE9dicat monture. Pour monter sur la monture, on peut utiliser une ability de type token action, avec !cof-en-selle @{selected|token_id} nom_de_la_monture. Pour en descendre, il suffit de cliquer \xE0 nouveau sur le bouton de l'ability. Si vous souhaitez \xE9viter que la monture apparaisse dans le turn tracker, vous pouvez ajouter un pr\xE9dicat aucuneActionCombat \xE0 la monture.
        9. +
        10. Cavalier \xE9m\xE9rite : Ajouter au combattant un pr\xE9dicat cavalierEmerite:2. Pour la d\xE9fense de la monture, ajouter \xE0 cellle-ci un pr\xE9dicat defDeriveeDe de valeur le nom du combattant (exactement tel qu'il appara\xEEt sur la fiche, il est possible que cela demande d'utiliser la syntaxe avec ::). Attention, cela suppose que le combattant a une meilleure DEF que sa monture. Si ce n'est pas le cas, faire les ajustements sur la fiche du combattant.
        11. +
        12. Massacrer la pi\xE9taille : En Attente
        13. +
        14. Charge : pas de support pour le d\xE9placement, mais
          • Pour l'attaque : utiliser --m2d20 --plus 1d6
          • -
          • Pour les créatures sur la trajectoire, utiliser !cof-jet FOR 18, et en cas de succès, infliger les DM (!cof-dmg 1d6)
          • +
          • Pour les cr\xE9atures sur la trajectoire, utiliser !cof-jet FOR 18, et en cas de succ\xE8s, infliger les DM (!cof-dmg 1d6)
        15. -
        16. Monture fantastique : faire un personnage pour la monture, avec un prédicat monture.
        17. +
        18. Monture fantastique : faire un personnage pour la monture, avec un pr\xE9dicat monture.

        Voie du commandement

          -
        1. Action concertée : utiliser !cof-echange-init @{selected|token_id} @{target|token_id} nn peut valoir 0, 1, 2 ou 3 selon le rang dans la voie et si la capacité est avancée.
        2. -
        3. À couvert (L) : !cof-a-couvert @{selected|token_id} @{target|token_id} le target est l'allié qui se déplace avec l'arquebusier. Se sélectionner soi-même si pas d'allié. Pas encore de support pour la capacité avancée.
        4. -
        5. Exemplaire : faire !cof-exemplaire, juste après l'attaque ratée.
        6. +
        7. Action concert\xE9e : utiliser !cof-echange-init @{selected|token_id} @{target|token_id} n o\xF9 n peut valoir 0, 1, 2 ou 3 selon le rang dans la voie et si la capacit\xE9 est avanc\xE9e.
        8. +
        9. \xC0 couvert (L) : !cof-a-couvert @{selected|token_id} @{target|token_id} le target est l'alli\xE9 qui se d\xE9place avec l'arquebusier. Se s\xE9lectionner soi-m\xEAme si pas d'alli\xE9. Pas encore de support pour la capacit\xE9 avanc\xE9e.
        10. +
        11. Exemplaire : faire !cof-exemplaire, juste apr\xE8s l'attaque rat\xE9e.
        12. Ordre de bataille : pas de support
        13. Charge fantastique (L) : !cof-charge-fantastique @{selected|token_id} --alliesEnVue --self --limiteParCombat 1
        -

        Voie de la férocité

        +

        Voie de la f\xE9rocit\xE9

        1. Cri de guerre : !cof-effet-combat criDeGuerre
        2. -
        3. Charge (L) : #Attaque -1 --bonusAttaque 2 --plus 1d6. Le déplacement n'est pas encore géré.
        4. -
        5. Rage du berserk (L) : utiliser !cof-rage-du-berserk, à la fois pour entrer en rage et pour tenter d'en sortir avant la fin du combat. Si le MJ souhaite mettre fin à la rage à cause d'un effet extérieur, il peut utiliser la commande !cof-effet-combat rageDuBerserk fin.
        6. -
        7. Même pas mal : ajouter un prédicat memePasMal. Le joueur doit lui-même activer la rage ou le furie si il souhaite en profiter.
        8. +
        9. Charge (L) : #Attaque -1 --bonusAttaque 2 --plus 1d6. Le d\xE9placement n'est pas encore g\xE9r\xE9.
        10. +
        11. Rage du berserk (L) : utiliser !cof-rage-du-berserk, \xE0 la fois pour entrer en rage et pour tenter d'en sortir avant la fin du combat. Si le MJ souhaite mettre fin \xE0 la rage \xE0 cause d'un effet ext\xE9rieur, il peut utiliser la commande !cof-effet-combat rageDuBerserk fin.
        12. +
        13. M\xEAme pas mal : ajouter un pr\xE9dicat memePasMal. Le joueur doit lui-m\xEAme activer la rage ou le furie si il souhaite en profiter.
        14. Attaque tourbillon (L) : !cof-explosion -1 --auto --disque 5 --saufAllies --limiteParCombat 1 tourbillon.

        Voie de la guerre

          -
        1. Posture de combat : !cof-posture-de-combat bonus attr1 attr2, où les deux attr peuvent être soit DEF soit ATT soit DM, et le bonus est retiré au premier attribut pour être ajouté au second. Le bonus peut être limité si le combattant a un prédicat voieDuSoldat qui indique son rang dans la voie. Exemple d'utilisation : !cof-posture-de-combat ?{Bonus|1|2|3|4|5} ?{Baisser|Défense,DEF|Attaque,ATT|Dégâts,DM} ?{Augmenter|Défense,DEF|Attaque,ATT|Dégâts,DM}. Normalement, la règle fait décider de sa posture au combattant à chaque tour, mais en pratique, il en change assez rarement. Une posture de combat reste donc active jusqu'à la fin du combat ou jusqu'à ce qu'on en change (elle est neutre si on a le même attribut à buffer et débuffer).
        2. -
        3. Désarmer (L) : !cof-desarmer @{selected|token_id} @{target|token_id}.
        4. -
        5. Double attaque (L) : faire deux attaques, avec l'option supplémentaire --bonusAttaque -2.
        6. -
        7. Attaque circulaire (L) : faire les attaques normalement, ce n'est pas considéré comme une aoe.
        8. +
        9. Posture de combat : !cof-posture-de-combat bonus attr1 attr2, o\xF9 les deux attr peuvent \xEAtre soit DEF soit ATT soit DM, et le bonus est retir\xE9 au premier attribut pour \xEAtre ajout\xE9 au second. Le bonus peut \xEAtre limit\xE9 si le combattant a un pr\xE9dicat voieDuSoldat qui indique son rang dans la voie. Exemple d'utilisation : !cof-posture-de-combat ?{Bonus|1|2|3|4|5} ?{Baisser|D\xE9fense,DEF|Attaque,ATT|D\xE9g\xE2ts,DM} ?{Augmenter|D\xE9fense,DEF|Attaque,ATT|D\xE9g\xE2ts,DM}. Normalement, la r\xE8gle fait d\xE9cider de sa posture au combattant \xE0 chaque tour, mais en pratique, il en change assez rarement. Une posture de combat reste donc active jusqu'\xE0 la fin du combat ou jusqu'\xE0 ce qu'on en change (elle est neutre si on a le m\xEAme attribut \xE0 buffer et d\xE9buffer).
        10. +
        11. D\xE9sarmer (L) : !cof-desarmer @{selected|token_id} @{target|token_id}.
        12. +
        13. Double attaque (L) : faire deux attaques, avec l'option suppl\xE9mentaire --bonusAttaque -2.
        14. +
        15. Attaque circulaire (L) : faire les attaques normalement, ce n'est pas consid\xE9r\xE9 comme une aoe.
        16. Attaque puissante : #Attaque -1 --avecd12crit --plus 2d6 --seulementContact.
        -

        Voie de la maîtrise des armes

        +

        Voie de la ma\xEEtrise des armes

          -
        1. Arme de prédilection : il est possible de préciser une famille d'armes de prédilection (un peu plus large que dans les règles), parmis arc, arbalete, fronde, hache, epee, marteau, masse, sabre, epieu, poudre, baton et rapiere. Si cela vous convient, ajoutez un prédicat armeDePredilection de valeur une de ces familles. Sinon, simplement ajouter le bonus sur les attaques dans la fiche.
        2. +
        3. Arme de pr\xE9dilection : il est possible de pr\xE9ciser une famille d'armes de pr\xE9dilection (un peu plus large que dans les r\xE8gles), parmis arc, arbalete, fronde, hache, epee, marteau, masse, sabre, epieu, poudre, baton et rapiere. Si cela vous convient, ajoutez un pr\xE9dicat armeDePredilection de valeur une de ces familles. Sinon, simplement ajouter le bonus sur les attaques dans la fiche.
        4. Science du critique : En Attente
        5. -
        6. Spécialisation : En Attente
        7. +
        8. Sp\xE9cialisation : En Attente
        9. Attaque parfaite (L) : En Attente
        10. Riposte : En Attente
        @@ -2743,61 +2749,61 @@

        Voie du pugilat

        1. Poings de fer : En Attente
        2. Peau de pierre : En Attente
        3. -
        4. Peau d’acier : En Attente
        5. -
        6. Déluge de coups (L) : En Attente
        7. -
        8. Force héroïque : En Attente
        9. +
        10. Peau d\x2019acier : En Attente
        11. +
        12. D\xE9luge de coups (L) : En Attente
        13. +
        14. Force h\xE9ro\xEFque : En Attente

        Voie de la puissance

        1. Argument de taille : En Attente
        2. Tour de force : En Attente
        3. Attaque brutale (L) : En Attente
        4. -
        5. Briseur d’os : En Attente
        6. -
        7. Vitalité débordante : En Attente
        8. +
        9. Briseur d\x2019os : En Attente
        10. +
        11. Vitalit\xE9 d\xE9bordante : En Attente

        5.3 Voies de la famille des aventuriers

        -

        Voie de l’acrobatie

        +

        Voie de l\x2019acrobatie

        1. Acrobate : En Attente
        2. -
        3. Grâce féline : En Attente
        4. +
        5. Gr\xE2ce f\xE9line : En Attente
        6. Lanceur de couteau : En Attente
        7. Esquive acrobatique : En Attente
        8. -
        9. Dextérité héroïque : En Attente
        10. +
        11. Dext\xE9rit\xE9 h\xE9ro\xEFque : En Attente
        -

        Voie de l’arbalètrie

        +

        Voie de l\x2019arbal\xE8trie

        1. Joli coup! : En Attente
        2. Cadence de tir : En Attente
        3. Tir double (L) : En Attente
        4. -
        5. As de la gâchette : En Attente
        6. +
        7. As de la g\xE2chette : En Attente
        8. Tir mortel : En Attente
        -

        Voie de l’archerie

        +

        Voie de l\x2019archerie

          -
        1. Sens affûtés : En Attente
        2. +
        3. Sens aff\xFBt\xE9s : En Attente
        4. Tir aveugle (L) : En Attente
        5. Tir rapide (L) : En Attente
        6. -
        7. Flèche de mort (L) : En Attente
        8. +
        9. Fl\xE8che de mort (L) : En Attente
        10. Dans le mille : En Attente
        -

        Voie de l’assassinat

        +

        Voie de l\x2019assassinat

          -
        1. Discrétion : En Attente
        2. +
        3. Discr\xE9tion : En Attente
        4. Attaque sournoise (L) : En Attente
        5. Frappe chirurgicale : En Attente
        6. Surprise : En Attente
        7. -
        8. Botte secrète : En Attente
        9. +
        10. Botte secr\xE8te : En Attente
        -

        Voie du bohème

        +

        Voie du boh\xE8me

          -
        1. Rumeurs et légendes : En Attente
        2. +
        3. Rumeurs et l\xE9gendes : En Attente
        4. Argumenter : En Attente
        5. -
        6. Débrouillard : En Attente
        7. -
        8. Déguisement : En Attente
        9. -
        10. Touche-à-tout : En Attente
        11. +
        12. D\xE9brouillard : En Attente
        13. +
        14. D\xE9guisement : En Attente
        15. +
        16. Touche-\xE0-tout : En Attente

        Voie du charme

          @@ -2805,15 +2811,15 @@

          Voie du charme

        1. Provocation (L) : En Attente
        2. Attaque flamboyante (L) : En Attente
        3. Suggestion (L) : En Attente
        4. -
        5. Charisme héroïque : En Attente
        6. +
        7. Charisme h\xE9ro\xEFque : En Attente

        Voie de la chasse

        1. Proche de la nature : En Attente
        2. -
        3. Nature nourricière : En Attente
        4. -
        5. Attaque éclair (L) : En Attente
        6. -
        7. Ennemis jurés : En Attente
        8. -
        9. Perception héroïque : En Attente
        10. +
        11. Nature nourrici\xE8re : En Attente
        12. +
        13. Attaque \xE9clair (L) : En Attente
        14. +
        15. Ennemis jur\xE9s : En Attente
        16. +
        17. Perception h\xE9ro\xEFque : En Attente

        Voie du compagnon animal

          @@ -2823,7 +2829,7 @@

          Voie du compagnon animal

        1. Empathie animale : En Attente
        2. Animal fabuleux : En Attente
        -

        Voie de l’escrime

        +

        Voie de l\x2019escrime

        1. Attaque en finesse : En Attente
        2. Intelligence du combat : En Attente
        3. @@ -2834,10 +2840,10 @@

          Voie de l’escrime

          Voie de la fourberie

          1. Doigts agiles : En Attente
          2. -
          3. Détecter les pièges : En Attente
          4. +
          5. D\xE9tecter les pi\xE8ges : En Attente
          6. Croc-en-jambe : En Attente
          7. Attaque paralysante (L) : En Attente
          8. -
          9. Attaque en traître : En Attente
          10. +
          11. Attaque en tra\xEEtre : En Attente
        @@ -2845,188 +2851,193 @@

        5.4 Voies de la fam

        Talents magiques

          -
        • Détection de la magie : pas de support.
        • +
        • D\xE9tection de la magie : pas de support.
        • Flamme : Faire une attaque magique de type feu pour l'attaque au contact. Pour l'illumination, !cof-lumiere @{selected|token_id} 5 1 --mana 0.
        • -
        • Inspiration : !cof-effet-temp inspiration [[2+@{selected|SAG}]] --target @{target|token_id} --lanceur @{selected|token_id} --portee 10. Pour l'instant le script ne vérifie pas que le sort n'est pas actif sur trop de cibles à la fois.
        • -
        • Lumières dansantes : !cof-lumiere @{selected|token_id} 20 15 --mana 0. Le script ne gère pas encore l'annulation de l'effet au moindre choc.
        • +
        • Inspiration : !cof-effet-temp inspiration [[2+@{selected|SAG}]] --target @{target|token_id} --lanceur @{selected|token_id} --portee 10. Pour l'instant le script ne v\xE9rifie pas que le sort n'est pas actif sur trop de cibles \xE0 la fois.
        • +
        • Lumi\xE8res dansantes : !cof-lumiere @{selected|token_id} 20 15 --mana 0. Le script ne g\xE8re pas encore l'annulation de l'effet au moindre choc.
        • Projectile de force : - Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4, portée 50, type Sortilège, modificateur auto dégâts contondants, option --mana 0. + Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d4, port\xE9e 50, type Sortil\xE8ge, modificateur auto d\xE9g\xE2ts contondants, option --mana 0.
        -

        Voie de l’alchimie

        -

        Pour créer ou juste voir ses élixirs, utiliser la commande !cof-elixirs. Pour cela, il faut aussi un prédicat voieDeLAlchimie avec comme valeur le rang dans la voie. Noter que la commande !cof-elixirs affiche une liste d'élixirs, et que pour effectivement créer un élixir, il faut cliquer sur le bouton correspondant dans cette liste.

        +

        Voie de l\x2019alchimie

        +

        Pour cr\xE9er ou juste voir ses \xE9lixirs, utiliser la commande !cof-elixirs. Pour cela, il faut aussi un pr\xE9dicat voieDeLAlchimie avec comme valeur le rang dans la voie. Noter que la commande !cof-elixirs affiche une liste d'\xE9lixirs, et que pour effectivement cr\xE9er un \xE9lixir, il faut cliquer sur le bouton correspondant dans cette liste.

          -
        1. Fortifiant : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables. Pour la version avancée, ajouter un prédicat fortiviantAvance
        2. -
        3. Feu grégeois : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables. Pas de support pour la version avancée pour l'instant : utiliser !cof-dmg rang --feu pour les personnages qui auraient raté leur jet de DEX.
        4. -
        5. Huile instable : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
        6. -
        7. Élixir de guérison : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
        8. -
        9. Élixirs de Protection : création à l'aide de !cof-elixirs, et utilisation avec la même commande, ou bien en utilisant !cof-consommables.
        10. +
        11. Fortifiant : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables. Pour la version avanc\xE9e, ajouter un pr\xE9dicat fortiviantAvance
        12. +
        13. Feu gr\xE9geois : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables. Pas de support pour la version avanc\xE9e pour l'instant : utiliser !cof-dmg rang --feu pour les personnages qui auraient rat\xE9 leur jet de DEX.
        14. +
        15. Huile instable : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
        16. +
        17. \xC9lixir de gu\xE9rison : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.
        18. +
        19. \xC9lixirs de Protection : cr\xE9ation \xE0 l'aide de !cof-elixirs, et utilisation avec la m\xEAme commande, ou bien en utilisant !cof-consommables.

        Voie des arts druidiques

        1. Langage des animaux : En Attente
        2. -
        3. Nuée d’insectes* : En Attente
        4. +
        5. Nu\xE9e d\x2019insectes* : En Attente
        6. Le guetteur : En Attente
        7. -
        8. Masque du prédateur* : En Attente
        9. -
        10. Sagesse héroïque : En Attente
        11. +
        12. Masque du pr\xE9dateur* : En Attente
        13. +
        14. Sagesse h\xE9ro\xEFque : En Attente

        Voie de la divination

          -
        1. Sixième sens : ajouter le bonus en DEF divers et initiative divers, ajouter une compétence vigilance, de valeur 5 (le bonus aux jet de surprise).
        2. -
        3. Détection de l’invisible* : En Attente
        4. +
        5. Sixi\xE8me sens : ajouter le bonus en DEF divers et initiative divers, ajouter une comp\xE9tence vigilance, de valeur 5 (le bonus aux jet de surprise).
        6. +
        7. D\xE9tection de l\x2019invisible* : En Attente
        8. Clairvoyance* : En Attente
        9. Prescience* : En Attente
        10. Hyperconscience : En Attente
        -

        Voie de l’envoûtement

        +

        Voie de l\x2019envo\xFBtement

        1. Injonction* : En Attente
        2. Sommeil* : En Attente
        3. Confusion* : En Attente
        4. -
        5. Amitié* : En Attente
        6. +
        7. Amiti\xE9* : En Attente
        8. Domination* : En Attente
        -

        Voie des forêts

        +

        Voie des for\xEAts

          -
        1. Peau d’écorce* : - !cof-effet-temp peauDEcorce [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 1|Économe (L),--mana 0|Étendue (L),--puissant duree --mana 1}. Si le personnage a un prédicat voieDesForets de valeur 4 ou plus, le bonus sera de +4 en DEF. Ajouter un prédicat peauDEcorceAvancee pour la version en capacité avancée.
        2. -
        3. Prison végétale* : En Attente
        4. +
        5. Peau d\x2019\xE9corce* : + !cof-effet-temp peauDEcorce [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 1|\xC9conome (L),--mana 0|\xC9tendue (L),--puissant duree --mana 1}. Si le personnage a un pr\xE9dicat voieDesForets de valeur 4 ou plus, le bonus sera de +4 en DEF. Ajouter un pr\xE9dicat peauDEcorceAvancee pour la version en capacit\xE9 avanc\xE9e.
        6. +
        7. Prison v\xE9g\xE9tale* : En Attente
        8. Baies magiques* : En Attente
        9. -
        10. Animation d’un arbre* : En Attente
        11. -
        12. Régénération* : En Attente
        13. +
        14. Animation d\x2019un arbre* : En Attente
        15. +
        16. R\xE9g\xE9n\xE9ration* : En Attente

        Voie des illusions

          -
        1. Image décalée* : !cof-effet-temp imageDecalee [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 1|Économe (L),--mana 0|Étendue (L),--puissant duree --mana 1}. Pour la version avancée de la capacité, ajouter un prédicat imageDecaleeAvancee.
        2. +
        3. Image d\xE9cal\xE9e* : !cof-effet-temp imageDecalee [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 1|\xC9conome (L),--mana 0|\xC9tendue (L),--puissant duree --mana 1}. Pour la version avanc\xE9e de la capacit\xE9, ajouter un pr\xE9dicat imageDecaleeAvancee.
        4. Mirage* : En Attente
        5. Imitation* : En Attente
        6. -
        7. Dédoublement* : En Attente
        8. +
        9. D\xE9doublement* : En Attente
        10. Tueur fantasmagorique* : En Attente
        -

        Voie de la magie élémentaliste

        +

        Voie de la magie \xE9l\xE9mentaliste

        1. Brumes* : - !cof-tenebres @{selected|token_id} @{target|token_id} --brumes --mana 1. La commande pose un token de brouillard pour visualiser la zone. Tous les tokens présents dans la zone au lancement du sort sont automatiquement dans l'état pénombre. Au MJ ensuite d'enlever l'état pénombre quand les cibles sortent de la zone. A la fin de la durée du sort, ou à la fin du combat, la zone et les états pénombre restant disparaissent automatiquement. Il est aussi possible de changer les valeurs par défaut du sort (portée 20m, rayon 20m) avec les options --portee X et --rayon X. En règle custom, l'option puissant permet de doubler la superficie couverte (le script calcule le rayon approprié si custom).
        2. + !cof-tenebres @{selected|token_id} @{target|token_id} --brumes --mana 1. La commande pose un token de brouillard pour visualiser la zone. Tous les tokens pr\xE9sents dans la zone au lancement du sort sont automatiquement dans l'\xE9tat p\xE9nombre. Au MJ ensuite d'enlever l'\xE9tat p\xE9nombre quand les cibles sortent de la zone. A la fin de la dur\xE9e du sort, ou \xE0 la fin du combat, la zone et les \xE9tats p\xE9nombre restant disparaissent automatiquement. Il est aussi possible de changer les valeurs par d\xE9faut du sort (port\xE9e 20m, rayon 20m) avec les options --portee X et --rayon X. En r\xE8gle custom, l'option puissant permet de doubler la superficie couverte (le script calcule le rayon appropri\xE9 si custom).
        3. Sous tension* :
            -
          • !cof-effet-temp sousTension [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 2|Économe (L),--mana 0|Étendue (L),--puissant duree --mana 2|Puissante (L),--puissant --mana 2} pour lancer le sort et mettre le personnage sous tension
          • -
          • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, portée 10, type Sortilège, dégâts électriques, options --si etat sousTension --fx beam-holy.
          • -
          • Utiliser un prédicat voieDeLaMagieElementaliste de valeur le rang dans la voie pour le passage des dégâts à 2d6 quand le personnage est touché.
          • -
          • Pas de support particulier pour la version avancée.
          • +
          • !cof-effet-temp sousTension [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 2|\xC9conome (L),--mana 0|\xC9tendue (L),--puissant duree --mana 2|Puissante (L),--puissant --mana 2} pour lancer le sort et mettre le personnage sous tension
          • +
          • Ajouter une attaque sur la fiche utilisant l'attaque magique, dommages 1d6+INT, port\xE9e 10, type Sortil\xE8ge, d\xE9g\xE2ts \xE9lectriques, options --si etat sousTension --fx beam-holy.
          • +
          • Utiliser un pr\xE9dicat voieDeLaMagieElementaliste de valeur le rang dans la voie pour le passage des d\xE9g\xE2ts \xE0 2d6 quand le personnage est touch\xE9.
          • +
          • Pas de support particulier pour la version avanc\xE9e.
        4. Armure de terre* : - bien utiliser un prédicat voieDeLaMagieElementaliste avec comme valeur le rang dans la voie. Pour lancer le sort, faire !cof-effet-temp protectionContreLesElements [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 3|Économe (L),--mana 1|Étendue (L),--puissant duree --mana 3}.
        5. + bien utiliser un pr\xE9dicat voieDeLaMagieElementaliste avec comme valeur le rang dans la voie. Pour lancer le sort, faire !cof-effet-temp protectionContreLesElements [[5+@{selected|SAG}]] ?{Magie|Normale,--mana 3|\xC9conome (L),--mana 1|\xC9tendue (L),--puissant duree --mana 3}.
        6. Boule de feu* : En Attente
        7. -
        8. Intelligence héroïque : En Attente
        9. +
        10. Intelligence h\xE9ro\xEFque : En Attente

        Voie de la magie runique

          -
        1. Forgeron* : Il faut un prédicat voieDuMetal pour connaître le rang (ou utiliser l'option --valeur). Lancer le sort avec !cof-effet-temp forgeron(L) [[5+@{selected|SAG}]]L est le label d'une attaque. Ensuite, chaque fois que cette attaque sera utilisée, les dégâts seront ajoutés. Limitations : si deux attaques utilisent la même arme, il faut faire deux fois l'action, une pour chaque attaque.
        2. -
        3. Rune d’énergie* : En Attente
        4. +
        5. Forgeron* : Il faut un pr\xE9dicat voieDuMetal pour conna\xEEtre le rang (ou utiliser l'option --valeur). Lancer le sort avec !cof-effet-temp forgeron(L) [[5+@{selected|SAG}]] o\xF9 L est le label d'une attaque. Ensuite, chaque fois que cette attaque sera utilis\xE9e, les d\xE9g\xE2ts seront ajout\xE9s. Limitations : si deux attaques utilisent la m\xEAme arme, il faut faire deux fois l'action, une pour chaque attaque.
        6. +
        7. Rune d\x2019\xE9nergie* : En Attente
        8. Rune de puissance* : En Attente
        9. Rune de garde* : En Attente
        10. Rune de tradition : En Attente

        Voie du mysticisme

          -
        1. Bénédiction* : En Attente
        2. +
        3. B\xE9n\xE9diction* : En Attente
        4. Protection contre le mal* : En Attente
        5. -
        6. Délivrance* : En Attente
        7. +
        8. D\xE9livrance* : En Attente
        9. Sanctuaire* : En Attente
        10. Rituel de puissance : En Attente

        Voie des sombres savoirs

        1. Saignements* : En Attente
        2. -
        3. Malédiction* : En Attente
        4. +
        5. Mal\xE9diction* : En Attente
        6. Pacte sanglant* : En Attente
        7. -
        8. Hémorragie* : En Attente
        9. -
        10. Invocation d’un démon* : En Attente
        11. +
        12. H\xE9morragie* : En Attente
        13. +
        14. Invocation d\x2019un d\xE9mon* : En Attente

        5.4 Voies de prestige

        -

        6. Markers Personnalisés

        -

        6.1 Présentation

        +

        6. Markers Personnalis\xE9s

        +

        6.1 Pr\xE9sentation

        -

        Roll20 peut être déroutant lors des premières utilisations pour des joueurs plus habitués au Jeu de Rôle sur table. Il introduit des notions peu courantes du fait que les combats vont se dérouler sur des "battlemaps" quadrillées ou non. Aussi on va prendre quelques minutes pour expliquer deux notions importantes : les tokens et les tokens markers (plus simplement appelés markers par la suite).

        -

        Le token : Un token est la représentation graphique d'un personnage (PJ ou PNJ) sur la battlemap. Grâce au token on sait à tout moment où se trouve le personnage, s'il subit un sort à effet de zone ou si sa ligne de tir est dégagée par exemple.

        -

        Le marker : Un marker est forcément attaché à un token. Il représente un "état" qui affecte le personnage (liste des états). Il se matérialise par une icône dans le coin en haut à doite du token. Un token peut afficher plusieurs markers au même moment. Ils représentent plusieurs états qui se cumulent pour ce personnage. +

        Roll20 peut \xEAtre d\xE9routant lors des premi\xE8res utilisations pour des joueurs plus habitu\xE9s au Jeu de R\xF4le sur table. Il introduit des notions peu courantes du fait que les combats vont se d\xE9rouler sur des "battlemaps" quadrill\xE9es ou non. Aussi on va prendre quelques minutes pour expliquer deux notions importantes : les tokens et les tokens markers (plus simplement appel\xE9s markers par la suite).

        +

        Le token : Un token est la repr\xE9sentation graphique d'un personnage (PJ ou PNJ) sur la battlemap. Gr\xE2ce au token on sait \xE0 tout moment o\xF9 se trouve le personnage, s'il subit un sort \xE0 effet de zone ou si sa ligne de tir est d\xE9gag\xE9e par exemple.

        +

        Le marker : Un marker est forc\xE9ment attach\xE9 \xE0 un token. Il repr\xE9sente un "\xE9tat" qui affecte le personnage (liste des \xE9tats). Il se mat\xE9rialise par une ic\xF4ne dans le coin en haut \xE0 doite du token. Un token peut afficher plusieurs markers au m\xEAme moment. Ils repr\xE9sentent plusieurs \xE9tats qui se cumulent pour ce personnage.

        -

        Dans l'image ci-dessus le token c'est le personnage à la cape bleue qui représente un PJ et le marker c'est le petit escargot qui signifie que ce même PJ est "ralenti". Le script gère les états des PJ et PNJ et il matérialisera leurs états grâce aux markers. Par exemple le MJ va demande un jet de surprise, le script effectue les jets de dés nécessaire et matérialise l'état "surpris" grâce à un marker pour les personnages qui ont raté leur jet de dé. Le script applique automatiquement le malus -5 à la DEF. Au bout d'un tour l'état "surpris" et le marker seront retirés automatiquement par le script. Le MJ peut aussi mettre directement un état à un personnage. Par exemple s'il considère que ses PJs voyagent trop chargés il peut ajouter le marker "encombré" qui lui rappelera que dorénavant les jets de DEX se font sur un d12 et plus sur un d20.

        -

        Il existe des markers qui ne représentent pas un état mais ils sont rares. On peut souligner les ronds de couleurs qui permmettent au joueur de retrouver son token plus facilement. De la même manière dans les markers cof il y existent deux marqueurs cof-init... qui permettent de repérer le prochain joueur pendant les combats. Ce n'est pas un état.

        +

        Dans l'image ci-dessus le token c'est le personnage \xE0 la cape bleue qui repr\xE9sente un PJ et le marker c'est le petit escargot qui signifie que ce m\xEAme PJ est "ralenti". Le script g\xE8re les \xE9tats des PJ et PNJ et il mat\xE9rialisera leurs \xE9tats gr\xE2ce aux markers. Par exemple le MJ va demande un jet de surprise, le script effectue les jets de d\xE9s n\xE9cessaire et mat\xE9rialise l'\xE9tat "surpris" gr\xE2ce \xE0 un marker pour les personnages qui ont rat\xE9 leur jet de d\xE9. Le script applique automatiquement le malus -5 \xE0 la DEF. Au bout d'un tour l'\xE9tat "surpris" et le marker seront retir\xE9s automatiquement par le script. Le MJ peut aussi mettre directement un \xE9tat \xE0 un personnage. Par exemple s'il consid\xE8re que ses PJs voyagent trop charg\xE9s il peut ajouter le marker "encombr\xE9" qui lui rappelera que dor\xE9navant les jets de DEX se font sur un d12 et plus sur un d20.

        +

        Il existe des markers qui ne repr\xE9sentent pas un \xE9tat mais ils sont rares. On peut souligner les ronds de couleurs qui permmettent au joueur de retrouver son token plus facilement. De la m\xEAme mani\xE8re dans les markers cof il y existent deux marqueurs cof-init... qui permettent de rep\xE9rer le prochain joueur pendant les combats. Ce n'est pas un \xE9tat.

        -

        6.2 Récupération des markers dédiés COF

        +

        6.2 R\xE9cup\xE9ration des markers d\xE9di\xE9s COF

        -

        Roll20 possède des markers par défaut mais ils ne sont pas toujours adaptés pour Chroniques Oubliées Fantasy. La communauté a voté pour choisir les tokens les plus pertinents dans le contexte COF. Voici le lien vers le post dans le forum BBE. N'hésitez pas à venir poser vos questions ou proposer vos talents de graphiste à la communauté.

        -

        Avant de pouvoir créer votre propre jeu de markers sur Roll20, vous devez préalablement télécharger ceux mis à disposition par la communauté depuis le repository GitHub du projet. Procédez comme suit :

        +

        Roll20 poss\xE8de des markers par d\xE9faut mais ils ne sont pas toujours adapt\xE9s pour Chroniques Oubli\xE9es Fantasy. La communaut\xE9 a vot\xE9 pour choisir les tokens les plus pertinents dans le contexte COF. Voici le lien vers le post dans le forum BBE. N'h\xE9sitez pas \xE0 venir poser vos questions ou proposer vos talents de graphiste \xE0 la communaut\xE9.

        +

        Avant de pouvoir cr\xE9er votre propre jeu de markers sur Roll20, vous devez pr\xE9alablement t\xE9l\xE9charger ceux mis \xE0 disposition par la communaut\xE9 depuis le repository GitHub du projet. Proc\xE9dez comme suit :

        -

        Une fois le fichier téléchargé sur votre PC dézippez le répertoire cof-marker-set et son sous-répertoire

        +

        Une fois le fichier t\xE9l\xE9charg\xE9 sur votre PC d\xE9zippez le r\xE9pertoire cof-marker-set et son sous-r\xE9pertoire

        6.3 Importation des markers dans Roll20

        -

        Dans le répertoire cof-marker-set vous trouverez tous les markers qui ont été choisis par la communauté. Dans le répertoire markers-alternatifs vous trouverez les glorieux seconds au vote que vous pouvez utiliser en lieu et place du marker choisi s'il vous plaît plus. Il vous suffit alors de glisser-déposer le fichier dans le répertoire principal et de confirmer l'écrasement de l'autre marker. Vous pouvez aussi choisir vos propres markers dans cette géniale bibliothéque d'icônes. Vous pouvez aussi déssiner vos propre marker. Les limites sont que la taille de l'image doit être exactement de 512x512 px. Un fichier PNG est préférable pour gérer la transparence. Enfin votre fichier doit porter exactement le même nom qu'indiqué dans cette documentation.

        +

        Dans le r\xE9pertoire cof-marker-set vous trouverez tous les markers qui ont \xE9t\xE9 choisis par la communaut\xE9. Dans le r\xE9pertoire markers-alternatifs vous trouverez les glorieux seconds au vote que vous pouvez utiliser en lieu et place du marker choisi s'il vous pla\xEEt plus. Il vous suffit alors de glisser-d\xE9poser le fichier dans le r\xE9pertoire principal et de confirmer l'\xE9crasement de l'autre marker. Vous pouvez aussi choisir vos propres markers dans cette g\xE9niale biblioth\xE9que d'ic\xF4nes. Vous pouvez aussi d\xE9ssiner vos propre marker. Les limites sont que la taille de l'image doit \xEAtre exactement de 512x512 px. Un fichier PNG est pr\xE9f\xE9rable pour g\xE9rer la transparence. Enfin votre fichier doit porter exactement le m\xEAme nom qu'indiqu\xE9 dans cette documentation.

        Dans Roll20 rendez-vous dans le menu "Outils" puis "Token Marker Library". Appuyez sur "Create Set". Puis renseignez le nom du marker set. "cof markers" par exemple. Appuyez sur "Create Set".

        -

        Vous arrivez alors sur la fenêtre suivante où il suffit de déposer les fichiers pour qu'ils soient uploadés sur Roll20

        +

        Vous arrivez alors sur la fen\xEAtre suivante o\xF9 il suffit de d\xE9poser les fichiers pour qu'ils soient upload\xE9s sur Roll20

        -

        A ce moment il y a deux écoles de vie : ceux qui lâchent tous leurs markers en même temps et qui laisse le soin aux serveurs de Roll20 de décider dans quel ordre ils verront apparaître les markers dans leur interface pour le restant de leur jour. Et ceux qui posent les fichiers un par un pour que l'ordre qu'ils souhaitent soit respecté par Roll20. Quand tout est prêt cliquez sur "Upload". Vous avez un message "Fichiers en cours de traitement" pendant 1 à 2 minutes. Ensuite Roll20 vous propose de renommer vos tokens. Ne changez rien et faîtes "Save". Ca y est, vos markers personnalisés sont enfin prêts !

        +

        A ce moment il y a deux \xE9coles de vie : ceux qui l\xE2chent tous leurs markers en m\xEAme temps et qui laisse le soin aux serveurs de Roll20 de d\xE9cider dans quel ordre ils verront appara\xEEtre les markers dans leur interface pour le restant de leur jour. Et ceux qui posent les fichiers un par un pour que l'ordre qu'ils souhaitent soit respect\xE9 par Roll20. Quand tout est pr\xEAt cliquez sur "Upload". Vous avez un message "Fichiers en cours de traitement" pendant 1 \xE0 2 minutes. Ensuite Roll20 vous propose de renommer vos tokens. Ne changez rien et fa\xEEtes "Save". Ca y est, vos markers personnalis\xE9s sont enfin pr\xEAts !

        -

        6.4 Activation et Vérification

        +

        6.4 Activation et V\xE9rification

        -

        Mais ce n'est pas fini il vous faut encore affecter vos markers à votre campagne. Cela se passe sur la page d'acceuil de votre campagne:

        +

        Mais ce n'est pas fini il vous faut encore affecter vos markers \xE0 votre campagne. Cela se passe sur la page d'acceuil de votre campagne:

        -

        Lancez votre campagne et vérifiez que les nouveaux markers apparaissent bien. Lancez ensuite la commande !cof-options pour cocher "Markers Personnalises". Enfin comme dernier contrôle allez dans la console des API, faîtes "restart API sandbox" et vérifiez que le message "Markers personnalisés activés" est bien présent. Si ce n'est pas le cas vous avez probablement oublié des markers "obligatoires" et le script n'a pas pu activer les markers cof pour cette raison. La liste des markers manquants devrait apparaître dans la console.

        +

        Lancez votre campagne et v\xE9rifiez que les nouveaux markers apparaissent bien. Lancez ensuite la commande !cof-options pour cocher "Markers Personnalises". Enfin comme dernier contr\xF4le allez dans la console des API, fa\xEEtes "restart API sandbox" et v\xE9rifiez que le message "Markers personnalis\xE9s activ\xE9s" est bien pr\xE9sent. Si ce n'est pas le cas vous avez probablement oubli\xE9 des markers "obligatoires" et le script n'a pas pu activer les markers cof pour cette raison. La liste des markers manquants devrait appara\xEEtre dans la console.

        7. Console API

        -

        7.1 Généralités sur la Console

        +

        7.1 G\xE9n\xE9ralit\xE9s sur la Console

        -

        Il est recommandé quand vous jouez de garder un onglet de votre navigateur ouvert sur la Console API de votre campagne (Paramètres -> Scripts API). En cas d'absence de réponse du jeu il vous permet de facilement prendre connaissance d'une éventuelle erreur et de prendre rapidement les actions correctives nécessaires.

        -

        Un message bloquant est écrit dans un bloc rouge en dehors de la fenêtre API Output Console et ressemble à l'image suivante :

        +

        Il est recommand\xE9 quand vous jouez de garder un onglet de votre navigateur ouvert sur la Console API de votre campagne (Param\xE8tres -> Scripts API). En cas d'absence de r\xE9ponse du jeu il vous permet de facilement prendre connaissance d'une \xE9ventuelle erreur et de prendre rapidement les actions correctives n\xE9cessaires.

        +

        Un message bloquant est \xE9crit dans un bloc rouge en dehors de la fen\xEAtre API Output Console et ressemble \xE0 l'image suivante :

        -

        Lorsqu'un message rouge comme celui-ci interrompt votre partie vérifiez s'il possède une solution identifiée dans le paragraphe ci-dessous. "Restart API sandbox" permet de relancer le script mais les mêmes causes provoqueront la même erreur. Si le message d'erreur n'est pas encore référencé ou ne propose pas de solution, essayez de comprendre quelle est votre dernière action ou quel bouton provoque cette erreur et terminez votre séance en évitant de l'utiliser. Retestez plus tard et si l'erreur se reproduit expliquez-nous votre problème sur ce post dans le forum BBE. Essayez d'être le plus exhaustif possible dans vos explications car malheureusement les messages de Roll20 ne sont pas précis du tout quant au contexte de l'erreur. Par exemple le numéro de la ligne de code incriminée ne nous est pas connue et l'on a donc besoin de toutes les précisions possibles pour comprendre le problème et être en capacité de le reproduire afin de le corriger.

        -

        Les messages qui sont à l'interieur de la fenêtre API Output Console sont des messages d'information ou d'alerte comme sur l'image suivante :

        +

        Lorsqu'un message rouge comme celui-ci interrompt votre partie v\xE9rifiez s'il poss\xE8de une solution identifi\xE9e dans le paragraphe ci-dessous. "Restart API sandbox" permet de relancer le script mais les m\xEAmes causes provoqueront la m\xEAme erreur. Si le message d'erreur n'est pas encore r\xE9f\xE9renc\xE9 ou ne propose pas de solution, essayez de comprendre quelle est votre derni\xE8re action ou quel bouton provoque cette erreur et terminez votre s\xE9ance en \xE9vitant de l'utiliser. Retestez plus tard et si l'erreur se reproduit expliquez-nous votre probl\xE8me sur ce post dans le forum BBE. Essayez d'\xEAtre le plus exhaustif possible dans vos explications car malheureusement les messages de Roll20 ne sont pas pr\xE9cis du tout quant au contexte de l'erreur. Par exemple le num\xE9ro de la ligne de code incrimin\xE9e ne nous est pas connue et l'on a donc besoin de toutes les pr\xE9cisions possibles pour comprendre le probl\xE8me et \xEAtre en capacit\xE9 de le reproduire afin de le corriger.

        +

        Les messages qui sont \xE0 l'interieur de la fen\xEAtre API Output Console sont des messages d'information ou d'alerte comme sur l'image suivante :

        -

        Malgré la gravité apparente de certains de ces messages (SyntaxError) ils n'empêchent jamais le bon fonctionnement du script. Seuls les messages bloquants apparaissants en rouge empêche le bon fonctionnement du script. Nous n'avons pas complétement la main sur l'apparition de ces messages d'alerte et nous travaillons activement avec Roll20 pour les éliminer. Des messages d'informations sont aussi présents comme par exemple le numéro de version du script que vous utilisez actuellement.

        +

        Malgr\xE9 la gravit\xE9 apparente de certains de ces messages (SyntaxError) ils n'emp\xEAchent jamais le bon fonctionnement du script. Seuls les messages bloquants apparaissants en rouge emp\xEAche le bon fonctionnement du script. Nous n'avons pas compl\xE9tement la main sur l'apparition de ces messages d'alerte et nous travaillons activement avec Roll20 pour les \xE9liminer. Des messages d'informations sont aussi pr\xE9sents comme par exemple le num\xE9ro de version du script que vous utilisez actuellement.

        7.2 Principaux messages bloquants

          -
        • There was an error communicating with the QuantumRoll server Erreur Roll20 courante. "Restart API Sandbox" règle normalement ce problème.
        • -
        • docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host? Erreur Roll20. "Restart API Sandbox" règle normalement ce problème.
        • -
        • SyntaxError: Invalid or unexpected token ... Erreur dans le code. Pas de solution évidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • -
        • SyntaxError: Unexpected token ... Erreur dans le code. Pas de solution évidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • -
        • TypeError: Cannot read property '...' of undefined Erreur dans le code. Pas de solution évidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • +
        • There was an error communicating with the QuantumRoll server Erreur Roll20 courante. "Restart API Sandbox" r\xE8gle normalement ce probl\xE8me.
        • +
        • docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host? Erreur Roll20. "Restart API Sandbox" r\xE8gle normalement ce probl\xE8me.
        • +
        • SyntaxError: Invalid or unexpected token ... Erreur dans le code. Pas de solution \xE9vidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • +
        • SyntaxError: Unexpected token ... Erreur dans le code. Pas de solution \xE9vidente. Le signaler uniquement si c'est un message bloquant (rouge).
        • +
        • TypeError: Cannot read property '...' of undefined Erreur dans le code. Pas de solution \xE9vidente. Le signaler uniquement si c'est un message bloquant (rouge).

        7.3 Principaux messages d'information et d'alerte

          -
        • COFantasy X.XX loaded Information : Le script a correctement démarré. Vous indique le numéro de version utilisé.
        • -
        • Markers personnalisés activés Information : Succès de l'activation des Markers Personnalisés.
        • +
        • COFantasy X.XX loaded Information : Le script a correctement d\xE9marr\xE9. Vous indique le num\xE9ro de version utilis\xE9.
        • +
        • Markers personnalis\xE9s activ\xE9s Information : Succ\xE8s de l'activation des Markers Personnalis\xE9s.
        • API sandbox shutdown due to campaign inactivity Information : "Restart API Sandbox" ou l'utilisation de la campagne remet en route la sandbox.
        • -
        • XXX dans l'équipe XXX est inconnu Alerte : Erreur dans le handout servant de sélection d'équipe. Vérifiez l'orthographe de vos personnages.
        • -
        • Markers personnalisés manquants -> Retour aux markers standards Roll20. Voir erreur(s) ci-dessus. Alerte : Impossibilité d'activer les Markers Personnalisés pour cause d'un marker obligatoire absent.
        • -
        • Marker cof-XXX introuvable Alerte : Erreur dans le nom d'un marker. Voir Markers Personnalisés ou liste des états.
        • -
        • Compétences sans caractéristique associéeAlerte : Erreur de déclaration dans le handout de jets de caractéristique.
        • +
        • XXX dans l'\xE9quipe XXX est inconnu Alerte : Erreur dans le handout servant de s\xE9lection d'\xE9quipe. V\xE9rifiez l'orthographe de vos personnages.
        • +
        • Markers personnalis\xE9s manquants -> Retour aux markers standards Roll20. Voir erreur(s) ci-dessus. Alerte : Impossibilit\xE9 d'activer les Markers Personnalis\xE9s pour cause d'un marker obligatoire absent.
        • +
        • Marker cof-XXX introuvable Alerte : Erreur dans le nom d'un marker. Voir Markers Personnalis\xE9s ou liste des \xE9tats.
        • +
        • Comp\xE9tences sans caract\xE9ristique associ\xE9eAlerte : Erreur de d\xE9claration dans le handout de jets de caract\xE9ristique.
        +

        7.4 Purger les variables d'\xE9tat du jeu

        +
        +

        Pour son bon fonctionnement, le script stoque des donn\xE9es, parfois complexes, et il peut arriver que ces donn\xE9es soient corrompues. Dans ce cas, le script peut planter de mani\xE8re syst\xE9matique, m\xEAme sur des actions simples. Si vous soup\xE7onnez une corruption des donn\xE9es, vous pouvez tenter de lancer la commande !cof-clean-global-state. +

        +

        8. Utiliser des personnages Pathfinder

        -

        Il existe un support basique des fiches Roll20 venant du système Pathfinder 1. La fonction !cof-pathfinder1 se lance en sélectionnant un ou plusieurs tokens liés à des fiches Pathfinder (par exemple obtenues en achetant des aventures Pathfinder sur le marketplace de Roll20). L'effet est d'une part de transformer une partie des attributs de la fiche en attributs compris par la fiche COF et le script COFantasy, de changer un peu le token associé à la fiche, mais surtout d'effacer les attributs inutiles pour COF. En effet, le script est relativement sensible au nombre total d'attributs en jeu, et les fiches Pathfinder ont tendence à en avoir vraiment beaucoup. Tout ce qui n'est pas compris par le script se retrouve dans un attribut Attributs Pathfinder. Mais le mieux est de compléter la fiche COF en se basant sur la fiche Pathfinder ouverte dans une autre partie.

        +

        Il existe un support basique des fiches Roll20 venant du syst\xE8me Pathfinder 1. La fonction !cof-pathfinder1 se lance en s\xE9lectionnant un ou plusieurs tokens li\xE9s \xE0 des fiches Pathfinder (par exemple obtenues en achetant des aventures Pathfinder sur le marketplace de Roll20). L'effet est d'une part de transformer une partie des attributs de la fiche en attributs compris par la fiche COF et le script COFantasy, de changer un peu le token associ\xE9 \xE0 la fiche, mais surtout d'effacer les attributs inutiles pour COF. En effet, le script est relativement sensible au nombre total d'attributs en jeu, et les fiches Pathfinder ont tendence \xE0 en avoir vraiment beaucoup. Tout ce qui n'est pas compris par le script se retrouve dans un attribut Attributs Pathfinder. Mais le mieux est de compl\xE9ter la fiche COF en se basant sur la fiche Pathfinder ouverte dans une autre partie.

        9. Statistiques

        Il est possible d'activer la collecte de statistiques en utilisant la commande !cof-demarrer-statistiques.

        -

        On peut arrêter la collecte avec !cof-arreter-statistiques, et la mettre en pause avec !cof-pause-statistiques.
        - Si on redémarre après une mise en pause, on reprend les statistiques comme elles étaient au moment de la pause. Si on redémarre des statistiques en court, cela remet les statistiques à zéro. +

        On peut arr\xEAter la collecte avec !cof-arreter-statistiques, et la mettre en pause avec !cof-pause-statistiques.
        + Si on red\xE9marre apr\xE8s une mise en pause, on reprend les statistiques comme elles \xE9taient au moment de la pause. Si on red\xE9marre des statistiques en court, cela remet les statistiques \xE0 z\xE9ro.

    -

    Ce site utilise des marques déposées et des droits d’auteurs qui sont la propriété de Black Book Editions comme l’y autorisent les conditions d’utilisation de Black Book Editions. Ce site n’est pas publié par Black Book Editions et n’a pas reçu son aval ni une quelconque approbation de sa part. Pour de plus amples informations sur Black Book Editions, consultez www.black-book-editions.fr.

    +

    Ce site utilise des marques d\xE9pos\xE9es et des droits d\x2019auteurs qui sont la propri\xE9t\xE9 de Black Book Editions comme l\x2019y autorisent les conditions d\x2019utilisation de Black Book Editions. Ce site n\x2019est pas publi\xE9 par Black Book Editions et n\x2019a pas re\xE7u son aval ni une quelconque approbation de sa part. Pour de plus amples informations sur Black Book Editions, consultez www.black-book-editions.fr.