diff --git a/module/rdd-main.js b/module/rdd-main.js index 80f1ab46..8aadd67e 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -15,6 +15,7 @@ import { RdDActorCreatureSheet } from "./actor-creature-sheet.js"; import { RdDActorHumanoideSheet } from "./actor-humanoide-sheet.js"; import { RdDUtility } from "./rdd-utility.js"; import { RdDCalendrier } from "./rdd-calendrier.js"; +import { RdDResolutionTable } from "./rdd-resolution-table.js"; /* -------------------------------------------- */ /* Foundry VTT Initialization */ @@ -112,12 +113,12 @@ Hooks.once("init", async function() { // Define custom Entity classes CONFIG.Actor.entityClass = RdDActor; - CONFIG.RDD = {} - CONFIG.RDD.resolutionTable = RdDUtility.buildResolutionTable(); - CONFIG.RDD.level_category = RdDUtility.getLevelCategory(); - CONFIG.RDD.carac_array = RdDUtility.getCaracArray(); - CONFIG.RDD.bonusmalus = RdDUtility.getBonusMalus(); - game.data.RdDUtility = RdDUtility; + CONFIG.RDD = { + resolutionTable : RdDResolutionTable.resolutionTable, + level_category : RdDUtility.getLevelCategory(), + carac_array : RdDUtility.getCaracArray(), + bonusmalus : RdDUtility.getBonusMalus() + } // Register sheet application classes Actors.unregisterSheet("core", ActorSheet); diff --git a/module/rdd-resolution-table.js b/module/rdd-resolution-table.js new file mode 100644 index 00000000..5aa236fa --- /dev/null +++ b/module/rdd-resolution-table.js @@ -0,0 +1,99 @@ + +export class RdDResolutionTable { + static resolutionTable = this.build() + + /* -------------------------------------------- */ + static build() { + let table = [] + for (var carac = 0; carac <= 30; carac++) { + table[carac] = this._computeRow(carac); + } + return table; + } + + /* -------------------------------------------- */ + static _computeRow(carac) { + let dataRow = [ + this._computeScore(-10, Math.max(Math.floor(carac / 4), 1)), + this._computeScore(-9, Math.max(Math.floor(carac / 2), 1)) + ] + for (var diff = -8; diff <= 22; diff++) { + dataRow[diff + 10] = this._computeScore(diff, Math.max(Math.floor(carac * (diff + 10) / 2), 1)); + } + return dataRow; + } + + static _computeScore(diff, score) { + return { + niveau: diff, + score: score, + sign: this._reussiteSignificative(score), + part: this._reussitePart(score), + epart: this._echecParticulier(score), + etotal: this._echecTotal(score) + } + } + + static _reussiteSignificative(score) { + return Math.floor(score / 2); + } + + static _reussitePart(score) { + return Math.ceil(score / 5); + } + + static _echecParticulier(score) { + return Math.ceil(score / 5) + 80; + } + + static _echecTotal(score) { + return Math.ceil(score / 10) + 91; + } + + /* -------------------------------------------- */ + static buildHTMLTable(caracValue, levelValue, minCarac = 1, maxCarac = 21, minLevel = -10, maxLevel = 11) { + return this._buildHTMLTable(caracValue, levelValue, minCarac, maxCarac, minLevel, maxLevel) + } + + /* -------------------------------------------- */ + static _buildHTMLTable(caracValue, levelValue, minCarac, maxCarac, minLevel, maxLevel) { + minCarac = Math.max(minCarac, 1); + maxCarac = Math.min(maxCarac, 30); + minLevel = Math.max(minLevel, -10); + maxLevel = Math.min(maxLevel, 22); + + var table = $("") + .append(this._buildHTMLHeader(this.resolutionTable[0], minLevel, maxLevel)); + + for (var carac = minCarac; carac <= maxCarac; carac++) { + table.append(this._buildHTMLRow(this.resolutionTable[carac], carac, caracValue, levelValue, minLevel, maxLevel)); + } + return table; + } + + static _buildHTMLHeader(dataRow, minLevel, maxLevel) { + var tr = $(""); + for (var difficulte = minLevel; difficulte <= maxLevel; difficulte++) { + const niveau = dataRow[difficulte + 10].niveau; + const txt = (niveau > 0 ? "+" : "") + niveau; + tr.append($(""); + for (var difficulte = minLevel; difficulte <= maxLevel; difficulte++) { + var td = $(""); - for (var colIndex=minLevel; colIndex <= maxLevel; colIndex++) { - let c = dataRow[colIndex]; - let txt = (c.niveau > 0) ? "+"+c.niveau : c.niveau; - row.append($(""); - for (var colIndex=minLevel; colIndex <= maxLevel; colIndex++) { - let c = dataRow[colIndex]; - if (rowIndex == caracValue && levelValue+10 == colIndex) { - row.append($("
").text(txt)); + } + return tr; + } + + static _buildHTMLRow(dataRow, rowIndex, caracValue, levelValue, minLevel, maxLevel) { + var tr = $("
"); + let score = dataRow[difficulte + 10].score; + if (rowIndex == caracValue && levelValue == difficulte) { + td.addClass('table-resolution-target'); + } else if (difficulte == -8) { + td.addClass('table-resolution-carac'); + } + tr.append(td.text(score)); + } + return tr; + } + +} \ No newline at end of file diff --git a/module/rdd-roll-dialog.js b/module/rdd-roll-dialog.js index a3bdbf71..c66316ae 100644 --- a/module/rdd-roll-dialog.js +++ b/module/rdd-roll-dialog.js @@ -1,132 +1,141 @@ +import { RdDResolutionTable } from "./rdd-resolution-table.js"; +import { RdDUtility } from "./rdd-utility.js"; + /** * Extend the base Dialog entity by defining a custom window to perform roll. * @extends {Dialog} */ - export class RdDRollDialog extends Dialog { - - /* -------------------------------------------- */ + + /* -------------------------------------------- */ constructor(mode, html, rollData, actor) { - let myButtons = { rollButton: { - label: "Lancer", - callback: html => this.performRollSort(html, false) - } }; + + let myButtons if (mode == "sort") { - myButtons['reserveButton'] = { label: "Mettre en reserve", - callback: html => this.performRollSort(html, true) - } + myButtons = { + rollButton: { label: "Lancer le sort", callback: html => this.performRollSort(html, false) }, + reserveButton: { label: "Mettre en reserve", callback: html => this.performRollSort(html, true) } + } } - + else { + myButtons = { + rollButton: { label: "Lancer", callback: html => this.actor.performRoll(this.rollData) } + }; + } + // Common conf - let dialogConf = { - content: html, - buttons: myButtons, - default: "rollButton" - } - let dialogOptions = { classes: [ "rdddialog"] } - + let dialogConf = { content: html, title: "Test", buttons: myButtons, default: "rollButton" } + let dialogOptions = { classes: ["rdddialog"], width: 600, height: 400 } + // Select proper roll dialog template and stuff - if (mode == "competence" ) { - dialogConf.title = "Test de compétence", - dialogOptions.width = 600; - dialogOptions.height = 360; + if (mode == "competence") { + dialogConf.title = "Test de compétence" + dialogConf.height = 400 } else if (mode == "arme") { - dialogConf.title = "Test de combat/arme", - dialogOptions.width = 600; - dialogOptions.height = 360; + dialogConf.title = "Test de combat/arme" + dialogConf.height = 430 } else if (mode == "carac") { - dialogConf.title = "Test de caractéristique", - dialogOptions.width = 600; - dialogOptions.height = 320; + dialogConf.title = "Test de caractéristique" + dialogOptions.height = 350 } else if (mode == "sort") { - dialogConf.title = "Lancer un sort", - dialogOptions.width = 600; - dialogOptions.height = 380; + dialogConf.title = "Lancer un sort" + dialogConf.height = 450 } - super(dialogConf, dialogOptions); + super(dialogConf, dialogOptions) - this.mode = mode; - this.rollData = rollData; - this.actor = actor; - } - - /* -------------------------------------------- */ - performRollSort (html, isReserve=false) { - this.rollData.isSortReserve = isReserve; - this.actor.performRoll( this.rollData ); + this.mode = mode + this.rollData = rollData + this.actor = actor } - /* -------------------------------------------- */ - activateListeners(html) { - super.activateListeners(html); - - // Get the rollData stuff - var rollData = this.rollData; - - function updateRollResult( rollData ) { - if ( rollData.competence ) - rollData.finalLevel = parseInt(rollData.competence.data.niveau) + parseInt(rollData.bmValue) + parseInt(rollData.etat); - else if ( rollData.draconicList ) - rollData.finalLevel = parseInt(rollData.selectedDraconic.data.niveau) + parseInt(rollData.selectedSort.data.difficulte) + parseInt(rollData.etat); - else - rollData.finalLevel = parseInt(rollData.bmValue) + parseInt(rollData.etat); - - rollData.finalLevelStr = (rollData.finalLevel >= 0 ) ? "+" + rollData.finalLevel : rollData.finalLevel; - $("#roll-param").text( rollData.selectedCarac.value + " / " + rollData.finalLevelStr ); - rollData.rollTarget = game.data.RdDUtility.getResolutionField( rollData.selectedCarac.value, rollData.finalLevel); + /* -------------------------------------------- */ + performRollSort(html, isReserve = false) { + this.rollData.isSortReserve = isReserve; + this.actor.performRoll(this.rollData); + } - let armeTitle = ( rollData.arme ) ? " ("+rollData.arme.name+") " : ""; // If a weapon is there, add it in the title - let niveauStr = ""; - if ( rollData.competence ) { - niveauStr = (rollData.competence.data.niveau >= 0) ? "+" + rollData.competence.data.niveau : rollData.competence.data.niveau; - $("#compdialogTitle").text( rollData.selectedCarac.label + "/" + rollData.competence.name + armeTitle + " " + niveauStr ); - } else if ( rollData.draconicList) { - $("#compdialogTitle").text( rollData.selectedDraconic.name + " - " + rollData.selectedSort.name ); - } else { - $("#compdialogTitle").text( rollData.selectedCarac.label ); - } + /* -------------------------------------------- */ + activateListeners(html) { + super.activateListeners(html); + + // Get the rollData stuff + var rollData = this.rollData; + + function updateRollResult(rollData) { + let caracValue = parseInt(rollData.selectedCarac.value) + let rollLevel = RdDRollDialog._computeFinalLevel(rollData); + + rollData.finalLevel = rollLevel; + rollData.finalLevelStr = (rollLevel > 0 ? "+" : "") + rollLevel; + rollData.rollTarget = RdDUtility.getResolutionField(rollData.selectedCarac.value, rollData.finalLevel); + + $("#roll-param").text(rollData.selectedCarac.value + " / " + rollData.finalLevelStr); + $("#compdialogTitle").text(RdDRollDialog._getTitle(rollData)); $(".table-resolution").remove(); - game.data.RdDUtility.makeHTMLResolutionTable( $("#resolutionTable"), rollData.selectedCarac.value-2, parseInt(rollData.selectedCarac.value) + 2, -10, 11, - rollData.selectedCarac.value, rollData.finalLevel ); + $("#resolutionTable").append(RdDResolutionTable.buildHTMLTable(caracValue, rollLevel, caracValue - 2, caracValue + 2)); } - + // Setup everything onload - $(function() { + $(function () { // Update html, according to data if (rollData.competence) { // Set the default carac from the competence item console.log(rollData.competence.data.defaut_carac, rollData.carac); rollData.selectedCarac = rollData.carac[rollData.competence.data.defaut_carac]; - $("#carac").val( rollData.competence.data.defaut_carac ); + $("#carac").val(rollData.competence.data.defaut_carac); } - $("#bonusmalus").val( rollData.bmValue ); + $("#bonusmalus").val(rollData.bmValue); updateRollResult(rollData); }); - + // Update ! - html.find('#bonusmalus').click((event) => { + html.find('#bonusmalus').click((event) => { rollData.bmValue = event.currentTarget.value; // Update the selected bonus/malus //console.log("BM CLICKED !!!", rollData.bmValue, rollData.competence.data.niveau, parseInt(rollData.competence.data.niveau) + parseInt(rollData.bmValue) ); updateRollResult(rollData); }); - html.find('#carac').click((event) => { - let caracKey = event.currentTarget.value; + html.find('#carac').click((event) => { + let caracKey = event.currentTarget.value; rollData.selectedCarac = rollData.carac[caracKey]; // Update the selectedCarac //console.log("CARAC CLICKED !!!", rollData.selectedCarac, rollData.competence.data.niveau, rollData.bmValue); updateRollResult(rollData); - }); - html.find('#draconic').click((event) => { - let draconicKey = event.currentTarget.value; + }); + html.find('#draconic').click((event) => { + let draconicKey = event.currentTarget.value; rollData.selectedDraconic = rollData.draconicList[draconicKey]; // Update the selectedCarac //console.log("CARAC CLICKED !!!", rollData.selectedCarac, rollData.competence.data.niveau, rollData.bmValue); updateRollResult(rollData); - }); - html.find('#sort').click((event) => { - let sortKey = event.currentTarget.value; + }); + html.find('#sort').click((event) => { + let sortKey = event.currentTarget.value; rollData.selectedSort = rollData.sortList[sortKey]; // Update the selectedCarac //console.log("CARAC CLICKED !!!", rollData.selectedCarac, rollData.competence.data.niveau, rollData.bmValue); updateRollResult(rollData); - }); + }); + + + } + static _computeFinalLevel(rollData) { + let etat = rollData.etat === undefined ? 0 : parseInt(rollData.etat); + if (rollData.competence) { + return etat + parseInt(rollData.competence.data.niveau) + parseInt(rollData.bmValue); + } + if (rollData.draconicList) { + return etat + parseInt(rollData.selectedDraconic.data.niveau) + parseInt(rollData.selectedSort.data.difficulte); + } + return etat + parseInt(rollData.bmValue); } + static _getTitle(rollData) { + if (rollData.competence) { + // If a weapon is there, add it in the title + let armeTitle = (rollData.arme) ? " (" + rollData.arme.name + ") " : ""; + let niveauStr = (rollData.competence.data.niveau > 0 ? "+" : "") + rollData.competence.data.niveau; + return rollData.selectedCarac.label + "/" + rollData.competence.name + armeTitle + " " + niveauStr + } + if (rollData.draconicList) { + return rollData.selectedDraconic.name + " - " + rollData.selectedSort.name; + } + return rollData.selectedCarac.label; + } } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index d0d57571..284ad567 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -1,8 +1,8 @@ /* Common useful functions shared between objects */ -import { RdDActor } from "./actor.js"; import { TMRUtility } from "./tmr-utility.js"; import { RdDRollTables } from "./rdd-rolltables.js"; +import { RdDResolutionTable } from "./rdd-resolution-table.js"; const level_category = { "generale": "-4", @@ -48,12 +48,12 @@ const specialResults = [ { "part": 0, "epart": 0, "etotal": 0 }, // 0 { "part": 19, "epart": 99, "etotal": 100 }, // 81-95 { "part": 20, "epart": 100, "etotal": 100 } // 96-00 ]; -const levelDown = [ { "level": -11, "score": 1, "part": 0, "epart": 2, "etotal": 90 }, - { "level": -12, "score": 1, "part": 0, "epart": 2, "etotal": 70 }, - { "level": -13, "score": 1, "part": 0, "epart": 2, "etotal": 50 }, - { "level": -14, "score": 1, "part": 0, "epart": 2, "etotal": 30 }, - { "level": -15, "score": 1, "part": 0, "epart": 2, "etotal": 10 }, - { "level": -16, "score": 1, "part": 0, "epart": 2, "etotal": 2 } +const levelDown = [ { "level": -11, "score": 1, "sign": 0, "part": 0, "epart": 2, "etotal": 90 }, + { "level": -12, "score": 1, "sign": 0, "part": 0, "epart": 2, "etotal": 70 }, + { "level": -13, "score": 1, "sign": 0, "part": 0, "epart": 2, "etotal": 50 }, + { "level": -14, "score": 1, "sign": 0, "part": 0, "epart": 2, "etotal": 30 }, + { "level": -15, "score": 1, "sign": 0, "part": 0, "epart": 2, "etotal": 10 }, + { "level": -16, "score": 1, "sign": 0, "part": 0, "epart": 2, "etotal": 2 } ]; 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 ], @@ -160,39 +160,6 @@ export class RdDUtility { return loadTemplates(templatePaths); } - - /* -------------------------------------------- */ - static buildResolutionTable( ) { - let tableRes = [] - for (var j=0; j<=21; j++) { - let subtab = []; - for (var i=-10; i<=22; i++) { - var m = (i + 10) * 0.5; - var v; - if (i == -9) { - v = Math.floor(j / 2); - } else if (i == -10) { - v = Math.floor(j / 4); - } else { - if (j % 2 == 0) { - var v = Math.ceil(j * m); - } else { - var v = Math.floor(j * m); - } - } - if (v < 1) v = 1; - let specResults - if ( v > 100 ) - specResults = { part: Math.ceil(v / 5), epart: 1000, etotal: 1000 }; - else - specResults = specialResults[Math.ceil(v / 5 )]; - let tabIndex = i+10; - subtab[tabIndex] = { niveau: i, score: v, part: specResults.part, epart: specResults.epart, etotal: specResults.etotal } - } - tableRes[j] = subtab; - } - return tableRes; - } /* -------------------------------------------- */ static getLevelCategory( ) @@ -208,55 +175,6 @@ export class RdDUtility { return bonusmalus; } - /* -------------------------------------------- */ - static __buildHTMLResolutionHead( dataRow, minLevel=0, maxLevel=32 ) { - let r = dataRow; - var row = $("
").text(txt) ); - } - return row; - } - - /* -------------------------------------------- */ - static __buildHTMLResolutionRow( dataRow, minLevel=0, maxLevel=32, rowIndex, caracValue, levelValue ) { - let r = dataRow; - var row = $("
").text(c.score)); - } else { - if ( colIndex == 2 ) - row.append($("").text(c.score)); - else - row.append($("").text(c.score)); - } - } - return row; - } - - /* -------------------------------------------- */ - static makeHTMLResolutionTable(container, minCarac = 1, maxCarac = 21, minLevel=-10, maxLevel=22, caracValue, levelValue) { - minCarac = (minCarac < 1) ? 1 : minCarac; - maxCarac = (maxCarac > 21) ? 21 : maxCarac; - let data = CONFIG.RDD.resolutionTable; - var table = $("").addClass('table-resolution'); - // Build first row of levels - minLevel = (minLevel < -10) ? 0 : minLevel+10; - maxLevel = (maxLevel > 22) ? 32 : maxLevel+10; - let row = this.__buildHTMLResolutionHead( data[0], minLevel, maxLevel ); - table.append(row); - // Then the rest... - for (var rowIndex=minCarac; rowIndex <= maxCarac; rowIndex++) { - let row = this.__buildHTMLResolutionRow( data[rowIndex], minLevel, maxLevel, rowIndex, caracValue, levelValue ); - table.append(row); - } - return container.append(table); - } - /* -------------------------------------------- */ static isTronc( compName ) { @@ -273,8 +191,9 @@ export class RdDUtility { static getResolutionField(caracValue, levelValue ) { if ( levelValue < -16 ) { - return { "score": 0, "part": 0, "epart": 1, "etotal": 1}; - } if ( levelValue < -10 ) { + return { score: 0, sign:0, part: 0, epart: 1, etotal: 1}; + } + if ( levelValue < -10 ) { return levelDown.find(levelData => levelData.level == levelValue); } return CONFIG.RDD.resolutionTable[caracValue][levelValue+10];