Signes draconiques aléatoires

This commit is contained in:
Vincent Vandemeulebrouck
2021-05-11 21:21:33 +02:00
parent 5a452aa17c
commit d1ac4b3d59
15 changed files with 204 additions and 145 deletions

View File

@ -2,59 +2,44 @@ import { ChatUtility } from "./chat-utility.js";
import { HtmlUtility } from "./html-utility.js";
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
import { Misc } from "./misc.js";
import { RdDRollTables } from "./rdd-rolltables.js";
import { TMRType, TMRUtility } from "./tmr-utility.js";
export class DialogCreateSigneDraconiqueForActors extends Dialog {
export class DialogCreateSigneDraconique extends Dialog {
static async createSigneForActors() {
const signe = await RdDItemSigneDraconique.randomSigneDraconique();
let dialogData = {
signe: {
name: 'Un signe draconique',
type: "signedraconique",
img: 'systems/foundryvtt-reve-de-dragon/icons/tmr/gift.webp',
data: {
typesTMR: DialogCreateSigneDraconiqueForActors.selectRandomTmrs(),
ephemere: true,
duree: "1 round",
difficulte: -5,
valeur: { norm: 10, sign: 10, part: 15 },
}
},
actors: game.actors.filter(actor => actor.isHautRevant()).map(it => duplicate(Misc.data(it)))
signe: signe,
tmrs: TMRUtility.listSelectedTMR(signe.data.typesTMR ?? []),
actors: game.actors.filter(actor => actor.isHautRevant()).map(actor => {
let actorData = duplicate(Misc.data(actor));
actorData.selected = actor.hasPlayerOwner;
return actorData;
})
};
dialogData.tmrs = TMRUtility.listSelectedTMR(dialogData.signe.data.typesTMR ?? []);
dialogData.actors.forEach(it => it.selected = false);
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique-actors.html", dialogData);
new DialogCreateSigneDraconiqueForActors(dialogData, html)
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique.html", dialogData);
new DialogCreateSigneDraconique(dialogData, html)
.render(true);
}
static selectRandomTmrs() {
let tmrs = Object.values(TMRType).map(value => Misc.upperFirst(value.name));
const nbTmr = tmrs.length;
let remove = Math.floor(Math.random() * (nbTmr - 1));
for (let i = nbTmr; i > remove; i--) {
tmrs.splice(Math.floor(Math.random() * i), 1);
}
return tmrs;
}
constructor(dialogData, html, callback) {
let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 650, 'z-index': 99999 };
let conf = {
title: "Créer un signe pour les personnages",
title: "Créer un signe",
content: html,
default: "Créer le signe",
buttons: { "Créer le signe": { label: "Créer le signe", callback: it => { this._onCreerSigne(); } } }
default: "Ajouter aux haut-rêvants",
buttons: {
"Ajouter aux haut-rêvants": { label: "Ajouter aux haut-rêvants", callback: it => { this._onCreerSigneActeurs(); } }
}
};
super(conf, options);
this.dialogData = dialogData;
}
async _onCreerSigne() {
async _onCreerSigneActeurs() {
this.validerSigne();
this.dialogData.actors.filter(it => it.selected).map(it => game.actors.get(it._id))
.forEach(actor => this._createSigneForActor(actor, this.dialogData.signe));
}
@ -70,30 +55,47 @@ export class DialogCreateSigneDraconiqueForActors extends Dialog {
});
}
validerSigne() {
this.dialogData.signe.name = $("[name='signe.name']").val();
this.dialogData.signe.data.valeur.norm = $("[name='signe.data.valeur.norm']").val();
this.dialogData.signe.data.valeur.sign = $("[name='signe.data.valeur.sign']").val();
this.dialogData.signe.data.valeur.part = $("[name='signe.data.valeur.part']").val();
this.dialogData.signe.data.difficulte = $("[name='signe.data.difficulte']").val();
this.dialogData.signe.data.ephemere = $("[name='signe.data.ephemere']").prop("checked");
this.dialogData.signe.data.duree = $("[name='signe.data.duree']").val();
this.dialogData.signe.data.typesTMR = $(".select-tmr").val();
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
this.setEphemere(this.dialogData.signe.data.ephemere);
html.find(".signe-name").change((event) => this.dialogData.signe.name = event.currentTarget.value);
html.find(".signe-data-ephemere").change((event) => this.setEphemere(event.currentTarget.checked));
html.find(".select-tmr").change((event) => this.onSelectTmr(event));
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
html.find("[name='signe.data.ephemere']").change((event) => this.setEphemere(event.currentTarget.checked));
html.find(".select-actor").change((event) => this.onSelectActor(event));
html.find(".valeur-xp-sort").change((event) => this.onValeurXpSort(event));
html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event));
}
async setEphemere(ephemere){
async setSigneAleatoire() {
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique();
$("[name='signe.name']").val(newSigne.name);
$("[name='signe.data.valeur.norm']").val(newSigne.data.valeur.norm);
$("[name='signe.data.valeur.sign']").val(newSigne.data.valeur.sign);
$("[name='signe.data.valeur.part']").val(newSigne.data.valeur.part);
$("[name='signe.data.difficulte']").val(newSigne.data.difficulte);
$("[name='signe.data.duree']").val(newSigne.data.duree);
$("[name='signe.data.ephemere']").prop("checked", newSigne.data.ephemere);
$(".select-tmr").val(newSigne.data.typesTMR);
this.setEphemere(newSigne.data.ephemere);
}
async setEphemere(ephemere) {
this.dialogData.signe.data.ephemere = ephemere;
HtmlUtility._showControlWhen($(".signe-data-duree"), ephemere);
}
async onSelectTmr(event) {
event.preventDefault();
this.dialogData.signe.data.typesTMR = $(".select-tmr").val();
}
async onSelectActor(event) {
event.preventDefault();
let selectActor = $(".select-actor");
const options = event.currentTarget.options;
for (var i = 0; i < options.length; i++) { // looping over the options
const actorId = options[i].attributes["data-actor-id"].value;

View File

@ -60,8 +60,23 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
if (!this.options.editable) return;
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
html.find(".select-tmr").change((event) => this.onSelectTmr(event));
html.find(".valeur-xp-sort").change((event) => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value)));
html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value)));
}
async setSigneAleatoire() {
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique();
// $("[name='signe.name']").val(newSigne.name);
// $("[name='signe.data.valeur.norm']").val(newSigne.data.valeur.norm);
// $("[name='signe.data.valeur.sign']").val(newSigne.data.valeur.sign);
// $("[name='signe.data.valeur.part']").val(newSigne.data.valeur.part);
// $("[name='signe.data.difficulte']").val(newSigne.data.difficulte);
// $("[name='signe.data.duree']").val(newSigne.data.duree);
// $("[name='signe.data.ephemere']").prop("checked", newSigne.data.ephemere);
// $(".select-tmr").val(newSigne.data.typesTMR);
// this.setEphemere(newSigne.data.ephemere);
this.object.update(newSigne);
}
async onSelectTmr(event) {

View File

@ -1,5 +1,15 @@
import { Misc } from "./misc.js";
import { RdDRollTables } from "./rdd-rolltables.js";
import { TMRType } from "./tmr-utility.js";
const tableSignesIndicatifs = [
{ rarete: "Très facile", difficulte: 0, xp: 6, nbCases: 14 },
{ rarete: "Facile", difficulte: -2, xp: 10, nbCases: 10 },
{ rarete: "Moyen", difficulte: -3, xp: 15, nbCases: 7 },
{ rarete: "Difficile", difficulte: -5, xp: 20, nbCases: 4 },
{ rarete: "Ardu", difficulte: -8, xp: 30, nbCases: 1 }
]
export class RdDItemSigneDraconique {
static prepareSigneDraconiqueMeditation(meditation, rolled) {
@ -57,4 +67,33 @@ export class RdDItemSigneDraconique {
}
}
static async randomSigneDraconique() {
let modele = await Misc.rollOneOf(tableSignesIndicatifs);
return {
name: await RdDItemSigneDraconique.randomSigneDescription(),
type: "signedraconique",
img: 'systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp',
data: {
typesTMR: await RdDItemSigneDraconique.randomTmrs(modele.nbCases),
ephemere: true,
duree: "1 round",
difficulte: modele.difficulte,
valeur: { norm: modele.xp, sign: modele.xp, part: Math.floor(modele.xp * 1.5) },
}
};
}
static async randomTmrs(nbTmr = undefined) {
let tmrs = Object.values(TMRType).map(value => Misc.upperFirst(value.name));
let keep = nbTmr ?? (await new Roll("1d" + TMRType.length).evaluate().total + 1);
for (let i = tmrs.length; i > keep; i--) {
tmrs.splice(await new Roll("1d" + i).evaluate().total, 1);
}
return tmrs;
}
static async randomSigneDescription() {
return await RdDRollTables.drawTextFromRollTable("Signes draconiques", false);
}
}

View File

@ -1,6 +1,6 @@
/* -------------------------------------------- */
import { DialogCreateSigneDraconiqueForActors } from "./dialog-create-signedraconique-actors.js";
import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js";
import { RdDItemCompetence } from "./item-competence.js";
import { Misc } from "./misc.js";
import { RdDCarac } from "./rdd-carac.js";
@ -325,7 +325,7 @@ export class RdDCommands {
}
async creerSignesDraconiques() {
DialogCreateSigneDraconiqueForActors.createSigneForActors();
DialogCreateSigneDraconique.createSigneForActors();
return true;
}

View File

@ -8,31 +8,20 @@ export class RdDRollTables {
const table = await pack.getDocument(entry._id);
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"});
console.log("RdDRollTables", tableName, toChat, ":", draw);
return draw;
return draw.results.length > 0 ? draw.results[0] : undefined;
}
/* -------------------------------------------- */
static async drawItemFromRollTable(tableName, toChat) {
const draw = await RdDRollTables.genericGetTableResult(tableName, toChat);
const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined;
if (drawnItemRef.data.collection) {
console.log(drawnItemRef);
const pack = game.packs.get(drawnItemRef.data.collection);
return await pack.getDocument(drawnItemRef.data.resultId);
}
ui.notifications.warn("le tirage ne correspond pas à une entrée d'un Compendium")
return drawnItemRef.text;
static async drawItemFromRollTable(tableName, toChat = false) {
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
const pack = game.packs.get(drawResult.data.collection);
return await pack.getDocument(drawResult.data.resultId);
}
/* -------------------------------------------- */
static async drawTextFromRollTable(tableName, toChat) {
const draw = await RdDRollTables.genericGetTableResult(tableName, toChat);
const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined;
if (drawnItemRef.collection) {
ui.notifications.warn("le tirage correspond à une entrée d'un Compendium, on attendait un texte")
return await pack.getDocument(drawnItemRef.resultId);
}
return drawnItemRef.text;
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
return drawResult.data.text;
}
/* -------------------------------------------- */

View File

@ -149,6 +149,8 @@ export class RdDTMRDialog extends Dialog {
}
_updateDemiReve() {
this.notifierResonanceSigneDraconique(this._getActorCoord());
if (!this.cacheTMR) {
this._setTokenPosition(this.demiReve);
}
@ -237,14 +239,14 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
updateValuesDisplay() {
Array.from(document.getElementsByClassName("lire-signe-draconique"))
.forEach(it => HtmlUtility._showControlWhen(it, this.actor.isResonanceSigneDraconique(this._getActorCoord())));
async updateValuesDisplay() {
const coord = this._getActorCoord();
const actorData = Misc.data(this.actor);
HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(coord));
let ptsreve = document.getElementById("tmr-pointsreve-value");
const actorData = Misc.data(this.actor);
ptsreve.innerHTML = actorData.data.reve.reve.value;
const coord = this._getActorCoord();
let tmrpos = document.getElementById("tmr-pos");
if (this.cacheTMR) {
@ -906,6 +908,7 @@ export class RdDTMRDialog extends Dialog {
Si la case est le demi-rêve, ne pas lancer de sort.
Si un lancement de sort est en cours, trouver un moyen de réafficher cette fenêtre si on essaie de lancer un sort (ou bloquer le lancer de sort)
*/
this.notifierResonanceSigneDraconique(targetCoord);
await this.actor.rollUnSort(targetCoord);
this.nettoyerRencontre();
}
@ -952,6 +955,15 @@ export class RdDTMRDialog extends Dialog {
}
}
async notifierResonanceSigneDraconique(coord) {
if (this.actor.isResonanceSigneDraconique(coord)) {
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html`, { alias: this.actor.name, typeTMR: TMRUtility.getTMRType(coord) })
});
}
}
/* -------------------------------------------- */
async postRencontre(tmr) {
if (!(this.viewOnly || this.currentRencontre)) {

View File

@ -338,7 +338,7 @@ export class TMRUtility {
static getTMRType(coord) {
const tmr = TMRMapping[coord];
return Misc.upperFirst(tmr.type);
return Misc.upperFirst(TMRType[tmr.type].name);
}
static getTMRDescr(coord) {