#51 Gestion des bonus de cases

This commit is contained in:
sladecraven 2020-12-04 20:52:04 +01:00
parent a831e8b0b2
commit ca84b593ec
11 changed files with 185 additions and 22 deletions

View File

@ -13,6 +13,7 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { RdDDice } from "./rdd-dice.js"; import { RdDDice } from "./rdd-dice.js";
import { RdDRollTables } from "./rdd-rolltables.js"; import { RdDRollTables } from "./rdd-rolltables.js";
import { ChatUtility } from "./chat-utility.js"; import { ChatUtility } from "./chat-utility.js";
import { RdDItemSort } from "./item-sort.js";
export class RdDActor extends Actor { export class RdDActor extends Actor {
@ -135,9 +136,13 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async performRoll(rollData, attacker = undefined) { async performRoll(rollData, attacker = undefined) {
// Cas des bonus de cases pour les sorts
let sortBonus = 0;
if (rollData.selectedSort) {
sortBonus = RdDItemSort.getCaseBonus( rollData.selectedSort, rollData.coord );
}
// garder le résultat // garder le résultat
rollData.rolled = await RdDResolutionTable.roll(rollData.caracValue, rollData.finalLevel); rollData.rolled = await RdDResolutionTable.roll(rollData.caracValue, rollData.finalLevel, sortBonus);
//console.log("performRoll", rollData) //console.log("performRoll", rollData)
if ( !rollData.attackerRoll) {// Store in the registry if not a defense roll if ( !rollData.attackerRoll) {// Store in the registry if not a defense roll
@ -313,8 +318,11 @@ export class RdDActor extends Actor {
if (rolled.isPart) { if (rolled.isPart) {
coutReve = Math.max(Math.ceil(coutReve / 2), 1); coutReve = Math.max(Math.ceil(coutReve / 2), 1);
} }
// Incrémenter/gére le bonus de case
RdDItemSort.incrementBonusCase(this, sort, rollData.coord);
if (myReve.value > coutReve){ if (myReve.value > coutReve){
explications += "<br>Réussite du sort: " + coutReve + " points de Rêve sont dépensés"; explications += "<br>Réussite du sort: " + coutReve + " points de Rêve sont dépensés (Bonus de case : +" + rolled.bonus + "%)";
if (rollData.isSortReserve) { if (rollData.isSortReserve) {
// Mise en réserve // Mise en réserve
@ -354,6 +362,7 @@ export class RdDActor extends Actor {
return explications return explications
} }
/* -------------------------------------------- */
async dormirChateauDormant() { async dormirChateauDormant() {
let message = { let message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs( this.name ), whisper: ChatUtility.getWhisperRecipientsAndGMs( this.name ),
@ -373,6 +382,7 @@ export class RdDActor extends Actor {
ChatMessage.create( message ); ChatMessage.create( message );
} }
/* -------------------------------------------- */
async _recupererBlessures(message, type, liste, moindres) { async _recupererBlessures(message, type, liste, moindres) {
let count = 0; let count = 0;
const definitions = RdDUtility.getDefinitionsBlessures(); const definitions = RdDUtility.getDefinitionsBlessures();
@ -813,7 +823,7 @@ export class RdDActor extends Actor {
let refoulement = duplicate(this.data.data.reve.refoulement); let refoulement = duplicate(this.data.data.reve.refoulement);
refoulement.value = refoulement.value + value; refoulement.value = refoulement.value + value;
let total = new Roll("d20").roll().total; let total = new Roll("1d20").roll().total;
if ( total <= refoulement.value ) { if ( total <= refoulement.value ) {
refoulement.value = 0; refoulement.value = 0;
this.ajouterSouffle(); this.ajouterSouffle();
@ -926,7 +936,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
testSiSonne( sante, endurance ) testSiSonne( sante, endurance )
{ {
let result = new Roll("d20").roll().total; let result = new Roll("1d20").roll().total;
if ( result <= endurance) if ( result <= endurance)
sante.sonne.value = false; sante.sonne.value = false;
if ( result > endurance || result == 20) // 20 is always a failure if ( result > endurance || result == 20) // 20 is always a failure

View File

@ -1,3 +1,5 @@
import { RdDItemSort } from "./item-sort.js";
/** /**
* Extend the basic ItemSheet with some very simple modifications * Extend the basic ItemSheet with some very simple modifications
* @extends {ItemSheet} * @extends {ItemSheet}
@ -25,6 +27,15 @@ export class RdDItemSheet extends ItemSheet {
sheetBody.css("height", bodyHeight); sheetBody.css("height", bodyHeight);
return position; return position;
} }
/* -------------------------------------------- */
getData() {
let data = super.getData();
data.bonusCaseList = RdDItemSort.getBonusCaseList(data, true);
return data;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -63,6 +74,9 @@ export class RdDItemSheet extends ItemSheet {
/** @override */ /** @override */
_updateObject(event, formData) { _updateObject(event, formData) {
// Données de bonus de cases ?
formData = RdDItemSort.buildBonusCaseStringFromFormData( formData );
return this.object.update(formData); return this.object.update(formData);
} }
} }

View File

@ -1,20 +1,28 @@
/* -------------------------------------------- */
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { TMRUtility } from "./tmr-utility.js";
/* -------------------------------------------- */
export class RdDItemSort extends Item { export class RdDItemSort extends Item {
/* -------------------------------------------- */
static isDifficulteVariable(sort) { static isDifficulteVariable(sort) {
return sort && (sort.data.difficulte.toLowerCase() == "variable"); return sort && (sort.data.difficulte.toLowerCase() == "variable");
} }
/* -------------------------------------------- */
static isCoutVariable(sort) { static isCoutVariable(sort) {
return sort && (sort.data.ptreve.toLowerCase() == "variable" || sort.data.ptreve.indexOf("+") >= 0); return sort && (sort.data.ptreve.toLowerCase() == "variable" || sort.data.ptreve.indexOf("+") >= 0);
} }
/* -------------------------------------------- */
static setCoutReveReel(sort){ static setCoutReveReel(sort){
if (sort) { if (sort) {
sort.data.ptreve_reel = this.isCoutVariable(sort) ? 1 : sort.data.ptreve; sort.data.ptreve_reel = this.isCoutVariable(sort) ? 1 : sort.data.ptreve;
} }
} }
/* -------------------------------------------- */
static getDifficulte(sort, variable) { static getDifficulte(sort, variable) {
if (sort && !RdDItemSort.isDifficulteVariable(sort)) { if (sort && !RdDItemSort.isDifficulteVariable(sort)) {
return Misc.toInt(sort.data.difficulte); return Misc.toInt(sort.data.difficulte);
@ -22,4 +30,89 @@ export class RdDItemSort extends Item {
return variable; return variable;
} }
/* -------------------------------------------- */
static buildBonusCaseList( caseBonusString, newCase ) {
let bonusCaseList = [];
let bonusCaseArray = caseBonusString.split(',');
for( let bonusCase of bonusCaseArray) {
let bonusSplit = bonusCase.split(':');
bonusCaseList.push( { case: bonusSplit[0], bonus: bonusSplit[1] } );
}
if ( newCase )
bonusCaseList.push( {case: "Nouvelle", bonus: 0} );
return bonusCaseList;
}
/* -------------------------------------------- */
/**
* Retourne une liste de bonus/case pour un item-sheet
* @param {} item
*/
static getBonusCaseList( data, newCase = false ) {
let bonusCaseList = [];
// Gestion spéciale case bonus
if ( data.item.type == 'sort') {
bonusCaseList = this.buildBonusCaseList(data.data.bonuscase, newCase );
}
return bonusCaseList;
}
/* -------------------------------------------- */
/** Met à jour les données de formulaire
* si static des bonus de cases sont présents
* */
static buildBonusCaseStringFromFormData( formData ) {
if ( formData.bonusValue ) {
let list = [];
for(let i=0; i<formData.bonusValue.length; i++) {
let caseTMR = formData.caseValue[i] || 'A1';
caseTMR = caseTMR.toUpperCase();
if ( TMRUtility.verifyTMRCoord( caseTMR ) ) { // Sanity check
let bonus = formData.bonusValue[i] || 0;
list.push( caseTMR+":"+bonus );
}
}
formData.bonusValue = undefined;
formData.caseValue = undefined;
formData['data.bonuscase'] = list.toString(); // Reset
}
return formData;
}
/* -------------------------------------------- */
static incrementBonusCase( actor, sort, coordTMR ) {
let bonusCaseList = this.buildBonusCaseList(sort.data.bonuscase, false);
//console.log("ITEMSORT", sort, bonusCaseList);
let found = false;
let StringList = [];
for( let bc of bonusCaseList) {
if (bc.case == coordTMR) { // Case existante
found = true;
bc.bonus = Number(bc.bonus) + 1;
}
StringList.push( bc.case+':'+bc.bonus );
}
if ( !found) { //Nouvelle case, bonus de 1
StringList.push(coordTMR+':1');
}
// Sauvegarde/update
let bonuscase = StringList.toString();
//console.log("Bonus cae :", bonuscase);
actor.updateEmbeddedEntity("OwnedItem", { _id: sort._id, 'data.bonuscase': bonuscase } );
}
/* -------------------------------------------- */
static getCaseBonus( sort, coordTMR) {
let bonusCaseList = this.buildBonusCaseList(sort.data.bonuscase, false);
for( let bc of bonusCaseList) {
if (bc.case == coordTMR) { // Case existante
return bc.bonus;
}
}
return 0;
}
} }

View File

@ -76,6 +76,7 @@ export class RdDResolutionTable {
return resultat; return resultat;
} }
/* -------------------------------------------- */
static explain(rolled) { static explain(rolled) {
let message = "<br>Jet : <strong>" + rolled.roll + "</strong> sur " + rolled.score + "%"; let message = "<br>Jet : <strong>" + rolled.roll + "</strong> sur " + rolled.score + "%";
if (rolled.caracValue != null && rolled.finalLevel!= null) { if (rolled.caracValue != null && rolled.finalLevel!= null) {
@ -84,19 +85,32 @@ export class RdDResolutionTable {
return message; return message;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async roll(caracValue, finalLevel) { static updateChancesWithBonus( chances, bonus ) {
let newScore = Number(chances.score) + Number(bonus);
chances.score = newScore;
chances.sign = this._reussiteSignificative(newScore);
chances.part = this._reussitePart(newScore);
chances.epart = this._echecParticulier(newScore);
chances.etotal = this._echecTotal(newScore);
}
/* -------------------------------------------- */
static async roll(caracValue, finalLevel, bonus = 0 ) {
let chances = this.computeChances(caracValue, finalLevel); let chances = this.computeChances(caracValue, finalLevel);
chances.showDice = true; chances.showDice = true;
this.updateChancesWithBonus( chances, bonus);
let rolled = await this.rollChances(chances); let rolled = await this.rollChances(chances);
rolled.caracValue = caracValue; rolled.caracValue = caracValue;
rolled.finalLevel = finalLevel; rolled.finalLevel = finalLevel;
rolled.bonus = bonus;
return rolled; return rolled;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async rollChances(chances) { static async rollChances(chances) {
let myRoll = new Roll("d100").roll(); let myRoll = new Roll("1d100").roll();
myRoll.showDice = chances.showDice; myRoll.showDice = chances.showDice;
await RdDDice.show(myRoll); await RdDDice.show(myRoll);
chances.roll = myRoll.total; chances.roll = myRoll.total;
@ -211,6 +225,7 @@ export class RdDResolutionTable {
return table; return table;
} }
/* -------------------------------------------- */
static _buildHTMLHeader(dataRow, minLevel, maxLevel) { static _buildHTMLHeader(dataRow, minLevel, maxLevel) {
let tr = $("<tr/>"); let tr = $("<tr/>");
@ -226,6 +241,7 @@ export class RdDResolutionTable {
return tr; return tr;
} }
/* -------------------------------------------- */
static _buildHTMLRow(dataRow, rowIndex, caracValue, levelValue, minLevel, maxLevel) { static _buildHTMLRow(dataRow, rowIndex, caracValue, levelValue, minLevel, maxLevel) {
let tr = $("<tr/>"); let tr = $("<tr/>");
let max = maxLevel; let max = maxLevel;

View File

@ -44,16 +44,17 @@ export class RdDRollDialog extends Dialog {
} }
super(dialogConf, dialogOptions) super(dialogConf, dialogOptions)
this.mode = mode this.mode = mode;
this.rollData = rollData this.rollData = rollData;
this.actor = actor this.actor = actor;
this.attacker = attacker if (attacker)
this.attacker = attacker;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
performRollSort(html, isSortReserve = false) { performRollSort(html, isSortReserve = false) {
this.rollData.isSortReserve = isSortReserve; this.rollData.isSortReserve = isSortReserve;
this.actor.performRoll(this.rollData, attacker); this.actor.performRoll(this.rollData, this.attacker);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@ -271,7 +271,7 @@ export class RdDTMRDialog extends Dialog {
let rencontre = this.rencontresExistantes.find(prev => prev.coord == coordTMR); let rencontre = this.rencontresExistantes.find(prev => prev.coord == coordTMR);
if (rencontre == undefined) { if (rencontre == undefined) {
let myRoll = new Roll("d7").roll(); let myRoll = new Roll("1d7").roll();
if (myRoll.total == 7) { if (myRoll.total == 7) {
rencontre = await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr); rencontre = await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr);
} }

View File

@ -540,7 +540,7 @@ export class RdDUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static getLocalisation( ) static getLocalisation( )
{ {
let result = new Roll("d20").roll().total; let result = new Roll("1d20").roll().total;
let txt = "" let txt = ""
if ( result <= 3 ) txt = "Jambe, genou, pied, jarret"; if ( result <= 3 ) txt = "Jambe, genou, pied, jarret";
else if ( result <= 7 ) txt = "Hanche, cuisse, fesse"; else if ( result <= 7 ) txt = "Hanche, cuisse, fesse";

View File

@ -253,9 +253,12 @@ const tmrMovePattern =
{ name: 'topleft', x: -1, y: -1 } { name: 'topleft', x: -1, y: -1 }
] ]
/* -------------------------------------------- */
/* -------------------------------------------- */ /* -------------------------------------------- */
export class TMRUtility { export class TMRUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static convertToTMRCoord( x, y ) static convertToTMRCoord( x, y )
{ {
@ -264,6 +267,18 @@ export class TMRUtility {
return letterX+y return letterX+y
} }
/* -------------------------------------------- */
static verifyTMRCoord( coord ) {
let TMRregexp = new RegExp(/([A-M])(\d+)/g);
let res = TMRregexp.exec( coord );
if (res && res[1] && res[2]) {
if (res[2] > 0 && res[2] < 16) {
return true;
}
}
return false;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static convertToCellCoord( coordTMR ) static convertToCellCoord( coordTMR )
{ {
@ -294,7 +309,7 @@ export class TMRUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static getDirectionPattern() { static getDirectionPattern() {
let index = new Roll("d"+tmrMovePattern.length+" -1").roll().total; let index = new Roll("1d"+tmrMovePattern.length+" -1").roll().total;
return tmrMovePattern[index]; return tmrMovePattern[index];
} }
@ -344,7 +359,7 @@ export class TMRUtility {
static async rencontreTMRTypeCase(typeTMR, roll=undefined) { static async rencontreTMRTypeCase(typeTMR, roll=undefined) {
if (!roll) { if (!roll) {
//roll = await RdDDice.show(new Roll("d100").evaluate()).total; //roll = await RdDDice.show(new Roll("d100").evaluate()).total;
roll = new Roll("d100").roll().total; roll = new Roll("1d100").roll().total;
console.log("rencontreTMRTypeCase", roll); console.log("rencontreTMRTypeCase", roll);
} }
typeTMR = typeTMR.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""); typeTMR = typeTMR.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
@ -373,7 +388,7 @@ export class TMRUtility {
return false; return false;
} }
if (roll == undefined) { if (roll == undefined) {
roll = new Roll("d100").evaluate().total; roll = new Roll("1d100").evaluate().total;
} }
roll = Math.max(1, Math.min(roll, 100)); roll = Math.max(1, Math.min(roll, 100));

View File

@ -5,7 +5,7 @@
"version": "1.1.0", "version": "1.1.0",
"minimumCoreVersion": "0.7.5", "minimumCoreVersion": "0.7.5",
"compatibleCoreVersion": "0.7.7", "compatibleCoreVersion": "0.7.7",
"templateVersion": 54, "templateVersion": 55,
"author": "LeRatierBretonnien", "author": "LeRatierBretonnien",
"esmodules": [ "module/rdd-main.js", "module/hook-renderChatLog.js" ], "esmodules": [ "module/rdd-main.js", "module/hook-renderChatLog.js" ],
"styles": ["styles/simple.css"], "styles": ["styles/simple.css"],

View File

@ -530,7 +530,7 @@
} }
}, },
"Item": { "Item": {
"types": ["objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle", "tete", "competencecreature", "tarot"], "types": ["objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle", "tete", "competencecreature", "tarot", "monnaie"],
"objet": { "objet": {
"description": "", "description": "",
"quantite": 1, "quantite": 1,
@ -611,7 +611,8 @@
"caseTMR": "", "caseTMR": "",
"caseTMRspeciale": "", "caseTMRspeciale": "",
"ptreve": "", "ptreve": "",
"xp": 0 "xp": 0,
"bonuscase": ""
}, },
"herbe": { "herbe": {
"description": "", "description": "",
@ -675,11 +676,17 @@
}, },
"tete": { "tete": {
"description": "" "description": ""
}, },
"tarot": { "tarot": {
"concept":"", "concept":"",
"aspect":"", "aspect":"",
"description": "" "description": ""
} },
"monnaie": {
"quantite": "",
"valeur_deniers":0,
"encombrement":0,
"description": ""
} }
} }
}

View File

@ -56,6 +56,13 @@
<label for="xp">XP </label> <label for="xp">XP </label>
<input class="attribute-value" type="text" name="data.xp" value="{{data.xp}}" data-dtype="Number"/> <input class="attribute-value" type="text" name="data.xp" value="{{data.xp}}" data-dtype="Number"/>
</div> </div>
{{#each bonusCaseList as |bcData key|}}
<div class="form-group">
<label for="bonuscase">Case/Bonus :</label>
<input class="attribute-value" type="text" name="caseValue" value="{{bcData.case}}" data-dtype="String"/>
<input class="attribute-value" type="text" name="bonusValue" value="{{bcData.bonus}}" data-dtype="Number"/>
</div>
{{/each}}
<div class="flexcol"> <div class="flexcol">
<span><label>Description : </label></span> <span><label>Description : </label></span>
<div class="form-group editor"> <div class="form-group editor">