Signes draconiques aléatoires
This commit is contained in:
parent
b80af454a2
commit
7c4d7987ac
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
||||
.idea
|
||||
todo.txt
|
||||
todo.md
|
||||
/.vscode
|
||||
|
BIN
icons/heures/de-heures.webp
Normal file
BIN
icons/heures/de-heures.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
BIN
icons/tmr/signe_draconique.webp
Normal file
BIN
icons/tmr/signe_draconique.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
@ -2,59 +2,43 @@ 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() {
|
||||
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 },
|
||||
}
|
||||
},
|
||||
signe: await RdDItemSigneDraconique.randomSigneDraconique(),
|
||||
actors: game.actors.filter(actor => actor.isHautRevant()).map(it => duplicate(Misc.data(it)))
|
||||
};
|
||||
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));
|
||||
}
|
||||
@ -71,29 +55,53 @@ 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-tmr").change((event) => this.onSelectTmr(event));
|
||||
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 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 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;
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,57 +0,0 @@
|
||||
<form class="skill-roll-dialog">
|
||||
<div>
|
||||
<h4>Un signe draconique éphémère se manifeste:
|
||||
<br><input class="signe-name" type="text" name="signe.name" value="{{signe.name}}" data-dtype="String" />
|
||||
</h4>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="actors">Personnages concernés</label>
|
||||
<select class="select-actor attribute-value" name="actors" id="actors" size="7" multiple>
|
||||
{{#each actors as |actor key|}}
|
||||
<option value="{{actor.name}}" data-actor-id="{{actor._id}}" {{#if actor.selected}}selected{{/if}}>
|
||||
<img class="chat-icon" src="{{actor.img}}" title="{{actor.name}}" alt="{{actor.name}}" />
|
||||
{{actor.name}}
|
||||
</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="signe.data.difficulte">Difficulte</label>
|
||||
<input class="attribute-value" type="number" name="signe.data.difficulte" value="{{signe.data.difficulte}}" data-dtype="Number" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="signe.data.valeur.norm">Expérience en sorts</label>
|
||||
<div class="flexrow">
|
||||
<input class="valeur-xp-sort" type="number" name="signe.data.valeur.norm" data-typereussite="norm"
|
||||
value="{{signe.data.valeur.norm}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Sign.</span>
|
||||
<input class="valeur-xp-sort" type="number" name="signe.data.valeur.sign" data-typereussite="sign"
|
||||
value="{{signe.data.valeur.sign}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Part.</span>
|
||||
<input class="valeur-xp-sort" type="number" name="signe.data.valeur.part" data-typereussite="part"
|
||||
value="{{signe.data.valeur.part}}" min="1" max="100" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span>
|
||||
<label for="signe.data.ephemere">Ephémère</label>
|
||||
<input class="attribute-value signe-data-ephemere" type="checkbox" name="signe.data.ephemere" {{#if signe.data.ephemere}}checked{{/if}} />
|
||||
</span>
|
||||
<span>
|
||||
<input class="signe-data-duree attribute-value" type="text" name="signe.data.duree" value="{{signe.data.duree}}" data-dtype="String" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="tmrs">Terres médianes</label>
|
||||
<select class="select-tmr attribute-value" name="tmrs" id="tmrs" size="{{tmrs.length}}" multiple>
|
||||
{{#each tmrs as |tmr key|}}
|
||||
<option value="{{tmr.name}}" {{#if tmr.selected}}selected{{/if}}>{{tmr.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</form>
|
52
templates/dialog-create-signedraconique.html
Normal file
52
templates/dialog-create-signedraconique.html
Normal file
@ -0,0 +1,52 @@
|
||||
<form class="skill-roll-dialog">
|
||||
<div>
|
||||
<h4>Paramétrer le signe draconique
|
||||
<span class="chat-card-button-area">
|
||||
<a class="signe-aleatoire chat-card-button">Signe aléatoire</a>
|
||||
</span>
|
||||
<br><input type="text" name="signe.name" value="{{signe.name}}" data-dtype="String" />
|
||||
</h4>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="signe.data.difficulte">Difficulte</label>
|
||||
<input type="number" name="signe.data.difficulte" value="{{signe.data.difficulte}}" data-dtype="Number" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="signe.data.valeur.norm">Expérience en sorts</label>
|
||||
<div class="flexrow">
|
||||
<input class="signe-xp-sort" type="number" name="signe.data.valeur.norm" data-typereussite="norm"
|
||||
value="{{signe.data.valeur.norm}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Sign.</span>
|
||||
<input class="signe-xp-sort" type="number" name="signe.data.valeur.sign" data-typereussite="sign"
|
||||
value="{{signe.data.valeur.sign}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Part.</span>
|
||||
<input class="signe-xp-sort" type="number" name="signe.data.valeur.part" data-typereussite="part"
|
||||
value="{{signe.data.valeur.part}}" min="1" max="100" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group flexrow">
|
||||
<label for="signe.data.ephemere">Ephémère</label>
|
||||
<input class="flex-shrink" type="checkbox" name="signe.data.ephemere" {{#if signe.data.ephemere}}checked{{/if}} />
|
||||
<span>
|
||||
<input type="text" name="signe.data.duree" value="{{signe.data.duree}}" data-dtype="String" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="tmrs">Terres médianes</label>
|
||||
<select class="select-tmr" name="tmrs" id="tmrs" size="{{tmrs.length}}" multiple>
|
||||
{{#each tmrs as |tmr key|}}
|
||||
<option value="{{tmr.name}}" {{#if tmr.selected}}selected{{/if}}>{{tmr.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="actors">Haut-rêvants concernés</label>
|
||||
<select class="select-actor" id="actors" size="7" multiple>
|
||||
{{#each actors as |actor key|}}
|
||||
<option value="{{actor.name}}" data-actor-id="{{actor._id}}" {{#if actor.selected}}selected{{/if}}>{{actor.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
@ -3,6 +3,7 @@
|
||||
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||
<div class="header-fields">
|
||||
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
|
||||
<a class="signe-aleatoire chat-card-button">Signe aléatoire</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@ -16,13 +17,13 @@
|
||||
<div class="form-group">
|
||||
<label for="data.valeur.norm">Expérience en sorts</label>
|
||||
<div class="flexrow">
|
||||
<input class="valeur-xp-sort" type="number" name="data.valeur.norm" data-typereussite="norm"
|
||||
<input class="signe-xp-sort" type="number" name="data.valeur.norm" data-typereussite="norm"
|
||||
value="{{data.valeur.norm}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Sign.</span>
|
||||
<input class="valeur-xp-sort" type="number" name="data.valeur.sign" data-typereussite="sign"
|
||||
<input class="signe-xp-sort" type="number" name="data.valeur.sign" data-typereussite="sign"
|
||||
value="{{data.valeur.sign}}" min="1" max="100" data-dtype="Number" />
|
||||
<span>Part.</span>
|
||||
<input class="valeur-xp-sort" type="number" name="data.valeur.part" data-typereussite="part"
|
||||
<input class="signe-xp-sort" type="number" name="data.valeur.part" data-typereussite="part"
|
||||
value="{{data.valeur.part}}" min="1" max="100" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user