#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 { RdDRollTables } from "./rdd-rolltables.js";
import { ChatUtility } from "./chat-utility.js";
import { RdDItemSort } from "./item-sort.js";
export class RdDActor extends Actor {
@ -135,9 +136,13 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
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
rollData.rolled = await RdDResolutionTable.roll(rollData.caracValue, rollData.finalLevel);
rollData.rolled = await RdDResolutionTable.roll(rollData.caracValue, rollData.finalLevel, sortBonus);
//console.log("performRoll", rollData)
if ( !rollData.attackerRoll) {// Store in the registry if not a defense roll
@ -313,8 +318,11 @@ export class RdDActor extends Actor {
if (rolled.isPart) {
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){
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) {
// Mise en réserve
@ -354,6 +362,7 @@ export class RdDActor extends Actor {
return explications
}
/* -------------------------------------------- */
async dormirChateauDormant() {
let message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs( this.name ),
@ -373,6 +382,7 @@ export class RdDActor extends Actor {
ChatMessage.create( message );
}
/* -------------------------------------------- */
async _recupererBlessures(message, type, liste, moindres) {
let count = 0;
const definitions = RdDUtility.getDefinitionsBlessures();
@ -813,7 +823,7 @@ export class RdDActor extends Actor {
let refoulement = duplicate(this.data.data.reve.refoulement);
refoulement.value = refoulement.value + value;
let total = new Roll("d20").roll().total;
let total = new Roll("1d20").roll().total;
if ( total <= refoulement.value ) {
refoulement.value = 0;
this.ajouterSouffle();
@ -926,7 +936,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
testSiSonne( sante, endurance )
{
let result = new Roll("d20").roll().total;
let result = new Roll("1d20").roll().total;
if ( result <= endurance)
sante.sonne.value = false;
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
* @extends {ItemSheet}
@ -26,6 +28,15 @@ export class RdDItemSheet extends ItemSheet {
return position;
}
/* -------------------------------------------- */
getData() {
let data = super.getData();
data.bonusCaseList = RdDItemSort.getBonusCaseList(data, true);
return data;
}
/* -------------------------------------------- */
/** @override */
@ -63,6 +74,9 @@ export class RdDItemSheet extends ItemSheet {
/** @override */
_updateObject(event, formData) {
// Données de bonus de cases ?
formData = RdDItemSort.buildBonusCaseStringFromFormData( formData );
return this.object.update(formData);
}
}

View File

@ -1,20 +1,28 @@
/* -------------------------------------------- */
import { Misc } from "./misc.js";
import { TMRUtility } from "./tmr-utility.js";
/* -------------------------------------------- */
export class RdDItemSort extends Item {
/* -------------------------------------------- */
static isDifficulteVariable(sort) {
return sort && (sort.data.difficulte.toLowerCase() == "variable");
}
/* -------------------------------------------- */
static isCoutVariable(sort) {
return sort && (sort.data.ptreve.toLowerCase() == "variable" || sort.data.ptreve.indexOf("+") >= 0);
}
/* -------------------------------------------- */
static setCoutReveReel(sort){
if (sort) {
sort.data.ptreve_reel = this.isCoutVariable(sort) ? 1 : sort.data.ptreve;
}
}
/* -------------------------------------------- */
static getDifficulte(sort, variable) {
if (sort && !RdDItemSort.isDifficulteVariable(sort)) {
return Misc.toInt(sort.data.difficulte);
@ -22,4 +30,89 @@ export class RdDItemSort extends Item {
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;
}
/* -------------------------------------------- */
static explain(rolled) {
let message = "<br>Jet : <strong>" + rolled.roll + "</strong> sur " + rolled.score + "%";
if (rolled.caracValue != null && rolled.finalLevel!= null) {
@ -84,19 +85,32 @@ export class RdDResolutionTable {
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);
chances.showDice = true;
this.updateChancesWithBonus( chances, bonus);
let rolled = await this.rollChances(chances);
rolled.caracValue = caracValue;
rolled.finalLevel = finalLevel;
rolled.bonus = bonus;
return rolled;
}
/* -------------------------------------------- */
static async rollChances(chances) {
let myRoll = new Roll("d100").roll();
let myRoll = new Roll("1d100").roll();
myRoll.showDice = chances.showDice;
await RdDDice.show(myRoll);
chances.roll = myRoll.total;
@ -211,6 +225,7 @@ export class RdDResolutionTable {
return table;
}
/* -------------------------------------------- */
static _buildHTMLHeader(dataRow, minLevel, maxLevel) {
let tr = $("<tr/>");
@ -226,6 +241,7 @@ export class RdDResolutionTable {
return tr;
}
/* -------------------------------------------- */
static _buildHTMLRow(dataRow, rowIndex, caracValue, levelValue, minLevel, maxLevel) {
let tr = $("<tr/>");
let max = maxLevel;

View File

@ -44,16 +44,17 @@ export class RdDRollDialog extends Dialog {
}
super(dialogConf, dialogOptions)
this.mode = mode
this.rollData = rollData
this.actor = actor
this.attacker = attacker
this.mode = mode;
this.rollData = rollData;
this.actor = actor;
if (attacker)
this.attacker = attacker;
}
/* -------------------------------------------- */
performRollSort(html, isSortReserve = false) {
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);
if (rencontre == undefined) {
let myRoll = new Roll("d7").roll();
let myRoll = new Roll("1d7").roll();
if (myRoll.total == 7) {
rencontre = await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr);
}

View File

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

View File

@ -253,9 +253,12 @@ const tmrMovePattern =
{ name: 'topleft', x: -1, y: -1 }
]
/* -------------------------------------------- */
/* -------------------------------------------- */
export class TMRUtility {
/* -------------------------------------------- */
static convertToTMRCoord( x, y )
{
@ -264,6 +267,18 @@ export class TMRUtility {
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 )
{
@ -294,7 +309,7 @@ export class TMRUtility {
/* -------------------------------------------- */
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];
}
@ -344,7 +359,7 @@ export class TMRUtility {
static async rencontreTMRTypeCase(typeTMR, roll=undefined) {
if (!roll) {
//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);
}
typeTMR = typeTMR.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
@ -373,7 +388,7 @@ export class TMRUtility {
return false;
}
if (roll == undefined) {
roll = new Roll("d100").evaluate().total;
roll = new Roll("1d100").evaluate().total;
}
roll = Math.max(1, Math.min(roll, 100));

View File

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

View File

@ -530,7 +530,7 @@
}
},
"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": {
"description": "",
"quantite": 1,
@ -611,7 +611,8 @@
"caseTMR": "",
"caseTMRspeciale": "",
"ptreve": "",
"xp": 0
"xp": 0,
"bonuscase": ""
},
"herbe": {
"description": "",
@ -675,11 +676,17 @@
},
"tete": {
"description": ""
},
},
"tarot": {
"concept":"",
"aspect":"",
"description": ""
}
},
"monnaie": {
"quantite": "",
"valeur_deniers":0,
"encombrement":0,
"description": ""
}
}
}

View File

@ -56,6 +56,13 @@
<label for="xp">XP </label>
<input class="attribute-value" type="text" name="data.xp" value="{{data.xp}}" data-dtype="Number"/>
</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">
<span><label>Description : </label></span>
<div class="form-group editor">