diff --git a/ChroniquesGalactiques/ReadMe.md b/ChroniquesGalactiques/ReadMe.md index beb811e03c..4d31085149 100644 --- a/ChroniquesGalactiques/ReadMe.md +++ b/ChroniquesGalactiques/ReadMe.md @@ -9,9 +9,29 @@ Cette feuilles de personnage inclue quelques jets et règles optionnelles. Le jeu complet est paru dans le magazine [Casus Belli](http://www.black-book-editions.fr/catalogue.php?id=207) #17,18 et 19. # Version courante -3.5 [Screenshot](cog_v3.png) +3.6 [Screenshot](cog_v3.png) # Notes de version +## V3.6 (2019-04-17) +### Fiche de PJ + +* Possibilité d'appliquer plusieurs états préjudiciables en même temps +* Gestion de l'encombrement (idem COF) +* Ajout d'un champ de texte sous la liste d'attaques pour les buffs "temporaires" + * Possibilité d'indiquer des buffs aux jets d'attaque et de dommages en langage quasi-naturel : le premier mot est le type d'attaque concernée, le deuxième est le modificateur (avec possibilité de référencer un autre attribut de la fiche en l'encadrant entre crochets []) et à partir du troisième, la description du buff. + * Indiquer ATC (contact), ATD (distance), INT (PSY Intuition), INF (PSY Influence), pour les types d'attaques, ATT pour toutes les attaques existantes. Indiquer d'abord DM pour un buff aux dommages + * Plusieurs buffs peuvent être indiqués et séparés par un point-virgule (;) + * Exemple : `DM ATC +2d6 Attaque en traître ; ATD +[PER] Visée` + * Il est nécessaire de cliquer en dehors du champ de saisie AVANT de presser un bouton d'attaque afin que le script sheet-worker approprié puisse s'exécuter. +* Ajout d'un bouton "Recycle" sur l'onglet Configuration pour forcer la fiche à recalculer quelques attributs (rangs atteints dans chaque voie, statbloc interne, encombrement) + +### Fiche de PNJ + +* Ajout Défense PSY +* Ajout d'une liste de capacités / traits +* Amélioration du script d'import de statblock +* Ajout d'un script de conversion d'attributs PNJ => PJ + ## V3.5 (2019-02-11) ### Remplacement des 5 champs de buffs par un champ unique * Un nombre quasi illimité de buffs est désormais possible pour chaque attribut diff --git a/ChroniquesGalactiques/cog.css b/ChroniquesGalactiques/cog.css index 5f47281ee2..d04e17e15e 100644 --- a/ChroniquesGalactiques/cog.css +++ b/ChroniquesGalactiques/cog.css @@ -195,6 +195,20 @@ button[type="action"].sheet-boxtitre:hover { border-radius: 2px; background-color:#7F989D; } +button[type="action"].sheet-iconbtn { + border: 0px; + background-color: transparent; + font-family: pictos; + font-size: large; +} + + img.sheet-iconimg { + width: 16px; +} + + img.sheet-iconimg:hover { + width: 32px; +} input, select{ border: none; box-shadow: none; diff --git a/ChroniquesGalactiques/cog.htm b/ChroniquesGalactiques/cog.htm index 719923565b..41743aea5b 100644 --- a/ChroniquesGalactiques/cog.htm +++ b/ChroniquesGalactiques/cog.htm @@ -1,8 +1,8 @@
- - + + @@ -10,6 +10,10 @@ + + + + @@ -35,6 +39,7 @@ + @@ -60,14 +65,19 @@ + + + + + -
+
- +
@@ -162,9 +172,9 @@ @@ -243,17 +253,31 @@
- Autres conditions :  - + + + + + + + + +
@@ -480,12 +504,12 @@ - + - +
ARMES / ATTAQUESARMES / ATTAQUES ATTAQUE CRIT. DM PORTÉESPÉCIALSPÉCIAL
@@ -495,7 +519,7 @@ - - - - + + +
- @@ -508,6 +532,7 @@ + + @@ -551,6 +576,7 @@ + + @@ -603,19 +629,12 @@  
Bonus visée (L) :  -  Attaque  -  DM  + +  Distance :  - -  
@@ -869,13 +888,16 @@
ÉQUIPEMENT : Consommables
Crédits :  - + + + /
- -  Qté - +   + + Qté +
@@ -936,8 +958,13 @@ - - + + Encombrement  + + + + +
@@ -1650,9 +1677,10 @@
-
DEF
+
DEF / DEP
- +  / +
@@ -1665,7 +1693,7 @@
- Capacités + Divers
@@ -1741,6 +1769,28 @@
 
+
+
+ Capacités +
+
+ + + + + + +
+ + + + +
+
+
+
 
+
Importer statblock
@@ -1931,7 +1981,7 @@ console.log(l); console.log('** CO sheetworker' + m + ' >>>'); } - + // C# String.Format() emulation function stringFormat(s) { var s = arguments[0]; @@ -1940,23 +1990,56 @@ } return s; } - + + function addTrait(npcObj, traitObj) { + if (traitObj['nom'] !== '' && traitObj['desc'] !== '') { + if (!npcObj['Capas']) npcObj['Capas'] = []; + npcObj['Capas'].push(`${traitObj['nom']}~${traitObj['desc']}`); + traitObj['nom'] = ''; + traitObj['desc'] = ''; + } + } + function importStatblock(text) { text = text.replace(/\r/g, ''); text = text.replace(/ \(DM/g, ' DM'); text = text.replace(/ \(RD/g, ' RD'); text = text.replace(/\, /g, ' '); + text = text.replace(/\n[ ]*\+/g,'+'); var npc = {}; var rows = text.split(/\n/); + var capacites = false; + var capacite = { 'nom': '', 'desc': '' }; console.log('** CO sheetworker : parsing text <<<'); - rows.forEach(function(row) { + rows.forEach(function(row, rownr) { console.log(row); - if (row.toUpperCase().indexOf('DM') != -1) { // this is an attack line + if (rownr === 0 && row.toUpperCase().indexOf('NC') === -1) { + npc['character_name'] = row.trim(); // assume first line is name + return; + } + if (!capacites && row.toUpperCase().indexOf('DM') !== -1) { // this is an attack line row = row.replace(/\)$/g, ''); // handle CG statblocks if (!npc.Atks) npc.Atks = []; npc.Atks.push(row); return; } + if (capacites) { // start parsing traits + let s = row.indexOf(':'); + if (s !== -1) { + addTrait(npc, capacite); + capacite['nom'] = row.substring(0, s - 1).trim(); + if (capacite['nom'].indexOf(' RD') !== -1) capacite['nom'] = capacite['nom'].replace(' RD', ' (RD'); + capacite['desc'] = row.substring(s + 1).trim(); + } else { + capacite['desc'] += ' ' + row.trim(); + } + return; + } + if (row.trim().startsWith('---')) { + if (capacites) addTrait(npc, capacite); + capacites = !capacites; + return; + } row = row.replace(/ \(/g, '('); // strip space before '( row = row.replace(/très /g, 'très~'); // handle 'très petite' size row = row.replace(/créature /g, 'PROFIL créature~'); // handle 'créature' mention @@ -1964,12 +2047,18 @@ for (var item = 0; item < items.length-1; item++) { if (item % 2 === 0) { var k = items[item].toUpperCase().replace(/\./g, ''); - var v = items[item + 1].replace(/~/g, ' '); - if (v.charAt(v.length - 1) == ')' && v.charAt(0) != '(') v = v.substring(0, v.length - 1); + var v = items[item + 1]; + if (v) { + v.replace(/~/g, ' '); + if (v.charAt(v.length - 1) === ')' && v.charAt(0) !== '(') v = v.substring(0, v.length - 1); + } else { + v = ''; + } npc[k] = v; } } }); + if (capacites) addTrait(npc, capacite); console.log('** CO sheetworker : parsing text >>>'); return npc; } @@ -2006,6 +2095,8 @@ var jnor = '1d20'; var jsup = '2d20kh1'; var pnjAttrs = {}; + if (pnjObj.hasOwnProperty('character_name')) pnjAttrs['character_name'] = pnjObj.character_name; + delete pnjObj['character_name']; pnjAttrs.NIVEAU = parseInt(pnjObj.NC) || 0; delete pnjObj.NC; pnjAttrs.TAILLE = pnjObj.TAILLE || ''; @@ -2035,6 +2126,10 @@ delete pnjObj.INIT; pnjAttrs.pnj_def = parseInt(pnjObj.DEF); delete pnjObj.DEF; + if (pnjObj.hasOwnProperty('DEP')) { + pnjAttrs.pnj_dep = parseInt(pnjObj.DEP); + delete pnjObj.DEP; + } pnjAttrs.pnj_pv = parseInt(pnjObj.PV); pnjAttrs.pnj_pv_max = parseInt(pnjObj.PV); delete pnjObj.PV; @@ -2078,7 +2173,7 @@ parsed += atkItems[item]; } consoleLog(atkNom + ' ' + atkBonus + ' ' + atkDM + ' ' + atkSpec); - if (atkBonus == -1) atkAtt = ''; // No attack bonus found, damage only + if (atkBonus == -1) atkAtt = '0'; // No attack bonus found, damage only var atkDmg = 'degats='; var atkNbDe = 0; var atkDe = ''; @@ -2089,7 +2184,7 @@ atkDM = atkDM.replace('-', '|-'); var dm = atkDM.split('|'); atkNbDe = parseInt(dm[0]) || 0; - if (atkNbDe == 0) atkDmg = ''; // No damage dice, attack only + if (atkNbDe == 0) atkDmg = '0'; // No damage dice, attack only atkDe = dm[1]; if (universe === 'COC') atkDe += '!'; atkBonusDM = parseInt(dm[2]) || 0; @@ -2112,12 +2207,65 @@ consoleLog(atkRow, 'adding attack'); setAttrs(atkRow); } else { - result = 'Err: impossible d\'analyser le contenu de "' + pnjObj.Atks[atk] + '"'; + result += (result.length > 0 ? '\n' : '') + 'Err: impossible d\'analyser le contenu de "' + pnjObj.Atks[atk] + '"'; + } + } + for (let attr of ['ATP(PER)', 'ATP(CHA)']) { + if (pnjObj.hasOwnProperty(attr)) { + newRowID = generateRowID(); + let atkRow = {}; + atkRow[`repeating_pnjatk_${newRowID}_atkatt`] = atkAtt; + if (attr === 'ATP(PER)') { + atkRow[`repeating_pnjatk_${newRowID}_atknom`] = 'Psy Intuition'; + } else if (attr === 'ATP(CHA)') { + atkRow[`repeating_pnjatk_${newRowID}_atknom`] = 'Psy Influence'; + } else { + continue; + } + atkRow[`repeating_pnjatk_${newRowID}_atkjet`] = '1d20'; + atkRow[`repeating_pnjatk_${newRowID}_atkbonus`] = parseInt(pnjObj[attr]); + atkRow[`repeating_pnjatk_${newRowID}_atkcrit`] = '20'; + atkRow[`repeating_pnjatk_${newRowID}_atkdmg`] = '0'; + atkRow[`repeating_pnjatk_${newRowID}_atkdmnbde`] = 0; + atkRow[`repeating_pnjatk_${newRowID}_atkdmde`] = ''; + atkRow[`repeating_pnjatk_${newRowID}_atkdmbonus`] = 0; + consoleLog(atkRow, 'adding attack'); + setAttrs(atkRow); + delete pnjObj[attr]; } } return result; } - + + function processTraits(universe, pnjObj) { + let result = ''; + for (let capa of pnjObj['Capas']) { + let capacite = capa.split('~') + if (capacite.length == 2) { + let name = capacite[0] || ''; + let desc = capacite[1] || ''; + if (name !== '' && desc !== '') { + newRowID = generateRowID(); + let capaRow = {}; + capaRow[`repeating_pnjcapas_${newRowID}_capanom`] = name; + desc = desc.replace(/\d+d\d+[+-]*\d*/g, '{{$&}}'); // search for d+/- + desc = desc.replace(/\[\d+d\d+[+-]*\d*\]/g, '{$&}'); // search for [d+/-] + desc = desc.replace(/\[{{/g, '[['); + desc = desc.replace(/}}\]/g, ']]'); + desc = desc.replace(/{{/g, '[['); + desc = desc.replace(/}}/g, ']]'); + capaRow[`repeating_pnjcapas_${newRowID}_capadesc`] = desc; + consoleLog(capaRow, 'adding trait'); + setAttrs(capaRow); + } + } else { + result += (result.length > 0 ? '\n' : '') + 'Err: impossible d\'analyser le contenu de "' + capacite + '"'; + } + } + + return result; + } + function buildCaracs() { getAttrs([ 'FORCE', 'DEXTERITE', 'CONSTITUTION', 'INTELLIGENCE', 'PERCEPTION', 'CHARISME', 'NIVEAU', @@ -2154,7 +2302,7 @@ }); }); } - + on('sheet:opened', function() { // **** Gestion transition de version getAttrs(["VERSION"], function(values) { @@ -2376,13 +2524,13 @@ } } }); - // MAJ Version - getAttrs(['verfdp'], function(values) { - setAttrs({ VERSION: values.verfdp }); - }); - // LAST_PV - getAttrs(['PV'], function(values) { - setAttrs({ LAST_PV: values.PV }) + // MAJ Version, LAST_PV, message + getAttrs(['verfdp', 'PV'], function(values) { + setAttrs({ + VERSION: values.verfdp, + LAST_PV: values.PV, + INFOMSG: ' ' + }); }); // ARMURE_MALUS getAttrs(['ARMURE_MALUS'], function(value) { @@ -2392,6 +2540,17 @@ for (let voie=1; voie <= 9; voie++) { setRank(voie.toString()); } + // seuil_enc (if needed) + getAttrs(['seuil_enc', 'FORCE'], function(values) { + let seuil_enc = parseInt(values.seuil_enc) || 0; + if (seuil_enc === 0) { + setAttrs({ + seuil_enc: parseInt(values.FORCE) || 0 + }); + } + }); + // encombrement (refresh) + encumbrance(); // CARACS buildCaracs(); }); @@ -2418,6 +2577,7 @@ bm *= 2; } v = v.replace(/[\+\-\[\]]/g, ''); + consoleLog(v); if (isNaN(v)) { // c'est une référence d'attribut if (v.toUpperCase().startsWith('VOIE')) { @@ -2468,6 +2628,7 @@ buffName = buffv[0].trim(); buffVal = buffValue(buffv[1], caracs); } + consoleLog(buffName); if (!buffName.startsWith('-')) buffSum += buffVal; } } @@ -2654,63 +2815,6 @@ }); }); - on('change:condition', function() { - getAttrs(['PCONDITION', 'CONDITION', 'ATKCAC_BUFF', 'ATKTIR_BUFF', 'INIT_BUFF', 'DEF_BUFF', 'ETATDE'], function(values) { - // setup helper objects - const conditions = { // condition names data object - 'aucune': '', - 'aveugle': 'A', - 'etourdi': 'E', - 'effraye': 'F', - 'immobilise': 'I', - 'panique': 'P', - 'renverse': 'R', - 'surpris': 'S' - } - const buffs = { // buffs values data object - '': { 'atc': 0, 'atd': 0, 'def': 0, 'init': 0 }, - 'A': { 'atc': 5, 'atd': 10, 'def': 5, 'init': 5 }, - 'E': { 'atc': 0, 'atd': 0, 'def': 5, 'init': 0 }, - 'F': { 'atc': 5, 'atd': 5, 'def': 0, 'init': 0 }, - 'I': { 'atc': 0, 'atd': 0, 'def': 0, 'init': 0 }, - 'P': { 'atc': 0, 'atd': 0, 'def': 2, 'init': 0 }, - 'R': { 'atc': 5, 'atd': 5, 'def': 5, 'init': 0 }, - 'S': { 'atc': 0, 'atd': 0, 'def': 5, 'init': 0 } - } - // check prior condition for die roll - let etatde = values.ETATDE; - switch (values.PCONDITION) { - case conditions.immobilise: - etatde = '20'; - break; - case conditions.panique: - etatde = '20'; - break; - } - // check condition for die roll - switch (values.CONDITION) { - case conditions.immobilise: - etatde = '12'; - break; - case conditions.panique: - etatde = '12'; - break; - case conditions.aucune: - etatde = '20'; - break; - } - // Now update all buffs and prior condition - setAttrs({ - ATKCAC_BUFF: values.ATKCAC_BUFF + buffs[values.PCONDITION].atc - buffs[values.CONDITION].atc, - ATKTIR_BUFF: values.ATKTIR_BUFF + buffs[values.PCONDITION].atd - buffs[values.CONDITION].atd, - INIT_BUFF: values.INIT_BUFF + buffs[values.PCONDITION].init - buffs[values.CONDITION].init, - DEF_BUFF: values.DEF_BUFF + buffs[values.PCONDITION].def - buffs[values.CONDITION].def, - ETATDE: etatde, - PCONDITION: values.CONDITION - }); - }); - }); - on('change:blessure', function() { getAttrs(['BLESSURE'], function(values) { var etatde = (values.BLESSURE == '1') ? '12' : '20'; @@ -2730,7 +2834,11 @@ JETNORMAL: jetn, JETSUP: jets, JETSUPHERO: jetsh, - JETRISQUE: jetr + JETRISQUE: jetr, + JDEX: jetn, + JDEXSUP: jets, + JDEXSUPHERO: jetsh, + JDEXRISQUE: jetr }); }); }); @@ -2749,6 +2857,12 @@ messages += result; delete pnjObj.Atks; } + if (pnjObj.hasOwnProperty('Capas')) { + result = processTraits(values.UNIVERS, pnjObj); + if (result != '' && messages != '') result = '\n' + result; + messages += result; + delete pnjObj['Capas']; + } // Other attributes go to DIVERS field var divers = ''; var otherAttrs = Object.keys(pnjObj); @@ -2766,14 +2880,127 @@ } }); }); - - on('change:type_personnage', function() { - getAttrs(['type_personnage'], function(values) { + + const npcAtkAttribs = [ + 'atkatt', + 'atknom', + 'atkjet', + 'atkbonus', + 'atkcrit', + 'atkdmg', + 'atkdmnbde', + 'atkdmde', + 'atkdmbonus', + 'atkportee', + 'atkspec' + ] + + function convertToPC() { + getAttrs([ + 'pnj_for', 'pnj_dex', 'pnj_con', 'pnj_int', 'pnj_per', 'pnj_cha', + 'pnj_jetfor', 'pnj_jetdex', 'pnj_jetcon', 'pnj_jetint', 'pnj_jetper', 'pnj_jetcha', + 'pnj_init', 'pnj_def', 'pnj_dep', 'pnj_pv', 'pnj_pv_max' + ], function(values) { let attrs = {}; - attrs['type_fiche'] = values.type_personnage; - if (values.type_personnage === 'pnj') attrs['pnj_togm'] = '/w gm '; + for (let attr of ['FORCE', 'DEXTERITE', 'CONSTITUTION', 'INTELLIGENCE', 'PERCEPTION', 'CHARISME']) { + let attrv = parseInt(values[`pnj_${attr.substring(0,3).toLowerCase()}`]) || 0; + attrs[attr] = 10 + (2 * attrv); + if (attr === 'DEXTERITE') { + let init = parseInt(values.pnj_init) || 0; + if (init === attrv + 1) { + attrs[attr]++; + } else { + attrs['INIT_BUFF_LIST'] = 'Bonus Init.'; + attrs['INIT_BUFF'] = init - attrs[attr]; + } + let defb = 10 + attrv; + let def = parseInt(values.pnj_def) || 0; + if (def !== defb) { + attrs['DEF_BUFF_LIST'] = 'Bonus DEF'; + attrs['DEF_BUFF'] = def - defb; + } + attrs['DEX_SUP'] = (values['pnj_jetdex'] === '2d20kh1') ? '@{JDEXSUP}' : '@{JDEX}'; + } else if (attr === 'CHARISME') { + let depb = 10 + attrv; + let dep = parseInt(values.pnj_dep) || 0; + if (dep !== depb) { + attrs['DEP_BUFF_LIST'] = 'Bonus DEP'; + attrs['DEP_BUFF'] = dep - depb; + } + } else { + attrs[`${attr.substring(0,3)}_SUP`] = (values[`pnj_jet${attr.substring(0,3).toLowerCase()}`] === '2d20kh1') ? '@{JETSUP}' : '@{JETNORMAL}'; + } + } + attrs['PV'] = parseInt(values.pnj_pv) || 0; + attrs['PV_max'] = parseInt(values.pnj_pv_max) || 0; + getSectionIDs('repeating_armes', function(ids) { + for (let id of ids) { + removeRepeatingRow(`repeating_armes_${id}`); + } + }); + getSectionIDs('repeating_pnjatk', function(ids) { + for (let id of ids) { + getAttrs([...npcAtkAttribs.map(attr => `repeating_pnjatk_${id}_${attr}`), 'pnj_for', 'pnj_dex', 'pnj_cha'], function(values) { + consoleLog(values); + let v = {}; + for (let attr of npcAtkAttribs) { + v[attr] = values[`repeating_pnjatk_${id}_${attr}`] || ''; + } + newRowID = generateRowID(); + let atkRow = {}; + atkRow[`repeating_armes_${newRowID}_armeatt`] = v['atkatt']; + atkRow[`repeating_armes_${newRowID}_armenom`] = v['atknom']; + let psyint = v['atknom'].toLowerCase().includes('psy intuition'); + let psyinf = v['atknom'].toLowerCase().includes('psy influence'); + let tohit = parseInt(v['atkbonus']) || 0; + let atk = 0; + let bdm = 0; + if (v['atkportee'] && v['atkportee'] !== '') { + atk = values.pnj_dex || 0; + if (psyint) atk = values.pnj_int || 0; + if (psyinf) atk = values.pnj_cha || 0; + atkRow[`repeating_armes_${newRowID}_armeatk`] = '@{ATKTIR}'; + if (psyint) atkRow[`repeating_armes_${newRowID}_armeatk`] = '@{ATKPSYINTUI}'; + if (psyinf) atkRow[`repeating_armes_${newRowID}_armeatk`] = '@{ATKPSYINFLU}'; + atkRow[`repeating_armes_${newRowID}_armedmcar`] = '0'; + } else { + atk = values.pnj_for || 0; + if (psyint) atk = values.pnj_int || 0; + if (psyinf) atk = values.pnj_cha || 0; + bdm = (psyint || psyinf) ? 0 : atk; + atkRow[`repeating_armes_${newRowID}_armeatk`] = '@{ATKCAC}'; + if (psyint) atkRow[`repeating_armes_${newRowID}_armeatk`] = '@{ATKPSYINTUI}'; + if (psyinf) atkRow[`repeating_armes_${newRowID}_armeatk`] = '@{ATKPSYINFLU}'; + atkRow[`repeating_armes_${newRowID}_armedmcar`] = (psyint || psyinf) ? '0' : '@{FOR}'; + } + if (tohit !== atk) atkRow[`repeating_armes_${newRowID}_armeatkdiv`] = tohit - atk; + atkRow[`repeating_armes_${newRowID}_armejetd`] = v['atkjet']; + atkRow[`repeating_armes_${newRowID}_armecrit`] = v['atkcrit']; + atkRow[`repeating_armes_${newRowID}_armedmg`] = v['atkdmg']; + atkRow[`repeating_armes_${newRowID}_armedmnbde`] = v['atkdmnbde']; + atkRow[`repeating_armes_${newRowID}_armedmde`] = v['atkdmde']; + let dmdiv = parseInt(v['atkdmbonus']) || 0; + if (dmdiv !== bdm) atkRow[`repeating_armes_${newRowID}_armedmdiv`] = dmdiv - bdm; + atkRow[`repeating_armes_${newRowID}_armeportee`] = v['atkportee']; + atkRow[`repeating_armes_${newRowID}_armespec`] = v['atkspec']; + setAttrs(atkRow); + }); + } + }); setAttrs(attrs); }); + } + + on('change:type_personnage', function(eventInfo) { + if (eventInfo.previousValue === 'pnj' && eventInfo.newValue === 'pj') convertToPC(); + // if (eventInfo.previousValue === 'pj' && eventInfo.newValue === 'pnj') convertToNPC(); + getAttrs(['type_personnage'], function(value) { + let attrs = {}; + attrs['type_fiche'] = value.type_personnage; + if (value.type_personnage === 'pnj') attrs['pnj_togm'] = '/w gm '; + setAttrs(attrs); + consoleLog(attrs); + }); }); on('change:pv', function() { @@ -2856,7 +3083,7 @@ }); function changeRanks(voie) { - return `change:voie${voie}-1 change:voie${voie}-2 change:voie${voie}-3 change:voie${voie}-4 change:voie${voie}-5`; + return `change:voie${voie}nom change:voie${voie}-1 change:voie${voie}-2 change:voie${voie}-3 change:voie${voie}-4 change:voie${voie}-5`; } function attrRanks(voie) { @@ -2921,7 +3148,9 @@ getAttrs(['DEFARMUREON', 'DEFARMUREMALUS'], function(values) { let armure_on = values.DEFARMUREON || 0; let armure_malus = values.DEFARMUREMALUS || 0; - setAttrs({ ARMURE_MALUS: armure_on * armure_malus }); + setAttrs({ + ARMURE_MALUS: armure_on * armure_malus + }); }); } @@ -2936,7 +3165,9 @@ let dmg2 = ''; if (dm2_desc !== '') dm2_desc = `[${dm2_desc}] `; if (dm2_de !== '') dmg2 = `[[${dm2_de}${dm2_desc}]]`; - setAttrs({ repeating_armes_armedmg2: dmg2 }); + setAttrs({ + repeating_armes_armedmg2: dmg2 + }); }); }); @@ -2953,7 +3184,7 @@ let portees = parseInt(portee) || 0; if (portees !== 0) { setAttrs({ - repeating_armes_armeportees: `${portees}${um} / ${portees*2}${um} / ${portees*3}${um}` + repeating_armes_armeportees: `${portees}m | ${portees*2}m (DM/2) | ${portees*3}m (DM/3)` }); } }); @@ -2965,15 +3196,362 @@ on('change:repeating_armes:arme_al', function() { getAttrs(['repeating_armes_arme_al'], function(value) { - setAttrs({ repeating_armes_armelim: actionLimitee(value) }); + setAttrs({ + repeating_armes_armelim: actionLimitee(value) + }); }); }); on('change:repeating_jetcapas:jetcapa_al', function() { getAttrs(['repeating_jetcapas_jetcapa_al'], function(value) { - setAttrs({ repeating_jetcapas_jetcapalim: actionLimitee(value) }); + setAttrs({ + repeating_jetcapas_jetcapalim: actionLimitee(value) + }); + }); + }); + + function encumbrance() { + getSectionIDs('repeating_equipement', function(ids) { + const encombrement = { + total: 0, + zeros: 0 + } + for (let id = 0; id < ids.length; id++) { + getAttrs([`repeating_equipement_${ids[id]}_equip-qte`, `repeating_equipement_${ids[id]}_equip-enc`], function(values) { + let qte = parseInt(values[Object.keys(values)[0]]) || 0; + let enc = parseInt(values[Object.keys(values)[1]]) || 0; + if (enc === 0) { + encombrement.zeros += qte; + if (encombrement.zeros >= 3) { + encombrement.total += Math.floor(encombrement.zeros / 3); + encombrement.zeros %= 3; + } + } else { + encombrement.total += qte*enc; + } + setAttrs({ + total_enc: encombrement.total + }); + }); + } + }); + } + + on('change:repeating_equipement:equip-qte change:repeating_equipement:equip-enc', function() { + encumbrance(); + }); + + on('change:total_enc', function() { + getAttrs(['use_encombrement', 'total_enc', 'seuil_enc'], function(values) { + let use_encombrement = values.use_encombrement === 1 ? true : false; + if (!use_encombrement) return; + let seuil_enc = parseInt(values.seuil_enc) || 0; + let encombrement = parseInt(values.total_enc) || 0; + if (seuil_enc > 0 && encombrement > 0) { + let cond = {}; + if (encombrement > seuil_enc * 3) { + cond.CONDITION = 'I'; // Immobilisé + } else if (encombrement > seuil_enc * 2) { + cond.CONDITION = 'L'; // Ralenti + cond.ETATDE = '12'; // +Affaibli + } else if (encombrement > seuil_enc) { + cond.CONDITION = ''; + cond.JDEX = '1d12'; + cond.JDEXSUP = '2d12kh1'; + cond.JDEXSUPHERO = '{2d12kh1, 0d12+10}kh1'; + cond.JDEXRISQUE = '2d12kl1'; + cond.ETATDE = '20'; + } else { + cond.CONDITION = ''; + cond.JDEX = '1d@{ETATDE}'; + cond.JDEXSUP = '2d@{ETATDE}kh1'; + cond.JDEXSUPHERO = '{2d@{ETATDE}kh1, 0d20+10}kh1'; + cond.JDEXRISQUE = '1d12'; + cond.ETATDE = '20'; + } + if (cond !== null) setAttrs(cond); + } }); }); + on('clicked:reset', function() { + for (let v=1; v <= 9; v++) { + setRank(v.toString()); + } + buildCaracs(); + encumbrance(); + }); + + on('change:mods_atk', function() { + let infomsg = 'Syntaxe non reconnue, corrigez SVP...'; + setAttrs({ INFOMSG: infomsg }); + getAttrs(['mods_atk', 'CARACS'], function(values) { + const aliases = { + 'attaque': 'att', + 'attaques': 'att', + 'cac': 'atc', + 'contact': 'atc', + 'cad': 'atd', + 'distance': 'atd', + 'psyinf': 'inf', + 'influ': 'inf', + 'psyint': 'int', + 'intui': 'int', + 'tir': 'atd' + }; + const modifiers = { + atc: '', + atcdm: '', + atd: '', + atddm: '', + inf: '', + infdm: '', + int: '', + intdm: '' + }; + let result = ' '; + if (values.mods_atk !== '') { + let caracs = JSON.parse(values.CARACS); + let mods = values.mods_atk.replace('\n', ';').split(';'); + for (let mod of mods) { + if (mod.trim() === '') continue; + let modv = mod.trim().split(' '); + let mod_attr = modv.shift().toLowerCase(); + let to_dm = false; + if (mod_attr === 'dm') { + to_dm = true; + mod_attr = modv.shift().toLowerCase(); + if (Object.keys(aliases).includes(mod_attr)) { + if (aliases[mod_attr] === 'att') mod_attr = 'dm'; + if (aliases[mod_attr] === 'atc') mod_attr = 'atcdm'; + if (aliases[mod_attr] === 'atd') mod_attr = 'atddm'; + if (aliases[mod_attr] === 'inf') mod_attr = 'infdm'; + if (aliases[mod_attr] === 'int') mod_attr = 'intdm'; + } else { + if (mod_attr === 'att') mod_attr = 'dm'; + if (mod_attr === 'atc') mod_attr = 'atcdm'; + if (mod_attr === 'atd') mod_attr = 'atddm'; + if (mod_attr === 'inf') mod_attr = 'infdm'; + if (mod_attr === 'int') mod_attr = 'intdm'; + } + } + let mod_sgn = '+'; + let mod_val = modv.shift(); + if (mod_val.startsWith('+') || mod_val.startsWith('-')) { + mod_sgn = mod_val.substring(0,1); + mod_val = mod_val.substring(1); + } + if (to_dm && mod_val.search(/\d+[dD]\d+/) !== -1) { + mod_val = `[[${mod_val}]]`; + } else { + mod_val = buffValue(mod_val, caracs); + if (mod_val === 0) continue; + } + let mod_desc = ` ${mod_sgn}${mod_val}[${modv.join(' ').trim()}]`; + switch (mod_attr) { + case 'atc': + case 'atcdm': + case 'atd': + case 'atddm': + case 'inf': + case 'infdm': + case 'int': + case 'intdm': + modifiers[mod_attr] += mod_desc; + break; + case 'att': + for (let attr of ['atc', 'atd', 'inf', 'int']) { + modifiers[attr] += mod_desc; + } + break; + case 'dm': + for (let attr of ['atcdm', 'atddm', 'infdm', 'intdm']) { + modifiers[attr] += mod_desc; + } + default: + if (Object.keys(aliases).includes(mod_attr)) { + modifiers[aliases[mod_attr]] += mod_desc; + result = ' '; + } else { + result = infomsg; + } + break; + } + } + } + getSectionIDs('repeating_armes', function(ids) { + for (const id of ids) { + getAttrs([`repeating_armes_${id}_armeatk`, `repeating_armes_${id}_armeportee`], function(values) { + let type = values[Object.keys(values)[0]] || ''; + let portee = values[Object.keys(values)[1]] || ''; + let attr = {}; + if (type === '@{ATKCAC}' || (type === '@{ATKTIR}' && portee === '')) { + attr[`repeating_armes_${id}_armebuff`] = modifiers.atc.trim(); + attr[`repeating_armes_${id}_armebuffdm`] = modifiers.atcdm.trim(); + } else if (type === '@{ATKTIR}') { + attr[`repeating_armes_${id}_armebuff`] = modifiers.atd.trim(); + attr[`repeating_armes_${id}_armebuffdm`] = modifiers.atddm.trim(); + } else if (type === '@{ATKPSYINFLU}') { + attr[`repeating_armes_${id}_armebuff`] = modifiers.inf.trim(); + attr[`repeating_armes_${id}_armebuffdm`] = modifiers.infdm.trim(); + } else if (type === '@{ATKPSYINTUI}') { + attr[`repeating_armes_${id}_armebuff`] = modifiers.int.trim(); + attr[`repeating_armes_${id}_armebuffdm`] = modifiers.intdm.trim(); + } + if (attr !== null) setAttrs(attr); + }); + } + }); + consoleLog(`[${result}]`); + setAttrs({ + INFOMSG: result + }); + }); + }); + + const conditions = { + 'aveugle': 'A', + 'effraye': 'F', + 'etourdi': 'E', + 'immobilise': 'I', + 'panique': 'P', + 'ralenti': 'L', + 'renverse': 'R', + 'surpris': 'S' + } + + const conditions_data = { + '': { + 'atc': 0, + 'atd': 0, + 'def': 0, + 'init': 0, + 'title': '' + }, + 'A': { + 'atc': 5, + 'atd': 10, + 'def': 5, + 'init': 5, + 'title': 'Aveuglé' + }, + 'E': { + 'atc': 0, + 'atd': 0, + 'def': 5, + 'init': 0, + 'title': 'Etourdi' + }, + 'F': { + 'atc': 5, + 'atd': 5, + 'def': 0, + 'init': 0, + 'title': 'Effrayé' + }, + 'I': { + 'atc': 0, + 'atd': 0, + 'def': 0, + 'init': 0, + 'title': 'Immobilisé' + }, + 'P': { + 'atc': 0, + 'atd': 0, + 'def': 2, + 'init': 0, + 'title': 'Paniqué' + }, + 'L': { + 'atc': 0, + 'atd': 0, + 'def': 0, + 'init': 0, + 'title': 'Ralenti' + }, + 'R': { + 'atc': 5, + 'atd': 5, + 'def': 5, + 'init': 0, + 'title': 'Renversé' + }, + 'S': { + 'atc': 0, + 'atd': 0, + 'def': 5, + 'init': 0, + 'title': 'Surpris' + } + } + + function applyConditions(buffs, conditionAttr, s) { + if (conditionAttr === '') return; + for (let cond of conditionAttr) { + buffs.atc += s * conditions_data[cond].atc; + buffs.atd += s * conditions_data[cond].atd; + buffs.def += s * conditions_data[cond].def; + buffs.init += s * conditions_data[cond].init; + } + } + + function clickedConditions() { + let clickedConditions = ''; + for (let condition of Object.keys(conditions)) { + clickedConditions += `clicked:cond_${condition} `; + } + return clickedConditions; + } + + on(clickedConditions(), function(eventInfo) { + var clickedCondition = conditions[eventInfo.triggerName.replace('clicked:cond_','')]; + getAttrs(['PCONDITION', 'CONDITION', 'ATKCAC_BUFF', 'ATKTIR_BUFF', 'INIT_BUFF', 'DEF_BUFF', 'ETATDE'], function(values) { + let buffs = { + 'atc': parseInt(values.ATKCAC_BUFF) || 0, + 'atd': parseInt(values.ATKTIR_BUFF) || 0, + 'def': parseInt(values.DEF_BUFF) || 0, + 'init': parseInt(values.INIT_BUFF) || 0 + }; + // debuffs prior condition + let pcondition = values.PCONDITION || ''; + applyConditions(buffs, pcondition, +1); + // change condition + let condition = values.CONDITION || ''; + if (condition.includes(clickedCondition)) { + condition = condition.replace(clickedCondition,''); + } else { + condition += clickedCondition; + } + // buff new condition + applyConditions(buffs, condition, -1); + // check prior condition for die roll + let etatde = values.ETATDE; + if (pcondition !== '' && (pcondition.includes(conditions.immobilise) || pcondition.includes(conditions.panique))) etatde = '20'; + // check condition for die roll + if (condition !== '' && (condition.includes(conditions.immobilise) || condition.includes(conditions.panique))) etatde = '12'; + // + let displayConditions = ''; + if (condition !== '') { + for (cond of Object.keys(conditions)) { + if (condition.includes(conditions[cond])) { + displayConditions += (displayConditions === '' ? '' : ', ') + conditions_data[conditions[cond]].title; + } + } + } + if (displayConditions === '') displayConditions = ' '; + setAttrs({ + ATKCAC_BUFF: buffs.atc, + ATKTIR_BUFF: buffs.atd, + DEF_BUFF: buffs.def, + INIT_BUFF: buffs.init, + ETATDE: etatde, + CONDITION: condition, + PCONDITION: condition, + conditions: displayConditions + }); + }); + }); + diff --git a/ChroniquesGalactiques/cond_aveugle.png b/ChroniquesGalactiques/cond_aveugle.png new file mode 100644 index 0000000000..5095be9864 Binary files /dev/null and b/ChroniquesGalactiques/cond_aveugle.png differ diff --git a/ChroniquesGalactiques/cond_effraye.png b/ChroniquesGalactiques/cond_effraye.png new file mode 100644 index 0000000000..fbfce3fdf9 Binary files /dev/null and b/ChroniquesGalactiques/cond_effraye.png differ diff --git a/ChroniquesGalactiques/cond_etourdi.png b/ChroniquesGalactiques/cond_etourdi.png new file mode 100644 index 0000000000..75c2f19f7a Binary files /dev/null and b/ChroniquesGalactiques/cond_etourdi.png differ diff --git a/ChroniquesGalactiques/cond_immobilise.png b/ChroniquesGalactiques/cond_immobilise.png new file mode 100644 index 0000000000..1a3a390a0b Binary files /dev/null and b/ChroniquesGalactiques/cond_immobilise.png differ diff --git a/ChroniquesGalactiques/cond_panique.png b/ChroniquesGalactiques/cond_panique.png new file mode 100644 index 0000000000..e73bfc19d5 Binary files /dev/null and b/ChroniquesGalactiques/cond_panique.png differ diff --git a/ChroniquesGalactiques/cond_ralenti.png b/ChroniquesGalactiques/cond_ralenti.png new file mode 100644 index 0000000000..df5d327027 Binary files /dev/null and b/ChroniquesGalactiques/cond_ralenti.png differ diff --git a/ChroniquesGalactiques/cond_renverse.png b/ChroniquesGalactiques/cond_renverse.png new file mode 100644 index 0000000000..21296fa459 Binary files /dev/null and b/ChroniquesGalactiques/cond_renverse.png differ diff --git a/ChroniquesGalactiques/cond_surpris.png b/ChroniquesGalactiques/cond_surpris.png new file mode 100644 index 0000000000..d6eb9d4304 Binary files /dev/null and b/ChroniquesGalactiques/cond_surpris.png differ diff --git a/ChroniquesOublieesContemporain/README.md b/ChroniquesOublieesContemporain/README.md index 7773219404..b992ba167a 100644 --- a/ChroniquesOublieesContemporain/README.md +++ b/ChroniquesOublieesContemporain/README.md @@ -9,10 +9,30 @@ Cette feuilles de personnage inclut quelques jets et règles optionnelles. Le jeu complet est disponible sur le site de l'éditeur [Black Book Editions](http://www.black-book-editions.fr/produit.php?id=4349). # Version courante -2.5 [Screenshot](coc_v2.png) +2.6 [Screenshot](coc_v2.png) # Notes de version +## v2.6 (2019-04-17) +### Fiche de PJ + +* Possibilité d'appliquer plusieurs états préjudiciables en même temps +* Gestion de l'encombrement (idem COF) +* Ajout d'un champ de texte sous la liste d'attaques pour les buffs "temporaires" + * Possibilité d'indiquer des buffs aux jets d'attaque et de dommages en langage quasi-naturel : le premier mot est le type d'attaque concernée, le deuxième est le modificateur (avec possibilité de référencer un autre attribut de la fiche en l'encadrant entre crochets []) et à partir du troisième, la description du buff. + * Indiquer ATC (contact), ATD (distance), MAG (att. magique), MEN (att. mentale), pour les types d'attaques, ATT pour toutes les attaques existantes. Indiquer d'abord DM pour un buff aux dommages + * Plusieurs buffs peuvent être indiqués et séparés par un point-virgule (;) + * Exemple : `DM ATC +2d6 Attaque en traître ; ATD +[PER] Visée` + * Il est nécessaire de cliquer en dehors du champ de saisie AVANT de presser un bouton d'attaque afin que le script sheet-worker approprié puisse s'exécuter. +* Ajout d'un bouton "Recycle" sur l'onglet Configuration pour forcer la fiche à recalculer quelques attributs (rangs atteints dans chaque voie, statbloc interne, encombrement) + +### Fiche de PNJ + +* Ajout Réduction de DM (RD) +* Ajout d'une liste de capacités / traits +* Amélioration du script d'import de statblock +* Ajout d'un script de conversion d'attributs PNJ => PJ + ## v2.5 (2019-02-12) * Gestion des buffs en langage naturel avec référence aux caracs ou voies/rangs * Réorganisation des lignes d'attaque (PJ et PNJ), gestion des DM secondaires sur la fiche PJ, actions limitées diff --git a/ChroniquesOublieesContemporain/coc.css b/ChroniquesOublieesContemporain/coc.css index c49e72e205..3f73d0283d 100644 --- a/ChroniquesOublieesContemporain/coc.css +++ b/ChroniquesOublieesContemporain/coc.css @@ -207,6 +207,21 @@ button[type="roll"].sheet-output:before { content: ""; } +button[type="action"].sheet-iconbtn { + border: 0px; + background-color: transparent; + font-family: pictos; + font-size: large; +} + +img.sheet-iconimg { + width: 16px; +} + +img.sheet-iconimg:hover { + width: 32px; +} + input, select { border: none; box-shadow: none; @@ -521,7 +536,7 @@ input[type="checkbox"].sheet-block-switch:checked + span::before { border-width: 1px; border-color: #D3D3D3; border-style: solid; - border-radius: 50%; + border-radius: 25% 12%; } .sheet-rolltemplate-co1 .inlinerollresult.fullcrit { @@ -529,7 +544,7 @@ input[type="checkbox"].sheet-block-switch:checked + span::before { border-width: 2px; border-color: #3FB315; border-style: solid; - border-radius: 50%; + border-radius: 25% 12%; } .sheet-rolltemplate-co1 .inlinerollresult.fullfail { @@ -537,7 +552,7 @@ input[type="checkbox"].sheet-block-switch:checked + span::before { border-width: 2px; border-color: #B31515; border-style: solid; - border-radius: 50%; + border-radius: 25% 12%; } .sheet-rolltemplate-co1 .inlinerollresult.importantroll { @@ -545,5 +560,5 @@ input[type="checkbox"].sheet-block-switch:checked + span::before { border-width: 2px; border-color: #5C2E05; border-style: solid; - border-radius: 50%; + border-radius: 25% 12%; } diff --git a/ChroniquesOublieesContemporain/coc.html b/ChroniquesOublieesContemporain/coc.html index 88e31be076..59795e5ee9 100644 --- a/ChroniquesOublieesContemporain/coc.html +++ b/ChroniquesOublieesContemporain/coc.html @@ -1,8 +1,8 @@
- - + + @@ -10,6 +10,11 @@ + + + + + @@ -27,6 +32,7 @@ + @@ -45,11 +51,16 @@ + + + + +
- +
@@ -172,9 +183,9 @@ -
@@ -300,7 +311,7 @@
+ + + + + + + + + +
@@ -580,7 +617,8 @@ - + + + +
- @@ -594,6 +632,7 @@ + + @@ -639,6 +678,7 @@ + + @@ -661,7 +701,7 @@ @@ -691,11 +731,19 @@  
Bonus visée (L) :  + + +
@@ -1076,13 +1124,16 @@
Consommables
Argent :  - + + + /
-   +   + Qté - +
@@ -1172,7 +1223,7 @@ - + Initiative  - + Bonus PC :   ( ) + + + + + + + Encombrement  + +
@@ -1562,9 +1622,10 @@
-
DEF
+
DEF / RD
- + / +
@@ -1578,7 +1639,7 @@
- Capacités + Divers
@@ -1654,6 +1715,28 @@
 
