diff --git a/module/actor.js b/module/actor.js index 5702e4df..ca31cda2 100644 --- a/module/actor.js +++ b/module/actor.js @@ -329,38 +329,76 @@ export class RdDActor extends Actor { } async dormir(heures=1) { + let message = { title : "Récupération", content :"Vous dormez " + heures + " heure" + (heures > 1 ? "s": "") }; + this.recupereEndurance(message); for (let i=0; i0) { + message.content += "
Vous récuperez " + recupere + " points d'endurance"; } } - async recuperationReve() { - const seuil = this.data.data.reve.seuil.value; - const reve = this.getReveActuel(); - console.log("recuperationReve", this.data.data); - let message = { title : "Récupération" } - if (reve > seuil) { - message.content = "Vous avez déjà récupéré suffisament (seuil " + seuil + ", rêve actuel "+reve+")"; - } - else { - let deRecuperation = await RdDDice.deDraconique(); - console.log("recuperationReve", deRecuperation); - if (deRecuperation>=7) - { - // Rêve de Dragon ! - message.content = "Vous faites un Rêve de Dragon de " + deRecuperation + " Points de rêve"; - message.content += await this.combattreReveDeDragon(deRecuperation); - } - else{ - message.content = "Vous récupérez " + deRecuperation + " Points de rêve"; - await this.updatePointsDeReve(deRecuperation); + async recupererFatigueUneHeure(message) { + let fatigue = duplicate(this.data.data.sante.fatigue) + if (fatigue.value == 0) { + message.content += "
Vous êtes déjà reposé"; + return; + } + const segments = RdDUtility.getSegmentsFatigue(this.data.data.sante.endurance.max); + let cumul = 0; + console.log("recupererFatigue", segments); + + let i; + for (i=0; i <11; i++) { + cumul += segments[i]; + let diff = cumul - fatigue.value ; + if (diff >= 0) + { + const limit2Segments = Math.floor(segments[i] / 2); + if (diff > limit2Segments && i > 0) { + cumul -= segments[i-1]; // le segment est à moins de la moitié, il est récupéré } + cumul -= segments[i]; + break; } - ChatMessage.create( message ); + } + fatigue.value = cumul; + await this.update( {"data.sante.fatigue": fatigue } ); + if (fatigue.value == 0) + { + message.content += "
Vous êtes bien reposé"; + } + } + + recuperationReve(message) { + const seuil = this.data.data.reve.seuil.value; + const reve = this.getReveActuel(); + if (reve >= seuil) { + message.content += "
Vous avez suffisament rêvé (seuil " + seuil + ", rêve actuel "+reve+")"; + } + else { + let deRecuperation = RdDDice.deDraconique(); + console.log("recuperationReve", deRecuperation); + if (deRecuperation>=7) + { + // Rêve de Dragon ! + message.content += "
Vous faites un Rêve de Dragon de " + deRecuperation + " Points de rêve"; + message.content += this.combattreReveDeDragon(deRecuperation); + } + else{ + message.content += "
Vous récupérez " + deRecuperation + " Points de rêve"; + this.updatePointsDeReve(deRecuperation); + } + } } combattreReveDeDragon(force){ @@ -370,6 +408,7 @@ export class RdDActor extends Actor { let difficulte = niveau - etat - force; let reveActuel = this.getReveActuel(); let rolled = RdDResolutionTable.roll(reveActuel, difficulte); + // TODO: xp particulière consome.log("combattreReveDeDragon", rolled ); return this.appliquerReveDeDragon(rolled, force); } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index d672e908..2195345b 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -27,22 +27,23 @@ const competence_xp_par_niveau = [ 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, const carac_array = [ "taille", "apparence", "constitution", "force", "agilite", "dexterite", "vue", "ouie", "odoratgout", "volonte", "intellect", "empathie", "reve", "chance", "melee", "tir", "lancer", "derobee"]; const difficultesLibres = [0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]; const ajustementsConditions = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10]; -const fatigueMatrix = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // Dummy filler for the array. - [2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3 ], - [2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3 ], - [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ], - [3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 4 ], - [3, 3, 4, 3, 3, 4, 3, 3, 4, 3, 3, 4 ], - [3, 3, 4, 3, 4, 4, 3, 3, 4, 3, 4, 4 ], - [3, 4, 4, 3, 4, 4, 3, 4, 4, 3, 4, 4 ], - [3, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4 ], - [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ], - [4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 5 ], - [4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5 ], - [4, 4, 5, 4, 5, 5, 4, 4, 5, 4, 5, 5 ], - [4, 5, 5, 4, 5, 5, 4, 5, 5, 4, 5, 5 ], - [4, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5 ], - [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 ] ]; + +function _buildAllSegmentsFatigue(max) { + const cycle = [5, 2, 4, 1, 3, 0]; + let fatigue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]; + for (let i = 0; i <= 40; i++) { + const ligneFatigue= duplicate(fatigue[i]); + const caseIncrementee = cycle[i % 6]; + ligneFatigue[caseIncrementee]++; + ligneFatigue[caseIncrementee + 6]++; + ligneFatigue.fatigueMax = 2 * (i + 1); + fatigue[i + 1] = ligneFatigue ; + } + return fatigue; +} + +const fatigueMatrix = _buildAllSegmentsFatigue(30); + const fatigueMalus = [ 0, 0, 0, -1, -1, -1, -2, -3, -4, -5, -6, -7 ]; // Provides the malus for each segment of fatigue const fatigueLineSize = [ 3, 6, 7, 8, 9, 10, 11, 12]; const fatigueLineMalus = [ 0, -1, -2, -3, -4, -5, -6, -7 ]; @@ -84,7 +85,6 @@ const definitionsEncaissement = { /* -------------------------------------------- */ export class RdDUtility { - /* -------------------------------------------- */ static async preloadHandlebarsTemplates( ) { const templatePaths = [ @@ -255,12 +255,12 @@ export class RdDUtility { /* -------------------------------------------- */ static computeCarac( data) { - let fmax = parseInt(data.carac.taille.value) + 4; - if ( data.carac.force.value > fmax ) - data.carac.force.value = fmax; + data.carac.force.value = Math.min(data.carac.force.value, parseInt(data.carac.taille.value) + 4); data.carac.derobee.value = Math.floor(parseInt(((21 - data.carac.taille.value)) + parseInt(data.carac.agilite.value)) / 2); let bonusDomKey = Math.floor( (parseInt(data.carac.force.value) + parseInt(data.carac.taille.value)) / 2); + + // TODO: gérer table des bonus dommages (et autres) des créatures data.attributs.plusdom.value = 2 if (bonusDomKey < 8) data.attributs.plusdom.value = -1; @@ -275,15 +275,12 @@ export class RdDUtility { data.carac.lancer.value = Math.floor( (parseInt(data.carac.tir.value) + parseInt(data.carac.force.value)) / 2); data.sante.vie.max = Math.ceil( (parseInt(data.carac.taille.value) + parseInt(data.carac.constitution.value)) /2 ); - if ( data.sante.vie.value > data.sante.vie.max) - data.sante.vie.value = data.sante.vie.max; - let endurance = Math.max( parseInt(data.carac.taille.value) + parseInt(data.carac.constitution.value), parseInt(data.sante.vie.max) + parseInt(data.carac.volonte.value) ); - data.sante.endurance.max = endurance; - if ( data.sante.endurance.value > endurance) - data.sante.endurance.value = endurance; - data.sante.fatigue.max = endurance*2; - if ( data.sante.fatigue.value > data.sante.fatigue.max ) - data.sante.fatigue.value = data.sante.fatigue.max; + + data.sante.vie.value = Math.min(data.sante.vie.value, data.sante.vie.max) + data.sante.endurance.max = Math.max( parseInt(data.carac.taille.value) + parseInt(data.carac.constitution.value), parseInt(data.sante.vie.max) + parseInt(data.carac.volonte.value) ); + data.sante.endurance.value = Math.min(data.sante.endurance.value, data.sante.endurance.max); + data.sante.fatigue.max = data.sante.endurance.max*2; + data.sante.fatigue.value = Math.min(data.sante.fatigue.value, data.sante.fatigue.max); data.attributs.sconst.value = 5; // Max ! if ( data.carac.constitution.value < 9 ) @@ -305,36 +302,52 @@ export class RdDUtility { //data.compteurs.chance.value = data.carac.chance.value; data.compteurs.chance.max = data.carac.chance.value; } - + + static getSegmentsFatigue(endurance) { + endurance = Math.max(endurance, 1); + endurance = Math.min(endurance, fatigueMatrix.length); + return fatigueMatrix[endurance]; + } + + static cumulSegments(segments) { + let cumuls = [segments[0]]; + for (let i = 1; i < 12; i++) { + cumuls[i] = segments[i] + cumuls[i - 1]; + } + return cumuls; + } + /* -------------------------------------------- */ // Build the nice (?) html table used to manage fatigue. - // max should Mbe the endurance max value - static makeHTMLfatigueMatrix( value, max ) - { - max = (max < 16) ? 16 : max; - max = (max > 30) ? 30 : max; - value = (value > max*2) ? max*2 : value; - value = (value < 0) ? 0 : value; - - let fatigueTab = fatigueMatrix[max]; + // max should be the endurance max value + static makeHTMLfatigueMatrix( fatigue, maxEndurance) { + let segments = this.getSegmentsFatigue(maxEndurance); + return this.makeHTMLfatigueMatrixForSegment(fatigue, segments); + } - let table = $("").addClass('table-fatigue'); + static makeHTMLfatigueMatrixForSegment(fatigue, segments) { + fatigue = Math.max(fatigue, 0); + fatigue = Math.min(fatigue, segments.fatigueMax); + + let table = $("
").addClass('table-fatigue'); let segmentIdx = 0; let fatigueCount = 0; - for (var line=0; line < fatigueLineSize.length; line++) { + for (var line = 0; line < fatigueLineSize.length; line++) { let row = $(""); let segmentsPerLine = fatigueLineSize[line]; row.append(""); while (segmentIdx < segmentsPerLine) { - let freeSize = fatigueTab[segmentIdx]; - for (let col=0; col <5; col++) { - if ( col < freeSize ) { - if (fatigueCount < value ) + let freeSize = segments[segmentIdx]; + for (let col = 0; col < 5; col++) { + if (col < freeSize) { + if (fatigueCount < fatigue) row.append("
" + fatigueLineMalus[line] + ""); + + else row.append(""); fatigueCount++; - } else { + } else { row.append(""); } } @@ -343,10 +356,9 @@ export class RdDUtility { } table.append(row); } - //console.log("fatigue", table); return table; } - + /* -------------------------------------------- */ static getLocalisation( ) { diff --git a/module/tmr-utility.js b/module/tmr-utility.js index 8f297aaf..996eb272 100644 --- a/module/tmr-utility.js +++ b/module/tmr-utility.js @@ -373,6 +373,7 @@ export class TMRUtility { msg += "Ce Tourbillon Noir disparait !" } else if (rencontre.name == "Rêve de Dragon") { + // TODO: xp particulière msg += "Vous maîtrisez le Rêve de Dragon !" msg += actor.appliquerReveDeDragon(rolled, rencontre.force); }