Compare commits
116 Commits
Author | SHA1 | Date | |
---|---|---|---|
c515e9bc66 | |||
|
b2e7a8a6e1 | ||
09045c0d53 | |||
4c4e1e8419 | |||
66bcc51102 | |||
|
32844bbf3c | ||
|
21d6f14b68 | ||
87a0bece5e | |||
e0f83e9be2 | |||
01c1978ccd | |||
47ae157781 | |||
0c092b9099 | |||
a6d1a84b13 | |||
82e8954d5c | |||
|
249850558b | ||
45b10f2c6b | |||
d39dac3bf9 | |||
|
1f5e8c084b | ||
|
0864721bc5 | ||
4c5685c20b | |||
a618200417 | |||
|
62eb6482d0 | ||
9b8ea03067 | |||
|
8090d0280d | ||
c31202fbd3 | |||
|
146c8d184c | ||
|
c251727dea | ||
|
19f5e2af59 | ||
8b2f02d4b0 | |||
03b88a269a | |||
|
32d016b9ad | ||
|
a0c1d063f1 | ||
1e5446fcde | |||
|
f76e0db046 | ||
b7c816129b | |||
|
c786757db0 | ||
|
78d4b48aae | ||
|
0a9e8e0ac6 | ||
5443cb52bb | |||
|
b232a8fa0c | ||
|
a68aa29b53 | ||
|
ccb9cd73f4 | ||
723d1e6b99 | |||
40f99da8ac | |||
|
76865d24d2 | ||
020824af7e | |||
cc8f432746 | |||
6435ce70da | |||
db9cbc693a | |||
|
b202352979 | ||
7ddedea204 | |||
2bca036d53 | |||
8f08f95dbf | |||
|
b5581ff9fb | ||
|
e06ae1937a | ||
0f7e1ef553 | |||
|
51afd9020c | ||
1bc5e06147 | |||
|
7f3a575349 | ||
c26ba66722 | |||
cb105dd311 | |||
76c88e530e | |||
03839397ce | |||
|
74ddc8893a | ||
790aa950c3 | |||
4672a3a7d6 | |||
2a8ab5e1ce | |||
|
4aaa72ed1a | ||
|
f087b61c27 | ||
|
96c6936c3e | ||
7d27d7d9f9 | |||
0d7ba3be69 | |||
8670456d9a | |||
b2c7ff4927 | |||
|
680fbee090 | ||
5c6a01b9f4 | |||
d45f5d625a | |||
2b1a9151d7 | |||
3335c41c27 | |||
|
329ae475d9 | ||
|
72f8c83caf | ||
|
d353b6ccaf | ||
a122a2e421 | |||
|
2465af4413 | ||
|
817c5d30ad | ||
|
87440cf7f9 | ||
965e45cead | |||
|
ac8610cd6c | ||
|
08cf1f49e1 | ||
|
4925cee756 | ||
|
43acbfb443 | ||
|
9a6fb1a850 | ||
42fb0c0b5e | |||
|
fa2b125459 | ||
|
e8d0748688 | ||
2972504640 | |||
3582fa9c8a | |||
|
d5277137dd | ||
|
dae852a1e0 | ||
1ea6b66483 | |||
d35f3ce5a2 | |||
|
bf9e74ef7c | ||
|
fd73b2c7af | ||
|
3aa13511cd | ||
94cebbb9e5 | |||
2a1495927f | |||
8d42871988 | |||
868ed01723 | |||
|
65c90c5bd4 | ||
c16101428a | |||
77d5646497 | |||
1c0c775de3 | |||
|
e8a59b56a4 | ||
|
39f6307058 | ||
|
a532a989d6 | ||
a802307dac |
BIN
fonts/goudyacc.woff
Normal file
BIN
fonts/heuresdraconiques2.ttf
Normal file
BIN
fonts/heuresdraconiques2.woff
Normal file
BIN
fonts/heuresdraconiques2.woff2
Normal file
BIN
icons/creatures/aligate_t.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
icons/creatures/araflate_t.webp
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
icons/creatures/bandersnatch_t.webp
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
icons/creatures/bramart_t.webp
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
icons/creatures/brolute_t.webp
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
icons/creatures/chamule_t.webp
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
icons/creatures/cheval_t.webp
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
icons/creatures/chiard_t.webp
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
icons/creatures/chien_t.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
icons/creatures/chrasme_t.webp
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
icons/creatures/cornicochon_t.webp
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
icons/creatures/dong_t.webp
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
icons/creatures/drakkule_t.webp
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
icons/creatures/felorn_t.webp
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
icons/creatures/harpie_t.webp
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
icons/heures/de-heures.webp
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
icons/heures/hd01.webp
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
icons/heures/hd02.webp
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
icons/heures/hd03.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
icons/heures/hd04.webp
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
icons/heures/hd05.webp
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
icons/heures/hd06.webp
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
icons/heures/hd07.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
icons/heures/hd08.webp
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
icons/heures/hd09.webp
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
icons/heures/hd10.webp
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
icons/heures/hd11.webp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
icons/heures/hd12.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
icons/tmr/gift.webp
Normal file
After Width: | Height: | Size: 528 B |
BIN
icons/tmr/pelerin.webp
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
icons/tmr/scroll.webp
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
icons/tmr/treasure-chest.webp
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
icons/tmr/wave.webp
Normal file
After Width: | Height: | Size: 1.8 KiB |
@ -126,6 +126,10 @@ export class RdDActorSheet extends ActorSheet {
|
||||
montures: this.actor.listeMontures(),
|
||||
suivants: this.actor.listeSuivants()
|
||||
}
|
||||
if (this.actor.getBestDraconic().data.niveau > -11 && !this.actor.isHautRevant()) {
|
||||
ui.notifications.error(`${this.actor.name} a des compétences draconiques, mais pas le don de Haut-Rêve!
|
||||
<br>Ajoutez-lui la tête "Don de Haut-Rêve" pour lui permettre d'utiliser ses compétences et d'accéder aux terres médianes du rêve`);
|
||||
}
|
||||
return formData;
|
||||
}
|
||||
|
||||
@ -148,16 +152,16 @@ export class RdDActorSheet extends ActorSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async creerObjet() {
|
||||
let itemType = $("#creer-equipement").val();
|
||||
let itemType = $(".item-type").val();
|
||||
await this.actor.createOwnedItem({ name: 'Nouveau ' + itemType, type: itemType }, { renderSheet: true });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async selectObjetType() {
|
||||
let itemType = ["objet", "arme", "armure", "conteneur", "herbe", "ingredient", "livre", "potion", "munition", "monnaie"];
|
||||
let options = '<span class="competence-label">Selectionnez le type d\'équipement</span><select id="creer-equipement">';
|
||||
for (let typeName of itemType) {
|
||||
options += '<option value="' + typeName + '">' + typeName + '</option>'
|
||||
let typeObjets = ["objet", "arme", "armure", "conteneur", "herbe", "ingredient", "livre", "potion", "munition", "monnaie"];
|
||||
let options = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
||||
for (let typeName of typeObjets) {
|
||||
options += `<option value="${typeName}">${typeName}</option>`
|
||||
}
|
||||
options += '</select>';
|
||||
let d = new Dialog({
|
||||
@ -174,6 +178,27 @@ export class RdDActorSheet extends ActorSheet {
|
||||
d.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async selectTypeOeuvre() {
|
||||
let typeOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu" ];
|
||||
let options = `<span class="competence-label">Selectionnez le type d'oeuvre</span><select class="item-type">`;
|
||||
for (let typeName of typeOeuvres) {
|
||||
options += `<option value="${typeName}">${typeName}</option>`
|
||||
}
|
||||
options += '</select>';
|
||||
let d = new Dialog({
|
||||
title: "Créer une oeuvre",
|
||||
content: options,
|
||||
buttons: {
|
||||
one: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Créer l'oeuvre",
|
||||
callback: () => this.creerObjet()
|
||||
}
|
||||
}
|
||||
});
|
||||
d.render(true);
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
activateListeners(html) {
|
||||
@ -221,12 +246,15 @@ export class RdDActorSheet extends ActorSheet {
|
||||
ev.preventDefault();
|
||||
}
|
||||
});
|
||||
html.find('#creer-tache').click(ev => {
|
||||
html.find('.creer-tache').click(ev => {
|
||||
this.createEmptyTache();
|
||||
});
|
||||
html.find('#creer-un-objet').click(ev => {
|
||||
html.find('.creer-un-objet').click(ev => {
|
||||
this.selectObjetType();
|
||||
});
|
||||
html.find('.creer-une-oeuvre').click(ev => {
|
||||
this.selectTypeOeuvre();
|
||||
});
|
||||
html.find('#nettoyer-conteneurs').click(ev => {
|
||||
this.actor.nettoyerConteneurs();
|
||||
});
|
||||
|
145
module/actor.js
@ -13,7 +13,6 @@ import { RdDItemSort } from "./item-sort.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { RdDEncaisser } from "./rdd-roll-encaisser.js";
|
||||
import { RdDCombat } from "./rdd-combat.js";
|
||||
import { DeDraconique } from "./de-draconique.js";
|
||||
import { RdDAudio } from "./rdd-audio.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { RdDItemArme } from "./item-arme.js";
|
||||
@ -131,6 +130,7 @@ export class RdDActor extends Actor {
|
||||
async _prepareCharacterData(actorData) {
|
||||
// Initialize empty items
|
||||
RdDCarac.computeCarac(actorData.data);
|
||||
this.computeIsHautRevant();
|
||||
this.computeEncombrementTotalEtMalusArmure();
|
||||
this.computePrixTotalEquipement();
|
||||
this.computeEtatGeneral();
|
||||
@ -156,6 +156,10 @@ export class RdDActor extends Actor {
|
||||
return this.data.type == 'personnage';
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
isHautRevant() {
|
||||
return Misc.templateData(this).attributs.hautrevant.value != ""
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getFatigueActuelle() {
|
||||
if (!this.isPersonnage()) {
|
||||
return 0;
|
||||
@ -171,8 +175,8 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getReveActuel() {
|
||||
const actorData = Misc.data(this);
|
||||
return Misc.toInt(actorData.data.reve?.reve?.value ?? actorData.data.carac.reve.value);
|
||||
const templateData = Misc.templateData(this);
|
||||
return Misc.toInt(templateData.reve?.reve?.value ?? templateData.carac.reve.value);
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getChanceActuel() {
|
||||
@ -538,7 +542,8 @@ export class RdDActor extends Actor {
|
||||
message.content += `Vous avez suffisament rêvé, au delà de votre seuil. `;
|
||||
}
|
||||
else {
|
||||
let deRecuperation = (await DeDraconique.ddr("selfroll")).total;
|
||||
const roll = new Roll("1dr").evaluate();
|
||||
let deRecuperation = roll.total;
|
||||
console.log("recuperationReve", deRecuperation);
|
||||
if (deRecuperation >= 7) {
|
||||
// Rêve de Dragon !
|
||||
@ -947,6 +952,14 @@ export class RdDActor extends Actor {
|
||||
return Math.max(0, Math.ceil(diffEnc));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async computeIsHautRevant() {
|
||||
const tplData = Misc.templateData(this);
|
||||
tplData.attributs.hautrevant.value = this.data.items.find(it => it.type == 'tete' && Grammar.toLowerCaseNoAccent(it.name) == 'don de haut-reve')
|
||||
? "Haut rêvant"
|
||||
: "";
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async computeEncombrementTotalEtMalusArmure() {
|
||||
let encTotal = 0;
|
||||
@ -1132,7 +1145,7 @@ export class RdDActor extends Actor {
|
||||
let newRencontres = rencontres.filter(it => it.coord != this.getDemiReve());
|
||||
if (newRencontres.length == rencontres.length) {
|
||||
newRencontres.push(currentRencontre);
|
||||
await this.update({ "data.reve.rencontre": newRencontres });
|
||||
await this.update({ "data.reve.rencontre.list": newRencontres });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1190,7 +1203,7 @@ export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async verifierSonneRound(round) {
|
||||
if (this.getSonne()) {
|
||||
if (round >= this.getSonneRound() + 1) {
|
||||
if (round > this.getSonneRound() + 1) {
|
||||
await this.setSonne(false, -1); // Nettoyer l'état sonné
|
||||
ChatMessage.create({ content: `${this.name} n'est plus sonné ce round !` });
|
||||
}
|
||||
@ -1427,9 +1440,8 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async moralIncDec(ajustementMoral) {
|
||||
|
||||
if (ajustementMoral != 0) {
|
||||
const actorData = Misc.data(this);
|
||||
if (ajustementMoral != 0) {
|
||||
let moral = Misc.toInt(actorData.data.compteurs.moral.value) + ajustementMoral
|
||||
if (moral > 3) { // exaltation
|
||||
const exaltation = Misc.toInt(actorData.data.compteurs.exaltation.value) + moral - 3;
|
||||
@ -1472,7 +1484,7 @@ export class RdDActor extends Actor {
|
||||
async ethylismeTest() {
|
||||
const actorData = Misc.data(this);
|
||||
let rollData = {
|
||||
vieValue: actorData.data.sante.vie.value,
|
||||
vieValue: actorData.data.sante.vie.max,
|
||||
etat: this.getEtatGeneral() - Math.min(0, actorData.data.compteurs.ethylisme.value), // Pour les jets d'Ethylisme, on ignore le degré d'éthylisme (p.162)
|
||||
diffNbDoses: -Number(actorData.data.compteurs.ethylisme.nb_doses || 0),
|
||||
finalLevel: 0,
|
||||
@ -1613,6 +1625,12 @@ export class RdDActor extends Actor {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
appliquerExperience(rollData) {
|
||||
const callback = this.createCallbackExperience();
|
||||
if (callback.condition(rollData)) { callback.action(rollData); }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
createCallbackExperience() {
|
||||
return {
|
||||
@ -1683,11 +1701,11 @@ export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async _appliquerAjoutExperience(rollData, display = true) {
|
||||
if (!this.isPersonnage()) return;
|
||||
let xpResult = this.appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence);
|
||||
let xpResult = await this.appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence);
|
||||
if (display && xpResult.result) {
|
||||
let xpmsg = "<br>Points d'expérience gagnés ! Carac: " + xpResult.xpCarac + ", Comp: " + xpResult.xpCompetence;
|
||||
let message = {
|
||||
whisher: ChatMessage.getWhisperRecipients(["GM", this.name]),
|
||||
whisher: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
||||
content: "<strong>" + rollData.selectedCarac.label + "</strong>" + xpmsg,
|
||||
}
|
||||
ChatMessage.create(message);
|
||||
@ -1948,6 +1966,32 @@ export class RdDActor extends Actor {
|
||||
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html');
|
||||
}
|
||||
|
||||
async rollCaracCompetence(caracName, compName, diff) {
|
||||
const carac = this.getCaracByName(caracName);
|
||||
if (!carac) {
|
||||
ui.notifications.warn(`${this.name} n'a pas de caractéristique correspondant à ${caracName}`)
|
||||
return;
|
||||
}
|
||||
const competence = this.getCompetence(compName);
|
||||
if (compName && !competence) {
|
||||
ui.notifications.warn(`${this.name} n'a pas de compétence correspondant à ${compName}`)
|
||||
return;
|
||||
}
|
||||
let rollData = {
|
||||
alias: this.name,
|
||||
caracValue: Number(carac.value),
|
||||
selectedCarac: carac,
|
||||
competence: competence,
|
||||
finalLevel: (competence?.data.niveau ?? 0) + diff,
|
||||
diffLibre: diff,
|
||||
showDice: true,
|
||||
show: { title: "Jets multiples" }
|
||||
};
|
||||
await RdDResolutionTable.rollData(rollData);
|
||||
this.appliquerExperience(rollData);
|
||||
RdDResolutionTable.displayRollData(rollData, this)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollCompetence(name) {
|
||||
let rollData = { competence: this.getCompetence(name) }
|
||||
@ -2249,9 +2293,9 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async chanceActuelleIncDec(value, limit = true) {
|
||||
chance = Math.max(Misc.templateData(this).compteurs.chance.value + value, 0);
|
||||
let chance = Math.max(Misc.templateData(this).compteurs.chance.value + value, 0);
|
||||
if (limit) {
|
||||
chance = Math.min(chance.value, this.getChance())
|
||||
chance = Math.min(chance, this.getChance())
|
||||
}
|
||||
await this.updateCompteurValue("chance", chance);
|
||||
}
|
||||
@ -2300,6 +2344,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
if (caracName == 'derobee') caracName = 'agilite';
|
||||
if (caracName == 'reve-actuel') caracName = 'reve';
|
||||
let xp = Math.abs(rolled.finalLevel);
|
||||
let xpCarac = Math.floor(xp / 2); // impair: arrondi inférieur en carac
|
||||
let xpComp = 0;
|
||||
@ -2313,7 +2358,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
if (xpCarac > 0) {
|
||||
let carac = duplicate(Misc.templateData(this).carac);
|
||||
let selectedCarac = RdDActor._findCaracByName(carac, caracName);
|
||||
let selectedCarac = RdDCarac.findCarac(carac, caracName);
|
||||
if (!selectedCarac.derivee) {
|
||||
selectedCarac.xp = Misc.toInt(selectedCarac.xp) + xpCarac;
|
||||
await this.update({ "data.carac": carac });
|
||||
@ -2360,39 +2405,17 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCaracByName(caracName) {
|
||||
switch (caracName) {
|
||||
case 'reve-actuel': case 'Rêve actuel':
|
||||
return {
|
||||
label: 'Rêve actuel',
|
||||
value: this.getReveActuel(),
|
||||
type: "number"
|
||||
getCaracAndActuel() {
|
||||
let caracs = {
|
||||
'reve-actuel': { label: 'Rêve actuel', value: this.getReveActuel(), type: "number" },
|
||||
'chance-actuelle': { label: 'Chance actuelle', value: this.getChanceActuel(), type: "number" }
|
||||
};
|
||||
case 'chance-actuelle': case 'Chance actuelle':
|
||||
return {
|
||||
label: 'Chance actuelle',
|
||||
value: this.getChanceActuel(),
|
||||
type: "number"
|
||||
};
|
||||
}
|
||||
return RdDActor._findCaracByName(Misc.templateData(this).carac, caracName);
|
||||
mergeObject(caracs, Misc.templateData(this).carac);
|
||||
return caracs
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _findCaracByName(carac, name) {
|
||||
name = name.toLowerCase();
|
||||
switch (name) {
|
||||
case 'reve-actuel': case 'rêve actuel':
|
||||
return carac.reve;
|
||||
case 'chance-actuelle': case 'chance actuelle':
|
||||
return carac.chance;
|
||||
}
|
||||
for (const [key, value] of Object.entries(carac)) {
|
||||
if (name == key || name == value.label.toLowerCase()) {
|
||||
return carac[key];
|
||||
}
|
||||
}
|
||||
return carac[name]; // Per default
|
||||
getCaracByName(caracName) {
|
||||
return RdDCarac.findCarac(this.getCaracAndActuel(), caracName);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -2427,6 +2450,12 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async displayTMR(mode = "normal") {
|
||||
let demiReve = this.listeEffets( it => it.label == "Demi-rêve");
|
||||
if ( mode != 'visu' && demiReve.length > 0 ) {
|
||||
ui.notifications.warn("Le joueur ou le MJ est déja dans les Terres Médianes avec ce personnage ! Visualisation uniquement");
|
||||
mode = "visu"; // bascule le mode en visu automatiquement
|
||||
}
|
||||
|
||||
let isRapide = mode == "rapide";
|
||||
if (mode != "visu") {
|
||||
let minReveValue = (isRapide && !EffetsDraconiques.isDeplacementAccelere(this) ? 3 : 2) + this.countMonteeLaborieuse();
|
||||
@ -3026,7 +3055,7 @@ export class RdDActor extends Actor {
|
||||
await this.addStatusEffect(StatusEffects.demiReve())
|
||||
}
|
||||
else {
|
||||
this.deleteStatusEffect(StatusEffects.demiReve())
|
||||
await this.deleteStatusEffect(StatusEffects.demiReve())
|
||||
}
|
||||
}
|
||||
|
||||
@ -3070,22 +3099,23 @@ export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
_deleteStatusEffectsByIds(effectIds, options) {
|
||||
this.deleteEmbeddedEntity('ActiveEffect', effectIds, options);
|
||||
this.applyActiveEffects();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async addStatusEffectById(id, options = { renderSheet: true }) {
|
||||
async addStatusEffectById(id, options = { renderSheet: false }) {
|
||||
const statusEffect = CONFIG.statusEffects.find(it => it.id == id);
|
||||
await this.addStatusEffect(statusEffect, options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async addStatusEffect(statusEffect, options = { renderSheet: true }) {
|
||||
async addStatusEffect(statusEffect, options = { renderSheet: false }) {
|
||||
this.deleteStatusEffectById(statusEffect.id, options);
|
||||
const effet = duplicate(statusEffect);
|
||||
effet["flags.core.statusId"] = effet.id;
|
||||
await this.createEmbeddedEntity('ActiveEffect', effet, options);
|
||||
this.applyActiveEffects();
|
||||
//effet["flags.core.statusId"] = effet.id;
|
||||
let entity = await this.createEmbeddedEntity('ActiveEffect', effet, options);
|
||||
if (entity) {
|
||||
await entity.setFlag('core', 'statusId', effet.id );
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -3108,6 +3138,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onDeleteOwnedItem(item, options, id) {
|
||||
switch (item.type) {
|
||||
case 'tete':
|
||||
@ -3122,8 +3153,9 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onCreateOwnedDraconique(item, options, id) {
|
||||
|
||||
if (Misc.isElectedUser()) {
|
||||
let draconique = Draconique.all().find(it => it.match(item));
|
||||
if (draconique) {
|
||||
draconique.onActorCreateOwned(this, item)
|
||||
@ -3131,22 +3163,29 @@ export class RdDActor extends Actor {
|
||||
this.notifyGestionTeteSouffleQueue(item, draconique.manualMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onDeleteOwnedDraconique(item, options, id) {
|
||||
|
||||
if (Misc.isElectedUser()) {
|
||||
let draconique = Draconique.all().find(it => it.match(item));
|
||||
if (draconique) {
|
||||
draconique.onActorDeleteOwned(this, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onDeleteOwnedCaseTmr(item, options, id) {
|
||||
if (Misc.isElectedUser()) {
|
||||
let draconique = Draconique.all().find(it => it.isCase(item));
|
||||
if (draconique) {
|
||||
draconique.onActorDeleteCaseTmr(this, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
notifyGestionTeteSouffleQueue(item, manualMessage = true) {
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
/**
|
||||
* Class providing helper methods to get the list of users, and
|
||||
@ -7,13 +8,13 @@ export class ChatUtility {
|
||||
/* -------------------------------------------- */
|
||||
static onSocketMessage(sockmsg) {
|
||||
switch (sockmsg.msg) {
|
||||
case "msg_delete_chat_message": return ChatUtility.onRemoveMessages(sockmsg.part, sockmsg.gmId);
|
||||
case "msg_delete_chat_message": return ChatUtility.onRemoveMessages(sockmsg.part);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static onRemoveMessages(part, gmId) {
|
||||
if (game.user._id == gmId) {
|
||||
static onRemoveMessages(part) {
|
||||
if (Misc.isElectedUser()) {
|
||||
const toDelete = game.messages.filter(it => it.data.content.includes(part));
|
||||
toDelete.forEach(it => it.delete());
|
||||
}
|
||||
@ -21,17 +22,13 @@ export class ChatUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static removeChatMessageContaining(part) {
|
||||
const gmId = game.user.isGM ? game.user._id : game.users.entities.find(u => u.isGM && u.active)?.id;
|
||||
|
||||
if (!gmId || game.user.isGM) {
|
||||
ChatUtility.onRemoveMessages(part, game.user._id);
|
||||
if (Misc.isElectedUser()) {
|
||||
ChatUtility.onRemoveMessages(part);
|
||||
}
|
||||
else {
|
||||
game.socket.emit("system.foundryvtt-reve-de-dragon", {
|
||||
msg: "msg_delete_chat_message", data: {
|
||||
part:part,
|
||||
gmId: gmId,
|
||||
}});
|
||||
msg: "msg_delete_chat_message", data: { part: part }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
1
module/constants.js
Normal file
@ -0,0 +1 @@
|
||||
export const SYSTEM_RDD = "foundryvtt-reve-de-dragon";
|
@ -1,27 +0,0 @@
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
export class DeDraconique extends Roll{
|
||||
|
||||
static async ddr(rollMode=undefined) {
|
||||
let ddr = new DeDraconique().evaluate();
|
||||
await RdDDice.show(ddr, rollMode);
|
||||
return ddr;
|
||||
}
|
||||
|
||||
constructor(){
|
||||
super("1d8x8 - 0")
|
||||
}
|
||||
|
||||
evaluate() {
|
||||
super.evaluate();
|
||||
const rerolls = Math.ceil(this.total / 8);
|
||||
this.terms[this.terms.length - 1] = rerolls;
|
||||
this.results[this.results.length - 1] = rerolls;
|
||||
this._total -= rerolls;
|
||||
return this;
|
||||
}
|
||||
|
||||
async render(chatOptions) {
|
||||
return super.render(chatOptions)
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
const competenceTroncs = [["Esquive", "Dague", "Corps à corps"],
|
||||
["Epée à 1 main", "Epée à 2 mains", "Hache à 1 main", "Hache à 2 mains", "Lance", "Masse à 1 main", "Masse à 2 mains"]];
|
||||
|
||||
@ -21,14 +24,14 @@ const limitesArchetypes = [
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const categorieCompetences = {
|
||||
"generale": { level: "-4", label: "Générales" },
|
||||
"particuliere": { level: "-8", label: "Particulières" },
|
||||
"specialisee": { level: "-11", label: "Spécialisées" },
|
||||
"connaissance": { level: "-11", label: "Connaissances" },
|
||||
"draconic": { level: "-11", label: "Draconics" },
|
||||
"melee": { level: "-6", label: "Mêlée" },
|
||||
"tir": { level: "-8", label: "Tir" },
|
||||
"lancer": { level: "-8", label: "Lancer" }
|
||||
"generale": { base: "-4", label: "Générales" },
|
||||
"particuliere": { base: "-8", label: "Particulières" },
|
||||
"specialisee": { base: "-11", label: "Spécialisées" },
|
||||
"connaissance": { base: "-11", label: "Connaissances" },
|
||||
"draconic": { base: "-11", label: "Draconics" },
|
||||
"melee": { base: "-6", label: "Mêlée" },
|
||||
"tir": { base: "-8", label: "Tir" },
|
||||
"lancer": { base: "-8", label: "Lancer" }
|
||||
}
|
||||
|
||||
const compendiumCompetences = {
|
||||
@ -61,7 +64,7 @@ export class RdDItemCompetence extends Item {
|
||||
return categorieCompetences;
|
||||
}
|
||||
static getNiveauBase(category) {
|
||||
return categorieCompetences[category].level;
|
||||
return categorieCompetences[category].base;
|
||||
}
|
||||
static getLabelCategorie(category) {
|
||||
return categorieCompetences[category].label;
|
||||
@ -130,10 +133,10 @@ export class RdDItemCompetence extends Item {
|
||||
list => list.map(name => RdDItemCompetence.findCompetence(competences, name))
|
||||
// calcul du coût xp jusqu'au niveau 0 maximum
|
||||
.map(it => RdDItemCompetence.computeDeltaXP(it?.data.base ?? -11, Math.min(it?.data.niveau ?? -11, 0)))
|
||||
.sort((a, b) => b - a) // tri descendant
|
||||
.splice(0, 1) // ignorer le coût xp le plus élevé
|
||||
.reduce((a, b) => a + b, 0)
|
||||
).reduce((a, b) => a + b, 0);
|
||||
.sort(Misc.ascending())
|
||||
.splice(0, list.length-1) // prendre toutes les valeurs sauf l'une des plus élevées
|
||||
.reduce(Misc.sum(), 0)
|
||||
).reduce(Misc.sum(), 0);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -183,8 +186,20 @@ export class RdDItemCompetence extends Item {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static findCompetence(list, name) {
|
||||
name = name.toLowerCase();
|
||||
return list.find(it => it.name.toLowerCase() == name && (it.type == "competence" || it.type == "competencecreature"))
|
||||
name = Grammar.toLowerCaseNoAccent(name);
|
||||
const competences = list.filter(it => Grammar.toLowerCaseNoAccent(it.name).includes(name) && (it.type == "competence" || it.type == "competencecreature"));
|
||||
if (competences.length == 0) {
|
||||
return undefined;
|
||||
}
|
||||
let competence = competences.find(it => Grammar.toLowerCaseNoAccent(it.name) == name);
|
||||
if (competence) {
|
||||
return competence;
|
||||
}
|
||||
if (competences.length>1) {
|
||||
const names = competences.map(it => it.name).reduce((a, b) => `${a}<br>${b}`);
|
||||
ui.notifications.info(`Plusieurs compétences possibles:<br>${names}<br>La première sera choisie: ${competences[0].name}`);
|
||||
}
|
||||
return competences[0];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -19,13 +19,13 @@ export class RdDItemCompetenceCreature extends Item {
|
||||
/* -------------------------------------------- */
|
||||
static toArme(itemData) {
|
||||
if (RdDItemCompetenceCreature.isCompetenceAttaque(itemData)) {
|
||||
itemData = Misc.data(itemData);
|
||||
let arme = { name: itemData.name, data: duplicate(itemData) };
|
||||
let arme = duplicate(Misc.data(itemData));
|
||||
mergeObject(arme.data,
|
||||
{
|
||||
competence: itemData.name,
|
||||
competence: arme.name,
|
||||
resistance: 100,
|
||||
equipe: true,
|
||||
dommagesReels: arme.data.dommages,
|
||||
penetration: 0,
|
||||
force: 0,
|
||||
rapide: true
|
||||
|
@ -102,7 +102,7 @@ export class RdDItemSheet extends ItemSheet {
|
||||
if ( actor ) {
|
||||
actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData);
|
||||
} else {
|
||||
ui.notifications.info("Impossible trouver un actur pour réaliser cette tache Alchimique.");
|
||||
ui.notifications.info("Impossible de trouver un acteur pour réaliser cette tâche alchimique.");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -18,6 +18,24 @@ export class Misc {
|
||||
return isPositiveNumber ? "+" + number : number
|
||||
}
|
||||
|
||||
static sum() {
|
||||
return (a, b) => a + b;
|
||||
}
|
||||
|
||||
static ascending(orderFunction = x=>x) {
|
||||
return (a, b) => Misc.sortingBy(orderFunction(a), orderFunction(b));
|
||||
}
|
||||
|
||||
static descending(orderFunction = x=>x) {
|
||||
return (a, b) => Misc.sortingBy(orderFunction(b), orderFunction(a));
|
||||
}
|
||||
|
||||
static sortingBy(a, b) {
|
||||
if (a > b) return 1;
|
||||
if (a < b) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the value to an integer, or to 0 if undefined/null/not representing integer
|
||||
* @param {*} value value to convert to an integer using parseInt
|
||||
@ -97,4 +115,15 @@ export class Misc {
|
||||
static templateData(it) {
|
||||
return Misc.data(it)?.data ?? {}
|
||||
}
|
||||
|
||||
static connectedGMOrUser(ownerId = undefined) {
|
||||
if (ownerId && game.user.id == ownerId){
|
||||
return ownerId;
|
||||
}
|
||||
return (game.user.isGM ? game.user.id : game.users.entities.find(u => u.isGM && u.active)?.id) ?? game.user.id;
|
||||
}
|
||||
|
||||
static isElectedUser() {
|
||||
return game.user.id == Misc.connectedGMOrUser();
|
||||
}
|
||||
}
|
@ -50,7 +50,7 @@ const poesieHautReve = [
|
||||
},
|
||||
{
|
||||
reference: 'Denis Gerfaud',
|
||||
extrait: `Ainsi se cuccèdent les Jours et les Ages.
|
||||
extrait: `Ainsi se succèdent les Jours et les Ages.
|
||||
<br>Les jours des Dragons sont les Ages des Hommes.`
|
||||
},
|
||||
{
|
||||
|
@ -50,19 +50,12 @@ export class RdDAlchimie {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getDifficulte(aspects) {
|
||||
let aspectsArray = aspects.split('-');
|
||||
let diff = 0;
|
||||
let nbDifferent = 0;
|
||||
let aspectsHash = {}
|
||||
for (let colconst of aspectsArray) {
|
||||
if ( aspectsHash[colconst] ){ // Deja present, augmente difficulté de 1
|
||||
diff -= 1;
|
||||
} else {
|
||||
nbDifferent++;
|
||||
aspectsHash[colconst] = colconst; // Keep track
|
||||
}
|
||||
}
|
||||
diff = diff - ((nbDifferent>1) ? nbDifferent : 0); // Ca doit marcher ....
|
||||
return Math.min(0, diff); // Pour être sur
|
||||
let elements = aspects.split('-');
|
||||
let composantes = elements.length;
|
||||
let distincts = Object.keys(Misc.classifyFirst(elements, it => it)).length;
|
||||
if (distincts == 1) {
|
||||
composantes--;
|
||||
}
|
||||
return Math.min(0, -composantes);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ export class RdDAstrologieEditeur extends Dialog {
|
||||
constructor(html, calendrier, calendrierData) {
|
||||
|
||||
let myButtons = {
|
||||
resetButton: { label: "Re-tirer les nombres astraux", callback: html => this.resetNombreAstraux() },
|
||||
saveButton: { label: "Fermer", callback: html => this.fillData() }
|
||||
};
|
||||
|
||||
@ -21,6 +22,14 @@ export class RdDAstrologieEditeur extends Dialog {
|
||||
this.updateData( calendrierData );
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
resetNombreAstraux() {
|
||||
game.system.rdd.calendrier.resetNombreAstral();
|
||||
game.system.rdd.calendrier.rebuildListeNombreAstral();
|
||||
|
||||
game.system.rdd.calendrier.showAstrologieEditor();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
fillData( ) {
|
||||
}
|
||||
|
@ -11,9 +11,9 @@ const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/'
|
||||
const heuresList = ["vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant"];
|
||||
const heuresDef = {
|
||||
"vaisseau": { label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' },
|
||||
"sirene": { label: "Sirène", lettreFont: 'S', saison: "printemps", heure: 1, icon: 'hd02.svg' },
|
||||
"sirene": { label: "Sirène", lettreFont: 'i', saison: "printemps", heure: 1, icon: 'hd02.svg' },
|
||||
"faucon": { label: "Faucon", lettreFont: 'f', saison: "printemps", heure: 2, icon: 'hd03.svg' },
|
||||
"couronne": { label: "Couronne", lettreFont: 'C', saison: "ete", heure: 3, icon: 'hd04.svg' },
|
||||
"couronne": { label: "Couronne", lettreFont: '', saison: "ete", heure: 3, icon: 'hd04.svg' },
|
||||
"dragon": { label: "Dragon", lettreFont: 'd', saison: "ete", heure: 4, icon: 'hd05.svg' },
|
||||
"epees": { label: "Epées", lettreFont: 'e', saison: "ete", heure: 5, icon: 'hd06.svg' },
|
||||
"lyre": { label: "Lyre", lettreFont: 'l', saison: "automne", heure: 6, icon: 'hd07.svg' },
|
||||
@ -135,6 +135,12 @@ export class RdDCalendrier extends Application {
|
||||
return astralData?.nombreAstral ?? "N/A";
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
resetNombreAstral( ) {
|
||||
this.listeNombreAstral = [];
|
||||
game.settings.set("foundryvtt-reve-de-dragon", "liste-nombre-astral", this.listeNombreAstral);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
rebuildListeNombreAstral() {
|
||||
let jourCourant = this.getCurrentDayIndex();
|
||||
@ -150,6 +156,7 @@ export class RdDCalendrier extends Application {
|
||||
this.listeNombreAstral = newList;
|
||||
game.settings.set("foundryvtt-reve-de-dragon", "liste-nombre-astral", this.listeNombreAstral);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
onCalendarButton(ev) {
|
||||
ev.preventDefault();
|
||||
@ -199,7 +206,7 @@ export class RdDCalendrier extends Application {
|
||||
/* -------------------------------------------- */
|
||||
syncPlayerTime(calendrier) {
|
||||
this.calendrier = duplicate(calendrier); // Local copy update
|
||||
this.updateDisplay(); // Then update
|
||||
this.updateDisplay();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -247,21 +254,19 @@ export class RdDCalendrier extends Application {
|
||||
console.log(request);
|
||||
let jourDiff = this.getLectureAstrologieDifficulte(request.date);
|
||||
let niveau = Number(request.astrologie.data.niveau) + Number(request.conditions) + Number(jourDiff) + Number(request.etat);
|
||||
let rolled = await RdDResolutionTable.rollData({
|
||||
let rollData= {
|
||||
caracValue: request.carac_vue,
|
||||
finalLevel: niveau,
|
||||
showDice: false
|
||||
});
|
||||
};
|
||||
await RdDResolutionTable.rollData(rollData);
|
||||
let nbAstral = this.getNombreAstral(request.date);
|
||||
let nbAstralFaux = nbAstral;
|
||||
request.rolled = rollData.rolled;
|
||||
request.isValid = true;
|
||||
request.rolled = rolled;
|
||||
if (!rolled.isSuccess) {
|
||||
if (!request.rolled.isSuccess) {
|
||||
request.isValid = false;
|
||||
while (nbAstralFaux == nbAstral) {
|
||||
nbAstralFaux = new Roll("1d12").roll().total;
|
||||
}
|
||||
nbAstral = nbAstralFaux;
|
||||
let nbAstralFaux = new Roll("1d11").evaluate().total;
|
||||
nbAstral = nbAstral==nbAstralFaux ? 12 : nbAstralFaux;
|
||||
// Mise à jour des nombres astraux du joueur
|
||||
let astralData = this.listeNombreAstral.find((nombreAstral, i) => nombreAstral.index == request.date);
|
||||
astralData.valeursFausses.push({ actorId: request.id, nombreAstral: nbAstralFaux });
|
||||
@ -338,7 +343,7 @@ export class RdDCalendrier extends Application {
|
||||
if (game.user.isGM) {
|
||||
dateHTML = dateHTML + " - NA: " + this.getCurrentNombreAstral();
|
||||
}
|
||||
for (let handle of document.getElementsByClassName("calendar-move-handle")) {
|
||||
for (let handle of document.getElementsByClassName("calendar-date-rdd")) {
|
||||
handle.innerHTML = dateHTML;
|
||||
}
|
||||
for (let heure of document.getElementsByClassName("calendar-heure-texte")) {
|
||||
@ -363,6 +368,11 @@ export class RdDCalendrier extends Application {
|
||||
this.rebuildListeNombreAstral();
|
||||
|
||||
this.updateDisplay();
|
||||
|
||||
game.socket.emit("system.foundryvtt-reve-de-dragon", {
|
||||
msg: "msg_sync_time",
|
||||
data: duplicate(this.calendrier)
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -38,6 +38,29 @@ const tableCaracDerivee = {
|
||||
|
||||
export class RdDCarac {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static findCarac(carac, name) {
|
||||
name = Grammar.toLowerCaseNoAccent(name);
|
||||
const pairs = Object.entries(carac)
|
||||
.filter(([key, value]) => key.includes(name) || Grammar.toLowerCaseNoAccent(value.label).includes(name));
|
||||
|
||||
let c = pairs.find(([key, value]) => key == name || Grammar.toLowerCaseNoAccent(value.label) == name);
|
||||
if (c) {
|
||||
return c[1];
|
||||
}
|
||||
|
||||
pairs.sort((a, b) => a[0].length- b[0].length);
|
||||
if (pairs.length > 0) {
|
||||
c = pairs[0][1];
|
||||
if (pairs.length > 1) {
|
||||
const labels = pairs.map(pair => pair[1].label).reduce((a, b) => `${a}<br>${b}`);
|
||||
ui.notifications.info(`Plusieurs caractéristiques possibles:<br>${labels}<br>La première sera choisie: ${c.label}.`);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static isAgiliteOuDerivee(selectedCarac) {
|
||||
return selectedCarac?.label.match(/(Agilité|Dérobée)/);
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ export class RdDCombatManager extends Combat {
|
||||
//if (!c) return results;
|
||||
|
||||
let rollFormula = formula; // Init per default
|
||||
console.log("RR :", rollFormula);
|
||||
if (!rollFormula) {
|
||||
let armeCombat, competence;
|
||||
if (c.actor.data.type == 'creature' || c.actor.data.type == 'entite') {
|
||||
@ -101,6 +102,7 @@ export class RdDCombatManager extends Combat {
|
||||
}
|
||||
}
|
||||
//console.log("Combatat", c);
|
||||
console.log("RR :", rollFormula);
|
||||
const roll = super._getInitiativeRoll(c, rollFormula);
|
||||
if (roll.total <= 0) roll.total = 0.00;
|
||||
console.log("Compute init for", rollFormula, roll.total);
|
||||
@ -180,6 +182,7 @@ export class RdDCombatManager extends Combat {
|
||||
ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
|
||||
return [];
|
||||
}
|
||||
const actorData = Misc.data(combatant.actor);
|
||||
let items = combatant.actor.data.items;
|
||||
let actions = []
|
||||
if (combatant.actor.isCreature()) {
|
||||
@ -192,10 +195,12 @@ export class RdDCombatManager extends Combat {
|
||||
.concat(RdDItemArme.mainsNues());
|
||||
|
||||
let competences = items.filter(it => it.type == 'competence');
|
||||
actions = actions.concat(RdDCombatManager.finalizeArmeList(armes, competences, Misc.data(combatant.actor).data.carac));
|
||||
actions = actions.concat(RdDCombatManager.finalizeArmeList(armes, competences, actorData.data.carac));
|
||||
|
||||
if (actorData.data.attributs.hautrevant.value) {
|
||||
actions.push({ name: "Draconic", data: { initOnly: true, competence: "Draconic" } });
|
||||
}
|
||||
}
|
||||
|
||||
actions.push({ name: "Autre action", data: { initOnly: true, competence: "Autre action" } });
|
||||
for (let index = 0; index < actions.length; index++) {
|
||||
@ -359,6 +364,8 @@ export class RdDCombat {
|
||||
return RdDCombat.onMsgEncaisser(sockmsg.data);
|
||||
case "msg_defense":
|
||||
return RdDCombat.onMsgDefense(sockmsg.data);
|
||||
case "msg_combat_passearme":
|
||||
return RdDCombat.onMsgPasseArme(sockmsg.data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,9 +399,8 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static combatNouveauTour(combat) {
|
||||
if (Misc.isElectedUser()) {
|
||||
let turn = combat.turns.find(t => t.tokenId == combat.current.tokenId);
|
||||
if (game.user.isGM) {
|
||||
// seul le GM notifie le status
|
||||
this.displayActorCombatStatus(combat, turn.actor);
|
||||
// TODO Playaudio for player??
|
||||
}
|
||||
@ -430,9 +436,31 @@ export class RdDCombat {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static messagePasseArme(data) {
|
||||
game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: "msg_combat_passearme", data: data });
|
||||
RdDCombat.onMsgPasseArme(data);
|
||||
}
|
||||
|
||||
static onMsgPasseArme(data) {
|
||||
switch (data.actionPasseArme) {
|
||||
case "store-attaque":
|
||||
game.system.rdd.combatStore.attaques[data.id] = data.rollData;
|
||||
break;
|
||||
case "store-defense":
|
||||
game.system.rdd.combatStore.defenses[data.id] = data.rollData;
|
||||
break;
|
||||
case "delete-attaque":
|
||||
delete game.system.rdd.combatStore.attaques[data.id];
|
||||
break;
|
||||
case "delete-defense":
|
||||
delete game.system.rdd.combatStore.defenses[data.id];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _storeAttaque(attackerId, attackerRoll) {
|
||||
game.system.rdd.combatStore.attaques[attackerId] = duplicate(attackerRoll);
|
||||
RdDCombat.messagePasseArme({ actionPasseArme: "store-attaque", id: attackerId, rollData: attackerRoll });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -442,12 +470,12 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _deleteAttaque(attackerId) {
|
||||
delete game.system.rdd.combatStore.attaques[attackerId];
|
||||
RdDCombat.messagePasseArme({ actionPasseArme: "delete-attaque", id: attackerId });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _storeDefense(defenderRoll) {
|
||||
game.system.rdd.combatStore.defenses[defenderRoll.passeArme] = duplicate(defenderRoll);
|
||||
static _storeDefense(passeArme, defenderRoll) {
|
||||
RdDCombat.messagePasseArme({ actionPasseArme: "store-defense", id: passeArme, rollData: defenderRoll });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -457,7 +485,7 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _deleteDefense(passeArme) {
|
||||
delete game.system.rdd.combatStore.defenses[passeArme];
|
||||
RdDCombat.messagePasseArme({ actionPasseArme: "delete-defense", id: passeArme });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -479,39 +507,35 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static onMsgEncaisser(data) {
|
||||
if (Misc.isElectedUser()) {
|
||||
let attackerRoll = RdDCombat._getAttaque(data.attackerId); // Retrieve the rolldata from the store
|
||||
|
||||
if (game.user.id === data.gmId) { // Seul le GM effectue l'encaissement sur la fiche
|
||||
let attacker = data.attackerId ? game.actors.get(data.attackerId) : null;
|
||||
let defender = canvas.tokens.get(data.defenderTokenId).actor;
|
||||
|
||||
defender.encaisserDommages(attackerRoll, attacker);
|
||||
}
|
||||
|
||||
RdDCombat._deleteDefense(attackerRoll.passeArme);
|
||||
RdDCombat._deleteAttaque(data.attackerId);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static onMsgDefense(msg) {
|
||||
let defenderToken = canvas.tokens.get(msg.defenderTokenId);
|
||||
if (defenderToken) {
|
||||
if (!game.user.isGM && !game.user.character) { // vérification / sanity check
|
||||
ui.notifications.error("Le joueur " + game.user.name + " n'est connecté à aucun personnage. Impossible de continuer.");
|
||||
return;
|
||||
}
|
||||
if ((game.user.isGM && !defenderToken.actor.hasPlayerOwner) || (defenderToken.actor.hasPlayerOwner && (game.user.character._id == defenderToken.actor.data._id))) {
|
||||
if (defenderToken && Misc.isElectedUser()) {
|
||||
const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
|
||||
if (rddCombat) {
|
||||
const defenderRoll = msg.defenderRoll;
|
||||
RdDCombat._storeAttaque(msg.attackerId, defenderRoll.attackerRoll);
|
||||
RdDCombat._storeDefense(defenderRoll);
|
||||
RdDCombat._storeDefense(defenderRoll.passeArme, defenderRoll);
|
||||
rddCombat.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
|
||||
rddCombat._chatMessageDefense(msg.paramChatDefense);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _callJetDeVie(event) {
|
||||
@ -663,7 +687,7 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
static isEchecTotal(rollData) {
|
||||
if (!rollData.attackerRoll && rollData.ajustements.surprise.used) {
|
||||
return rollData.rolled.isEchec;
|
||||
return rollData.rolled.isEchec && rollData.rolled.code != 'notSign';
|
||||
}
|
||||
return rollData.rolled.isETotal;
|
||||
}
|
||||
@ -728,7 +752,6 @@ export class RdDCombat {
|
||||
surpriseDefenseur: this.defender.getSurprise(true),
|
||||
essais: {}
|
||||
};
|
||||
rollData.diviseurSignificative = this._getDiviseurSignificative(rollData);
|
||||
|
||||
if (this.attacker.isCreature()) {
|
||||
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
||||
@ -772,7 +795,7 @@ export class RdDCombat {
|
||||
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
|
||||
// Save rollData for defender
|
||||
RdDCombat._storeAttaque(this.attackerId, attackerRoll);
|
||||
RdDCombat._storeDefense(defenderRoll)
|
||||
RdDCombat._storeDefense(defenderRoll.passeArme, defenderRoll);
|
||||
|
||||
attackerRoll.show = {
|
||||
cible: this.target ? this.defender.data.name : 'la cible',
|
||||
@ -823,8 +846,7 @@ export class RdDCombat {
|
||||
dmg: attackerRoll.dmg,
|
||||
};
|
||||
|
||||
const selfMessage = essaisPrecedents != undefined;
|
||||
if (!selfMessage && (!game.user.isGM || this.defender.hasPlayerOwner)) {
|
||||
if (!Misc.isElectedUser()) {
|
||||
this._socketSendMessageDefense(paramChatDefense, defenderRoll);
|
||||
}
|
||||
else {
|
||||
@ -971,7 +993,6 @@ export class RdDCombat {
|
||||
carac: this.defender.data.data.carac,
|
||||
show: {}
|
||||
};
|
||||
defenderRoll.diviseurSignificative = this._getDiviseurSignificative(defenderRoll);
|
||||
|
||||
if (this.defender.isCreature()) {
|
||||
RdDItemCompetenceCreature.setRollDataCreature(defenderRoll);
|
||||
@ -980,24 +1001,6 @@ export class RdDCombat {
|
||||
return defenderRoll;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_getDiviseurSignificative(defenderRoll) {
|
||||
let facteurSign = 1;
|
||||
if (defenderRoll.surprise == 'demi') {
|
||||
facteurSign *= 2;
|
||||
}
|
||||
if (defenderRoll.needParadeSignificative) {
|
||||
facteurSign *= 2;
|
||||
}
|
||||
if (RdDBonus.isDefenseAttaqueFinesse(defenderRoll)) {
|
||||
facteurSign *= 2;
|
||||
}
|
||||
if (!ReglesOptionelles.isUsing('tripleSignificative')) {
|
||||
facteurSign = Math.min(facteurSign, 4);
|
||||
}
|
||||
return facteurSign;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_onParadeParticuliere(defenderRoll) {
|
||||
console.log("RdDCombat._onParadeParticuliere >>>", defenderRoll);
|
||||
@ -1028,7 +1031,7 @@ export class RdDCombat {
|
||||
|
||||
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
|
||||
this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true });
|
||||
RdDCombat._storeDefense(defenderRoll);
|
||||
RdDCombat._storeDefense(defenderRoll.passeArme, defenderRoll);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -1070,7 +1073,6 @@ export class RdDCombat {
|
||||
carac: this.defender.data.data.carac,
|
||||
show: {}
|
||||
};
|
||||
rollData.diviseurSignificative = this._getDiviseurSignificative(rollData);
|
||||
|
||||
if (this.defender.isCreature()) {
|
||||
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
||||
@ -1101,7 +1103,7 @@ export class RdDCombat {
|
||||
|
||||
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
|
||||
this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true })
|
||||
RdDCombat._storeDefense(defenderRoll);
|
||||
RdDCombat._storeDefense(defenderRoll.passeArme, defenderRoll);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -1203,7 +1205,7 @@ export class RdDCombat {
|
||||
_computeImpactRecul(attaque) {
|
||||
const taille = this.defender.getTaille();
|
||||
const force = this.attacker.getForce();
|
||||
const dommages = attaque.arme.data.dommagesReels;
|
||||
const dommages = attaque.arme.data.dommagesReels ?? attaque.arme.data.dommages;
|
||||
return taille - (force + dommages);
|
||||
}
|
||||
|
||||
@ -1221,7 +1223,7 @@ export class RdDCombat {
|
||||
this._onEchecTotal(defenderRoll);
|
||||
}
|
||||
|
||||
if (game.user.isGM) { // Current user is the GM -> direct access
|
||||
if (Misc.isElectedUser()) {
|
||||
attackerRoll.attackerId = this.attackerId;
|
||||
attackerRoll.defenderTokenId = defenderTokenId;
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* -------------------------------------------- */
|
||||
|
||||
import { DeDraconique } from "./de-draconique.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
@ -11,9 +10,9 @@ import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
|
||||
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { TMRRencontres } from "./tmr-rencontres.js";
|
||||
import { TMRType, TMRUtility } from "./tmr-utility.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
|
||||
const rddRollNumeric = /(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
|
||||
const rddRollNumeric = /$(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDCommands {
|
||||
@ -64,9 +63,11 @@ export class RdDCommands {
|
||||
descr: `Effectue un jet de dés dans la table de résolution. Exemples:
|
||||
<br><strong>/rdd</strong> ouvre la table de résolution
|
||||
<br><strong>/rdd 10 3</strong> effectue un jet 10 à +3
|
||||
<br><strong>/rdd 10 +2</strong> effectue un jet 10 à +2
|
||||
<br><strong>/rdd 15 -2</strong> effectue un jet 15 à -2
|
||||
<br><strong>/rdd 15 0 s</strong> effectue un jet 15 à 0, avec significative requise`
|
||||
<br><strong>/rdd 15 0 s</strong> effectue un jet 15 à 0, avec significative requise
|
||||
<br><strong>/rdd Vue Vigilance -2</strong> effectue un jet de Vue/Vigilance à -2 pour les tokens sélectionnés
|
||||
<br><strong>/rdd vol déser +2</strong> effectue un jet de Volonté/Survie en désert à +2 pour les tokens sélectionnés
|
||||
`
|
||||
});
|
||||
rddCommands.registerCommand({ path: ["/ddr"], func: (content, msg, params) => rddCommands.rollDeDraconique(msg), descr: "Lance un Dé Draconique" });
|
||||
|
||||
@ -164,11 +165,25 @@ export class RdDCommands {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
help(msg, table = undefined) {
|
||||
async help(msg) {
|
||||
this.help(msg, undefined);
|
||||
}
|
||||
async help(msg, table) {
|
||||
let list = []
|
||||
this._buildSubTableHelp(list, table || this.commandsTable);
|
||||
const messageAide = list.reduce((a, b) => a + '</li><li class="list-item">' + b);
|
||||
RdDCommands._chatAnswer(msg, `Commandes disponibles<ul class="alterne-list"><li class="list-item">${messageAide}</li></ul>`);
|
||||
|
||||
let html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/settings/dialog-aide-commands.html", { commands: list });
|
||||
let d = new Dialog(
|
||||
{
|
||||
title: "Commandes disponibles dans le tchat",
|
||||
content: html,
|
||||
buttons: {},
|
||||
},
|
||||
{
|
||||
width: 600, height: 500,
|
||||
});
|
||||
|
||||
d.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -217,6 +232,27 @@ export class RdDCommands {
|
||||
await this.rollRdDNumeric(msg, carac, diff, significative);
|
||||
return;
|
||||
}
|
||||
|
||||
let actors = canvas.tokens.controlled.map(it => it.actor).filter(it => it);
|
||||
if (actors && actors.length > 0) {
|
||||
let length = params.length;
|
||||
let diff = Number(params[length - 1]);
|
||||
if (Number.isInteger(Number(diff))) {
|
||||
length--;
|
||||
}
|
||||
else {
|
||||
diff = 0;
|
||||
}
|
||||
const caracName = params[0];
|
||||
const compName = length > 1 ? params.slice(1, length).reduce((a, b) => `${a} ${b}`) : undefined;
|
||||
for (let actor of actors) {
|
||||
await actor.rollCaracCompetence(caracName, compName, diff);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ui.notifications.warn("Sélectionnez au moins un personnage pour lancer les dés")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,7 +271,7 @@ export class RdDCommands {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollDeDraconique(msg) {
|
||||
let ddr = new DeDraconique().evaluate();
|
||||
let ddr = new Roll("1dr + 7").evaluate();
|
||||
ddr.showDice = true;
|
||||
await RdDDice.showDiceSoNice(ddr);
|
||||
RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr.total}`);
|
||||
|
@ -1,10 +1,140 @@
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { SYSTEM_RDD } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
function img(src) {
|
||||
return `<img src="${src}" class="dice-img" />`
|
||||
}
|
||||
|
||||
function iconHeure(heure) {
|
||||
if (heure < 10) {
|
||||
heure = '0' + heure;
|
||||
}
|
||||
return `systems/foundryvtt-reve-de-dragon/icons/heures/hd${heure}.webp`
|
||||
}
|
||||
const imagesHeures = [1, 2, 3, 4, 5, 6, 7, 9, 9, 10, 11, 12].map(it => iconHeure(it));
|
||||
|
||||
const imgSigneDragon = img(imagesHeures[4]);
|
||||
|
||||
/** De7 pour les jets de rencontre */
|
||||
export class De7 extends Die {
|
||||
/** @override */
|
||||
static DENOMINATION = "7";
|
||||
|
||||
static diceSoNiceData(system) {
|
||||
return {
|
||||
type: "d7",
|
||||
font: "HeuresDraconiques",
|
||||
fontScale : 0.7,
|
||||
labels: ['1', '2', '3', '4', '5', '6', 'd', '0'],
|
||||
system: system
|
||||
}
|
||||
}
|
||||
|
||||
constructor(termData) {
|
||||
termData.faces = 8;
|
||||
super(termData);
|
||||
}
|
||||
|
||||
evaluate() {
|
||||
super.evaluate();
|
||||
this.explode("x=8");
|
||||
return this;
|
||||
}
|
||||
|
||||
get total() {
|
||||
return this.values.filter(it => it != 8).reduce(Misc.sum(), 0);
|
||||
}
|
||||
|
||||
static getResultLabel(result) {
|
||||
switch (result) {
|
||||
case 7: return imgSigneDragon;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/** DeDraconique pour le D8 sans limite avec 8=>0 */
|
||||
export class DeDraconique extends Die {
|
||||
static DENOMINATION = "r";
|
||||
|
||||
static diceSoNiceData(system) {
|
||||
return {
|
||||
type: "dr",
|
||||
font: "HeuresDraconiques",
|
||||
fontScale : 0.7,
|
||||
labels: ['1', '2', '3', '4', '5', '6', 'd', '0'],
|
||||
system: system
|
||||
}
|
||||
}
|
||||
|
||||
constructor(termData) {
|
||||
termData.faces = 8;
|
||||
super(termData);
|
||||
}
|
||||
|
||||
evaluate() {
|
||||
super.evaluate();
|
||||
this.explode("x=7");
|
||||
return this;
|
||||
}
|
||||
|
||||
get total() {
|
||||
return this.values.filter(it => it != 8).reduce(Misc.sum(), 0);
|
||||
}
|
||||
|
||||
static getResultLabel(result) {
|
||||
switch (result) {
|
||||
case 7: return imgSigneDragon;
|
||||
case 8: return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/** De 12 avec les heures */
|
||||
export class DeHeure extends Die {
|
||||
|
||||
/** @override */
|
||||
static DENOMINATION = "h";
|
||||
|
||||
static diceSoNiceData(system) {
|
||||
return {
|
||||
type: "dh",
|
||||
font: "HeuresDraconiques",
|
||||
labels: ['v', 'i', 'f', 'o', 'd', 'e', 'l', 's', 'p', 'a', 'r', 'c'],
|
||||
system: system
|
||||
}
|
||||
}
|
||||
|
||||
constructor(termData) {
|
||||
termData.faces = 12;
|
||||
super(termData);
|
||||
}
|
||||
|
||||
static getResultLabel(result) {
|
||||
return img(imagesHeures[result-1]);
|
||||
}
|
||||
}
|
||||
|
||||
export class RdDDice {
|
||||
static init() {
|
||||
CONFIG.Dice.terms[De7.DENOMINATION] = De7;
|
||||
CONFIG.Dice.terms[DeDraconique.DENOMINATION] = DeDraconique;
|
||||
CONFIG.Dice.terms[DeHeure.DENOMINATION] = DeHeure;
|
||||
}
|
||||
|
||||
static diceSoNiceReady(dice3d) {
|
||||
for (const system of Object.keys(dice3d.DiceFactory.systems)) {
|
||||
dice3d.addDicePreset(De7.diceSoNiceData(system));
|
||||
dice3d.addDicePreset(DeDraconique.diceSoNiceData(system));
|
||||
dice3d.addDicePreset(DeHeure.diceSoNiceData(system));
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async show(roll, rollMode = undefined) {
|
||||
if (roll.showDice || game.settings.get("foundryvtt-reve-de-dragon", "dice-so-nice") == true) {
|
||||
if (roll.showDice || game.settings.get(SYSTEM_RDD, "dice-so-nice") == true) {
|
||||
await this.showDiceSoNice(roll, rollMode);
|
||||
}
|
||||
return roll;
|
||||
|
@ -22,13 +22,13 @@ import { RdDTokenHud } from "./rdd-token-hud.js";
|
||||
import { RdDCommands } from "./rdd-commands.js";
|
||||
import { RdDCombatManager, RdDCombat } from "./rdd-combat.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { StatusEffects } from "./status-effects.js";
|
||||
import { RddCompendiumOrganiser } from "./rdd-compendium-organiser.js";
|
||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
||||
import { TMRRencontres } from "./tmr-rencontres.js";
|
||||
import { RdDHotbar } from "./rdd-hotbar-drop.js"
|
||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
@ -46,7 +46,8 @@ Hooks.once("init", async function () {
|
||||
game.system.rdd = {
|
||||
TMRUtility,
|
||||
RdDUtility,
|
||||
RdDHotbar
|
||||
RdDHotbar,
|
||||
RdDResolutionTable
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -153,6 +154,7 @@ Hooks.once("init", async function () {
|
||||
CONFIG.Combat.entityClass = RdDCombatManager;
|
||||
|
||||
// préparation des différents modules
|
||||
RdDDice.init();
|
||||
RdDCommands.init();
|
||||
RdDCombat.init();
|
||||
RdDCombatManager.init(),
|
||||
@ -211,7 +213,12 @@ Hooks.once("ready", function () {
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
/* Dice-so-nice ready */
|
||||
/* -------------------------------------------- */
|
||||
Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d));
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT chat message */
|
||||
/* -------------------------------------------- */
|
||||
Hooks.on("chatMessage", (html, content, msg) => {
|
||||
if (content[0] == '/') {
|
||||
|
@ -51,10 +51,8 @@ const reussites = [
|
||||
{ code: "error", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: 0, ptQualite: 0, quality: "Jet de dés invalide", condition: (target, roll) => (roll <= 0 || roll > 100) }
|
||||
];
|
||||
|
||||
const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false }
|
||||
/* -------------------------------------------- */
|
||||
const reussiteSignificative = reussites.find(r => r.code == "sign");
|
||||
const reussiteNormale = reussites.find(r => r.code == "norm");
|
||||
const echecNormal = reussites.find(r => r.code == "echec");
|
||||
const caracMaximumResolution = 60;
|
||||
/* -------------------------------------------- */
|
||||
export class RdDResolutionTable {
|
||||
@ -115,7 +113,7 @@ export class RdDResolutionTable {
|
||||
this._updateChancesFactor(chances, diviseur);
|
||||
chances.showDice = showDice;
|
||||
|
||||
let rolled = await this.rollChances(chances);
|
||||
let rolled = await this.rollChances(chances, diviseur);
|
||||
rolled.caracValue = caracValue;
|
||||
rolled.finalLevel = finalLevel;
|
||||
rolled.bonus = bonus;
|
||||
@ -150,12 +148,12 @@ export class RdDResolutionTable {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async rollChances(chances) {
|
||||
static async rollChances(chances, diviseur) {
|
||||
let myRoll = new Roll("1d100").roll();
|
||||
myRoll.showDice = chances.showDice;
|
||||
await RdDDice.show(myRoll);
|
||||
chances.roll = myRoll.total;
|
||||
mergeObject(chances, this.computeReussite(chances, chances.roll), { overwrite: true });
|
||||
mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
|
||||
return chances;
|
||||
}
|
||||
|
||||
@ -167,7 +165,8 @@ export class RdDResolutionTable {
|
||||
if (difficulte < -10) {
|
||||
return duplicate(levelDown.find(levelData => levelData.level == difficulte));
|
||||
}
|
||||
return duplicate(RdDResolutionTable.resolutionTable[caracValue][difficulte + 10]);
|
||||
const chances = RdDResolutionTable.resolutionTable[caracValue][difficulte + 10];
|
||||
return chances ? duplicate(chances) : RdDResolutionTable._computeCell(difficulte, RdDResolutionTable.computeChances(caracValue, difficulte));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -216,22 +215,36 @@ export class RdDResolutionTable {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static computeReussite(chances, roll) {
|
||||
return reussites.find(x => x.condition(chances, roll));
|
||||
static computeReussite(chances, roll, diviseur) {
|
||||
const reussite = reussites.find(x => x.condition(chances, roll));
|
||||
if (diviseur > 1 && reussite.code == 'norm') {
|
||||
return reussiteInsuffisante;
|
||||
}
|
||||
return reussite;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _computeRow(caracValue) {
|
||||
let dataRow = [
|
||||
this._computeCell(-10, Math.max(Math.floor(caracValue / 4), 1)),
|
||||
this._computeCell(-9, Math.max(Math.floor(caracValue / 2), 1))
|
||||
]
|
||||
for (var diff = -8; diff <= 22; diff++) {
|
||||
dataRow[diff + 10] = this._computeCell(diff, Math.max(Math.floor(caracValue * (diff + 10) / 2), 1));
|
||||
let dataRow = [];
|
||||
for (var diff = -10; diff <= 22; diff++) {
|
||||
dataRow[diff + 10] = this._computeCell(diff, RdDResolutionTable._computePercentage(caracValue, diff));
|
||||
}
|
||||
return dataRow;
|
||||
}
|
||||
|
||||
static _computePercentage(caracValue, diff) {
|
||||
if (diff <-10) {
|
||||
return 1;
|
||||
}
|
||||
if (diff == -10){
|
||||
return Math.max(Math.floor(caracValue / 4), 1);
|
||||
}
|
||||
if (diff == -9) {
|
||||
return Math.max(Math.floor(caracValue / 2), 1)
|
||||
}
|
||||
return Math.max(Math.floor(caracValue * (diff + 10) / 2), 1);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _computeCell(niveau, percentage) {
|
||||
return {
|
||||
|
@ -7,6 +7,7 @@ import { Misc } from "./misc.js";
|
||||
import { RdDBonus } from "./rdd-bonus.js";
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { ReglesOptionelles } from "./regles-optionelles.js";
|
||||
|
||||
/**
|
||||
* Extend the base Dialog entity to select roll parameters
|
||||
@ -64,13 +65,32 @@ export class RdDRoll extends Dialog {
|
||||
canClose: true
|
||||
};
|
||||
|
||||
|
||||
mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false });
|
||||
if (rollData.forceCarac) {
|
||||
rollData.carac = rollData.forceCarac;
|
||||
}
|
||||
rollData.diviseurSignificative = RdDRoll.getDiviseurSignificative(rollData);
|
||||
|
||||
RollDataAjustements.calcul(rollData, actor);
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static getDiviseurSignificative(rollData) {
|
||||
let facteurSign = 1;
|
||||
if (rollData.surprise == 'demi') {
|
||||
facteurSign *= 2;
|
||||
}
|
||||
if (rollData.needParadeSignificative) {
|
||||
facteurSign *= 2;
|
||||
}
|
||||
if (RdDBonus.isDefenseAttaqueFinesse(rollData)) {
|
||||
facteurSign *= 2;
|
||||
}
|
||||
if (!ReglesOptionelles.isUsing('tripleSignificative')) {
|
||||
facteurSign = Math.min(facteurSign, 4);
|
||||
}
|
||||
return facteurSign;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _ensureCorrectActions(actions) {
|
||||
@ -122,7 +142,6 @@ export class RdDRoll extends Dialog {
|
||||
await RdDResolutionTable.rollData(this.rollData);
|
||||
console.log("RdDRoll -=>", this.rollData, this.rollData.rolled);
|
||||
this.actor.setRollWindowsOpened(false);
|
||||
|
||||
if (action.callbacks)
|
||||
for (let callback of action.callbacks) {
|
||||
if (callback.condition == undefined || callback.condition(this.rollData)) {
|
||||
|
@ -202,13 +202,12 @@ export class RdDTMRDialog extends Dialog {
|
||||
close() {
|
||||
this.actor.santeIncDec("fatigue", this.cumulFatigue).then(super.close()); // moving 1 cell costs 1 fatigue
|
||||
this.actor.tmrApp = undefined; // Cleanup reference
|
||||
this.actor.setStatusDemiReve(false);
|
||||
if (!this.viewOnly) {
|
||||
this.actor.setStatusDemiReve(false);
|
||||
this._tellToGM(this.actor.name + " a quitté les terres médianes");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async derober() {
|
||||
await this.actor.addTMRRencontre(this.currentRencontre);
|
||||
@ -292,6 +291,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async quitterLesTMRInconscient() {
|
||||
if (this.currentRencontre?.isPersistant) {
|
||||
await this.refouler();
|
||||
@ -360,6 +360,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_rollPresentCite(rencontreData) {
|
||||
let rolled = RdDResolutionTable.computeChances(rencontreData.reve, 0);
|
||||
mergeObject(rolled, { caracValue: rencontreData.reve, finalLevel: 0, roll: rolled.score });
|
||||
@ -420,6 +421,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_presentCite(tmr, postRencontre) {
|
||||
const presentCite = this.casesSpeciales.find(c => EffetsDraconiques.presentCites.isCase(c, tmr.coord));
|
||||
if (presentCite) {
|
||||
@ -429,6 +431,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
return presentCite;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _utiliserPresentCite(presentCite, typeRencontre, tmr, postRencontre) {
|
||||
this.currentRencontre = TMRRencontres.getRencontre(typeRencontre);
|
||||
await TMRRencontres.evaluerForceRencontre(this.currentRencontre);
|
||||
|
@ -101,6 +101,8 @@ export class RdDUtility {
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor-liste-blessures-partial.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html',
|
||||
//Items
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-competence-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-competencecreature-sheet.html',
|
||||
@ -553,7 +555,10 @@ export class RdDUtility {
|
||||
// Gestion du bouton payer
|
||||
html.on("click", '#payer-button', event => {
|
||||
let sumdenier = event.currentTarget.attributes['data-somme-denier'].value;
|
||||
let quantite = event.currentTarget.attributes['data-quantite'].value;
|
||||
let quantite = 1;
|
||||
if ( event.currentTarget.attributes['data-quantite'] ) {
|
||||
quantite = event.currentTarget.attributes['data-quantite'].value;
|
||||
}
|
||||
let jsondata = event.currentTarget.attributes['data-jsondata']
|
||||
let objData
|
||||
if (jsondata) {
|
||||
@ -695,16 +700,20 @@ export class RdDUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static afficherHeuresChanceMalchance(heureNaissance) {
|
||||
if ( game.user.isGM) {
|
||||
if (heureNaissance) {
|
||||
let ajustement = game.system.rdd.calendrier.getAjustementAstrologique(heureNaissance);
|
||||
ChatMessage.create({
|
||||
content: `A l'heure ${game.system.rdd.calendrier.getCurrentHeure()}, le modificateur de Chance/Malchance pour l'heure de naissance ${heureNaissance} est de : ${ajustement}.`,
|
||||
whisper: ChatMessage.getWhisperRecipients("MJ")
|
||||
whisper: ChatMessage.getWhisperRecipients("GM")
|
||||
});
|
||||
}
|
||||
else {
|
||||
ui.notifications.warn("Pas d'heure de naissance selectionnée")
|
||||
}
|
||||
} else {
|
||||
ui.notifications.warn("Vous n'avez pas accès à cette commande")
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------- */
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { DeDraconique } from "./de-draconique.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
@ -269,7 +268,7 @@ const rencontresStandard = [
|
||||
{ code: "reflet", name: "Reflet d'ancien Rêve", type: "reflet", genre: "m", force: "2d6", isPersistant: true },
|
||||
{ code: "tbblanc", name: "Tourbillon blanc", type: "tbblanc", genre: "m", force: "2d6", isPersistant: true },
|
||||
{ code: "tbnoir", name: "Tourbillon noir", type: "tbnoir", genre: "m", force: "2d8", isPersistant: true },
|
||||
{ code: "rdd", name: "Rêve de Dragon", type: "rdd", genre: "m", force: "1ddr + 7", refoulement: 2, quitterTMR: true }
|
||||
{ code: "rdd", name: "Rêve de Dragon", type: "rdd", genre: "m", force: "1dr + 7", refoulement: 2, quitterTMR: true }
|
||||
];
|
||||
|
||||
const rencontresPresentCite = [
|
||||
@ -381,13 +380,7 @@ export class TMRRencontres {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async evaluerForceRencontre(rencontre) {
|
||||
if (TMRRencontres.isReveDeDragon(rencontre)) {
|
||||
const ddr = await DeDraconique.ddr("selfroll")
|
||||
rencontre.force = 7 + ddr.total;
|
||||
}
|
||||
else {
|
||||
rencontre.force = new Roll(rencontre.force).evaluate().total;
|
||||
}
|
||||
return rencontre.force;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ export class Periple extends Draconique {
|
||||
|
||||
|
||||
code() { return 'periple' }
|
||||
tooltip(linkData) { return `Votre Périple passe par ${this.tmrDescr(linkData)}` }
|
||||
tooltip(linkData) { return `Votre Périple passe par ${this.tmrLabel(linkData)}` }
|
||||
img() { return 'icons/svg/acid.svg' }
|
||||
|
||||
createSprite(pixiTMR) {
|
||||
|
@ -34,7 +34,6 @@
|
||||
{"_id":"CMtQM06J3BZsHHxH","name":"Sandales","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/sandales.webp","effects":[]}
|
||||
{"_id":"CQSxJv1mgmIeMCbM","name":"Grappin","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.5,"equipe":false,"resistance":0,"qualite":0,"cout":2},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/grappin.webp","effects":[]}
|
||||
{"_id":"D5Z3FaUv91B8eCOP","name":"Obyssum vert","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"ingredient","data":{"description":"<p>Poudre verdâtre apparaissant sur les tiges de certains roseaux.</p>\n<p>VUE/Alchimie à -2</p>","niveau":0,"encombrement":0.001,"base":0,"quantite":1,"milieu":"Lieux humides","rarete":"","categorie":"Alchimie","cout":0.05},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/l_obyssum_vert.webp","effects":[]}
|
||||
{"_id":"ESU3IRLnBrFznFa3","name":"Dragons (pièces d'or)","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":10},"flags":{},"img":"icons/commodities/currency/coins-plain-stack-gold.webp","effects":[]}
|
||||
{"_id":"ElweMV283IUpqaik","name":"Sable-Poudre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"potion","data":{"description":"<p>Granulés. Poudre blanche.</p>","quantite":1,"encombrement":0.1,"rarete":"","categorie":"Alchimie","cout":2},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp","effects":[]}
|
||||
{"_id":"Eospy1EFNlhgOyXc","name":"Lacet de cuir (1 m)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.06},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/lacet.webp","effects":[]}
|
||||
{"_id":"F0hcXfGaaYKQ0229","name":"Narcos, voie des Sortilèges","permission":{"default":0,"jOzRscDxoXZWpGS6":3},"type":"livre","data":{"description":"<p>Ce tome imposant, ouvertement destiné aux haut-rêvants, révèle que la voie de Narcos ne possède pas que des rituels, mais également des sortilèges. En saisir le sens demande toutefois un minimum de +4 en voie de Narcos. Il permet de comprendre le principe des sorts de transformation et d’envisager la synthèse de <em>Flèche de feu</em>,<em> Dague de force</em>, <em>Dragonne lame</em> et <em>Gourdindragon</em>. Sans son assimilation préalable, la synthèse de ces sorts est totalement inenvisageable. Sa difficulté de lecture est de -6, son assimilation requiert 28 points de tâche, périodicité 1 heure.</p>","auteur":"Segamor le Transformiste","quantite":1,"difficulte":-6,"points_de_tache":28,"encombrement":0,"xp":"","cout":0,"competence":""},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.png","effects":[]}
|
||||
@ -78,7 +77,6 @@
|
||||
{"_id":"PrnJrG50u1UPdlJN","name":"Liqueur de Bagdol","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"potion","data":{"description":"<p>Fluide. Liquide noir et odorant.</p>","quantite":1,"encombrement":0.1,"rarete":"","categorie":"Alchimie","cout":0.5},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp","effects":[]}
|
||||
{"_id":"PuuPn6WGfU8uBAyb","name":"Robe de soie","permission":{"default":0,"jOzRscDxoXZWpGS6":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":10},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/robe_soie.webp","effects":[]}
|
||||
{"name":"Bâton","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"arme","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":2,"equipe":false,"dommages":"1","penetration":0,"force":"9","resistance":8,"competence":"Masse à 2 mains","cout":0.5,"portee_courte":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":false,"initpremierround":"baton"},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/baton.webp","effects":[],"_id":"Qh4Tp7lZ6wLnX4w0"}
|
||||
{"_id":"RC1co7jmHMDqlJGy","name":"Deniers (pièces d'étain)","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.005,"equipe":false,"resistance":0,"qualite":0,"cout":0.01},"flags":{},"img":"icons/commodities/currency/coins-assorted-mix-platinum.webp","effects":[]}
|
||||
{"_id":"RGdDQ3yJYMkSuA5G","name":"Provisions cuites (1 sust)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"<p>pain, fromage, viande séchée...</p>","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.02},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp","effects":[]}
|
||||
{"_id":"RKr1ZhTvC6poiNa1","name":"Gros Clou","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.05},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/gros_clou.webp","effects":[]}
|
||||
{"_id":"RNxCQWMDy06uQ8uj","name":"Ecuelle de fer","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.15},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/ecuelle_fer.webp","effects":[]}
|
||||
@ -93,7 +91,6 @@
|
||||
{"_id":"Sm28dG9isppoQzPQ","name":"Bas de lin","permission":{"default":0,"jOzRscDxoXZWpGS6":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/bas_lin.webp","effects":[]}
|
||||
{"_id":"SrV0r5hnGdKeSIHR","name":"Cuillère de bois","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.03,"equipe":false,"resistance":0,"qualite":0,"cout":0.03},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/cuillere_bois.webp","effects":[]}
|
||||
{"_id":"SsnGNjTekvB50uWa","name":"Chapeau de cuir souple","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.08,"equipe":false,"resistance":0,"qualite":0,"cout":0.5},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/chapeau_cuir.webp","effects":[]}
|
||||
{"_id":"T9UiLcJonuHmGNwq","name":"Sols (pièces d'argent)","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.005,"equipe":false,"resistance":0,"qualite":0,"cout":1},"flags":{},"img":"icons/commodities/currency/coins-assorted-mix-silver.webp","effects":[]}
|
||||
{"name":"Hache de bataille","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"arme","data":{"categorie_parade":"haches","description":"","quantite":1,"encombrement":2,"equipe":false,"dommages":"3/4","penetration":0,"force":"12/11","resistance":8,"competence":"Hache à 1 main","cout":15,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"hachebataille"},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/hache_bataille.webp","effects":[],"_id":"TKsUXJq9w7ezcFGQ"}
|
||||
{"_id":"TY6Ft8a6WfxD6pD9","name":"Bobineau de fil","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/bobineau.webp","effects":[]}
|
||||
{"_id":"UDmq6CY3NsttcHe4","name":"Peigne en corne","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.04,"equipe":false,"resistance":0,"qualite":0,"cout":0.4},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/peigne.webp","effects":[]}
|
||||
@ -120,12 +117,14 @@
|
||||
{"_id":"Z0ij7qpoYeWMVocP","name":"Ceinturon de cuir","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"conteneur","data":{"description":"","capacite":6,"encombrement":0.1,"equipe":false,"qualite":0,"contenu":[],"cout":0.5},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/ceinturon.webp","effects":[]}
|
||||
{"_id":"ZLda3pfrbiKucSea","name":"Cornebouffe","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"objet","data":{"description":null,"quantite":1,"encombrement":null,"equipe":false,"resistance":0,"qualite":0,"cout":2},"flags":{"core":{"sourceId":"Item.yXOePj4twuchMblc"}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/cornebouffe.webp","effects":[]}
|
||||
{"_id":"a3Wj2WNKFrzqRGVG","name":"Chemise de soie","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":6},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/chemise_soie.webp","effects":[]}
|
||||
{"name":"Or (10 sols)","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"monnaie","data":{"quantite":0,"valeur_deniers":1000,"encombrement":0.01,"description":""},"flags":{"pick-up-stix":{"pick-up-stix":{"owner":"3ajJ5ZIa9bdcKUZQ"}}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp","effects":[],"_id":"aOgha34ew68iyMnM"}
|
||||
{"_id":"b0f08L5CDeFIMluC","name":"Cuir Souple","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"armure","data":{"description":"<p>Même épaisseur que nos modernes blousons de cuir. Pourpoint ou cotte de cuir souple + culottes de cuir souple + bottes de cuir souple.</p>\n<p> </p>","quantite":1,"encombrement":0,"equipe":false,"protection":2,"deterioration":0,"malus":0,"cout":6},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp","effects":[]}
|
||||
{"_id":"bA0JDA7awoWhu0vO","name":"Teinture d'Erozonne","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"potion","data":{"description":"<p>Fluide. </p>\n<p>Liquide rosâtre.</p>","quantite":1,"encombrement":0.1,"rarete":"","categorie":"Alchimie","cout":2},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/teinture_erozonne.webp","effects":[]}
|
||||
{"_id":"beQ9d4QQwZDQl5NA","name":"Flûte à bec","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.09,"equipe":false,"resistance":0,"qualite":0,"cout":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/flute_bec.webp","effects":[]}
|
||||
{"_id":"bgkEBYUEFLvAaeVf","name":"Luth, viole","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":7},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/luth.webp","effects":[]}
|
||||
{"_id":"bxDITKRhXiyvLhMz","name":"Candique","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"ingredient","data":{"description":"<p>Poudre blanche apparaissant sous l’écorce de nombreux arbres,</p>\n<p>VUE/Alchimie à 0.</p>","niveau":0,"encombrement":0.001,"base":0,"quantite":1,"milieu":"Forêts","rarete":"","categorie":"Alchimie","cout":0.02},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/candique.webp","effects":[]}
|
||||
{"_id":"cVZbnh5cYxBx6P5b","name":"Burin, gouge, ciseau","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.2,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/gouge.webp","effects":[]}
|
||||
{"name":"Bronze (10 deniers)","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"monnaie","data":{"quantite":6,"valeur_deniers":10,"encombrement":0.01,"description":""},"flags":{"pick-up-stix":{"pick-up-stix":{"owner":"3ajJ5ZIa9bdcKUZQ"}}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp","effects":[],"_id":"caw96HJsdScvPk7g"}
|
||||
{"_id":"ckKnviu9SHvWgya0","name":"Bougie de cire (2 heures)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.05},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/bougie.webp","effects":[]}
|
||||
{"_id":"cobfvOmFpti5lJuK","name":"Chemise de lin","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0,"equipe":false,"resistance":0,"qualite":0,"cout":0.3},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/chemise_lin.webp","effects":[]}
|
||||
{"_id":"dBR6KXvfmjjIcwsc","name":"Pilon en marbre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.1,"equipe":false,"resistance":0,"qualite":0,"cout":0.2},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/pilon.webp","effects":[]}
|
||||
@ -183,6 +182,7 @@
|
||||
{"name":"Sang","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"munition","data":{"description":"<p>1 mesure (20cl) de sang.</p>","quantite":1,"encombrement":0.1,"equipe":false,"qualite":0,"cout":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_sang.webp","effects":[],"_id":"slusKo2nVCtFwDkN"}
|
||||
{"_id":"snupUovwaPAe46aD","name":"Fiole en grès (20 cl)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"conteneur","data":{"description":"","capacite":0.1,"encombrement":0.1,"equipe":false,"qualite":0,"contenu":[],"cout":0.1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/fiole_gres.webp","effects":[]}
|
||||
{"_id":"szOThadvQvFcS79R","name":"Cuir Epais","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"armure","data":{"description":"<p>Cuir très épais comme le cuir de botte. Pectoral de cuir épais + jupon de bandes ou de tresses de cuir ou cuissards de cuir épais sur culottes de cuir souple + bottes dures + casque de cuir.</p>\n<p> </p>","quantite":1,"encombrement":2,"equipe":false,"protection":3,"deterioration":0,"malus":-1,"cout":10},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_epais.webp","effects":[]}
|
||||
{"name":"Etain (1 denier)","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"monnaie","data":{"quantite":4,"valeur_deniers":1,"encombrement":0.01,"description":""},"flags":{"pick-up-stix":{"pick-up-stix":{"owner":"3ajJ5ZIa9bdcKUZQ"}}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp","effects":[],"_id":"t1sIGhFtmxjAIfWv"}
|
||||
{"_id":"tBFt4h3jqINsOxLI","name":"Outre (2 litres)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"conteneur","data":{"description":"","capacite":1,"encombrement":0.08,"equipe":false,"qualite":0,"contenu":[],"cout":0.2},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/outre.webp","effects":[]}
|
||||
{"name":"Marteau","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"arme","data":{"categorie_parade":"","description":"","quantite":1,"encombrement":0.3,"equipe":false,"dommages":"2","penetration":0,"force":"7","resistance":8,"competence":"Masse à 1 main","cout":1,"portee_courte":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"portee_moyenne":0,"portee_extreme":0,"rapide":false,"deuxmains":false,"unemain":false,"initpremierround":"masse"},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/marteau.webp","effects":[],"_id":"tMWzePiuMtiCQnAU"}
|
||||
{"_id":"tY3shj5FA8nwMgxX","name":"Vin","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"munition","data":{"description":"<p>1 mesure (20cl) de vin.</p>","quantite":1,"encombrement":0.1,"equipe":false,"qualite":0,"cout":0},"flags":{"core":{"sourceId":"Item.QNNWTG5yqQKmcpJ7"}},"img":"systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_vin.webp","effects":[]}
|
||||
@ -203,6 +203,7 @@
|
||||
{"_id":"yILNvELKbsz2OOln","name":"Ecritoire","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":1,"equipe":false,"resistance":0,"qualite":0,"cout":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/ecritoire.webp","effects":[]}
|
||||
{"_id":"yO9Vx7tqF8qbZoYw","name":"Besace de cuir","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"conteneur","data":{"description":"","capacite":10,"encombrement":0.2,"equipe":false,"qualite":0,"contenu":[],"cout":0.5},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/besace.webp","effects":[]}
|
||||
{"_id":"z3xiBzZBZXlaRVzZ","name":"Le Grand Iris","permission":{"default":0,"jOzRscDxoXZWpGS6":3},"type":"livre","data":{"description":"<p>Cette judicieuse réflexion sur les sorts d’illusion visuelle d’Hypnos ne peut être assimilée que si l’on possède au minimum zéro en voie d’Hypnos. Il confère un bonus de synthèse de +2 et de 12 points de sorts aux trois yeux d’Hypnos : Invisibilité, Transfiguration, Métamorphose. Sa difficulté de lecture est de -3, son assimilation requiert 16 points de tâche, périodicité une heure.</p>","auteur":"Khrachtchoum le Problémeux","quantite":1,"difficulte":-3,"points_de_tache":16,"encombrement":0,"xp":"0","cout":0,"competence":""},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_hypnos.png","effects":[]}
|
||||
{"name":"Argent (1 sol)","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"monnaie","data":{"quantite":17,"valeur_deniers":100,"encombrement":0.01,"description":""},"flags":{"pick-up-stix":{"pick-up-stix":{"owner":"3ajJ5ZIa9bdcKUZQ"}}},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp","effects":[],"_id":"z8nkjovgrEj2d8kD"}
|
||||
{"_id":"zQWlnUsd8bPySujd","name":"Aiguille à coudre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"objet","data":{"description":"","quantite":1,"encombrement":0.01,"equipe":false,"resistance":0,"qualite":0,"cout":0.1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/aiguille.webp","effects":[]}
|
||||
{"_id":"zYI8mDiysWtmsSyy","name":"Carquois","permission":{"default":0,"jOzRscDxoXZWpGS6":3},"type":"conteneur","data":{"description":"","capacite":2,"encombrement":0.1,"equipe":false,"qualite":0,"cout":0.5},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/carquois.webp","effects":[]}
|
||||
{"_id":"zlDa1vwmls6Uf4pt","name":"Bourse de cuir","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"conteneur","data":{"description":"","capacite":0.5,"encombrement":0.01,"equipe":false,"qualite":0,"contenu":[],"cout":0.1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/objets/bourse.webp","effects":[]}
|
||||
|
81
packs/signes-draconiques.txt
Normal file
@ -0,0 +1,81 @@
|
||||
des centaines de graines emportées par le vent
|
||||
des cheminées de fées
|
||||
des cristaux de neige étincelants au soleil
|
||||
des feux follets dans la nuit
|
||||
des fumeroles s'échappant de fissures dans le sol
|
||||
des grêlons de la taille d'un oeuf de pigeon
|
||||
des lichens à l'assaut d'une souche
|
||||
des mirages sur l'horizon
|
||||
des nuages accrochées aux flancs d'une montagne
|
||||
des nuées dans le ciel nocturne
|
||||
des plumes duveteuses accrochées dans les fougères
|
||||
des roches sculptées par l'érosion
|
||||
des signes comme gravés à même la pierre évoquant la langue des Dragons
|
||||
des silhouettes imprécises dans la brume
|
||||
des sons de flûtes provenant du sous bois
|
||||
des traces de fossiles dans une roche
|
||||
des uages noirs qui moutonnent juste avant la pluie
|
||||
des veinures aux reflets métalliques dans la roche
|
||||
des voiles d'aurores boréales tombant dans le ciel nocturne
|
||||
des éclairs zébrant le ciel à l'horizon
|
||||
l'entrelacs des branches d'un arbre millénaire
|
||||
l'écoulement d'une chute l'eau
|
||||
l'écume sur les vagues salées
|
||||
la brillance d'étoiles alignées
|
||||
la coloration verte des flammes
|
||||
la course hypnotique des balles d'un jongleur
|
||||
la formation de givre sur une étendue d'eau
|
||||
la lueur du crépuscule sur les cimes à l'horizon
|
||||
la lune rouge sang
|
||||
la rosée dans une toile d'araignée
|
||||
la teinte rouge de la lune à travers les nuages
|
||||
le faisceau d'ondes causé par un insecte aquatique
|
||||
le mouvement de grains de sable poussés par le vent
|
||||
le mouvement de vagues battant le rivage
|
||||
le mouvement régulier des pales d'un moulin à vent
|
||||
le rythme de l'eau qui emporte les aubes d'un moulin
|
||||
le soleil masqué par un passage de nuages
|
||||
le tableau abstrait de tâches sur le sol
|
||||
les cicatrices et boutons du visage d'un malade
|
||||
les colorations violacées et oranges du ciel matinal
|
||||
les figures de la rouille sur un vieux casque
|
||||
les filaments d'une fleur carnivore enlaçant un insecte
|
||||
les rayons du soleil couchant
|
||||
les reflets d'eau à travers les plantes aquatiques
|
||||
les remous cascadant d’un torrent tels un liquide en ébullition dans une marmite de gigant
|
||||
les restes d'un mur antique
|
||||
les vagues du vent dans les herbes hautes
|
||||
un arbre mort fendu par la foudre
|
||||
un arc-en-ciel double
|
||||
un arc-en-ciel très lumineux
|
||||
un cadavre d'animal inconnu
|
||||
un dragon de nuages prenant son envol
|
||||
un empilement de pierres
|
||||
un enfant sautant dans les flaques d'eau
|
||||
un fantôme de poussière étincellant au soleil
|
||||
un geyser projetant eau et vapeur à la face des Dragons
|
||||
un manche d'outil poli par l'usure
|
||||
un moustique gorgé de sang
|
||||
un nid d'oiseau inconnu
|
||||
un nuage d'insectes assombrissant le ciel
|
||||
un panache de fumée volcaniques s'élevant à l'horizon
|
||||
un parterre de fleurs
|
||||
un prairie brumeuse
|
||||
un rideau de pluie éclairé d'un rai de lumière diffus
|
||||
un tourbillon dans l'eau
|
||||
un tourbillon de poussière
|
||||
un vol d'oiseaux migrateurs alignés traçant des lettres dans le ciel
|
||||
une braise attisée par le vent
|
||||
une coloration bleutée de la lune
|
||||
une concrétion rocheuse évoquant une cascade figée
|
||||
une fine couche de terre craquelée par le soleil
|
||||
une forme animale évoquée par les courbes d'une écorce
|
||||
une gerbe d'étincelles échappant du feu
|
||||
une mante religieuse dévorrant son male
|
||||
une mue de lézard
|
||||
une nuée chaotique d'oiseaux tourbillonnant dans le vent
|
||||
une ondée illuminée tombant tel un voile
|
||||
une phosphorescence dans l'eau
|
||||
une tornade dans le lointain
|
||||
une étoile filante
|
||||
une étrange disposition d'ossements sur le sol
|
@ -20,8 +20,13 @@
|
||||
src: url('../fonts/CaslonAntique.ttf') format("truetype");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "heures Draconiques";
|
||||
src: url('../fonts/heures_draconiques.ttf') format("truetype");
|
||||
font-family: 'HeuresDraconiques';
|
||||
src:
|
||||
url('../fonts/heuresdraconiques2.woff') format('woff'),
|
||||
url('../fonts/heuresdraconiques2.woff2') format('woff2'),
|
||||
url('../fonts/heuresdraconiques2.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
:root {
|
||||
@ -240,6 +245,9 @@ table {border: 1px solid #7a7971;}
|
||||
object-position: 50% 0;
|
||||
}
|
||||
|
||||
.dice-img {
|
||||
border-width: 0;
|
||||
}
|
||||
.button-img {
|
||||
vertical-align: baseline;
|
||||
width: 8%;
|
||||
@ -365,6 +373,20 @@ table {border: 1px solid #7a7971;}
|
||||
border-bottom: 1px solid #BBB;
|
||||
}
|
||||
|
||||
.blessure-inactive{
|
||||
color:rgba(150, 150, 150, 0.4)
|
||||
}
|
||||
.blessure-active-legere{
|
||||
color:rgba(60, 60, 60, 0.9);
|
||||
text-shadow: rgba(60, 60, 60, 0.7);
|
||||
}
|
||||
.blessure-active-grave{
|
||||
color:rgba(218, 126, 21, 0.9);
|
||||
}
|
||||
.blessure-active-critique{
|
||||
color:rgba(173, 36, 26, 0.9);
|
||||
|
||||
}
|
||||
.foundryvtt-reve-de-dragon .items-list .item .item-image {
|
||||
-webkit-box-flex: 0;
|
||||
-ms-flex: 0 0 24px;
|
||||
@ -406,7 +428,7 @@ table {border: 1px solid #7a7971;}
|
||||
border-radius: 6px; padding: 3px;
|
||||
background:linear-gradient(30deg, rgba(7, 76, 0, 0.3), rgba(66, 163, 65, 0.2), rgba(184, 226, 163, 0.1), rgba(66, 163, 65, 0.2), rgba(184, 226, 163, 0.3));
|
||||
}
|
||||
.rdd-roll-echec{
|
||||
.rdd-roll-notSign, .rdd-roll-echec{
|
||||
border-radius: 6px; padding: 3px;
|
||||
background-image: linear-gradient(150deg, rgba(255, 0, 0, 0.3), rgba(255, 200, 128, 0.05),rgba(255, 200, 128, 0.1), rgba(255,10,0,0.3));
|
||||
}
|
||||
@ -627,6 +649,23 @@ ul, li {
|
||||
padding: 0.125rem;
|
||||
flex: 1 1 5rem;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
margin: 0.125rem;
|
||||
padding: 0.125rem;
|
||||
flex: 1 1 5rem;
|
||||
}
|
||||
|
||||
.alterne-row > .row-item:hover {
|
||||
background: rgba(100, 100, 50, 0.25);
|
||||
}
|
||||
.alterne-row > .row-item:nth-child(even) {
|
||||
background: rgba(80, 60, 0, 0.10);
|
||||
}
|
||||
.alterne-row > .row-item:nth-child(odd) {
|
||||
background: rgb(160, 130, 100, 0.05);
|
||||
}
|
||||
|
||||
.item-display-show {
|
||||
display: block;
|
||||
}
|
||||
@ -1093,12 +1132,7 @@ ul, li {
|
||||
.calendar-date-rdd {
|
||||
font-family: "GoudyAcc";
|
||||
color: #CCC;
|
||||
font-weight: bold;
|
||||
font-size: 1.10rem;
|
||||
opacity: 90;
|
||||
}
|
||||
#calendar-move-handle {
|
||||
font-family: "GoudyAcc";
|
||||
font-size: 13px;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
|
@ -2,11 +2,11 @@
|
||||
"name": "foundryvtt-reve-de-dragon",
|
||||
"title": "Rêve de Dragon",
|
||||
"description": "Rêve de Dragon RPG for FoundryVTT",
|
||||
"version": "1.3.36",
|
||||
"version": "1.3.63",
|
||||
"manifestPlusVersion": "1.0.0",
|
||||
"minimumCoreVersion": "0.7.5",
|
||||
"compatibleCoreVersion": "0.7.9",
|
||||
"templateVersion": 96,
|
||||
"templateVersion": 103,
|
||||
"author": "LeRatierBretonnien",
|
||||
"authors": [
|
||||
{
|
||||
|
@ -430,6 +430,12 @@
|
||||
"value": 0,
|
||||
"label": "Protection naturelle",
|
||||
"derivee": false
|
||||
},
|
||||
"hautrevant": {
|
||||
"type": "string",
|
||||
"value": "",
|
||||
"label": "Haut rêvant",
|
||||
"derivee": true
|
||||
}
|
||||
},
|
||||
"reve": {
|
||||
|
24
templates/actor-blessure-partial.html
Normal file
@ -0,0 +1,24 @@
|
||||
<tr class="table-row alterne-row item" data-blessure-type="{{gravite}}" data-attribute={{key}} data-blessure-index="{{key}}" >
|
||||
<td class="item-control blessure-control" title="Blessure {{title}}" data-blessure-active="{{bless.active}}">
|
||||
{{#if bless.active}}
|
||||
<i class="fas fa-skull-crossbones blessure-active-{{gravite}}"></i>
|
||||
{{!-- <i class="fas fa-first-aid"></i> --}}
|
||||
{{!-- <i class="fas fa-plus-square"></i> --}}
|
||||
{{else}}
|
||||
{{!-- <i class="fas fa-genderless"></i> --}}
|
||||
<i class="fas fa-skull-crossbones blessure-inactive"></i>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
<input class="blessures-soins" type="text" name='localisation' data-dtype="String" value="{{bless.loc}}"/>
|
||||
</td>
|
||||
<td>
|
||||
<input class="blessures-soins" type="text" name='premiers_soins' data-dtype="number" value="{{bless.premiers_soins}}"/>
|
||||
</td>
|
||||
<td>
|
||||
<input class="blessures-soins" type="text" name='soins_complets' data-dtype="number" value="{{bless.soins_complets}}"/>
|
||||
</td>
|
||||
<td>
|
||||
<input class="blessures-soins" type="text" name='jours' data-dtype="number" value="{{bless.jours}}"/>
|
||||
</td>
|
||||
</tr>
|
@ -139,68 +139,14 @@
|
||||
|
||||
{{!-- blessures Tab --}}
|
||||
<div class="tab blessures" data-group="primary" data-tab="blessures" style="height:200px">
|
||||
<span class="blessures-title">Blessures Légeres :</span>
|
||||
<div class="blessure-data alterne-list">
|
||||
{{#each data.blessures.legeres.liste as |bless key|}}
|
||||
<li class="item flexrow blessure-data list-item" data-blessure-type="legere" data-attribute={{key}}
|
||||
data-blessure-index="{{key}}">
|
||||
<a class="item-control blessure-control" title="Blessure Légère"
|
||||
data-blessure-active="{{bless.active}}">{{#if bless.active}}<i class="fas fa-circle"></i>{{else}}<i
|
||||
class="fas fa-genderless"></i>{{/if}}</a>
|
||||
Premiers soins <input class="blessures-soins" type="text" name='premiers_soins' data-dtype="number"
|
||||
value="{{this.premiers_soins}}" /> -
|
||||
Soins complets <input class="blessures-soins" type="text" name='soins_complets' data-dtype="number"
|
||||
value="{{this.soins_complets}}" /> -
|
||||
Jours <input class="blessures-soins" type="text" name='jours' data-dtype="number" value="{{this.jours}}" />
|
||||
-
|
||||
Loc. <input class="blessures-soins" type="text" name='localisation' data-dtype="String"
|
||||
value="{{this.loc}}" />
|
||||
</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
<span class="blessures-title">Blessures Graves :</span>
|
||||
<div class="blessure-data alterne-list">
|
||||
{{#each data.blessures.graves.liste as |bless key|}}
|
||||
<li class="item flexrow list-item" data-blessure-type="grave" data-attribute={{key}} data-blessure-index="{{key}}">
|
||||
<a class="item-control blessure-control" title="Blessure Grave"
|
||||
data-blessure-active="{{bless.active}}">{{#if bless.active}}<i class="fas fa-circle"></i>{{else}}<i
|
||||
class="fas fa-genderless"></i>{{/if}}</a>
|
||||
Premiers soins <input class="blessures-soins" type="text" name="premiers_soins" data-dtype="number"
|
||||
value="{{bless.premiers_soins}}" /> -
|
||||
Soins complets <input class="blessures-soins" type="text" name="soins_complets" data-dtype="number"
|
||||
value="{{bless.soins_complets}}" /> -
|
||||
Jours <input class="blessures-soins" type="text" name="jours" data-dtype="number" value="{{bless.jours}}" />
|
||||
-
|
||||
Loc. <input class="blessures-soins" type="text" name="localisation" data-dtype="String"
|
||||
value="{{bless.loc}}" />
|
||||
</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
<span class="blessures-title">Blessure Critique :</span>
|
||||
<div class="blessure-data alterne-list">
|
||||
{{#each data.blessures.critiques.liste as |bless key|}}
|
||||
<li class="item flexrow list-item" data-blessure-type="critique" data-attribute={{key}} data-blessure-index="{{key}}">
|
||||
<a class="item-control blessure-control" title="Blessure Critique"
|
||||
data-blessure-active="{{bless.active}}">{{#if bless.active}}<i class="fas fa-circle"></i>{{else}}<i
|
||||
class="fas fa-genderless"></i>{{/if}}</a>
|
||||
Premiers soins <input class="blessures-soins" type="text" name="premiers_soins" data-dtype="number"
|
||||
value="{{bless.premiers_soins}}" /> -
|
||||
Soins complets <input class="blessures-soins" type="text" name="soins_complets" data-dtype="number"
|
||||
value="{{bless.soins_complets}}" /> -
|
||||
Jours <input class="blessures-soins" type="text" name="jours" data-dtype="number" value="{{bless.jours}}" />
|
||||
-
|
||||
Loc. <input class="blessures-soins" type="text" name="localisation" data-dtype="String"
|
||||
value="{{bless.loc}}" />
|
||||
</li>
|
||||
</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{!-- Liste de blessures --}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-liste-blessures-partial.html" this}}
|
||||
</div>
|
||||
|
||||
{{!-- Equipment Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="items">
|
||||
<span class="item-name">Encombrement total/max : {{numberFormat calc.encTotal decimals=2}} / {{data.attributs.encombrement.value}} <b>{{calc.surEncombrementMessage}}</b></span> -
|
||||
<span class="item-name"><a id="creer-un-objet">Créer un objet</a></span>
|
||||
<span class="item-name"><a class="creer-un-objet">Créer un objet</a></span>
|
||||
{{#if options.isGM}}
|
||||
<span class="item-name"> - <a id="nettoyer-conteneurs">Vider tout les conteneurs</a></span>
|
||||
{{/if}}
|
||||
|
26
templates/actor-liste-blessures-partial.html
Normal file
@ -0,0 +1,26 @@
|
||||
<h3>Blessures:</h3>
|
||||
<table class="table-container" role="table">
|
||||
<thead>
|
||||
<tr class="competence-header competence-title competence-label" >
|
||||
<th></th>
|
||||
<th>Localisation</th>
|
||||
<th>Premiers soins</th>
|
||||
<th>Soins complets</th>
|
||||
<th>Age (jours)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="table-row alterne-row" ><td/><td colspan="4">Légères</td></tr>
|
||||
{{#each data.blessures.legeres.liste as |bless key|}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html" bless=bless key=key gravite="legere" title="Légère"}}
|
||||
{{/each}}
|
||||
<tr class="table-row alterne-row"><td/><td colspan="4">Graves</td></tr>
|
||||
{{#each data.blessures.graves.liste as |bless key|}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html" bless=bless key=key gravite="grave" title="Grave"}}
|
||||
{{/each}}
|
||||
<tr class="table-row alterne-row"><td/><td colspan="4">Critiques</td></tr>
|
||||
{{#each data.blessures.critiques.liste as |bless key|}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html" bless=bless key=key gravite="critique" title="Critique"}}
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
@ -1,3 +1,5 @@
|
||||
{{log 'calc' calc}}
|
||||
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
|
||||
{{!-- Sheet Header --}}
|
||||
@ -59,9 +61,11 @@
|
||||
<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 id="dormir-une-heure"><a title="Dormir une heure"><img class="button-img" src="icons/svg/sleep.svg" alt="Dormir une heure"/></a></span>
|
||||
<span id="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}}
|
||||
<span id="monte-tmr"><a title="Montée dans les Terres Médianes !"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg" alt="Montée dans les Terres Médianes !"/></a></span>
|
||||
<span id="monte-tmr-rapide"><a title="Montée accélérée dans les Terres Mé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édianes !"/></a></span>
|
||||
<span id="visu-tmr"><a title="Regarder les Terres Médianes"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-view.svg" alt="Regarder les Terres Médianes"/></a></span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="flexrow">
|
||||
<span class="tooltip">Malus de fatigue : {{calc.fatigue.malus}}
|
||||
@ -160,6 +164,7 @@
|
||||
</span>
|
||||
</li>
|
||||
{{#each data.attributs as |attr key|}}
|
||||
{{#unless (eq key 'hautrevant')}}
|
||||
<li class="competence flexrow list-item" data-attribute="{{key}}">
|
||||
<span class="competence-label flexrow" name="data.attributs.{{key}}.label">{{attr.label}} :
|
||||
{{#if (eq key 'protection')}}
|
||||
@ -169,6 +174,7 @@
|
||||
{{/if}}
|
||||
</span>
|
||||
</li>
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
<ul class="carac-list alterne-list">
|
||||
@ -295,14 +301,17 @@
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
{{#if data.attributs.hautrevant.value}}
|
||||
<header class="competence-header flexrow">
|
||||
<span class="competence-title">Draconic</span>
|
||||
</header>
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each data.competenceByCategory.draconic as |comp key|}}
|
||||
{{#each competenceByCategory.draconic as |comp key|}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
|
||||
<div>
|
||||
<ul class="item-list">
|
||||
<li class="item flexrow">
|
||||
@ -356,112 +365,25 @@
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
|
||||
{{!-- Liste de blessures --}}
|
||||
<h3 class="blessures-title">Blessures:</h3>
|
||||
<div class="flex-group-left flexcol competence-column">
|
||||
<h4 class="blessures-title">Légères:</h4>
|
||||
<ul class="blessure-data flexrow alterne-list blessures-list">
|
||||
{{#each data.blessures.legeres.liste as |bless key|}}
|
||||
<li class="item flexrow blessure-data list-item" data-blessure-type="legere" data-attribute={{key}} data-blessure-index="{{key}}">
|
||||
<ul>
|
||||
<li class="item-control blessure-control" title="Blessure Légère" data-blessure-active="{{bless.active}}">
|
||||
{{#if bless.active}}
|
||||
<i class="fas fa-circle"></i>
|
||||
{{else}}
|
||||
<i class="fas fa-genderless"></i>
|
||||
{{/if}}
|
||||
</li>
|
||||
<li>
|
||||
Premiers soins
|
||||
<input class="blessures-soins" type="text" name='premiers_soins' data-dtype="number" value="{{bless.premiers_soins}}"/>
|
||||
</li>
|
||||
<li>
|
||||
Soins complets
|
||||
<input class="blessures-soins" type="text" name='soins_complets' data-dtype="number" value="{{bless.soins_complets}}"/>
|
||||
</li>
|
||||
<li>
|
||||
Jours
|
||||
<input class="blessures-soins" type="text" name='jours' data-dtype="number" value="{{bless.jours}}"/>
|
||||
</li>
|
||||
<li>
|
||||
Loc.
|
||||
<input class="blessures-soins" type="text" name='localisation' data-dtype="String" value="{{bless.loc}}"/>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<h4 class="blessures-title">Graves :</h4>
|
||||
<ul class="flexrow alterne-list blessures-list">
|
||||
{{#each data.blessures.graves.liste as |bless key|}}
|
||||
<li class="item flexrow list-item" data-blessure-type="grave" data-attribute={{key}} data-blessure-index="{{key}}" >
|
||||
<ul>
|
||||
<li class="item-control blessure-control" title="Blessure Grave" data-blessure-active="{{bless.active}}">
|
||||
{{#if bless.active}}
|
||||
<i class="fas fa-circle"></i>
|
||||
{{else}}
|
||||
<i class="fas fa-genderless"></i>
|
||||
{{/if}}
|
||||
</li>
|
||||
<li>
|
||||
Premiers soins
|
||||
<input class="blessures-soins" type="text" name='premiers_soins' data-dtype="number" value="{{bless.premiers_soins}}"/>
|
||||
</li>
|
||||
<li>
|
||||
Soins complets
|
||||
<input class="blessures-soins" type="text" name='soins_complets' data-dtype="number" value="{{bless.soins_complets}}"/>
|
||||
</li>
|
||||
<li>
|
||||
Jours
|
||||
<input class="blessures-soins" type="text" name='jours' data-dtype="number" value="{{bless.jours}}"/>
|
||||
</li>
|
||||
<li>
|
||||
Loc.
|
||||
<input class="blessures-soins" type="text" name='localisation' data-dtype="String" value="{{bless.loc}}"/>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<h4 class="blessures-title">Critique :</h4>
|
||||
<ul class="flexrow alterne-list blessures-list">
|
||||
{{#each data.blessures.critiques.liste as |bless key|}}
|
||||
<li class="item list-item flexrow" data-blessure-type="critique" data-attribute={{key}} data-blessure-index="{{key}}" >
|
||||
<ul>
|
||||
<li class="flex-group-center item-control blessure-control" title="Blessure Critique" data-blessure-active="{{bless.active}}">
|
||||
{{#if bless.active}}
|
||||
<i class="fas fa-circle"></i>
|
||||
{{else}}
|
||||
<i class="fas fa-genderless"></i>
|
||||
{{/if}}
|
||||
</li>
|
||||
<li>
|
||||
Premiers soins
|
||||
<input class="blessures-soins" type="text" name='premiers_soins' data-dtype="number" value="{{bless.premiers_soins}}"/>
|
||||
</li>
|
||||
<li>
|
||||
Soins complets
|
||||
<input class="blessures-soins" type="text" name='soins_complets' data-dtype="number" value="{{bless.soins_complets}}"/>
|
||||
</li>
|
||||
<li>
|
||||
Jours
|
||||
<input class="blessures-soins" type="text" name='jours' data-dtype="number" value="{{bless.jours}}"/>
|
||||
</li>
|
||||
<li>
|
||||
Loc.
|
||||
<input class="blessures-soins" type="text" name='localisation' data-dtype="String" value="{{bless.loc}}"/>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-liste-blessures-partial.html" this}}
|
||||
</div>
|
||||
|
||||
{{!-- Connaissances Tab --}}
|
||||
<div class="tab connaissances" data-group="primary" data-tab="connaissances">
|
||||
<h3>Oeuvres diverses :</h3>
|
||||
<h3>Tâches</h3><a class='creer-tache'>Créer une nouvelle Tâche</a>
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each data.taches as |tache id|}}
|
||||
<li class="item flexrow list-item" data-item-id="{{tache._id}}"><span class="competence-title tache-label"><a>{{tache.name}} ({{tache.data.points_de_tache_courant}}/{{tache.data.points_de_tache}})</a></span>
|
||||
<div class="item-controls">
|
||||
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<hr>
|
||||
<h3>Oeuvres diverses :</h3><a class="creer-une-oeuvre">Créer une oeuvre</a>
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each data.chants as |chant id|}}
|
||||
<li class="item flexrow list-item" data-item-id="{{chant._id}}"><span>Chant</span><span class="competence-title chant-label"><a>{{chant.name}} (niveau {{chant.data.niveau}})</a></span>
|
||||
@ -526,25 +448,21 @@
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<h3>Tâches</h3><a id='creer-tache'>Créer une nouvelle Tâche</a>
|
||||
<ul class="item-list alterne-list">
|
||||
{{#each data.taches as |tache id|}}
|
||||
<li class="item flexrow list-item" data-item-id="{{tache._id}}"><span class="competence-title tache-label"><a>{{tache.name}} ({{tache.data.points_de_tache_courant}}/{{tache.data.points_de_tache}})</a></span>
|
||||
<div class="item-controls">
|
||||
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
|
||||
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<hr>
|
||||
<h3>Astrologie</h3>
|
||||
<span class="astrologie-label"><a id="jet-astrologie">Astrologie : Nombres Astraux</a></span>
|
||||
</div>
|
||||
|
||||
{{!-- hautreve Tab --}}
|
||||
<div class="tab hautreve " data-group="primary" data-tab="hautreve" style="height:200px">
|
||||
<div>
|
||||
<h3>Haut rêve:</h3>
|
||||
{{#if data.attributs.hautrevant.value}}
|
||||
<h3>Haut rêvant</h3>
|
||||
{{else}}
|
||||
<h3>Vous n'avez pas le don de haut-rêve! Il faut attribuer la Tête de Dragon 'Don de Haut Rêve' si votre personnage est ou devient Haut-Rêvant.</h3>
|
||||
{{/if}}
|
||||
<ul class="item-list">
|
||||
{{#if data.attributs.hautrevant.value}}
|
||||
<li class="item flexrow">
|
||||
<span class="competence-label">Position en TMR :</span>
|
||||
<span>
|
||||
@ -555,6 +473,7 @@
|
||||
{{/if}}
|
||||
</span>
|
||||
</li>
|
||||
{{/if}}
|
||||
<li class="item flexrow">
|
||||
<span class="competence-label">Seuil de Rêve :</span>
|
||||
<span>
|
||||
@ -575,12 +494,10 @@
|
||||
{{/if}}
|
||||
</span>
|
||||
</li>
|
||||
<li class="item flexrow" >
|
||||
<span class="astrologie-label"><a id="jet-astrologie">Astrologie : Nombres Astraux</a></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<hr>
|
||||
{{#if data.attributs.hautrevant.value}}
|
||||
<div>
|
||||
<h3>Sorts:</h3>
|
||||
<ul class="item-list">
|
||||
@ -649,9 +566,10 @@
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<hr>
|
||||
{{/if}}
|
||||
|
||||
{{!-- Queues, Souffles, Tetes, Ombre --}}
|
||||
<hr>
|
||||
<h3>Queues:</h3>
|
||||
<ul class="flex-group-left">
|
||||
{{#each data.queues as |queue key|}}
|
||||
@ -723,7 +641,7 @@
|
||||
<span class="item-name">Estimation de l'équipement : {{numberFormat calc.prixTotalEquipement decimals=2}} Sols</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="item-name"><a id="creer-un-objet">Créer un objet</a></span>
|
||||
<span class="item-name"><a class="creer-un-objet">Créer un objet</a></span>
|
||||
{{#if options.isGM}}
|
||||
<span class="item-name"> - <a id="nettoyer-conteneurs">Vider tout les conteneurs</a></span>
|
||||
{{/if}}
|
||||
|
@ -69,7 +69,7 @@
|
||||
{{!-- Equipment Tab --}}
|
||||
<div class="tab items" data-group="primary" data-tab="items">
|
||||
<span class="item-name">Encombrement total/max : {{numberFormat calc.encTotal decimals=2}} / {{data.capacite_encombrement}} <b>{{calc.surEncombrementMessage}}</b></span> -
|
||||
<span class="item-name"><a id="creer-un-objet">Créer un objet</a></span>
|
||||
<span class="item-name"><a class="creer-un-objet">Créer un objet</a></span>
|
||||
{{#if options.isGM}}
|
||||
<span class="item-name"> - <a id="nettoyer-conteneurs">Vider tout les conteneurs</a></span>
|
||||
{{/if}}
|
||||
|
@ -17,6 +17,6 @@
|
||||
{{/if}}
|
||||
<a class='chat-card-button' id='echec-total-attaque' data-attackerId='{{attackerId}}'
|
||||
data-defenderTokenId='{{defenderTokenId}}'>
|
||||
Tirer l'échec total !
|
||||
Tirer la maladresse !
|
||||
</a>
|
||||
</div>
|
@ -7,11 +7,11 @@
|
||||
<div>
|
||||
{{#if (eq tactique 'charge')}}
|
||||
<img class="chat-icon" src="icons/svg/thrust.svg" alt="charge" height="32" width="32" />
|
||||
C'est une charge, vos parades auront un -4 et vous ne pourrez pas esquiver!
|
||||
C'est une charge, les parades de {{alias}} auront un -4 et il/elle ne pourra pas esquiver!
|
||||
{{ else if (eq tactique 'feinte')}}
|
||||
{{#if rolled.isSuccess}}
|
||||
<img class="chat-icon" src="systems/foundryvtt-reve-de-dragon/icons/heures/hd06.svg" alt="feinte" height="32" width="32" />
|
||||
Votre feinte peut faire mouche!
|
||||
La feinte de {{alias}} peut faire mouche!
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
@ -26,15 +26,15 @@
|
||||
{{else}}
|
||||
<span class="rdd-roll-etotal">{{numberFormat dmg.total decimals=0 sign=true}}</span> (entités de cauchemar)
|
||||
{{~/if}}.
|
||||
{{#if show.isRecul}}Si votre adversaire n'esquive pas, il devra résister à l'impact ou reculer sous le choc!{{/if}}
|
||||
{{#if show.isRecul}}Si l'adversaire de {{alias}} n'esquive pas, il devra résister à l'impact ou reculer sous le choc!{{/if}}
|
||||
</span>
|
||||
{{#if (eq particuliere 'rapidite')}}
|
||||
<span>
|
||||
<br>Votre attaque rapide vous permet une deuxième attaque, ou défense supplémentaire!
|
||||
<br>L'attaque rapide de {{alias}} lui permet une deuxième attaque, ou défense supplémentaire!
|
||||
</span>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<span>Votre attaque a échoué!</span>
|
||||
<span>L'attaque de {{alias}} a échoué!</span>
|
||||
{{/if}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||
</div>
|
@ -1,6 +1,6 @@
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.data.competence}}" />
|
||||
<h4>
|
||||
{{alias}} tente de chanter la chanson : {{oeuvre.name}} (niveau {{oeuvre.data.niveau}})
|
||||
{{alias}} tente de chanter : {{oeuvre.name}} (niveau {{oeuvre.data.niveau}})
|
||||
</h4>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||
<hr>
|
||||
|
@ -16,7 +16,7 @@
|
||||
</span>
|
||||
</h4>
|
||||
<div>
|
||||
Je d'encaissement de {{roll.total}}
|
||||
Jet d'encaissement de {{roll.total}}
|
||||
{{#unless (eq armure 0)}}, l'armure a protègé de {{armure}} {{#unless (eq penetration 0)}}(pénétration de {{penetration}})
|
||||
{{/unless}}
|
||||
{{/unless}}, total: <span class="rdd-roll-echec">{{total}}</span>
|
||||
|
@ -8,10 +8,10 @@
|
||||
<span>Attaque esquivée!</span>
|
||||
{{#if rolled.isPart}}
|
||||
<!-- TODO: cas de parade à mains nues, texte à modifier -->
|
||||
<span><strong>Vous pouvez faire une deuxième esquive!</strong></span>
|
||||
<span><strong>{{alias}} peut faire une deuxième esquive!</strong></span>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<span>Votre esquive a échoué!</span>
|
||||
<span>{{alias}} a échoué son esquive!</span>
|
||||
{{/if}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||
</div>
|
||||
|
@ -12,12 +12,12 @@
|
||||
<hr>
|
||||
<span>
|
||||
{{#if rolled.isSuccess}}
|
||||
Vous parvenez à {{maitrise.verbe}} {{le tmr.genre}} {{tmr.label}} !
|
||||
{{alias}} parvient à {{maitrise.verbe}} {{le tmr.genre}} {{tmr.label}} !
|
||||
{{else}}
|
||||
Vous ne parvenez pas à {{maitrise.verbe}} {{le tmr.genre}} {{tmr.label}}.
|
||||
Vous <strong>quittez les Terres Médianes</strong> !
|
||||
{{alias}} ne parvient pas à {{maitrise.verbe}} {{le tmr.genre}} {{tmr.label}}.
|
||||
{{alias}} <strong>quitte les Terres Médianes</strong> !
|
||||
{{#if souffle}}
|
||||
<br>De plus, votre échec total vous fait subir un Souffle de Dragon : {{souffle.name}}
|
||||
<br>De plus, l'échec total de {{alias}} lui fait subir un Souffle de Dragon : {{souffle.name}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</span>
|
||||
|
@ -24,6 +24,12 @@
|
||||
</span>
|
||||
</div>
|
||||
<hr>
|
||||
{{#if rolled.isETotal}}
|
||||
Le sort a des effets imprévus!
|
||||
{{else if rolled.isSuccess}}
|
||||
{{#unless isSortReserve}}
|
||||
<span class="poesie-extrait">
|
||||
{{{selectedSort.data.description}}}
|
||||
</span>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
@ -6,9 +6,9 @@
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||
<hr>
|
||||
<div>
|
||||
Après {{tache.data.periodicite}} vous avez obtenu {{rolled.ptTache}} point{{~#if (gt rolled.ptTache 1)}}s{{/if}} de tâche,
|
||||
votre avancement est de <span class="rdd-roll-{{#if (gt tache.data.points_de_tache_courant 0)}}norm{{else}}etotal{{/if}}">{{tache.data.points_de_tache_courant}} sur {{tache.data.points_de_tache}}</span> point{{~#if (gt tache.data.points_de_tache_courant 1)}}s{{/if}} de tâche.
|
||||
{{#if tache.data.fatigue}}<br><span>Vous vous êtes fatigué de {{tache.data.fatigue}} case{{~#if (gt tache.data.fatigue 1)}}s{{/if}}.</span>{{/if}}
|
||||
{{#if rolled.isETotal}}<br><span>Votre échec total augmente de 1 la difficulté de la tâche!</span>{{/if~}}
|
||||
Après {{tache.data.periodicite}}, {{alias}} a obtenu {{rolled.ptTache}} point{{~#if (gt rolled.ptTache 1)}}s{{/if}} de tâche,
|
||||
son avancement est de <span class="rdd-roll-{{#if (gt tache.data.points_de_tache_courant 0)}}norm{{else}}etotal{{/if}}">{{tache.data.points_de_tache_courant}} sur {{tache.data.points_de_tache}}</span> point{{~#if (gt tache.data.points_de_tache_courant 1)}}s{{/if}} de tâche.
|
||||
{{#if tache.data.fatigue}}<br><span>{{alias}} s'est fatigué de {{tache.data.fatigue}} case{{~#if (gt tache.data.fatigue 1)}}s{{/if}}.</span>{{/if}}
|
||||
{{#if rolled.isETotal}}<br><span>L'échec total de {{alias}} augmente de 1 la difficulté de la tâche!</span>{{/if~}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||
</div>
|
||||
|
30
templates/item-nombreastral-sheet.html
Normal file
@ -0,0 +1,30 @@
|
||||
<form class="{{cssClass}}" autocomplete="off">
|
||||
<header class="sheet-header">
|
||||
<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>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="sheet-body">
|
||||
<div class="form-group">
|
||||
<label for="xp">Nombre</label>
|
||||
<input class="attribute-value" type="text" name="data.value" value="{{data.value}}" data-dtype="Number"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="xp">Nombre valide ? </label>
|
||||
<input class="attribute-value" type="checkbox" name="data.istrue" {{#if data.istrue}}checked{{/if}}/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="xp">Index du jour concerné</label>
|
||||
<input class="attribute-value" type="text" name="data.jourindex" value="{{data.jourindex}}" data-dtype="Number"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="xp">Label du jour</label>
|
||||
<input class="attribute-value" type="text" name="data.jourlabel" value="{{data.jourlabel}}" data-dtype="String"/>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</form>
|
@ -24,16 +24,16 @@
|
||||
<label>Exotisme</label>
|
||||
<input class="attribute-value" type="text" name="data.exotisme" value="{{data.exotisme}}" data-dtype="Number"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Référence / Auteur</label>
|
||||
<input class="attribute-value" type="text" name="data.reference" value="{{data.reference}}" data-dtype="String"/>
|
||||
</div>
|
||||
<div class="flexcol">
|
||||
<span><label>Ingrédients : </label></span>
|
||||
<div class="form-group editor">
|
||||
{{editor content=data.ingredients target="data.ingredients" button=true owner=owner editable=editable}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Référence / Auteur</label>
|
||||
<input class="attribute-value" type="text" name="data.reference" value="{{data.reference}}" data-dtype="String"/>
|
||||
</div>
|
||||
<div class="flexcol">
|
||||
<span><label>Description : </label></span>
|
||||
<div class="form-group editor">
|
||||
|
20
templates/settings/dialog-aide-commands.html
Normal file
@ -0,0 +1,20 @@
|
||||
<h3>Dés spéciaux</h3>
|
||||
<ul class="alterne-list">
|
||||
<li class="list-item">
|
||||
<strong>/roll 1d7</strong>: lance un dé de rencontre
|
||||
</li>
|
||||
<li class="list-item">
|
||||
<strong>/roll 1dr</strong>: lance un dé draconique (de 0à 7, relance et additionne en cas de 7)
|
||||
</li>
|
||||
<li class="list-item">
|
||||
<strong>/roll 1dh</strong>: lance le dé des heures (de 1 à 12)
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Commandes disponibles</h3>
|
||||
<ul class="alterne-list">
|
||||
{{#each commands as |command key|}}
|
||||
<li class="list-item">
|
||||
{{{command}}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|