+
+
+ Capacités +
+
+ + + + + + +
+ + + + +
+
+
+
 
+
Importer statblock
@@ -1716,79 +1799,96 @@
{{desc}}
- {{/desc}} {{#DV}} + {{/desc}} + {{#DV}} PV gagnés {{DV}} - {{/DV}} {{#carac}} + {{/DV}} + {{#carac}} {{#jet}} - {{jet}} - {{/jet}} {{^jet}} - Jet + {{jet}} + {{/jet}} + {{^jet}} + Jet {{/jet}} {{carac}} - {{/carac}} {{#test}} + {{/carac}} + {{#test}} {{test}} - {{#rollWasCrit() test}} - - -
{{test_crit}}
- - - {{/rollWasCrit() test}} {{#rollWasFumble() test}} - - -
{{test_fumble}}
- - - {{/rollWasFumble() test}} {{/test}} {{#attaque}} {{#rollWasCrit() attaque}} - - Critique ! - - {{/rollWasCrit() attaque}} {{#rollWasFumble() attaque}} - - Fumble ! - - {{/rollWasFumble() attaque}} - - Jet - {{attaque}} contre DEF - - {{#degats}} - - Dégâts - - {{degats}} {{#rollWasCrit() attaque}} - + {{degats}} {{/rollWasCrit() attaque}} {{dmtype}} - - - {{#degats2}} - - + - {{degats2}} {{dm2type}} - - {{/degats2}} {{/degats}} {{/attaque}} {{^attaque}} {{#degats}} - - Dégâts - {{degats}} {{dmtype}} - - {{#degats2}} - - + - {{degats2}} {{dm2type}} - - {{/degats2}} {{/degats}} {{/attaque}} {{#special}} + {{#rollWasCrit() test}} + + +
{{test_crit}}
+ + + {{/rollWasCrit() test}} + {{#rollWasFumble() test}} + + +
{{test_fumble}}
+ + + {{/rollWasFumble() test}} + {{/test}} + {{#attaque}} + {{#rollWasCrit() attaque}} + + Critique ! + + {{/rollWasCrit() attaque}} + {{#rollWasFumble() attaque}} + + Fumble ! + + {{/rollWasFumble() attaque}} + + Jet + {{attaque}} contre DEF + + {{#degats}} + + Dégâts + + {{degats}} {{#rollWasCrit() attaque}} + + {{degats}} {{/rollWasCrit() attaque}} {{dmtype}} + + + {{#degats2}} + + + + {{degats2}} {{dm2type}} + + {{/degats2}} + {{/degats}} + {{/attaque}} + {{^attaque}} + {{#degats}} + + Dégâts + {{degats}} {{dmtype}} + + {{#degats2}} + + + + {{degats2}} {{dm2type}} + + {{/degats2}} + {{/degats}} + {{/attaque}} + {{#special}}
{{special}}
- {{/special}} {{#text}} + {{/special}} + {{#text}}
{{text}}
@@ -1815,22 +1915,55 @@ console.log('** CO sheetworker' + m + ' >>>'); } + function addTrait(npcObj, traitObj) { + if (traitObj['nom'] !== '' && traitObj['desc'] !== '') { + if (!npcObj['Capas']) npcObj['Capas'] = []; + npcObj['Capas'].push(`${traitObj['nom']}~${traitObj['desc']}`); + traitObj['nom'] = ''; + traitObj['desc'] = ''; + } + } + function importStatblock(text) { text = text.replace(/\r/g, ''); text = text.replace(/ \(DM/g, ' DM'); text = text.replace(/ \(RD/g, ' RD'); text = text.replace(/\, /g, ' '); + text = text.replace(/\n[ ]*\+/g,'+'); var npc = {}; var rows = text.split(/\n/); + var capacites = false; + var capacite = { 'nom': '', 'desc': '' }; console.log('** CO sheetworker : parsing text <<<'); for (var row = 0; row < rows.length; row++) { console.log(rows[row]); - if (rows[row].toUpperCase().indexOf('DM') !== -1) { // this is an attack line + if (row === 0 && rows[row].toUpperCase().indexOf('NC') === -1) { + npc['character_name'] = rows[row].trim(); // assume first line is name + continue; + } + if (!capacites && rows[row].toUpperCase().indexOf('DM') !== -1) { // this is an attack line rows[row] = rows[row].replace(/\)$/g, ''); // handle CG statblocks if (!npc['Atks']) npc['Atks'] = []; npc['Atks'].push(rows[row]); continue; } + if (capacites) { // start parsing traits + let s = rows[row].indexOf(':'); + if (s !== -1) { + addTrait(npc, capacite); + capacite['nom'] = rows[row].substring(0, s - 1).trim(); + if (capacite['nom'].indexOf(' RD') !== -1) capacite['nom'] = capacite['nom'].replace(' RD', ' (RD'); + capacite['desc'] = rows[row].substring(s + 1).trim(); + } else { + capacite['desc'] += ' ' + rows[row].trim(); + } + continue; + } + if (rows[row].trim().startsWith('---')) { + addTrait(npc, capacite); + capacites = !capacites; + continue; + } rows[row] = rows[row].replace(/ \(/g, '('); // strip space before '( rows[row] = rows[row].replace(/très /g, 'très~'); // handle 'très petite' size rows[row] = rows[row].replace(/créature /g, 'PROFIL créature~'); // handle 'créature' mention @@ -1838,12 +1971,18 @@ for (var item = 0; item < items.length; item++) { if (item % 2 === 0) { var k = items[item].toUpperCase().replace(/\./g, ''); - var v = items[item + 1].replace(/~/g, ' '); - if (v.charAt(v.length - 1) === ')' && v.charAt(0) !== '(') v = v.substring(0, v.length - 1); + var v = items[item + 1]; + if (v) { + v.replace(/~/g, ' '); + if (v.charAt(v.length - 1) === ')' && v.charAt(0) !== '(') v = v.substring(0, v.length - 1); + } else { + v = ''; + } npc[k] = v; } } } + if (capacites) addTrait(npc, capacite); console.log('** CO sheetworker : parsing text >>>'); return npc; } @@ -1877,6 +2016,8 @@ var jnor = '1d20'; var jsup = '2d20kh1'; var pnjAttrs = {}; + if (pnjObj.hasOwnProperty('character_name')) pnjAttrs['character_name'] = pnjObj.character_name; + delete pnjObj['character_name']; pnjAttrs['NIVEAU'] = parseInt(pnjObj.NC) || 0; delete pnjObj['NC']; pnjAttrs['TAILLE'] = pnjObj.TAILLE || ''; @@ -1984,12 +2125,42 @@ consoleLog(atkRow, 'adding attack'); setAttrs(atkRow); } else { - result = 'Err: impossible d\'analyser le contenu de "' + pnjObj.Atks[atk] + '"'; + result += (result.length > 0 ? '\n' : '') + 'Err: impossible d\'analyser le contenu de "' + pnjObj.Atks[atk] + '"'; } } return result; } + + function processTraits(universe, pnjObj) { + let result = ''; + + for (let capa of pnjObj['Capas']) { + let capacite = capa.split('~') + if (capacite.length == 2) { + let name = capacite[0] || ''; + let desc = capacite[1] || ''; + if (name !== '' && desc !== '') { + newRowID = generateRowID(); + let capaRow = {}; + capaRow[`repeating_pnjcapas_${newRowID}_capanom`] = name; + desc = desc.replace(/\d+d\d+[+-]*\d*/g, '{{$&}}'); // search for d+/- + desc = desc.replace(/\[\d+d\d+[+-]*\d*\]/g, '{$&}'); // search for [d+/-] + desc = desc.replace(/\[{{/g, '[['); + desc = desc.replace(/}}\]/g, ']]'); + desc = desc.replace(/{{/g, '[['); + desc = desc.replace(/}}/g, ']]'); + capaRow[`repeating_pnjcapas_${newRowID}_capadesc`] = desc; + consoleLog(capaRow, 'adding trait'); + setAttrs(capaRow); + } + } else { + result += (result.length > 0 ? '\n' : '') + 'Err: impossible d\'analyser le contenu de "' + capacite + '"'; + } + } + + return result; + } function buildCaracs() { getAttrs([ @@ -2170,27 +2341,34 @@ } } }); - // MAJ Version - getAttrs(['VERFDP'], function(values) { + // MAJ Version, LAST_PV, messsage + getAttrs(['VERFDP', 'PV'], function(values) { setAttrs({ - VERSION: values.VERFDP + VERSION: values.VERFDP, + LAST_PV: values.PV, + INFOMSG: ' ' }); }); - // PC - getAttrs(['PC_DESC'], function(values) { - var pc_desc = (values.PC_DESC) ? '' : 'Points de Chance'; + // PC (one time only) + getAttrs(['PC_DESC'], function(value) { + var pc_desc = (value.PC_DESC) ? '' : 'Points de Chance'; if (pc_desc != '') { setAttrs({ PC_DESC: pc_desc }); } }); - // LAST_PV - getAttrs(['PV'], function(values) { - setAttrs({ - LAST_PV: values.PV - }); + // seuil_enc (if needed) + getAttrs(['seuil_enc', 'FORCE'], function(values) { + let seuil_enc = parseInt(values.seuil_enc) || 0; + if (seuil_enc === 0) { + setAttrs({ + seuil_enc: parseInt(values.FORCE) || 0 + }); + } }); + // encombrement (refresh) + encumbrance(); // CARACS buildCaracs(); }); @@ -2251,9 +2429,12 @@ buffv.pop(); buffName = buffv.join(' ').trim(); } else { - buffName = buffv[0]; + buffName = buffv[0].trim(); buffVal = buffValue(buffv[1], caracs); } + consoleLog(buff); + consoleLog(buffName); + consoleLog(buffVal); if (!buffName.startsWith('-')) buffSum += buffVal; } } @@ -2268,7 +2449,7 @@ const caracs = ['FOR', 'DEX', 'CON', 'INT', 'PER', 'CHA']; let mod = e.sourceAttribute.substring(0, 3).toUpperCase(); if (!caracs.includes(mod)) return; - const attrs = [...caracs, 'ATKCAC', 'ATKTIR', 'PSYINTUI', 'PSYINFLU', 'INIT', 'DEF', 'DEP']; + const attrs = [...caracs, 'ATKCAC', 'ATKTIR', 'ATKMAG', 'ATKMEN', 'INIT', 'DEF']; for (let a = 0; a < attrs.length; a++) { attrs[a] = `${attrs[a]}_BUFF_LIST`; } @@ -2345,104 +2526,7 @@ on('change:def_buff_list', function() { parseBuff('DEF'); }); - - on('change:condition', function() { - getAttrs(['PCONDITION', 'CONDITION', 'ATKCAC_BUFF', 'ATKTIR_BUFF', 'INIT_BUFF', 'DEF_BUFF', 'ETATDE'], function(values) { - // setup helper objects - const conditions = { - 'aucune': '', - 'aveugle': 'A', - 'etourdi': 'E', - 'effraye': 'F', - 'immobilise': 'I', - 'panique': 'P', - 'renverse': 'R', - 'surpris': 'S' - } - const buffs = { - '': { - 'atc': 0, - 'atd': 0, - 'def': 0, - 'init': 0 - }, - 'A': { - 'atc': 5, - 'atd': 10, - 'def': 5, - 'init': 5 - }, - 'E': { - 'atc': 0, - 'atd': 0, - 'def': 5, - 'init': 0 - }, - 'F': { - 'atc': 5, - 'atd': 5, - 'def': 0, - 'init': 0 - }, - 'I': { - 'atc': 0, - 'atd': 0, - 'def': 0, - 'init': 0 - }, - 'P': { - 'atc': 0, - 'atd': 0, - 'def': 2, - 'init': 0 - }, - 'R': { - 'atc': 5, - 'atd': 5, - 'def': 5, - 'init': 0 - }, - 'S': { - 'atc': 0, - 'atd': 0, - 'def': 5, - 'init': 0 - } - } - // check prior condition for die roll - let etatde = values.ETATDE; - switch (values.PCONDITION) { - case conditions.immobilise: - etatde = '20'; - break; - case conditions.panique: - etatde = '20'; - break; - } - // check condition for die roll - switch (values.CONDITION) { - case conditions.immobilise: - etatde = '12'; - break; - case conditions.panique: - etatde = '12'; - break; - case conditions.aucune: - etatde = '20'; - break; - } - // Now update all buffs and prior condition - setAttrs({ - ATKCAC_BUFF: values.ATKCAC_BUFF + buffs[values.PCONDITION].atc - buffs[values.CONDITION].atc, - ATKTIR_BUFF: values.ATKTIR_BUFF + buffs[values.PCONDITION].atd - buffs[values.CONDITION].atd, - INIT_BUFF: values.INIT_BUFF + buffs[values.PCONDITION].init - buffs[values.CONDITION].init, - DEF_BUFF: values.DEF_BUFF + buffs[values.PCONDITION].def - buffs[values.CONDITION].def, - ETATDE: etatde, - PCONDITION: values.CONDITION - }); - }); - }); - + on('change:blessure', function() { getAttrs(['BLESSURE'], function(values) { var etatde = (values.BLESSURE === '1') ? '12' : '20'; @@ -2462,7 +2546,11 @@ JETNORMAL: jetn, JETSUP: jets, JETSUPHERO: jetsh, - JETRISQUE: jetr + JETRISQUE: jetr, + JDEX: jetn, + JDEXSUP: jets, + JDEXSUPHERO: jetsh, + JDEXRISQUE: jetr }); }); }); @@ -2498,6 +2586,12 @@ messages += result; delete pnjObj['Atks']; } + if (pnjObj.hasOwnProperty('Capas')) { + result = processTraits(values.UNIVERS, pnjObj); + if (result != '' && messages != '') result = '\n' + result; + messages += result; + delete pnjObj['Capas']; + } // Other attributes go to DIVERS field var divers = ''; var otherAttrs = Object.keys(pnjObj); @@ -2516,7 +2610,98 @@ }); }); - on('change:type_personnage', function() { + const npcAtkAttribs = [ + 'atkatt', + 'atknom', + 'atkjet', + 'atkbonus', + 'atkcrit', + 'atkdmg', + 'atkdmnbde', + 'atkdmde', + 'atkdmbonus', + 'atkportee', + 'atkspec' + ] + + function convertToPC() { + getAttrs([ + 'pnj_for', 'pnj_dex', 'pnj_con', 'pnj_int', 'pnj_per', 'pnj_cha', + 'pnj_jetfor', 'pnj_jetdex', 'pnj_jetcon', 'pnj_jetint', 'pnj_jetper', 'pnj_jetcha', + 'pnj_init', 'pnj_def', 'pnj_pv', 'pnj_pv_max' + ], function(values) { + let attrs = {}; + for (let attr of ['FORCE', 'DEXTERITE', 'CONSTITUTION', 'INTELLIGENCE', 'PERCEPTION', 'CHARISME']) { + let attrv = parseInt(values[`pnj_${attr.substring(0,3).toLowerCase()}`]) || 0; + attrs[attr] = 10 + (2 * attrv); + if (attr === 'DEXTERITE') { + let init = parseInt(values.pnj_init) || 0; + if (init === attrv + 1) { + attrs[attr]++; + } else { + attrs['INIT_BUFF'] = init - attrs[attr]; + } + let defb = 10 + attrv; + let def = parseInt(values.pnj_def) || 0; + if (def !== defb) attrs['DEF_BUFF'] = def - defb; + attrs['DEX_SUP'] = (values['pnj_jetdex'] === '2d20kh1') ? '@{JDEXSUP}' : '@{JDEX}'; + } else { + attrs[`${attr.substring(0,3)}_SUP`] = (values[`pnj_jet${attr.substring(0,3).toLowerCase()}`] === '2d20kh1') ? '@{JETSUP}' : '@{JETNORMAL}'; + } + } + attrs['PV'] = parseInt(values.pnj_pv) || 0; + attrs['PV_max'] = parseInt(values.pnj_pv_max) || 0; + getSectionIDs('repeating_armes', function(ids) { + for (let id of ids) { + removeRepeatingRow(`repeating_armes_${id}`); + } + }); + getSectionIDs('repeating_pnjatk', function(ids) { + for (let id of ids) { + getAttrs([...npcAtkAttribs.map(attr => `repeating_pnjatk_${id}_${attr}`), 'pnj_for', 'pnj_dex', 'pnj_cha'], function(values) { + consoleLog(values); + let v = {}; + for (let attr of npcAtkAttribs) { + v[attr] = values[`repeating_pnjatk_${id}_${attr}`] || ''; + } + newRowID = generateRowID(); + let atkRow = {}; + atkRow[`repeating_armes_${newRowID}_armeatt`] = v['atkatt']; + atkRow[`repeating_armes_${newRowID}_armenom`] = v['atknom']; + let magic = v['atknom'].toLowerCase().includes('attaque magique'); + let tohit = parseInt(v['atkbonus']) || 0; + let atk = 0; + let bdm = 0; + if (v['atkportee'] && v['atkportee'] !== '') { + atk = magic ? values.pnj_cha || 0 : values.pnj_dex || 0; + atkRow[`repeating_armes_${newRowID}_armeatk`] = magic ? '@{ATKMAG}' : '@{ATKTIR}'; + } else { + atk = magic ? values.pnj_cha || 0 : values.pnj_for || 0; + bdm = magic ? 0 : atk; + atkRow[`repeating_armes_${newRowID}_armeatk`] = magic ? '@{ATKMAG}' : '@{ATKCAC}'; + atkRow[`repeating_armes_${newRowID}_armedmcar`] = magic ? '' : '@{FOR}'; + } + if (tohit !== atk) atkRow[`repeating_armes_${newRowID}_armeatkdiv`] = tohit - atk; + atkRow[`repeating_armes_${newRowID}_armejetd`] = v['atkjet']; + atkRow[`repeating_armes_${newRowID}_armecrit`] = v['atkcrit']; + atkRow[`repeating_armes_${newRowID}_armedmg`] = v['atkdmg']; + atkRow[`repeating_armes_${newRowID}_armedmnbde`] = v['atkdmnbde']; + atkRow[`repeating_armes_${newRowID}_armedmde`] = v['atkdmde']; + let dmdiv = parseInt(v['atkdmbonus']) || 0; + if (dmdiv !== bdm) atkRow[`repeating_armes_${newRowID}_armedmdiv`] = dmdiv - bdm; + atkRow[`repeating_armes_${newRowID}_armeportee`] = v['atkportee']; + atkRow[`repeating_armes_${newRowID}_armespec`] = v['atkspec']; + setAttrs(atkRow); + }); + } + }); + setAttrs(attrs); + }); + } + + on('change:type_personnage', function(eventInfo) { + if (eventInfo.previousValue === 'pnj' && eventInfo.newValue === 'pj') convertToPC(); + // if (eventInfo.previousValue === 'pj' && eventInfo.newValue === 'pnj') convertToNPC(); getAttrs(['type_personnage'], function(values) { setAttrs({ type_fiche: values.type_personnage @@ -2525,7 +2710,7 @@ }); function changeRanks(voie) { - return `change:voie${voie}-1 change:voie${voie}-2 change:voie${voie}-3 change:voie${voie}-4 change:voie${voie}-5`; + return `change:voie${voie}nom change:voie${voie}-1 change:voie${voie}-2 change:voie${voie}-3 change:voie${voie}-4 change:voie${voie}-5`; } function attrRanks(voie) { @@ -2612,7 +2797,7 @@ let portees = parseInt(portee) || 0; if (portees !== 0) { setAttrs({ - repeating_armes_armeportees: `${portees}${um} / ${portees*2}${um} / ${portees*3}${um}` + repeating_armes_armeportees: `${portees}m | ${portees*2}m (-5) | ${portees*3}m (-10)` }); } }); @@ -2652,7 +2837,6 @@ var pilote = value.PILOTE.trim() || ''; if (pilote === '') return; getSectionIDs('repeating_jetv', function(ids) { - let items = {}; for (let id = 0; id < ids.length; id++) { getAttrs([`repeating_jetv_${ids[id]}_jetvcaracpil`, `repeating_jetv_${ids[id]}_jetvcaracp`], function(values) { let attr = values[Object.keys(values)[0]]; @@ -2676,6 +2860,347 @@ }); }); }); + + function encumbrance() { + getSectionIDs('repeating_equipement', function(ids) { + const encombrement = { + total: 0, + zeros: 0 + } + for (let id = 0; id < ids.length; id++) { + getAttrs([`repeating_equipement_${ids[id]}_equip-qte`, `repeating_equipement_${ids[id]}_equip-enc`], function(values) { + let qte = parseInt(values[Object.keys(values)[0]]) || 0; + let enc = parseInt(values[Object.keys(values)[1]]) || 0; + if (enc === 0) { + encombrement.zeros += qte; + if (encombrement.zeros >= 3) { + encombrement.total += Math.floor(encombrement.zeros / 3); + encombrement.zeros %= 3; + } + } else { + encombrement.total += qte*enc; + } + setAttrs({ + total_enc: encombrement.total + }); + }); + } + }); + } + on('change:repeating_equipement:equip-qte change:repeating_equipement:equip-enc', function() { + encumbrance(); + }); + + on('change:total_enc', function() { + getAttrs(['use_encombrement', 'total_enc', 'seuil_enc'], function(values) { + let use_encombrement = values.use_encombrement === 1 ? true : false; + if (!use_encombrement) return; + let seuil_enc = parseInt(values.seuil_enc) || 0; + let encombrement = parseInt(values.total_enc) || 0; + if (seuil_enc > 0 && encombrement > 0) { + let cond = {}; + if (encombrement > seuil_enc * 3) { + cond.CONDITION = 'I'; // Immobilisé + } else if (encombrement > seuil_enc * 2) { + cond.CONDITION = 'L'; // Ralenti + cond.ETATDE = '12'; // +Affaibli + } else if (encombrement > seuil_enc) { + cond.CONDITION = ''; + cond.JDEX = '1d12'; + cond.JDEXSUP = '2d12kh1'; + cond.JDEXSUPHERO = '{2d12kh1, 0d12+10}kh1'; + cond.JDEXRISQUE = '2d12kl1'; + cond.ETATDE = '20'; + } else { + cond.CONDITION = ''; + cond.JDEX = '1d@{ETATDE}'; + cond.JDEXSUP = '2d@{ETATDE}kh1'; + cond.JDEXSUPHERO = '{2d@{ETATDE}kh1, 0d20+10}kh1'; + cond.JDEXRISQUE = '1d12'; + cond.ETATDE = '20'; + } + if (cond !== null) setAttrs(cond); + } + }); + }); + + on('clicked:reset', function() { + for (let v=1; v <= 9; v++) { + setRank(v.toString()); + } + buildCaracs(); + encumbrance(); + }); + + on('change:mods_atk', function() { + let infomsg = 'Syntaxe non reconnue, corrigez SVP...'; + setAttrs({ INFOMSG: infomsg }); + getAttrs(['mods_atk', 'CARACS'], function(values) { + const aliases = { + 'attaque': 'att', + 'attaques': 'att', + 'cac': 'atc', + 'contact': 'atc', + 'cad': 'atd', + 'distance': 'atd', + 'magie': 'mag', + 'mental': 'men', + 'mentale': 'men', + 'tir': 'atd' + }; + const modifiers = { + atc: '', + atcdm: '', + atd: '', + atddm: '', + mag: '', + magdm: '', + men: '', + mendm: '' + }; + let result = ' '; + if (values.mods_atk !== '') { + let caracs = JSON.parse(values.CARACS); + let mods = values.mods_atk.replace('\n', ';').split(';'); + for (let mod of mods) { + if (mod.trim() === '') continue; + let modv = mod.trim().split(' '); + let mod_attr = modv.shift().toLowerCase(); + let to_dm = false; + if (mod_attr === 'dm') { + to_dm = true; + mod_attr = modv.shift().toLowerCase(); + if (Object.keys(aliases).includes(mod_attr)) { + if (aliases[mod_attr] === 'att') mod_attr = 'dm'; + if (aliases[mod_attr] === 'atc') mod_attr = 'atcdm'; + if (aliases[mod_attr] === 'atd') mod_attr = 'atddm'; + if (aliases[mod_attr] === 'mag') mod_attr = 'magdm'; + if (aliases[mod_attr] === 'men') mod_attr = 'mendm'; + } else { + if (mod_attr === 'att') mod_attr = 'dm'; + if (mod_attr === 'atc') mod_attr = 'atcdm'; + if (mod_attr === 'atd') mod_attr = 'atddm'; + if (mod_attr === 'mag') mod_attr = 'magdm'; + if (mod_attr === 'men') mod_attr = 'mendm'; + } + } + let mod_sgn = '+'; + let mod_val = modv.shift(); + if (mod_val.startsWith('+') || mod_val.startsWith('-')) { + mod_sgn = mod_val.substring(0,1); + mod_val = mod_val.substring(1); + } + if (to_dm && mod_val.search(/\d+[dD]\d+/) !== -1) { + mod_val = `[[${mod_val}]]`; + } else { + mod_val = buffValue(mod_val, caracs); + if (mod_val === 0) continue; + } + let mod_desc = ` ${mod_sgn}${mod_val}[${modv.join(' ').trim()}]`; + switch (mod_attr) { + case 'atc': + case 'atcdm': + case 'atd': + case 'atddm': + case 'mag': + case 'magdm': + case 'men': + case 'mendm': + modifiers[mod_attr] += mod_desc; + break; + case 'att': + for (let attr of ['atc', 'atd', 'mag', 'men']) { + modifiers[attr] += mod_desc; + } + break; + case 'dm': + for (let attr of ['atcdm', 'atddm', 'magdm', 'mendm']) { + modifiers[attr] += mod_desc; + } + break; + default: + if (Object.keys(aliases).includes(mod_attr)) { + modifiers[aliases[mod_attr]] += mod_desc; + result = ' '; + } else { + result = infomsg; + } + break; + } + } + } + getSectionIDs('repeating_armes', function(ids) { + for (const id of ids) { + getAttrs([`repeating_armes_${id}_armeatk`, `repeating_armes_${id}_armeportee`], function(values) { + let type = values[Object.keys(values)[0]] || ''; + let portee = values[Object.keys(values)[1]] || ''; + let attr = {}; + if (type === '@{ATKCAC}' || (type === '@{ATKTIR}' && portee === '')) { + attr[`repeating_armes_${id}_armebuff`] = modifiers.atc.trim(); + attr[`repeating_armes_${id}_armebuffdm`] = modifiers.atcdm.trim(); + } else if (type === '@{ATKTIR}') { + attr[`repeating_armes_${id}_armebuff`] = modifiers.atd.trim(); + attr[`repeating_armes_${id}_armebuffdm`] = modifiers.atddm.trim(); + } else if (type === '@{ATKMAG}') { + attr[`repeating_armes_${id}_armebuff`] = modifiers.mag.trim(); + attr[`repeating_armes_${id}_armebuffdm`] = modifiers.magdm.trim(); + } else if (type === '@{ATKMEN}') { + attr[`repeating_armes_${id}_armebuff`] = modifiers.men.trim(); + attr[`repeating_armes_${id}_armebuffdm`] = modifiers.mendm.trim(); + } + if (attr !== null) setAttrs(attr); + }); + } + }); + consoleLog(`[${result}]`); + setAttrs({ INFOMSG: result }); + }); + }); + + const conditions = { + 'aveugle': 'A', + 'effraye': 'F', + 'etourdi': 'E', + 'immobilise': 'I', + 'panique': 'P', + 'ralenti': 'L', + 'renverse': 'R', + 'surpris': 'S' + } + + const conditions_data = { + '': { + 'atc': 0, + 'atd': 0, + 'def': 0, + 'init': 0, + 'title': '' + }, + 'A': { + 'atc': 5, + 'atd': 10, + 'def': 5, + 'init': 5, + 'title': 'Aveuglé' + }, + 'E': { + 'atc': 0, + 'atd': 0, + 'def': 5, + 'init': 0, + 'title': 'Etourdi' + }, + 'F': { + 'atc': 5, + 'atd': 5, + 'def': 0, + 'init': 0, + 'title': 'Effrayé' + }, + 'I': { + 'atc': 0, + 'atd': 0, + 'def': 0, + 'init': 0, + 'title': 'Immobilisé' + }, + 'P': { + 'atc': 0, + 'atd': 0, + 'def': 2, + 'init': 0, + 'title': 'Paniqué' + }, + 'L': { + 'atc': 0, + 'atd': 0, + 'def': 0, + 'init': 0, + 'title': 'Ralenti' + }, + 'R': { + 'atc': 5, + 'atd': 5, + 'def': 5, + 'init': 0, + 'title': 'Renversé' + }, + 'S': { + 'atc': 0, + 'atd': 0, + 'def': 5, + 'init': 0, + 'title': 'Surpris' + } + } + + function applyConditions(buffs, conditionAttr, s) { + if (conditionAttr === '') return; + for (let cond of conditionAttr) { + buffs.atc += s * conditions_data[cond].atc; + buffs.atd += s * conditions_data[cond].atd; + buffs.def += s * conditions_data[cond].def; + buffs.init += s * conditions_data[cond].init; + } + } + + function clickedConditions() { + let clickedConditions = ''; + for (let condition of Object.keys(conditions)) { + clickedConditions += `clicked:cond_${condition} `; + } + return clickedConditions; + } + + on(clickedConditions(), function(eventInfo) { + var clickedCondition = conditions[eventInfo.triggerName.replace('clicked:cond_','')]; + getAttrs(['PCONDITION', 'CONDITION', 'ATKCAC_BUFF', 'ATKTIR_BUFF', 'INIT_BUFF', 'DEF_BUFF', 'ETATDE'], function(values) { + let buffs = { + 'atc': parseInt(values.ATKCAC_BUFF) || 0, + 'atd': parseInt(values.ATKTIR_BUFF) || 0, + 'def': parseInt(values.DEF_BUFF) || 0, + 'init': parseInt(values.INIT_BUFF) || 0 + }; + // debuffs prior condition + let pcondition = values.PCONDITION || ''; + applyConditions(buffs, pcondition, +1); + // change condition + let condition = values.CONDITION || ''; + if (condition.includes(clickedCondition)) { + condition = condition.replace(clickedCondition,''); + } else { + condition += clickedCondition; + } + // buff new condition + applyConditions(buffs, condition, -1); + // check prior condition for die roll + let etatde = values.ETATDE; + if (pcondition !== '' && (pcondition.includes(conditions.immobilise) || pcondition.includes(conditions.panique))) etatde = '20'; + // check condition for die roll + if (condition !== '' && (condition.includes(conditions.immobilise) || condition.includes(conditions.panique))) etatde = '12'; + // + let displayConditions = ''; + if (condition !== '') { + for (cond of Object.keys(conditions)) { + if (condition.includes(conditions[cond])) { + displayConditions += (displayConditions === '' ? '' : ', ') + conditions_data[conditions[cond]].title; + } + } + } + if (displayConditions === '') displayConditions = ' '; + setAttrs({ + ATKCAC_BUFF: buffs.atc, + ATKTIR_BUFF: buffs.atd, + DEF_BUFF: buffs.def, + INIT_BUFF: buffs.init, + ETATDE: etatde, + CONDITION: condition, + PCONDITION: condition, + conditions: displayConditions + }); + }); + }); + diff --git a/ChroniquesOublieesContemporain/cond_aveugle.png b/ChroniquesOublieesContemporain/cond_aveugle.png new file mode 100644 index 0000000000..5095be9864 Binary files /dev/null and b/ChroniquesOublieesContemporain/cond_aveugle.png differ diff --git a/ChroniquesOublieesContemporain/cond_effraye.png b/ChroniquesOublieesContemporain/cond_effraye.png new file mode 100644 index 0000000000..fbfce3fdf9 Binary files /dev/null and b/ChroniquesOublieesContemporain/cond_effraye.png differ diff --git a/ChroniquesOublieesContemporain/cond_etourdi.png b/ChroniquesOublieesContemporain/cond_etourdi.png new file mode 100644 index 0000000000..75c2f19f7a Binary files /dev/null and b/ChroniquesOublieesContemporain/cond_etourdi.png differ diff --git a/ChroniquesOublieesContemporain/cond_immobilise.png b/ChroniquesOublieesContemporain/cond_immobilise.png new file mode 100644 index 0000000000..1a3a390a0b Binary files /dev/null and b/ChroniquesOublieesContemporain/cond_immobilise.png differ diff --git a/ChroniquesOublieesContemporain/cond_panique.png b/ChroniquesOublieesContemporain/cond_panique.png new file mode 100644 index 0000000000..e73bfc19d5 Binary files /dev/null and b/ChroniquesOublieesContemporain/cond_panique.png differ diff --git a/ChroniquesOublieesContemporain/cond_ralenti.png b/ChroniquesOublieesContemporain/cond_ralenti.png new file mode 100644 index 0000000000..df5d327027 Binary files /dev/null and b/ChroniquesOublieesContemporain/cond_ralenti.png differ diff --git a/ChroniquesOublieesContemporain/cond_renverse.png b/ChroniquesOublieesContemporain/cond_renverse.png new file mode 100644 index 0000000000..21296fa459 Binary files /dev/null and b/ChroniquesOublieesContemporain/cond_renverse.png differ diff --git a/ChroniquesOublieesContemporain/cond_surpris.png b/ChroniquesOublieesContemporain/cond_surpris.png new file mode 100644 index 0000000000..d6eb9d4304 Binary files /dev/null and b/ChroniquesOublieesContemporain/cond_surpris.png differ