Merge branch 'working' into 'master'
Encore du refactoring See merge request LeRatierBretonnien/foundryvtt-reve-de-dragon!10
This commit is contained in:
commit
a554f173c1
318
module/actor.js
318
module/actor.js
@ -7,6 +7,7 @@ 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 { RdDTMRDialog } from "./rdd-tmr-dialog.js";
|
import { RdDTMRDialog } from "./rdd-tmr-dialog.js";
|
||||||
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
|
|
||||||
export class RdDActor extends Actor {
|
export class RdDActor extends Actor {
|
||||||
|
|
||||||
@ -91,20 +92,17 @@ export class RdDActor extends Actor {
|
|||||||
getCurrentReve() {
|
getCurrentReve() {
|
||||||
return this.data.data.reve.reve.value;
|
return this.data.data.reve.reve.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getBestDraconic() {
|
getBestDraconic() {
|
||||||
|
const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau);
|
||||||
let draconic = {name: "none", niveau: -11 };
|
if (list.length==0)
|
||||||
for (const item of this.data.items) {
|
{
|
||||||
//console.log(item);
|
return { name: "none", niveau: -11 };
|
||||||
if ( item.data.categorie && item.data.categorie.toLowerCase() == "draconic") {
|
|
||||||
if (item.data.niveau > draconic.niveau) draconic = duplicate(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return draconic;
|
return duplicate(list[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async deleteSortReserve(coordTMR) {
|
async deleteSortReserve(coordTMR) {
|
||||||
let reserve = duplicate(this.data.data.reve.reserve);
|
let reserve = duplicate(this.data.data.reve.reserve);
|
||||||
@ -122,148 +120,110 @@ export class RdDActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async performRoll( rollData ) {
|
async performRoll(rollData) {
|
||||||
|
|
||||||
let result = new Roll("d100").roll().total;
|
|
||||||
let quality = "Echec";
|
|
||||||
let xpmsg = "";
|
|
||||||
let tache = 0;
|
|
||||||
//console.log(">>> ROLL", rollData.selectedCarac.label, rollData.rollTarget.score, myroll.total );
|
|
||||||
if (result <= rollData.rollTarget.part) {
|
|
||||||
quality = "Réussite Particulière!";
|
|
||||||
if ( rollData.finalLevel < 0 ) {
|
|
||||||
let xpcarac = Math.floor( Math.abs(rollData.finalLevel) / 2);
|
|
||||||
let xpcomp = (Math.abs(rollData.finalLevel) % 2 == 1) ? xpcarac+1 : xpcarac;
|
|
||||||
xpmsg = "<br>Points d'expérience gagné ! " + xpcarac + " - " + xpcomp;
|
|
||||||
}
|
|
||||||
rollData.pointsDeTache = 4;
|
|
||||||
rollData.qualite = 2;
|
|
||||||
} else if (result <= (rollData.rollTarget.score /2) ) {
|
|
||||||
quality = "Réussite Significative";
|
|
||||||
rollData.pointsDeTache = 2;
|
|
||||||
rollData.qualite = 1;
|
|
||||||
} else if (result <= (rollData.rollTarget.score) ) {
|
|
||||||
quality = "Réussite Normale";
|
|
||||||
rollData.pointsDeTache = 1;
|
|
||||||
rollData.qualite = 0;
|
|
||||||
} else if (result < (rollData.rollTarget.epart) ) {
|
|
||||||
quality = "Echec Normal";
|
|
||||||
rollData.pointsDeTache = 0;
|
|
||||||
rollData.qualite = -2;
|
|
||||||
} else if (result < (rollData.rollTarget.etotal) ) {
|
|
||||||
quality = "Echec Particulier";
|
|
||||||
rollData.pointsDeTache = -2;
|
|
||||||
rollData.qualite = -4;
|
|
||||||
} else if (result >= (rollData.rollTarget.etotal) ) {
|
|
||||||
quality = "Echec Total";
|
|
||||||
rollData.pointsDeTache = -4;
|
|
||||||
rollData.qualite = -6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage weapon categories when parrying (cf. page 115 )
|
// Manage weapon categories when parrying (cf. page 115 )
|
||||||
let need_significative = false; // Do we need to have a sgnificative ?
|
let need_resist = false; // Do we need to make resistance roll for defender ?
|
||||||
let need_resist = false; // Do we need to have a sgnificative ?
|
if (rollData.arme && rollData.attackerRoll) { // Manage parade depeding on weapon type, and change roll results
|
||||||
if ( rollData.arme && rollData.attackerRoll ) { // Manage parade depeding on weapon type, and change roll results
|
let attCategory = RdDUtility.getArmeCategory(rollData.attackerRoll.arme);
|
||||||
let attCategory = RdDUtility.getArmeCategory( rollData.attackerRoll.arme );
|
let defCategory = RdDUtility.getArmeCategory(rollData.arme);
|
||||||
let defCategory = RdDUtility.getArmeCategory( rollData.arme );
|
if (defCategory == "bouclier")
|
||||||
if ( defCategory == "bouclier" )
|
rollData.needSignificative = true;
|
||||||
need_significative = true;
|
else if (attCategory != defCategory)
|
||||||
else if ( attCategory != defCategory )
|
rollData.needSignificative = true;
|
||||||
need_significative = true;
|
if (attCategory.match("epee") && (defCategory == "hache" || defCategory == "lance"))
|
||||||
if ( attCategory.match("epee") && ( defCategory == "hache" || defCategory == "lance") )
|
|
||||||
need_resist = true;
|
need_resist = true;
|
||||||
}
|
}
|
||||||
|
if (this.data.data.sante.sonne.value)
|
||||||
// Sonne management or if need_significative is set
|
{
|
||||||
if ( this.data.data.sante.sonne.value || need_significative) {
|
rollData.needSignificative = true;
|
||||||
if (rollData.pointsDeTache >= 2 ) { // Reussite normale dès que significative
|
|
||||||
quality = "Réussite Normale";
|
|
||||||
rollData.pointsDeTache = 1;
|
|
||||||
rollData.qualite = 0;
|
|
||||||
} else if (rollData.pointsDeTache < 2 ) { // Not a "significative"
|
|
||||||
quality = "Echec Normal";
|
|
||||||
rollData.pointsDeTache = 0;
|
|
||||||
rollData.qualite = -2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let rolled = RdDResolutionTable.rollChances(rollData.rollTarget);
|
||||||
|
let result = rolled.roll;
|
||||||
|
let quality = rolled.quality
|
||||||
|
|
||||||
|
console.log(">>> ROLL", rollData, rolled);
|
||||||
|
let xpmsg = RdDResolutionTable.buildXpMessage(rolled, rollData.finalLevel);
|
||||||
|
|
||||||
|
let specialStr = "<br>Points de taches : " + rolled.tache + ", Points de qualité: " + rolled.qualite;
|
||||||
|
|
||||||
// Fight management !
|
// Fight management !
|
||||||
let defenseMsg;
|
let defenseMsg;
|
||||||
let encaisser = false;
|
let encaisser = false;
|
||||||
let specialStr = "<br>Points de taches : " + rollData.pointsDeTache; // Per default
|
if (rollData.arme) {
|
||||||
if ( rollData.arme ) { // In case of fight, replace the "tache" message per dommages + localization. "tache" indicates if result is OK or not
|
// In case of fight, replace the message per dommages + localization. it indicates if result is OK or not
|
||||||
if ( rollData.attackerRoll) { // Defense case !
|
if (rollData.attackerRoll) { // Defense case !
|
||||||
if ( rollData.pointsDeTache > 0 ) { // Réussite !
|
if (rolled.isSuccess) {
|
||||||
specialStr = "<br><strong>Attaque parée/esquivée !</strong>";
|
specialStr = "<br><strong>Attaque parée/esquivée !</strong>";
|
||||||
} else {
|
} else {
|
||||||
specialStr = "<br><strong>Esquive/Parade échouée, encaissement !</strong>";
|
specialStr = "<br><strong>Esquive/Parade échouée, encaissement !</strong>";
|
||||||
encaisser = true;
|
encaisser = true;
|
||||||
}
|
}
|
||||||
} else { // This is the attack roll!
|
} else { // This is the attack roll!
|
||||||
if ( rollData.pointsDeTache > 0 ) {
|
if (rolled.isSuccess > 0) {
|
||||||
let myroll = new Roll("2d10");
|
|
||||||
myroll.roll();
|
|
||||||
rollData.domArmePlusDom = parseInt(rollData.arme.data.dommages);
|
rollData.domArmePlusDom = parseInt(rollData.arme.data.dommages);
|
||||||
if ( rollData.selectedCarac.label == "Mêlée" ) // +dom only for Melee
|
if (rollData.selectedCarac.label == "Mêlée") // +dom only for Melee
|
||||||
rollData.domArmePlusDom += parseInt(this.data.data.attributs.plusdom.value);
|
rollData.domArmePlusDom += parseInt(this.data.data.attributs.plusdom.value);
|
||||||
if ( rollData.selectedCarac.label == "Lancer" ) { // +dom only for Melee/Lancer
|
if (rollData.selectedCarac.label == "Lancer") { // +dom only for Melee/Lancer
|
||||||
let bdom = parseInt(this.data.data.attributs.plusdom.value);
|
let bdom = parseInt(this.data.data.attributs.plusdom.value);
|
||||||
if ( bdom > parseInt(rollData.arme.data.dommages))
|
if (bdom > parseInt(rollData.arme.data.dommages))
|
||||||
bdom = parseInt(rollData.arme.data.dommages);
|
bdom = parseInt(rollData.arme.data.dommages);
|
||||||
rollData.domArmePlusDom += bdom
|
rollData.domArmePlusDom += bdom
|
||||||
}
|
}
|
||||||
rollData.degats = parseInt(myroll.result) + rollData.domArmePlusDom;
|
let encaissement = new Roll("2d10 + @domArmePlusDom", {domArmePlusDom : rollData.domArmePlusDom});
|
||||||
|
rollData.degats = parseInt(encaissement.roll().total);
|
||||||
rollData.loc = RdDUtility.getLocalisation();
|
rollData.loc = RdDUtility.getLocalisation();
|
||||||
for (let target of game.user.targets) {
|
for (let target of game.user.targets) {
|
||||||
defenseMsg = RdDUtility.buildDefenseChatCard(this, target, rollData );
|
defenseMsg = RdDUtility.buildDefenseChatCard(this, target, rollData);
|
||||||
specialStr = "<br><strong>Cible</strong> : " + target.actor.data.name;
|
specialStr = "<br><strong>Cible</strong> : " + target.actor.data.name;
|
||||||
}
|
}
|
||||||
specialStr += "<br>Dommages : " + rollData.degats + "<br>Localisation : " + rollData.loc.label;
|
specialStr += "<br>Dommages : " + rollData.degats + "<br>Localisation : " + rollData.loc.label;
|
||||||
} else {
|
} else {
|
||||||
specialStr = "<br>Echec ! Pas de dommages";
|
specialStr = "<br>Echec ! Pas de dommages";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort management
|
// Sort management
|
||||||
let lvl = ""
|
let lvl = ""
|
||||||
if ( rollData.selectedSort) { // Lancement de sort !
|
if (rollData.selectedSort) { // Lancement de sort !
|
||||||
let draconic = rollData.selectedSort.data.draconic;
|
let draconic = rollData.selectedSort.data.draconic;
|
||||||
specialStr = "<br>Lancement du sort <strong>" + rollData.selectedSort.name + "</strong> : " + draconic.charAt(0).toUpperCase() + draconic.slice(1) + "/" + rollData.selectedSort.data.difficulte +
|
specialStr = "<br>Lancement du sort <strong>" + rollData.selectedSort.name + "</strong> : " + draconic.charAt(0).toUpperCase() + draconic.slice(1) + "/" + rollData.selectedSort.data.difficulte +
|
||||||
"/" + rollData.selectedSort.data.caseTMR + "/R" + rollData.selectedSort.data.ptreve;
|
"/" + rollData.selectedSort.data.caseTMR + "/R" + rollData.selectedSort.data.ptreve;
|
||||||
specialStr += "<br>Depuis la case " + rollData.coord + " (" + TMRUtility.getTMRDescription(rollData.coord).label + ")";
|
specialStr += "<br>Depuis la case " + rollData.coord + " (" + TMRUtility.getTMRDescription(rollData.coord).label + ")";
|
||||||
lvl = rollData.selectedDraconic.name +"/"+ rollData.selectedSort.name;
|
lvl = rollData.selectedDraconic.name + "/" + rollData.selectedSort.name;
|
||||||
let costReve = rollData.selectedSort.data.ptreve;
|
let costReve = rollData.selectedSort.data.ptreve;
|
||||||
let myReve = duplicate(this.data.data.reve.reve);
|
let myReve = duplicate(this.data.data.reve.reve);
|
||||||
if ( rollData.pointsDeTache > 0 ) { // Réussite du sort !
|
if (rollData.tache > 0) { // Réussite du sort !
|
||||||
if (rollData.pointsDeTache >= 4 ) costReve = Math.ceil(costReve/2);
|
if (rollData.tache >= 4) costReve = Math.ceil(costReve / 2);
|
||||||
if (costReve < 1 ) costReve = 1;
|
if (costReve < 1) costReve = 1;
|
||||||
myReve.value = myReve.value - costReve; // Todo 0 pts de reve !!!!
|
myReve.value = myReve.value - costReve; // Todo 0 pts de reve !!!!
|
||||||
if (myReve.value < 0) myReve.value = 0;
|
if (myReve.value < 0) myReve.value = 0;
|
||||||
await this.update( {"data.reve.reve": myReve } );
|
await this.update({ "data.reve.reve": myReve });
|
||||||
specialStr += "<br>Réussite du sort pour " + costReve + " Points de Rêve";
|
specialStr += "<br>Réussite du sort pour " + costReve + " Points de Rêve";
|
||||||
if ( !rollData.isSortReserve) {
|
if (!rollData.isSortReserve) {
|
||||||
this.currentTMR.close(); // Close TMR !
|
this.currentTMR.close(); // Close TMR !
|
||||||
} else { // Mise en réserve
|
} else { // Mise en réserve
|
||||||
let reserve = duplicate(this.data.data.reve.reserve);
|
let reserve = duplicate(this.data.data.reve.reserve);
|
||||||
reserve.list.push( { coord: rollData.coord, sort: duplicate(rollData.selectedSort), draconic: duplicate(rollData.selectedDraconic) });
|
reserve.list.push({ coord: rollData.coord, sort: duplicate(rollData.selectedSort), draconic: duplicate(rollData.selectedDraconic) });
|
||||||
await this.update( {"data.reve.reserve": reserve} );
|
await this.update({ "data.reve.reserve": reserve });
|
||||||
this.currentTMR.updateSortReserve();
|
this.currentTMR.updateSortReserve();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( rollData.pointsDeTache == -4) { // Echec total !
|
if (rollData.tache == -4) { // Echec total !
|
||||||
costReve *= 2;
|
costReve *= 2;
|
||||||
myReve.value = myReve.value - costReve; // Todo 0 pts de reve !!!!
|
myReve.value = myReve.value - costReve; // Todo 0 pts de reve !!!!
|
||||||
if (myReve.value < 0) myReve.value = 0;
|
if (myReve.value < 0) myReve.value = 0;
|
||||||
await this.update( {"data.reve.reve": myReve } );
|
await this.update({ "data.reve.reve": myReve });
|
||||||
specialStr += "<br><strong>Echec TOTAL</strong> du sort : " + costReve + " Points de Rêve";
|
specialStr += "<br><strong>Echec TOTAL</strong> du sort : " + costReve + " Points de Rêve";
|
||||||
} else {
|
} else {
|
||||||
specialStr += "<br>Echec du sort !";
|
specialStr += "<br>Echec du sort !";
|
||||||
}
|
}
|
||||||
this.currentTMR.close(); // Close TMR !
|
this.currentTMR.close(); // Close TMR !
|
||||||
}
|
}
|
||||||
if (myReve.value == 0) { // 0 points de reve
|
if (myReve.value == 0) { // 0 points de reve
|
||||||
ChatMessage.create( {title: "Zero Points de Reve !", content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" } );
|
ChatMessage.create({ title: "Zero Points de Reve !", content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" });
|
||||||
this.currentTMR.close(); // Close TMR !
|
this.currentTMR.close(); // Close TMR !
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -271,37 +231,38 @@ export class RdDActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save it for fight in the flags area
|
// Save it for fight in the flags area
|
||||||
await this.setFlag( 'world', 'rollData', null );
|
await this.setFlag('world', 'rollData', null);
|
||||||
await this.setFlag( 'world', 'rollData', rollData );
|
await this.setFlag('world', 'rollData', rollData);
|
||||||
|
|
||||||
// Final chat message
|
// Final chat message
|
||||||
let chatOptions = { content: "<strong>Test : " + rollData.selectedCarac.label + " / " + lvl + "</strong><br>Jet : " +
|
let chatOptions = {
|
||||||
rollData.selectedCarac.value + " / " + rollData.finalLevelStr + " -> " + rollData.rollTarget.score + "%<br><strong>Résutat : </strong>" + result + "<br>" +
|
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + lvl + "</strong><br>Jet : " +
|
||||||
"<strong>" + quality + "</strong>" + specialStr + xpmsg,
|
rollData.selectedCarac.value + " / " + rollData.finalLevelStr + " -> " + rolled.score + "%<br><strong>Résutat : </strong>" + result + "<br>" +
|
||||||
user: game.user._id,
|
"<strong>" + quality + "</strong>" + specialStr + xpmsg,
|
||||||
title: "Résultat du test"
|
user: game.user._id,
|
||||||
}
|
title: "Résultat du test"
|
||||||
ChatMessage.create( chatOptions );
|
}
|
||||||
|
ChatMessage.create(chatOptions);
|
||||||
|
|
||||||
// This an attack, generate the defense message
|
// This an attack, generate the defense message
|
||||||
if ( defenseMsg ) {
|
if (defenseMsg) {
|
||||||
if ( defenseMsg.toSocket) {
|
if (defenseMsg.toSocket) {
|
||||||
game.socket.emit("system.foundryvtt-reve-de-dragon", {
|
game.socket.emit("system.foundryvtt-reve-de-dragon", {
|
||||||
msg: "msg_defense",
|
msg: "msg_defense",
|
||||||
data: defenseMsg
|
data: defenseMsg
|
||||||
} );
|
});
|
||||||
} else {
|
} else {
|
||||||
defenseMsg.whisper = [ game.user];
|
defenseMsg.whisper = [game.user];
|
||||||
ChatMessage.create( defenseMsg );
|
ChatMessage.create(defenseMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get damages!
|
// Get damages!
|
||||||
if ( encaisser ) {
|
if (encaisser) {
|
||||||
this.encaisserDommages( rollData.attackerRoll );
|
this.encaisserDommages(rollData.attackerRoll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
updateCarac( caracName, caracValue )
|
updateCarac( caracName, caracValue )
|
||||||
{
|
{
|
||||||
@ -638,62 +599,45 @@ export class RdDActor extends Actor {
|
|||||||
|
|
||||||
this.update( { "data.blessures": blessures } );
|
this.update( { "data.blessures": blessures } );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async stressTest( ) {
|
async stressTest() {
|
||||||
|
let target = RdDResolutionTable.computeChances(this.data.data.carac.reve.value, 0);
|
||||||
|
let stressRoll = this._stressRoll(target);
|
||||||
|
|
||||||
let compteurs = duplicate(this.data.data.compteurs);
|
let compteurs = duplicate(this.data.data.compteurs);
|
||||||
let stress = compteurs.stress;
|
let convertion = Math.floor(compteurs.stress.value * stressRoll.factor);
|
||||||
let xp = compteurs.experience;
|
|
||||||
|
compteurs.experience.value += convertion;
|
||||||
|
compteurs.stress.value = Math.max(compteurs.stress.value - convertion - 1, 0);
|
||||||
|
|
||||||
let scoreTarget = RdDUtility.getResolutionField( this.data.data.carac.reve.value, 0 );
|
ChatMessage.create({
|
||||||
scoreTarget.sig = Math.floor(scoreTarget.score / 2);
|
title: "Jet de Stress", content: "Vous avez transformé " + convertion + " points de Stress en Expérience avec une réussite " + stressRoll.comment,
|
||||||
|
whisper: ChatMessage.getWhisperRecipients(game.user.name)
|
||||||
let scoreValue = new Roll("d100").roll().total;
|
});
|
||||||
let newXP = xp.value;
|
await this.update({ "data.compteurs": compteurs });
|
||||||
let factor = 0;
|
|
||||||
let comment = "Echec Total (0%)"
|
|
||||||
|
|
||||||
if (scoreValue <= scoreTarget.part ) {
|
|
||||||
scoreValue = new Roll("d100").roll().total;
|
|
||||||
if (scoreValue <= scoreTarget.sig) {
|
|
||||||
factor = 1.5;
|
|
||||||
comment = "Double Particulière (150%)"
|
|
||||||
} else {
|
|
||||||
factor = 1;
|
|
||||||
comment = "Particulière (100%)"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( scoreValue <= scoreTarget.sig ) {
|
|
||||||
factor = 0.75;
|
|
||||||
comment = "Significative (75%)"
|
|
||||||
} else {
|
|
||||||
if ( scoreValue <= scoreTarget.score ) {
|
|
||||||
factor = 0.5;
|
|
||||||
comment = "Normale (50%)"
|
|
||||||
} else if (scoreValue <= scoreTarget.epart) {
|
|
||||||
factor = 0.2;
|
|
||||||
comment = "Echec (20%)"
|
|
||||||
} else if (scoreValue <= scoreTarget.etotal) {
|
|
||||||
factor = 0.1;
|
|
||||||
comment = "Echec (10%)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let xpValue = Math.floor(stress.value * factor);
|
|
||||||
stress.value -= xpValue;
|
|
||||||
stress.value -= 1;
|
|
||||||
if (stress.value < 0 ) stress.value = 0;
|
|
||||||
|
|
||||||
ChatMessage.create( { title: "Jet de Stress", content: "Vous avez transformé "+ xpValue + " points de Stress en Expérience avec une réussite " + comment ,
|
|
||||||
whisper: ChatMessage.getWhisperRecipients(game.user.name) } );
|
|
||||||
|
|
||||||
xp.value += xpValue;
|
|
||||||
await this.update( { "data.compteurs": compteurs } );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
_stressRoll(target) {
|
||||||
async rollUnSort( coord ) {
|
let result = RdDResolutionTable.rollChances(target)
|
||||||
|
switch (result.quality) {
|
||||||
|
case "sign": return { factor: 0.75, comment: "Significative (75%) - " + result.roll }
|
||||||
|
case "norm": return { factor: 0.5, comment: "Normale (50%) - " + result.roll }
|
||||||
|
case "echec": return { factor: 0.2, comment: "Echec (20%) - " + result.roll }
|
||||||
|
case "epart": return { factor: 0.1, comment: "Echec particulier(10%) - " + result.roll }
|
||||||
|
case "etotal": return { factor: 0, comment: "Echec Total (0%) - " + result.roll }
|
||||||
|
}
|
||||||
|
let second = RdDResolutionTable.rollChances(target)
|
||||||
|
switch (second.qualite) {
|
||||||
|
case "part": case "sign":
|
||||||
|
return { factor: 1.5, comment: "Double Particulière (150%) - " + result + " puis " + second }
|
||||||
|
default:
|
||||||
|
return { factor: 1, comment: "Particulière (100%) - " + result + " puis " + second }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollUnSort(coord) {
|
||||||
let draconicList = this.getDraconicList();
|
let draconicList = this.getDraconicList();
|
||||||
let sortList = this.getSortList();
|
let sortList = this.getSortList();
|
||||||
|
|
||||||
@ -727,24 +671,14 @@ export class RdDActor extends Actor {
|
|||||||
new RdDRollDialog("carac", html, rollData, this ).render(true);
|
new RdDRollDialog("carac", html, rollData, this ).render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getSortList( ) {
|
getSortList() {
|
||||||
let sortList = []
|
return this.data.items.filter(item => item.type == "sort");
|
||||||
for (const item of this.data.items) {
|
|
||||||
if (item.type == "sort" )
|
|
||||||
sortList.push(item);
|
|
||||||
}
|
|
||||||
return sortList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getDraconicList( ) {
|
getDraconicList() {
|
||||||
let draconicList = []
|
return this.data.items.filter(item => item.data.categorie == 'draconic')
|
||||||
for (const item of this.data.items) {
|
|
||||||
if (item.type == "competence" && item.data.categorie == 'draconic' )
|
|
||||||
draconicList.push(item);
|
|
||||||
}
|
|
||||||
return draconicList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -1,4 +1,58 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* difficultés au delà de -10
|
||||||
|
*/
|
||||||
|
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: 0, etotal: 2 }
|
||||||
|
];
|
||||||
|
const levelImpossible = { score: 0, sign: 0, part: 0, epart: 0, etotal: 1 };
|
||||||
|
/**
|
||||||
|
* Table des résultats spéciaux - inutilisée, conservée si on veut afficher la table
|
||||||
|
*/
|
||||||
|
const specialResults = [
|
||||||
|
{ part: 0, epart: 0, etotal: 0, min: 0, max: 0 },
|
||||||
|
{ part: 1, epart: 81, etotal: 92, min: 1, max: 5 },
|
||||||
|
{ part: 2, epart: 82, etotal: 92, min: 6, max: 10 },
|
||||||
|
{ part: 3, epart: 83, etotal: 93, min: 11, max: 15 },
|
||||||
|
{ part: 4, epart: 84, etotal: 93, min: 16, max: 20 },
|
||||||
|
{ part: 5, epart: 85, etotal: 94, min: 21, max: 25 },
|
||||||
|
{ part: 6, epart: 86, etotal: 94, min: 26, max: 30 },
|
||||||
|
{ part: 7, epart: 87, etotal: 95, min: 31, max: 35 },
|
||||||
|
{ part: 8, epart: 88, etotal: 95, min: 36, max: 40 },
|
||||||
|
{ part: 9, epart: 89, etotal: 96, min: 41, max: 45 },
|
||||||
|
{ part: 10, epart: 90, etotal: 96, min: 46, max: 50 },
|
||||||
|
{ part: 11, epart: 91, etotal: 97, min: 51, max: 55 },
|
||||||
|
{ part: 12, epart: 92, etotal: 97, min: 56, max: 60 },
|
||||||
|
{ part: 13, epart: 93, etotal: 98, min: 61, max: 65 },
|
||||||
|
{ part: 14, epart: 94, etotal: 98, min: 65, max: 70 },
|
||||||
|
{ part: 15, epart: 95, etotal: 99, min: 71, max: 75 },
|
||||||
|
{ part: 16, epart: 96, etotal: 99, min: 76, max: 80 },
|
||||||
|
{ part: 17, epart: 97, etotal: 100, min: 81, max: 85 },
|
||||||
|
{ part: 18, epart: 98, etotal: 100, min: 86, max: 90 },
|
||||||
|
{ part: 19, epart: 99, etotal: 100, min: 81, max: 95 },
|
||||||
|
{ part: 20, epart: 100, etotal: 100, min: 96, max: 100 }
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const reussites = [
|
||||||
|
{ code: "etotal", isPart: false, isSign: false, isSuccess: false, isEPart: true, isETotal: true, tache: -4, qualite: -6, quality: "Echec total", condition: (target, roll) => roll >= target.etotal && roll <= 100 },
|
||||||
|
{ code: "epart", isPart: false, isSign: false, isSuccess: false, isEPart: true, isETotal: false, tache: -2, qualite: -4, quality: "Echec particulier", condition: (target, roll) => (roll >= target.epart && roll < target.etotal) },
|
||||||
|
{ code: "echec", isPart: false, isSign: false, isSuccess: false, isEPart: false, isETotal: false, tache: 0, qualite: -2, quality: "Echec normal", condition: (target, roll) => (roll > target.score && roll < target.etotal) },
|
||||||
|
{ code: "norm", isPart: false, isSign: false, isSuccess: true, isEPart: false, isETotal: false, tache: 1, qualite: 0, quality: "Réussite normale", condition: (target, roll) => (roll > target.sign && roll <= target.score) },
|
||||||
|
{ code: "sign", isPart: false, isSign: true, isSuccess: true, isEPart: false, isETotal: false, tache: 2, qualite: 1, quality: "Réussite significative", condition: (target, roll) => (roll > target.part && roll <= target.sign) },
|
||||||
|
{ code: "part", isPart: true, isSign: true, isSuccess: true, isEPart: false, isETotal: false, tache: 3, qualite: 2, quality: "Réussite Particulière!", condition: (target, roll) => (roll > 0 && roll <= target.part) },
|
||||||
|
{ code: "error", isPart: false, isSign: false, isSuccess: false, isEPart: true, isETotal: true, tache: 0, qualite: 0, quality: "Jet de dés invalide", condition: (target, roll) => (roll <= 0 || roll > 100) }
|
||||||
|
];
|
||||||
|
|
||||||
|
const reussiteSignificative = reussites.find(r => r.code == "sign");
|
||||||
|
const reussiteNormale = reussites.find(r => r.code == "norm");
|
||||||
|
const echecNormal = reussites.find(r => r.code == "echec");
|
||||||
|
|
||||||
export class RdDResolutionTable {
|
export class RdDResolutionTable {
|
||||||
static resolutionTable = this.build()
|
static resolutionTable = this.build()
|
||||||
|
|
||||||
@ -12,25 +66,71 @@ export class RdDResolutionTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
static roll(carac, difficulte) {
|
||||||
|
return this.rollChances(this.computeChances(carac, difficulte));
|
||||||
|
}
|
||||||
|
|
||||||
|
static rollChances(chances) {
|
||||||
|
chances.roll = new Roll("d100").roll().total;
|
||||||
|
mergeObject(chances, this._computeReussite(chances, chances.roll));
|
||||||
|
return chances;
|
||||||
|
}
|
||||||
|
|
||||||
|
static computeChances(carac, difficulte) {
|
||||||
|
if (difficulte < -16) {
|
||||||
|
return duplicate(levelImpossible);
|
||||||
|
}
|
||||||
|
if (difficulte < -10) {
|
||||||
|
return duplicate(levelDown.find(levelData => levelData.level == difficulte));
|
||||||
|
}
|
||||||
|
return duplicate(this.resolutionTable[carac][difficulte + 10]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static buildXpMessage(rolled, level)
|
||||||
|
{
|
||||||
|
if (rolled.isPart && level < 0) {
|
||||||
|
const xp = Math.abs(level);
|
||||||
|
const xpcarac = Math.floor(xp / 2);
|
||||||
|
const xpcomp = xp - xpcarac;
|
||||||
|
return "<br>Points d'expérience gagnés ! Carac: " + xpcarac + ", Comp: " + xpcomp;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _computeReussite(chances, roll) {
|
||||||
|
const reussite = reussites.find(x => x.condition(chances, roll));
|
||||||
|
if (chances.needSignificative) {
|
||||||
|
if (reussite.isSign) {
|
||||||
|
return reussiteNormale;
|
||||||
|
}
|
||||||
|
if (reussite.isSuccess){
|
||||||
|
return echecNormal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reussite;
|
||||||
|
}
|
||||||
|
|
||||||
static _computeRow(carac) {
|
static _computeRow(carac) {
|
||||||
let dataRow = [
|
let dataRow = [
|
||||||
this._computeScore(-10, Math.max(Math.floor(carac / 4), 1)),
|
this._computeCell(-10, Math.max(Math.floor(carac / 4), 1)),
|
||||||
this._computeScore(-9, Math.max(Math.floor(carac / 2), 1))
|
this._computeCell(-9, Math.max(Math.floor(carac / 2), 1))
|
||||||
]
|
]
|
||||||
for (var diff = -8; diff <= 22; diff++) {
|
for (var diff = -8; diff <= 22; diff++) {
|
||||||
dataRow[diff + 10] = this._computeScore(diff, Math.max(Math.floor(carac * (diff + 10) / 2), 1));
|
dataRow[diff + 10] = this._computeCell(diff, Math.max(Math.floor(carac * (diff + 10) / 2), 1));
|
||||||
}
|
}
|
||||||
return dataRow;
|
return dataRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _computeScore(diff, score) {
|
static _computeCell(niveau, percentage) {
|
||||||
return {
|
return {
|
||||||
niveau: diff,
|
niveau: niveau,
|
||||||
score: score,
|
score: percentage,
|
||||||
sign: this._reussiteSignificative(score),
|
sign: this._reussiteSignificative(percentage),
|
||||||
part: this._reussitePart(score),
|
part: this._reussitePart(percentage),
|
||||||
epart: this._echecParticulier(score),
|
epart: this._echecParticulier(percentage),
|
||||||
etotal: this._echecTotal(score)
|
etotal: this._echecTotal(percentage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
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.
|
* Extend the base Dialog entity by defining a custom window to perform roll.
|
||||||
@ -67,7 +66,7 @@ export class RdDRollDialog extends Dialog {
|
|||||||
|
|
||||||
rollData.finalLevel = rollLevel;
|
rollData.finalLevel = rollLevel;
|
||||||
rollData.finalLevelStr = (rollLevel > 0 ? "+" : "") + rollLevel;
|
rollData.finalLevelStr = (rollLevel > 0 ? "+" : "") + rollLevel;
|
||||||
rollData.rollTarget = RdDUtility.getResolutionField(rollData.selectedCarac.value, rollData.finalLevel);
|
rollData.rollTarget = RdDResolutionTable.computeChances(rollData.selectedCarac.value, rollData.finalLevel);
|
||||||
|
|
||||||
$("#roll-param").text(rollData.selectedCarac.value + " / " + rollData.finalLevelStr);
|
$("#roll-param").text(rollData.selectedCarac.value + " / " + rollData.finalLevelStr);
|
||||||
$("#compdialogTitle").text(RdDRollDialog._getTitle(rollData));
|
$("#compdialogTitle").text(RdDRollDialog._getTitle(rollData));
|
||||||
@ -80,7 +79,8 @@ export class RdDRollDialog extends Dialog {
|
|||||||
// Update html, according to data
|
// Update html, according to data
|
||||||
if (rollData.competence) {
|
if (rollData.competence) {
|
||||||
// Set the default carac from the competence item
|
// Set the default carac from the competence item
|
||||||
console.log(rollData.competence.data.defaut_carac, rollData.carac);
|
console.log("RdDDialogRoll", rollData.competence.data.defaut_carac, rollData.carac);
|
||||||
|
|
||||||
rollData.selectedCarac = rollData.carac[rollData.competence.data.defaut_carac];
|
rollData.selectedCarac = rollData.carac[rollData.competence.data.defaut_carac];
|
||||||
$("#carac").val(rollData.competence.data.defaut_carac);
|
$("#carac").val(rollData.competence.data.defaut_carac);
|
||||||
}
|
}
|
||||||
@ -91,30 +91,32 @@ export class RdDRollDialog extends Dialog {
|
|||||||
// Update !
|
// Update !
|
||||||
html.find('#bonusmalus').click((event) => {
|
html.find('#bonusmalus').click((event) => {
|
||||||
rollData.bmValue = event.currentTarget.value; // Update the selected bonus/malus
|
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) );
|
console.debug("RdDRollDialog","BM CLICKED !!!", rollData.bmValue, rollData.competence.data.niveau, parseInt(rollData.competence.data.niveau) + parseInt(rollData.bmValue) );
|
||||||
updateRollResult(rollData);
|
updateRollResult(rollData);
|
||||||
});
|
});
|
||||||
html.find('#carac').click((event) => {
|
html.find('#carac').click((event) => {
|
||||||
let caracKey = event.currentTarget.value;
|
let caracKey = event.currentTarget.value;
|
||||||
rollData.selectedCarac = rollData.carac[caracKey]; // Update the selectedCarac
|
rollData.selectedCarac = rollData.carac[caracKey]; // Update the selectedCarac
|
||||||
//console.log("CARAC CLICKED !!!", rollData.selectedCarac, rollData.competence.data.niveau, rollData.bmValue);
|
console.debug("RdDRollDialog","CARAC CLICKED !!!", rollData.selectedCarac, rollData.competence.data.niveau, rollData.bmValue);
|
||||||
updateRollResult(rollData);
|
updateRollResult(rollData);
|
||||||
});
|
});
|
||||||
html.find('#draconic').click((event) => {
|
html.find('#draconic').click((event) => {
|
||||||
let draconicKey = event.currentTarget.value;
|
let draconicKey = event.currentTarget.value;
|
||||||
rollData.selectedDraconic = rollData.draconicList[draconicKey]; // Update the selectedCarac
|
rollData.selectedDraconic = rollData.draconicList[draconicKey]; // Update the selectedCarac
|
||||||
//console.log("CARAC CLICKED !!!", rollData.selectedCarac, rollData.competence.data.niveau, rollData.bmValue);
|
console.debug("RdDRollDialog","CARAC CLICKED !!!", rollData.selectedCarac, rollData.competence.data.niveau, rollData.bmValue);
|
||||||
updateRollResult(rollData);
|
updateRollResult(rollData);
|
||||||
});
|
});
|
||||||
html.find('#sort').click((event) => {
|
html.find('#sort').click((event) => {
|
||||||
let sortKey = event.currentTarget.value;
|
let sortKey = event.currentTarget.value;
|
||||||
rollData.selectedSort = rollData.sortList[sortKey]; // Update the selectedCarac
|
rollData.selectedSort = rollData.sortList[sortKey]; // Update the selectedCarac
|
||||||
//console.log("CARAC CLICKED !!!", rollData.selectedCarac, rollData.competence.data.niveau, rollData.bmValue);
|
console.debug("RdDRollDialog","CARAC CLICKED !!!", rollData.selectedCarac, rollData.competence.data.niveau, rollData.bmValue);
|
||||||
updateRollResult(rollData);
|
updateRollResult(rollData);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
static _computeFinalLevel(rollData) {
|
static _computeFinalLevel(rollData) {
|
||||||
let etat = rollData.etat === undefined ? 0 : parseInt(rollData.etat);
|
let etat = rollData.etat === undefined ? 0 : parseInt(rollData.etat);
|
||||||
if (rollData.competence) {
|
if (rollData.competence) {
|
||||||
|
@ -1,45 +1,43 @@
|
|||||||
export class RdDRollTables {
|
export class RdDRollTables {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async genericGetTableResult( tableName, toChat)
|
static async genericGetTableResult(tableName, toChat) {
|
||||||
{
|
const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
|
||||||
let pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
|
const index = await pack.getIndex();
|
||||||
await pack.getIndex();
|
const entry = index.find(e => e.name === tableName);
|
||||||
let entry = pack.index.find(e => e.name === tableName);
|
const table = await pack.getEntity(entry._id);
|
||||||
let rollQueues = await pack.getEntity(entry._id);
|
const result = await table.draw({ displayChat: toChat });
|
||||||
let result = await rollQueues.draw( { displayChat: toChat } );
|
console.log("RdDRollTables", tableName, toChat, ":", result);
|
||||||
console.log("CAT", result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getSouffle( toChat ) {
|
static async getSouffle(toChat) {
|
||||||
return genericGetTableResult( "Souffles de Dragon", toChat);
|
return RdDRollTables.genericGetTableResult("Souffles de Dragon", toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getQueue( toChat = true) {
|
static async getQueue(toChat = true) {
|
||||||
return genericGetTableResult( "Queues de dragon", toChat);
|
return RdDRollTables.genericGetTableResult("Queues de dragon", toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getTete( toChat = true ) {
|
static async getTete(toChat = true) {
|
||||||
return genericGetTableResult( "Têtes de Dragon pour haut-rêvants", toChat);
|
return RdDRollTables.genericGetTableResult("Têtes de Dragon pour haut-rêvants", toChat);
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async getTeteHR( toChat = true ) {
|
|
||||||
return genericGetTableResult( "Têtes de Dragon pour tous personnages", toChat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getOmbre( toChat = true ) {
|
static async getTeteHR(toChat = true) {
|
||||||
return genericGetTableResult( "Ombre de Thanatos", toChat);
|
return RdDRollTables.genericGetTableResult("Têtes de Dragon pour tous personnages", toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getTarot( toChat = true ) {
|
static async getOmbre(toChat = true) {
|
||||||
return genericGetTableResult( "Tarot Draconique", toChat);
|
return RdDRollTables.genericGetTableResult("Ombre de Thanatos", toChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/* -------------------------------------------- */
|
||||||
|
static async getTarot(toChat = true) {
|
||||||
|
return RdDRollTables.genericGetTableResult("Tarot Draconique", toChat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,6 +5,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 { RdDRollTables } from "./rdd-rolltables.js";
|
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||||
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
|
|
||||||
/** Helper functions */
|
/** Helper functions */
|
||||||
export class RdDTMRDialog extends Dialog {
|
export class RdDTMRDialog extends Dialog {
|
||||||
@ -130,13 +131,14 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
this.actor.deleteTMRRencontreAtPosition( ); // Remove the stored rencontre if necessary
|
this.actor.deleteTMRRencontreAtPosition( ); // Remove the stored rencontre if necessary
|
||||||
this.updatePreviousRencontres();
|
this.updatePreviousRencontres();
|
||||||
|
|
||||||
let draconic = this.actor.getBestDraconic();
|
const draconic = this.actor.getBestDraconic();
|
||||||
let carac = this.actor.getCurrentReve();
|
const carac = this.actor.getCurrentReve();
|
||||||
let level = draconic.data.niveau - this.currentRencontre.force;
|
const difficulte = draconic.data.niveau - this.currentRencontre.force;
|
||||||
console.log("Maitriser", carac, draconic.data.niveau, this.currentRencontre.force);
|
console.log("Maitriser", carac, draconic.data.niveau, this.currentRencontre.force);
|
||||||
let scoreDef = CONFIG.RDD.resolutionTable[carac][level+10];
|
|
||||||
let result = new Roll("d100").roll().total;
|
const roll = RdDResolutionTable.roll(carac, difficulte);
|
||||||
if ( result > scoreDef.score ) {
|
|
||||||
|
if ( roll.roll > scoreDef.score ) {
|
||||||
TMRUtility.processRencontreEchec( this.actor, this.currentRencontre);
|
TMRUtility.processRencontreEchec( this.actor, this.currentRencontre);
|
||||||
ChatMessage.create( { title: "TMR", content: "Vous avez <strong>échoué</strong> à votre maîtrise d'un " . this.currentRencontre.name + " de force " +
|
ChatMessage.create( { title: "TMR", content: "Vous avez <strong>échoué</strong> à votre maîtrise d'un " . this.currentRencontre.name + " de force " +
|
||||||
this.currentRencontre.force +
|
this.currentRencontre.force +
|
||||||
@ -157,28 +159,16 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
async manageRencontre(coordTMR, cellDescr)
|
async manageRencontre(coordTMR, cellDescr)
|
||||||
{
|
{
|
||||||
// Roll until diffent than '8'
|
// Roll until diffent than '8'
|
||||||
let rencontre
|
|
||||||
this.currentRencontre = undefined;
|
this.currentRencontre = undefined;
|
||||||
for (let previousRencontre of this.rencontresExistantes ) {
|
|
||||||
if ( previousRencontre.coord == coordTMR)
|
let rencontre = this.rencontresExistantes.find(prev => prev.coord == coordTMR);
|
||||||
rencontre = previousRencontre.rencontre;
|
if (rencontre == undefined && new Roll("d7").roll().total == 7) {
|
||||||
|
rencontre = TMRUtility.rencontreTMRRoll(coordTMR, cellDescr);
|
||||||
}
|
}
|
||||||
if ( rencontre == undefined ) {
|
|
||||||
let val = 8;
|
|
||||||
while (val == 8) {
|
|
||||||
let myroll = new Roll("d7");
|
|
||||||
myroll.roll();
|
|
||||||
val = myroll.total;
|
|
||||||
if ( val == 7 ) {
|
|
||||||
rencontre = TMRUtility.rencontreTMRRoll(coordTMR, cellDescr);
|
|
||||||
rencontre.force = new Roll(rencontre.data.force).roll().total;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rencontre) { // Manages it
|
if (rencontre) { // Manages it
|
||||||
this.currentRencontre = duplicate(rencontre);
|
this.currentRencontre = duplicate(rencontre);
|
||||||
let diag = new Dialog( { title: "Rencontre en TMR!",
|
let dialog = new Dialog( { title: "Rencontre en TMR!",
|
||||||
content: "Vous recontrez un " + rencontre.name + " de force " + rencontre.force + "<br>",
|
content: "Vous recontrez un " + rencontre.name + " de force " + rencontre.force + "<br>",
|
||||||
buttons: {
|
buttons: {
|
||||||
derober: {
|
derober: {
|
||||||
@ -198,7 +188,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
diag.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,46 +222,49 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async manageCaseHumide( cellDescr ) {
|
async manageCaseHumide(cellDescr) {
|
||||||
if ( cellDescr.type == "lac" || cellDescr.type == "fleuve" || cellDescr.type == "marais" ) {
|
if (cellDescr.type == "lac" || cellDescr.type == "fleuve" || cellDescr.type == "marais") {
|
||||||
let draconic = this.actor.getBestDraconic();
|
let draconic = this.actor.getBestDraconic();
|
||||||
let carac = this.actor.getCurrentReve();
|
let carac = this.actor.getCurrentReve();
|
||||||
let level = draconic.data.niveau - 7;
|
let level = draconic.data.niveau - 7;
|
||||||
let scoreDef = CONFIG.RDD.resolutionTable[carac][level+10];
|
let rolled = RdDResolutionTable.roll(carac, level);//RdDResolutionTable.computeChances(carac, level);
|
||||||
let result = new Roll("d100").roll().total;
|
|
||||||
|
console.log(">>>>", rolled);
|
||||||
|
|
||||||
|
this.toclose = rolled.isSuccess;
|
||||||
let content = "";
|
let content = "";
|
||||||
let mycallback;
|
if (!rolled.isSuccess) {
|
||||||
console.log(">>>>", scoreDef);
|
content += "Vous êtes entré sur une case humide, et vous avez <strong>raté</strong> votre maîtrise ! Vous <strong>quittez les Terres Médianes</strong> !"
|
||||||
if ( result > scoreDef.score ) {
|
}
|
||||||
content = "Vous êtes entré sur une case humide, et vous avez <strong>raté</strong> votre maîtrise ! Vous <strong>quittez les Terres Médianes</strong> ! ("+ draconic.name +") :" + carac + " / " + level + " -> " + result + " / " + scoreDef.score;
|
else {
|
||||||
if ( result >= scoreDef.etotal ) {
|
content += "Vous êtes entré sur une case humide, et vous avez <strong>réussi</strong> votre maîtrise !"
|
||||||
let souffle = RdDRollTables.getSouffle(true);
|
}
|
||||||
content += "<br>Vous avez fait un Echec Total. Vous subissez un Souffle de Dragon : " + souffle.name ;
|
|
||||||
this.actor.createOwnedItem( souffle );
|
content += " " + draconic.name + ": " + carac + " / " + level + " -> " + rolled.roll + " / " + rolled.score;
|
||||||
}
|
|
||||||
this.toclose = true;
|
if (rolled.isETotal) {
|
||||||
} else {
|
let souffle = RdDRollTables.getSouffle(true);
|
||||||
content = "Vous êtes entré sur une case humide, et vous avez <strong>réussi</strong> votre maîtrise ! ("+ draconic.name +") :" + carac + " / " + level + " -> " + result + " / " + scoreDef.score;
|
content += "<br>Vous avez fait un Echec Total. Vous subissez un Souffle de Dragon : " + souffle.name;
|
||||||
if ( result <= scoreDef.part ) {
|
this.actor.createOwnedItem(souffle);
|
||||||
content += "<br>Vous avez fait une Réussite Particulière";
|
}
|
||||||
if ( level < 0 ) {
|
if (rolled.isPart) {
|
||||||
let xpcarac = Math.floor( Math.abs(level) / 2);
|
content += "<br>Vous avez fait une Réussite Particulière";
|
||||||
let xpcomp = (Math.abs(level) % 2 == 1) ? xpcarac+1 : xpcarac;
|
content += RdDResolutionTable.buildXpMessage(rolled, level)
|
||||||
content += "<br>Points d'expérience gagné ! " + xpcarac + " - " + xpcomp;
|
}
|
||||||
|
|
||||||
|
let humideDiag = new Dialog({
|
||||||
|
title: "Case humide",
|
||||||
|
content: content,
|
||||||
|
buttons: {
|
||||||
|
choice: {
|
||||||
|
icon: '<i class="fas fa-check"></i>',
|
||||||
|
label: "Fermer",
|
||||||
|
callback: () => this.manageCaseHumideResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let humideDiag = new Dialog( {title: "Case humide",
|
);
|
||||||
content: content,
|
|
||||||
buttons: {
|
|
||||||
choice: { icon: '<i class="fas fa-check"></i>',
|
|
||||||
label: "Fermer",
|
|
||||||
callback: () => this.manageCaseHumideResult()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
humideDiag.render(true);
|
humideDiag.render(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,39 +22,11 @@ const competence_xp = {
|
|||||||
"-6" : [ 10, 20, 35, 50, 65, 80, 100, 120, 140],
|
"-6" : [ 10, 20, 35, 50, 65, 80, 100, 120, 140],
|
||||||
"-4" : [ 15, 30, 45, 60, 80, 100, 120]
|
"-4" : [ 15, 30, 45, 60, 80, 100, 120]
|
||||||
}
|
}
|
||||||
|
|
||||||
// This table starts at 0 -> niveau -10
|
// This table starts at 0 -> niveau -10
|
||||||
const competence_xp_par_niveau = [ 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, 20, 20, 20, 30, 30, 40, 40, 60, 60, 100, 100, 100, 100, 100, 100, 100, 100, 100];
|
const competence_xp_par_niveau = [ 5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, 20, 20, 20, 30, 30, 40, 40, 60, 60, 100, 100, 100, 100, 100, 100, 100, 100, 100];
|
||||||
const carac_array = [ "taille", "apparence", "constitution", "force", "agilite", "dexterite", "vue", "ouie", "odoratgout", "volonte", "intellect", "empathie", "reve", "chance", "melee", "tir", "lancer", "derobee"];
|
const carac_array = [ "taille", "apparence", "constitution", "force", "agilite", "dexterite", "vue", "ouie", "odoratgout", "volonte", "intellect", "empathie", "reve", "chance", "melee", "tir", "lancer", "derobee"];
|
||||||
const bonusmalus = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10];
|
const bonusmalus = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10];
|
||||||
const specialResults = [ { "part": 0, "epart": 0, "etotal": 0 }, // 0
|
|
||||||
{ "part": 1, "epart": 81, "etotal": 92 }, // 01-05
|
|
||||||
{ "part": 2, "epart": 82, "etotal": 92 }, // 06-10
|
|
||||||
{ "part": 3, "epart": 83, "etotal": 93 }, // 11-15
|
|
||||||
{ "part": 4, "epart": 84, "etotal": 93 }, // 16-20
|
|
||||||
{ "part": 5, "epart": 85, "etotal": 94 }, // 21-25
|
|
||||||
{ "part": 6, "epart": 86, "etotal": 94 }, // 26-30
|
|
||||||
{ "part": 7, "epart": 87, "etotal": 95 }, // 31-35
|
|
||||||
{ "part": 8, "epart": 88, "etotal": 95 }, // 36-40
|
|
||||||
{ "part": 9, "epart": 89, "etotal": 96 }, // 41-45
|
|
||||||
{ "part": 10, "epart": 90, "etotal": 96 }, // 46-50
|
|
||||||
{ "part": 11, "epart": 91, "etotal": 97 }, // 51-55
|
|
||||||
{ "part": 12, "epart": 92, "etotal": 97 }, // 56-60
|
|
||||||
{ "part": 13, "epart": 93, "etotal": 98 }, // 61-65
|
|
||||||
{ "part": 14, "epart": 94, "etotal": 98 }, // 65-70
|
|
||||||
{ "part": 15, "epart": 95, "etotal": 99 }, // 71-75
|
|
||||||
{ "part": 16, "epart": 96, "etotal": 99 }, // 76-80
|
|
||||||
{ "part": 17, "epart": 97, "etotal": 100 }, // 81-85
|
|
||||||
{ "part": 18, "epart": 98, "etotal": 100 }, // 86-90
|
|
||||||
{ "part": 19, "epart": 99, "etotal": 100 }, // 81-95
|
|
||||||
{ "part": 20, "epart": 100, "etotal": 100 } // 96-00
|
|
||||||
];
|
|
||||||
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.
|
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, 2, 3, 3, 2, 3, 3, 2, 3, 3 ],
|
||||||
[2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3 ],
|
[2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3 ],
|
||||||
@ -239,18 +211,6 @@ export class RdDUtility {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static getResolutionField(caracValue, levelValue )
|
|
||||||
{
|
|
||||||
if ( levelValue < -16 ) {
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static computeCompetenceXPCost( competence )
|
static computeCompetenceXPCost( competence )
|
||||||
{
|
{
|
||||||
@ -451,12 +411,7 @@ export class RdDUtility {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static findCompetence(compList, compName)
|
static findCompetence(compList, compName)
|
||||||
{
|
{
|
||||||
for (const item of compList) {
|
return compList.find(item => item.name == compName && (item.type =="competence" || item.type =="competencecreature"))
|
||||||
if (item.name == compName) {
|
|
||||||
//console.log("Found item !", item);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -269,13 +269,14 @@ export class TMRUtility {
|
|||||||
let val = new Roll("d100").roll().total;
|
let val = new Roll("d100").roll().total;
|
||||||
//console.log("Rencontre !!!!", val, coordTMR, cellDescr);
|
//console.log("Rencontre !!!!", val, coordTMR, cellDescr);
|
||||||
|
|
||||||
for( let renc of rencontresTable) {
|
for( let rencontre of rencontresTable) {
|
||||||
let scoreDef = renc.data[cellDescr.type];
|
let scoreDef = rencontre.data[cellDescr.type];
|
||||||
let min = scoreDef.substr(0,2);
|
let min = scoreDef.substr(0,2);
|
||||||
let max = scoreDef.substr(3,2);
|
let max = scoreDef.substr(3,2);
|
||||||
//console.log(val, scoreDef, min, max);
|
//console.log(val, scoreDef, min, max);
|
||||||
if ( val >= min && val <= max) {
|
if ( val >= min && val <= max) {
|
||||||
return renc;
|
rencontre.force = new Roll(rencontre.data.force).roll().total;
|
||||||
|
return rencontre;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user