Merge branch 'v1.5-options-repos' into 'v1.5'

Options de repos #205

See merge request LeRatierBretonnien/foundryvtt-reve-de-dragon!283
This commit is contained in:
Leratier Bretonnien 2021-06-26 07:21:04 +00:00
commit 95e3f61540
8 changed files with 209 additions and 61 deletions

View File

@ -14,6 +14,7 @@ import { RdDCarac } from "./rdd-carac.js";
import { RdDItem } from "./item.js"; import { RdDItem } from "./item.js";
import { DialogSplitItem } from "./dialog-split-item.js"; import { DialogSplitItem } from "./dialog-split-item.js";
import { ReglesOptionelles } from "./regles-optionelles.js"; import { ReglesOptionelles } from "./regles-optionelles.js";
import { DialogRepos } from "./dialog-repos.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
export class RdDActorSheet extends ActorSheet { export class RdDActorSheet extends ActorSheet {
@ -372,11 +373,8 @@ export class RdDActorSheet extends ActorSheet {
this.actor.displayTMR("rapide"); this.actor.displayTMR("rapide");
}); });
html.find('.dormir-une-heure').click(async event => { html.find('.repos').click(async event => {
this.actor.dormir(1); await DialogRepos.create(this.actor);
});
html.find('.dormir-chateau-dormant').click(async event => {
this.actor.dormirChateauDormant();
}); });
html.find('.enlever-tous-effets').click(async event => { html.find('.enlever-tous-effets').click(async event => {
this.actor.enleverTousLesEffets(); this.actor.enleverTousLesEffets();

View File

@ -33,7 +33,6 @@ import { RollDataAjustements } from "./rolldata-ajustements.js";
import { DialogItemAchat } from "./dialog-item-achat.js"; import { DialogItemAchat } from "./dialog-item-achat.js";
import { RdDItem } from "./item.js"; import { RdDItem } from "./item.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
/** /**
* Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system. * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
@ -371,11 +370,16 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getBestDraconic() { getBestDraconic() {
const list = this.getDraconicList(); const list = this.getDraconicList();
return duplicate(list[0]);
}
getDraconicOrZero() {
const list = this.getDraconicList().filter(it => Misc.data(it).data.niveau >= 0);
if (list.length == 0) { if (list.length == 0) {
return { name: "Aucun", data: { name: "Aucun", data: { niveau: 0 } } }; return { name: "Aucun", data: { niveau: 0 } };
} }
return duplicate(list[0]); return duplicate(list[0]);
} }
getDemiReve() { getDemiReve() {
return Misc.templateData(this).reve.tmrpos.coord; return Misc.templateData(this).reve.tmrpos.coord;
} }
@ -432,6 +436,34 @@ export class RdDActor extends Actor {
return ''; return '';
} }
/* -------------------------------------------- */
async grisReve(nGrisReve) {
let message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: `${nGrisReve} jours de gris rêve sont passés. `
};
for (let i = 0; i < nGrisReve; i++) {
await this.dormir(6, { grisReve: true });
const blessures = duplicate(Misc.templateData(this).blessures);
await this._recupererBlessures(message, "legere", blessures.legeres.liste.filter(b => b.active), []);
await this._recupererBlessures(message, "grave", blessures.graves.liste.filter(b => b.active), blessures.legeres.liste);
await this._recupererBlessures(message, "critique", blessures.critiques.liste.filter(b => b.active), blessures.graves.liste);
await this.update({ "data.blessures": blessures });
await this._recupererVie(message);
const moralActuel = Misc.toInt(Misc.templateData(this).compteurs.moral.value);
if (moralActuel != 0) {
await this.moralIncDec(-Math.sign(moralActuel));
}
await this._recupereChance();
await this.transformerStress();
this.bonusRecuperationPotion = 0; // Reset potion
}
ChatMessage.create(message);
this.sheet.render(true);
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async dormirChateauDormant() { async dormirChateauDormant() {
let message = { let message = {
@ -452,8 +484,10 @@ export class RdDActor extends Actor {
this.bonusRecuperationPotion = 0; // Reset potion this.bonusRecuperationPotion = 0; // Reset potion
await this.retourSust(message); await this.retourSust(message);
await this.verifierPotionsEnchantees(); await this.verifierPotionsEnchantees();
if (message.content != "") {
message.content = `A la fin Chateau Dormant, ${message.content}<br>Un nouveau jour se lève`; message.content = `A la fin Chateau Dormant, ${message.content}<br>Un nouveau jour se lève`;
ChatMessage.create(message); ChatMessage.create(message);
}
this.sheet.render(true); this.sheet.render(true);
} }
@ -588,22 +622,45 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async dormir(heures) { async dormir(heures, options = { grisReve: false }) {
let message = { let message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: `${this.name}: Vous dormez ${heures == 1 ? 'une' : heures} heure${heures == 1 ? '' : 's'}.` content: ""
}; };
await this.recupereEndurance(message); await this.recupereEndurance(message);
for (let i = 0; i < heures; i++) { let sep = ""
let recuperationReve = "";
let i = 0;
for (; i < heures; i++) {
await this._recupererEthylisme(message); await this._recupererEthylisme(message);
await this.recupererFatigue(message); await this.recupererFatigue(message);
await this.recuperationReve(message, 1); if (!options.grisReve) {
if (EffetsDraconiques.isDonDoubleReve(this)) { let r = await this.recuperationReve(message);
await this.recuperationReve(message, 2); if (r >= 0) {
recuperationReve += sep + r;
sep = "+";
}
if (r >= 0 && EffetsDraconiques.isDonDoubleReve(this)) {
r = await this.recuperationReve(message);
if (r >= 0) {
recuperationReve += sep + r;
} }
} }
if (r < 0) {
i++;// rêve de dragon pendant l'heure en cours
break;
}
}
}
if (!options.grisReve) {
message.content = `${this.name}: Vous dormez ${i == 0 ? 'une' : i} heure${i == 1 ? '' : 's'}. `
+ (recuperationReve == "" ? "" : `Vous récupérez ${recuperationReve} Points de rêve. `)
+ message.content;
ChatMessage.create(message); ChatMessage.create(message);
}
this.sheet.render(true); this.sheet.render(true);
return i;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -635,7 +692,6 @@ export class RdDActor extends Actor {
let fatigue = Misc.templateData(this).sante.fatigue.value; let fatigue = Misc.templateData(this).sante.fatigue.value;
const fatigueMin = this._computeFatigueMin(); const fatigueMin = this._computeFatigueMin();
if (fatigue <= fatigueMin) { if (fatigue <= fatigueMin) {
message.content += "Vous êtes déjà reposé. ";
return; return;
} }
fatigue = Math.max(fatigueMin, this._calculRecuperationSegment(fatigue)); fatigue = Math.max(fatigueMin, this._calculRecuperationSegment(fatigue));
@ -667,27 +723,24 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async recuperationReve(message, demiHeure) { async recuperationReve(message) {
const seuil = Misc.templateData(this).reve.seuil.value; const seuil = Misc.templateData(this).reve.seuil.value;
const reveActuel = this.getReveActuel(); const reveActuel = this.getReveActuel();
if (reveActuel >= seuil) { if (reveActuel < seuil) {
if (demiHeure == 1) {
message.content += `Vous avez suffisament rêvé, au delà de votre seuil. `;
}
}
else {
let deRecuperation = await RdDDice.rollTotal("1dr"); let deRecuperation = await RdDDice.rollTotal("1dr");
console.log("recuperationReve", deRecuperation); console.log("recuperationReve", deRecuperation);
if (deRecuperation >= 7) { if (deRecuperation >= 7) {
// Rêve de Dragon ! // Rêve de Dragon !
message.content += `Vous faites un <strong>Rêve de Dragon</strong> de ${deRecuperation} Points de rêve! `; message.content += `Vous faites un <strong>Rêve de Dragon</strong> de ${deRecuperation} Points de rêve qui vous réveille! `;
await this.combattreReveDeDragon(deRecuperation); await this.combattreReveDeDragon(deRecuperation);
return -1;
} }
else { else {
message.content += `Vous récupérez ${deRecuperation} Points de rêve. `;
await this.reveActuelIncDec(deRecuperation); await this.reveActuelIncDec(deRecuperation);
return deRecuperation;
} }
} }
return 0;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -724,7 +777,7 @@ export class RdDActor extends Actor {
async combattreReveDeDragon(force) { async combattreReveDeDragon(force) {
let rollData = { let rollData = {
actor: this, actor: this,
competence: duplicate(this.getBestDraconic()), competence: duplicate(this.getDraconicOrZero()),
canClose: false, canClose: false,
rencontre: duplicate(TMRRencontres.getRencontre('rdd')), rencontre: duplicate(TMRRencontres.getRencontre('rdd')),
tmr: true, tmr: true,
@ -744,7 +797,7 @@ export class RdDActor extends Actor {
label: 'Maîtriser le Rêve de Dragon', label: 'Maîtriser le Rêve de Dragon',
callbacks: [ callbacks: [
this.createCallbackExperience(), this.createCallbackExperience(),
{ action: r => this.resultCombatReveDeDragon(r) } { action: async r => this.resultCombatReveDeDragon(r) }
] ]
} }
); );
@ -1694,14 +1747,14 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async jetDeMoral(situation, messageReussi = undefined, messageManque = undefined) { async jetDeMoral(situation, messageReussi = undefined, messageManque = undefined) {
let jetMoral = await this._jetMoral(situation) let jetMoral = await this._jetMoral(situation)
if (jetMoral.ajustement != 0) {
let defaultMessage = `Vous ${jetMoral.ajustement > 0 ? "gagnez du moral" : jetMoral.ajustement < 0 ? "perdez du moral" : "gardez votre moral"}.`; let defaultMessage = jetMoral.ajustement > 0 ? "Vous gagnez du moral" : "Vous perdez du moral";
let finMessage = jetMoral.succes ? (messageReussi != undefined ? messageReussi : defaultMessage) : (messageManque != undefined ? messageManque : defaultMessage); let finMessage = jetMoral.succes ? (messageReussi != undefined ? messageReussi : defaultMessage) : (messageManque != undefined ? messageManque : defaultMessage);
let message = `Jet de moral ${jetMoral.succes ? "réussi" : "manqué"} en situation ${situation} (${jetMoral.jet}/${jetMoral.difficulte}). <br/>${finMessage}`;
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
content: message content: `${finMessage} - jet ${jetMoral.succes ? "réussi" : "manqué"} en situation ${situation} (${jetMoral.jet}/${jetMoral.difficulte}).`
}); });
}
return jetMoral.ajustement; return jetMoral.ajustement;
} }

56
module/dialog-repos.js Normal file
View File

@ -0,0 +1,56 @@
import { Misc } from "./misc.js";
export class DialogRepos extends Dialog {
static async create(actor) {
let actorData = Misc.data(actor)
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-repos.html", actorData);
new DialogRepos(html, actor).render(true);
}
constructor(html, actor) {
let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 400, 'z-index': 99999 };
let conf = {
title: "Se reposer",
content: html,
default: "repos",
buttons: {
"repos": { label: "Se reposer", callback: async it => { this.repos(); } }
}
};
super(conf, options);
this.actor = actor;
}
async repos() {
await $("[name='nb-heures']").change();
await $("[name='nb-jours']").change();
const selection = await $("[name='repos']:checked").val();
const nbHeures = Number.parseInt(await $("[name='nb-heures']").val());
const nbJours = Number.parseInt(await $("[name='nb-jours']").val());
switch (selection) {
case "sieste": {
await this.actor.dormir(nbHeures);
return;
}
case "nuit": {
let heuresDormies = await this.actor.dormir(nbHeures);
if (heuresDormies == nbHeures){
await this.actor.dormirChateauDormant();
}
return;
}
case "chateau-dormant":
await this.actor.dormirChateauDormant();
return;
case "gris-reve": {
await this.actor.grisReve(nbJours);
return;
}
}
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
}
}

View File

@ -25,7 +25,7 @@
/* -------------------------------------------- */ /* -------------------------------------------- */
async resetNombreAstraux() { async resetNombreAstraux() {
game.system.rdd.calendrier.resetNombreAstral(); game.system.rdd.calendrier.resetNombreAstral();
await game.system.rdd.calendrier.rebuildListeNombreAstral( 'reset' ); await game.system.rdd.calendrier.rebuildListeNombreAstral();
game.system.rdd.calendrier.showAstrologieEditor(); game.system.rdd.calendrier.showAstrologieEditor();
} }

View File

@ -88,7 +88,7 @@ export class RdDCalendrier extends Application {
// nombre astral // nombre astral
if (game.user.isGM) { if (game.user.isGM) {
this.listeNombreAstral = this._loadListNombreAstral(); this.listeNombreAstral = this._loadListNombreAstral();
await this.rebuildListeNombreAstral(); // Ensure always up-to-date await this.rebuildListeNombreAstral(false); // Ensure always up-to-date
} }
console.log(this.calendrier, this.calendrierPos, this.listeNombreAstral); console.log(this.calendrier, this.calendrierPos, this.listeNombreAstral);
} }
@ -148,13 +148,15 @@ export class RdDCalendrier extends Application {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async ajouterNombreAstral(index, showdice = true) { async ajouterNombreAstral(index, showDice = true) {
const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showdice, rollMode: "selfroll" }); const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showDice, hideDice: !showDice, rollMode: "selfroll" });
const dateFuture = this.getDateFromIndex(index); const dateFuture = this.getDateFromIndex(index);
if (showDice) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatMessage.getWhisperRecipients("GM"), whisper: ChatMessage.getWhisperRecipients("GM"),
content: `Le chiffre astrologique du ${dateFuture} sera le ${nombreAstral}` content: `Le chiffre astrologique du ${dateFuture} sera le ${nombreAstral}`
}); });
}
return { return {
nombreAstral: nombreAstral, nombreAstral: nombreAstral,
valeursFausses: [], valeursFausses: [],
@ -197,7 +199,7 @@ export class RdDCalendrier extends Application {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async rebuildListeNombreAstral( raison = 'incjour') { async rebuildListeNombreAstral(showDice = true) {
if (game.user.isGM) { if (game.user.isGM) {
let jourCourant = this.getCurrentDayIndex(); let jourCourant = this.getCurrentDayIndex();
@ -208,7 +210,7 @@ export class RdDCalendrier extends Application {
if (na) { if (na) {
newList[i] = duplicate(na); newList[i] = duplicate(na);
} else { } else {
newList[i] = await this.ajouterNombreAstral(dayIndex, raison == 'incjour' ); newList[i] = await this.ajouterNombreAstral(dayIndex, showDice );
} }
} }
console.log("SAVE list", newList, jourCourant); console.log("SAVE list", newList, jourCourant);
@ -438,7 +440,7 @@ export class RdDCalendrier extends Application {
this.calendrier.heureRdD = RdDCalendrier.getDefSigne(calendrierData.heureKey); // Index dans heuresList this.calendrier.heureRdD = RdDCalendrier.getDefSigne(calendrierData.heureKey); // Index dans heuresList
game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier)); game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier));
await this.rebuildListeNombreAstral( 'reset' ); await this.rebuildListeNombreAstral();
game.socket.emit("system.foundryvtt-reve-de-dragon", { game.socket.emit("system.foundryvtt-reve-de-dragon", {
msg: "msg_sync_time", msg: "msg_sync_time",

View File

@ -134,12 +134,14 @@ export class RdDDice {
static async roll(formula, options = { showDice: false, rollMode: undefined }) { static async roll(formula, options = { showDice: false, rollMode: undefined }) {
const roll = new Roll(formula); const roll = new Roll(formula);
await roll.evaluate({ async: true }); await roll.evaluate({ async: true });
if (!options.hideDice) {
roll.showDice = options.showDice; roll.showDice = options.showDice;
await RdDDice.show(roll, options.rollMode ?? game.settings.get("core", "rollMode")); await RdDDice.show(roll, options.rollMode ?? game.settings.get("core", "rollMode"));
}
return roll; return roll;
} }
static async rollTotal(formula, options = { showDice: false }) { static async rollTotal(formula, options = { showDice: false, hideDice: false }) {
const roll = await RdDDice.roll(formula, options); const roll = await RdDDice.roll(formula, options);
return roll.total; return roll.total;
} }

View File

@ -57,8 +57,7 @@
<div> <div>
<span class="encaisser-direct"><a title="Encaisser des dommages"><img class="button-img" src="icons/svg/bones.svg" alt="Encaisser des dommages"/></a></span> <span class="encaisser-direct"><a title="Encaisser des dommages"><img class="button-img" src="icons/svg/bones.svg" alt="Encaisser des dommages"/></a></span>
<span class="gm-only remise-a-neuf"><a title="Remise à neuf"><img class="button-img" src="icons/svg/regen.svg" alt="Remise à neuf"/></a></span> <span class="gm-only remise-a-neuf"><a title="Remise à neuf"><img class="button-img" src="icons/svg/regen.svg" alt="Remise à neuf"/></a></span>
<span class="dormir-une-heure"><a title="Dormir une heure"><img class="button-img" src="icons/svg/sleep.svg" alt="Dormir une heure"/></a></span> <span class="repos"><a title="Repos"><img class="button-img" src="icons/svg/sleep.svg" alt="Se reposer"/></a></span>
<span class="dormir-chateau-dormant"><a title="Chateau Dormant"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg" alt="Chateau Dormant"/></a></span>
{{#if data.attributs.hautrevant.value}} {{#if data.attributs.hautrevant.value}}
<span class="monte-tmr"><a title="Montée dans les Terres M&eacute;dianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg" alt="Montée dans les Terres M&eacute;dianes !"/></a></span> <span class="monte-tmr"><a title="Montée dans les Terres M&eacute;dianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg" alt="Montée dans les Terres M&eacute;dianes !"/></a></span>
<span class="monte-tmr-rapide"><a title="Montée accélérée dans les Terres M&eacute;dianes !"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-rapide.svg" alt="Montée accélérée dans les Terres M&eacute;dianes !"/></a></span> <span class="monte-tmr-rapide"><a title="Montée accélérée dans les Terres M&eacute;dianes !"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-rapide.svg" alt="Montée accélérée dans les Terres M&eacute;dianes !"/></a></span>

View File

@ -0,0 +1,38 @@
<form class="skill-roll-dialog">
<div class="flexcol">
<div class="flex-group-left">
<div class="flexrow"><span>
<img class="chat-icon" src="{{img}}" title="{{name}}" alt="{{name}}" />
<h4>{{name}} se repose</h4>
</span></div>
<div class="flexrow"><span>
<input type="radio" name="repos" id="chateau-dormant" value="chateau-dormant">
<label for="chateau-dormant">Château Dormant</label>
</span></div>
<hr>
<div class="flexrow"><span>
<input class type="radio" name="repos" id="sieste" value="sieste">
<label for="sieste">Sieste de quelques heures</label>
</span></div>
<div class="flexrow"><span>
<input type="radio" name="repos" id="nuit" value="nuit" checked>
<label for="nuit">Dormir la nuit</label>
</span></div>
<br>
<div class="flexrow">
<label for="nb-heures">Nombre d'heures</label>
<input type="number" name="nb-heures" value="4" data-dtype="Number" />
</div>
<hr>
<div class="flexrow"><span>
<input type="radio" name="repos" id="gris-reve" value="gris-reve">
<label for="gris-reve">Gris rêve</label>
</span></div>
<br>
<div class="flexrow">
<label for="nb-jours">Nombre de jours</label>
<input type="number" name="nb-jours" value="2" data-dtype="Number" />
</div>
</div>
</div>
</form>