Appel à la chance

+ ajout RdDRoll pour jet avec callbacks
This commit is contained in:
Vincent Vandemeulebrouck 2020-12-06 19:29:10 +01:00
parent 29eb489b27
commit 6cc594bb76
5 changed files with 292 additions and 1 deletions

View File

@ -258,6 +258,10 @@ export class RdDActorSheet extends ActorSheet {
this.actor.rollCarac( 'chance-actuel' ); this.actor.rollCarac( 'chance-actuel' );
}); });
html.find('#chance-appel').click((event) => {
this.actor.appelChance();
});
// Roll Skill // Roll Skill
html.find('.competence-label a').click((event) => { html.find('.competence-label a').click((event) => {
let compName = event.currentTarget.text; let compName = event.currentTarget.text;

View File

@ -6,6 +6,7 @@
import { RdDUtility } from "./rdd-utility.js"; import { RdDUtility } from "./rdd-utility.js";
import { TMRUtility } from "./tmr-utility.js"; import { TMRUtility } from "./tmr-utility.js";
import { RdDRollDialog } from "./rdd-roll-dialog.js"; import { RdDRollDialog } from "./rdd-roll-dialog.js";
import { RdDRoll } from "./rdd-roll.js";
import { RdDTMRDialog } from "./rdd-tmr-dialog.js"; import { RdDTMRDialog } from "./rdd-tmr-dialog.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
@ -107,6 +108,10 @@ export class RdDActor extends Actor {
return this.data.data.reve.reve.value; return this.data.data.reve.reve.value;
} }
getChanceActuel() {
return this.data.data.compteurs.chance.value;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getBestDraconic() { getBestDraconic() {
const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau); const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau);
@ -1004,7 +1009,7 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async reveActuelIncDec( value ) { async reveActuelIncDec( value ) {
let reve = duplicate(this.data.data.reve.reve); let reve = duplicate(this.data.data.reve.reve);
reve.value = Math.max(reve.value + value, 0); reve.value = Math.max(reve.value + value, 0);
await this.update( {"data.reve.reve": reve } ); await this.update( {"data.reve.reve": reve } );
@ -1294,6 +1299,52 @@ export class RdDActor extends Actor {
new RdDRollDialog("carac", html, rollData, this ).render(true); new RdDRollDialog("carac", html, rollData, this ).render(true);
} }
async appelChance( )
{
let rollData = {
selectedCarac: this.getCaracByName('chance-actuelle'),
diffConditions: this.ajustementAstrologique()
}
const dialog = await RdDRoll.create(
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
this,
rollData,
{
name: 'appelChance',
label: 'Appel à la chance',
callbacks: [
{ action: rollData => this._appelChanceResultat(rollData) }
]
}
);
dialog.render(true);
}
_appelChanceResultat(rollData) {
const message = {
user: game.user._id,
alias: this.name,
content: this.name + " fait appel à la chance" + RdDResolutionTable.explain(rollData.rolled)
};
if (rollData.rolled.isSuccess) {
message.content += "<br>Dépense d'un point de chance, l'action peut être retentée"
this.chanceActuelleIncDec(-1)
}
ChatMessage.create(message);
}
async chanceActuelleIncDec(value) {
let chance = duplicate(this.data.data.compteurs.chance);
chance.value = Math.max(chance.value + value, 0);
await this.update( {"data.compteurs.chance": chance } );
}
ajustementAstrologique() {
//TODO: selon heure et heure de naissance...
return 0;
}
getCaracByName(caracName) { getCaracByName(caracName) {
switch (caracName) switch (caracName)
{ {

View File

@ -97,6 +97,11 @@ export class RdDResolutionTable {
} }
} }
static async rollData(rollData ) {
rollData.rolled = await this.roll(rollData.caracValue, rollData.finalLevel, rollData.bonus);
return rollData;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static async roll(caracValue, finalLevel, bonus = 0 ) { static async roll(caracValue, finalLevel, bonus = 0 ) {
let chances = this.computeChances(caracValue, finalLevel); let chances = this.computeChances(caracValue, finalLevel);

230
module/rdd-roll.js Normal file
View File

@ -0,0 +1,230 @@
import { HtmlUtility } from "./html-utility.js";
import { RdDItemSort } from "./item-sort.js";
import { Misc } from "./misc.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
/**
* Extend the base Dialog entity to select roll parameters
* @extends {Dialog}
*/
export class RdDRoll extends Dialog {
static async create(htmlTemplate, actor, rollData, ...actions) {
RdDRoll._ensureCorrectActions(actions);
RdDRoll._setDefaultOptions(actor, rollData);
const html = await renderTemplate(htmlTemplate, rollData);
return new RdDRoll(actor, rollData, html, {
classes: ["rdddialog"],
width: 600, height: 500, 'z-index': 99999
}, actions);
}
static _setDefaultOptions(actor, rollData) {
mergeObject(rollData,
{
ajustementsConditions: CONFIG.RDD.ajustementsConditions,
difficultesLibres: CONFIG.RDD.difficultesLibres,
etat: actor.data.data.compteurs.etat.value,
finalLevel: 0,
diffConditions: 0,
diffLibre: 0,
malusArmureValue: 0,
surencMalusFlag: actor.data.data.attributs ? actor.data.data.attributs.malusarmure.value : 0,
surencMalusValue: actor.data.data.compteurs.surenc.value,
surencMalusApply: false,
isNatation: false,
useEncForNatation: false
},
{ overwrite: false });
}
static _ensureCorrectActions(actions) {
if (actions.length==0) {
throw 'No action defined';
}
actions.forEach(action => {
if (action.callbacks == undefined) {
action.callbacks = [{action: r => console.log(action.name, r)}];
}
});
}
constructor(actor, rollData, html, options, actions) {
let conf = {
title: actions[0].label,
content: html,
buttons: {},
default: actions[0].name
};
for (let action of actions) {
conf.buttons[action.name] = { label: action.label, callback: html => this.onAction(action, html) };
}
super(conf, options);
this.actor = actor;
this.rollData = rollData;
}
async onAction(action, html) {
await RdDResolutionTable.rollData(this.rollData);
if (action.callbacks)
for (let callback of action.callbacks) {
if (callback.condition == undefined || callback.condition(this.rollData.rolled)) {
callback.action(this.rollData);
}
}
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
this.bringToTop();
var rollData = this.rollData;
function updateRollResult(rollData) {
let caracValue = parseInt(rollData.selectedCarac.value)
let rollLevel = RdDRoll._computeFinalLevel(rollData);
rollData.finalLevel = rollLevel;
rollData.caracValue = caracValue
HtmlUtility._showControlWhen(".etat-general", !RdDRoll._isIgnoreEtatGeneral(rollData));
// Sort management
if (rollData.selectedSort) {
//console.log("Toggle show/hide", rollData.selectedSort);
HtmlUtility._showControlWhen("#div-sort-difficulte", RdDItemSort.isDifficulteVariable(rollData.selectedSort))
HtmlUtility._showControlWhen("#div-sort-ptreve", RdDItemSort.isCoutVariable(rollData.selectedSort))
}
// Mise à jour valeurs
$("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
$("#compdialogTitle").text(RdDRoll._getTitle(rollData));
$(".table-resolution").remove();
$("#resolutionTable").append(RdDResolutionTable.buildHTMLTableExtract(caracValue, rollLevel));
}
// Setup everything onload
$(function () {
// Update html, according to data
if (rollData.competence) {
// Set the default carac from the competence item
rollData.selectedCarac = rollData.carac[rollData.competence.data.defaut_carac];
$("#carac").val(rollData.competence.data.defaut_carac);
}
RdDItemSort.setCoutReveReel(rollData.selectedSort);
$("#diffLibre").val(Misc.toInt(rollData.diffLibre));
$("#diffConditions").val(Misc.toInt(rollData.diffConditions));
updateRollResult(rollData);
});
// Update !
html.find('#diffLibre').change((event) => {
rollData.diffLibre = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
//console.log("RdDRollSelectDialog","BM CLICKED !!!", rollData);
updateRollResult(rollData);
});
html.find('#diffConditions').change((event) => {
rollData.diffConditions = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
//console.log("RdDRollSelectDialog","BM CLICKED !!!", rollData);
updateRollResult(rollData);
});
html.find('#carac').change((event) => {
let caracKey = event.currentTarget.value;
this.rollData.selectedCarac = rollData.carac[caracKey]; // Update the selectedCarac
//console.log("RdDRollSelectDialog","CARAC CLICKED !!!", rollData);
updateRollResult(rollData);
});
html.find('#draconic').change((event) => {
let draconicKey = Misc.toInt(event.currentTarget.value);
this.rollData.selectedDraconic = rollData.draconicList[draconicKey]; // Update the selectedCarac
//console.log("RdDRollSelectDialog","CARAC CLICKED !!!", rollData);
updateRollResult(rollData);
});
html.find('#sort').change((event) => {
let sortKey = Misc.toInt(event.currentTarget.value);
this.rollData.selectedSort = rollData.sortList[sortKey]; // Update the selectedCarac
RdDItemSort.setCoutReveReel(rollData.selectedSort);
//console.log("RdDRollSelectDialog - Sort selection", rollData.selectedSort);
updateRollResult(rollData);
});
html.find('#ptreve-variable').change((event) => {
let ptreve = Misc.toInt(event.currentTarget.value);
this.rollData.selectedSort.data.ptreve_reel = ptreve;
console.log("RdDRollSelectDialog - Cout reve", ptreve);
updateRollResult(rollData);
});
html.find('#ptreve-variable').change((event) => {
let ptreve = Misc.toInt(event.currentTarget.value);
this.rollData.selectedSort.data.ptreve_reel = ptreve; // Update the selectedCarac
console.log("RdDRollSelectDialog - Cout reve", ptreve);
updateRollResult(rollData);
});
html.find('#coupsNonMortels').change((event) => {
this.rollData.mortalite = event.currentTarget.checked ? "non-mortel" : "non-mortel";
});
html.find('#surencMalusApply').change((event) => {
this.rollData.surencMalusApply = event.currentTarget.checked;
updateRollResult(rollData);
});
html.find('#useEncForNatation').change((event) => {
this.rollData.useEncForNatation = event.currentTarget.checked;
updateRollResult(rollData);
});
}
static _isIgnoreEtatGeneral(rollData) {
return rollData.selectedCarac.ignoreEtatGeneral;
}
/* -------------------------------------------- */
static _computeFinalLevel(rollData) {
const etat = RdDRoll._isIgnoreEtatGeneral(rollData) ? 0 : Misc.toInt(rollData.etat);
const diffConditions = Misc.toInt(rollData.diffConditions);
let malusEnc = (rollData.surencMalusApply) ? rollData.surencMalusValue : 0;
let diffLibre = Misc.toInt(rollData.diffLibre);
let malusEncNatation = (rollData.useEncForNatation) ? -rollData.encValueForNatation : 0;
// Gestion malus armure
let malusArmureValue = 0;
if (rollData.malusArmureValue != 0 && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) {
$("#addon-message").text("Malus armure appliqué : " + rollData.malusArmureValue);
malusArmureValue = rollData.malusArmureValue;
} else {
$("#addon-message").text("");
}
let diffCompetence = 0;
if (rollData.competence) {
diffCompetence = Misc.toInt(rollData.competence.data.niveau);
}
else if (rollData.draconicList) {
diffCompetence = Misc.toInt(rollData.selectedDraconic.data.niveau);
diffLibre = RdDItemSort.getDifficulte(rollData.selectedSort, diffLibre);
}
return etat + diffCompetence + diffLibre + diffConditions + malusEnc + malusEncNatation + malusArmureValue;
}
/* -------------------------------------------- */
static _getTitle(rollData) {
if (rollData.competence) {
// If a weapon is there, add it in the title
let armeTitle = (rollData.arme) ? " (" + rollData.arme.name + ") " : "";
let niveau = Misc.toSignedString(rollData.competence.data.niveau);
return rollData.selectedCarac.label + "/" + rollData.competence.name + armeTitle + " " + niveau
}
if (rollData.draconicList) {
return rollData.selectedDraconic.name + " - " + rollData.selectedSort.name;
}
return rollData.selectedCarac.label;
}
}

View File

@ -150,6 +150,7 @@
{{/if}} {{/if}}
{{/each}} {{/each}}
</ul> </ul>
<ul class="carac-list"></ul>
</div> </div>
</div> </div>
</div> </div>