Gestion des signes draconiques #455

Closed
vincent.vandeme wants to merge 233 commits from v1.4-signes-draconiques into master
27 changed files with 204 additions and 50 deletions
Showing only changes of commit e98d99638e - Show all commits

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.vscode/settings.json .vscode/settings.json
.idea
todo.txt todo.txt
todo.md todo.md

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
icons/heures/hd01.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
icons/heures/hd02.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
icons/heures/hd03.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
icons/heures/hd04.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
icons/heures/hd05.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
icons/heures/hd06.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
icons/heures/hd07.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
icons/heures/hd08.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
icons/heures/hd09.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
icons/heures/hd10.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
icons/heures/hd11.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
icons/heures/hd12.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -13,7 +13,6 @@ import { RdDItemSort } from "./item-sort.js";
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { RdDEncaisser } from "./rdd-roll-encaisser.js"; import { RdDEncaisser } from "./rdd-roll-encaisser.js";
import { RdDCombat } from "./rdd-combat.js"; import { RdDCombat } from "./rdd-combat.js";
import { DeDraconique } from "./de-draconique.js";
import { RdDAudio } from "./rdd-audio.js"; import { RdDAudio } from "./rdd-audio.js";
import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemCompetence } from "./item-competence.js";
import { RdDItemArme } from "./item-arme.js"; import { RdDItemArme } from "./item-arme.js";
@ -629,7 +628,7 @@ export class RdDActor extends Actor {
} }
} }
else { else {
let deRecuperation = (await DeDraconique.ddr("selfroll")).total; let deRecuperation = new Roll("1dr + 7").evaluate().total;
console.log("recuperationReve", deRecuperation); console.log("recuperationReve", deRecuperation);
if (deRecuperation >= 7) { if (deRecuperation >= 7) {
// Rêve de Dragon ! // Rêve de Dragon !

1
module/constants.js Normal file
View File

@ -0,0 +1 @@
export const SYSTEM_RDD = "foundryvtt-reve-de-dragon";

View File

@ -1,26 +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].number = rerolls;
this._total -= rerolls;
return this;
}
async render(chatOptions) {
return super.render(chatOptions)
}
}

View File

@ -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 heuresList = ["vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant"];
const heuresDef = { const heuresDef = {
"vaisseau": { label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' }, "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' }, "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' }, "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' }, "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' }, "lyre": { label: "Lyre", lettreFont: 'l', saison: "automne", heure: 6, icon: 'hd07.svg' },
@ -41,6 +41,7 @@ export class RdDCalendrier extends Application {
this.calendrier = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier")); this.calendrier = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier"));
//console.log("CALENDRIER", this.calendrier); //console.log("CALENDRIER", this.calendrier);
if (this.calendrier == undefined || this.calendrier.moisRdD == undefined) { if (this.calendrier == undefined || this.calendrier.moisRdD == undefined) {
this.calendrier = {};
this.calendrier.heureRdD = 0; // Index dans heuresList this.calendrier.heureRdD = 0; // Index dans heuresList
this.calendrier.minutesRelative = 0; this.calendrier.minutesRelative = 0;
this.calendrier.moisRdD = 0; // Index dans heuresList this.calendrier.moisRdD = 0; // Index dans heuresList
@ -52,6 +53,7 @@ export class RdDCalendrier extends Application {
// position // position
this.calendrierPos = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier-pos")); this.calendrierPos = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier-pos"));
if (this.calendrierPos == undefined || this.calendrierPos.top == undefined) { if (this.calendrierPos == undefined || this.calendrierPos.top == undefined) {
this.calendrierPos = {};
this.calendrierPos.top = 200; this.calendrierPos.top = 200;
this.calendrierPos.left = 200; this.calendrierPos.left = 200;
if (game.user.isGM) { // Uniquement si GM if (game.user.isGM) { // Uniquement si GM

View File

@ -1,6 +1,5 @@
/* -------------------------------------------- */ /* -------------------------------------------- */
import { DeDraconique } from "./de-draconique.js";
import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemCompetence } from "./item-competence.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { RdDCarac } from "./rdd-carac.js"; import { RdDCarac } from "./rdd-carac.js";
@ -166,11 +165,25 @@ export class RdDCommands {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
help(msg, table = undefined) { async help(msg) {
this.help(msg, undefined);
}
async help(msg, table) {
let list = [] let list = []
this._buildSubTableHelp(list, table || this.commandsTable); 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);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -221,23 +234,23 @@ export class RdDCommands {
} }
let actors = canvas.tokens.controlled.map(it => it.actor).filter(it => it); let actors = canvas.tokens.controlled.map(it => it.actor).filter(it => it);
if (actors && actors.length > 0){ if (actors && actors.length > 0) {
let length = params.length; let length = params.length;
let diff = Number(params[length-1]); let diff = Number(params[length - 1]);
if (Number.isInteger(Number(diff))){ if (Number.isInteger(Number(diff))) {
length --; length--;
} }
else { else {
diff = 0; diff = 0;
} }
const caracName = params[0]; const caracName = params[0];
const compName = length>1 ? params.slice(1, length).reduce((a, b) => `${a} ${b}`): undefined; const compName = length > 1 ? params.slice(1, length).reduce((a, b) => `${a} ${b}`) : undefined;
for (let actor of actors) { for (let actor of actors) {
await actor.rollCaracCompetence(caracName, compName, diff); await actor.rollCaracCompetence(caracName, compName, diff);
} }
return; return;
} }
else{ else {
ui.notifications.warn("Sélectionnez au moins un personnage pour lancer les dés") ui.notifications.warn("Sélectionnez au moins un personnage pour lancer les dés")
} }
} }
@ -258,7 +271,7 @@ export class RdDCommands {
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollDeDraconique(msg) { async rollDeDraconique(msg) {
let ddr = new DeDraconique().evaluate(); let ddr = new Roll("1dr + 7").evaluate();
ddr.showDice = true; ddr.showDice = true;
await RdDDice.showDiceSoNice(ddr); await RdDDice.showDiceSoNice(ddr);
RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr.total}`); RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr.total}`);

View File

@ -1,15 +1,145 @@
import { ChatUtility } from "./chat-utility.js"; 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 { 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) { 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); await this.showDiceSoNice(roll, rollMode);
} }
return roll; return roll;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async showDiceSoNice(roll, rollMode = undefined) { static async showDiceSoNice(roll, rollMode = undefined) {
if (game.modules.get("dice-so-nice") && game.modules.get("dice-so-nice").active) { if (game.modules.get("dice-so-nice") && game.modules.get("dice-so-nice").active) {

View File

@ -30,6 +30,7 @@ import { RdDHotbar } from "./rdd-hotbar-drop.js"
import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
import { RdDHerbes } from "./rdd-herbes.js"; import { RdDHerbes } from "./rdd-herbes.js";
import { RdDItem } from "./item.js"; import { RdDItem } from "./item.js";
import { RdDDice } from "./rdd-dice.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
/* Foundry VTT Initialization */ /* Foundry VTT Initialization */
@ -171,6 +172,7 @@ Hooks.once("init", async function () {
// préparation des différents modules // préparation des différents modules
RdDUtility.init(); RdDUtility.init();
RdDDice.init();
RdDCommands.init(); RdDCommands.init();
RdDCombat.init(); RdDCombat.init();
RdDCombatManager.init(), RdDCombatManager.init(),
@ -230,7 +232,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) => { Hooks.on("chatMessage", (html, content, msg) => {
if (content[0] == '/') { if (content[0] == '/') {

View File

@ -1,4 +1,3 @@
import { DeDraconique } from "./de-draconique.js";
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { TMRUtility } from "./tmr-utility.js"; import { TMRUtility } from "./tmr-utility.js";
@ -382,7 +381,7 @@ export class TMRRencontres {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async evaluerForceRencontre(rencontre) { static async evaluerForceRencontre(rencontre) {
if (TMRRencontres.isReveDeDragon(rencontre)) { if (TMRRencontres.isReveDeDragon(rencontre)) {
const ddr = await DeDraconique.ddr("selfroll") const ddr = new Roll("1dr + 7").evaluate();
rencontre.force = 7 + ddr.total; rencontre.force = 7 + ddr.total;
} }
else { else {

View File

@ -20,10 +20,15 @@
src: url('../fonts/CaslonAntique.ttf') format("truetype"); src: url('../fonts/CaslonAntique.ttf') format("truetype");
} }
@font-face { @font-face {
font-family: "heures Draconiques"; font-family: 'HeuresDraconiques';
src: url('../fonts/heures_draconiques.ttf') format("truetype"); 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 { :root {
/* =================== 1. ACTOR SHEET FONT STYLES =========== */ /* =================== 1. ACTOR SHEET FONT STYLES =========== */
--window-header-title-font-family: CaslonAntique; --window-header-title-font-family: CaslonAntique;
@ -242,6 +247,9 @@ table {border: 1px solid #7a7971;}
object-position: 50% 0; object-position: 50% 0;
} }
.dice-img {
border-width: 0;
}
.button-img { .button-img {
vertical-align: baseline; vertical-align: baseline;
width: 8%; width: 8%;

View 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>