Compare commits
	
		
			116 Commits
		
	
	
		
			9b37533bdf
			...
			master
		
	
	| 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({
 | 
			
		||||
@@ -173,7 +177,28 @@ 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();
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										169
									
								
								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) {
 | 
			
		||||
 | 
			
		||||
    const actorData = Misc.data(this);
 | 
			
		||||
    if (ajustementMoral != 0) {
 | 
			
		||||
      const actorData = Misc.data(this);
 | 
			
		||||
      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);
 | 
			
		||||
  }
 | 
			
		||||
@@ -2262,7 +2306,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
    if (destinee > 0) {
 | 
			
		||||
      ChatMessage.create({ content: `<span class="rdd-roll-part">${this.name} a fait appel à la Destinée !</span>` });
 | 
			
		||||
      destinee--;
 | 
			
		||||
      await this.updateCompteurValue( "destinee", destinee);
 | 
			
		||||
      await this.updateCompteurValue("destinee", destinee);
 | 
			
		||||
      onSuccess();
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
@@ -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"
 | 
			
		||||
        };
 | 
			
		||||
      case 'chance-actuelle': case 'Chance actuelle':
 | 
			
		||||
        return {
 | 
			
		||||
          label: 'Chance actuelle',
 | 
			
		||||
          value: this.getChanceActuel(),
 | 
			
		||||
          type: "number"
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    return RdDActor._findCaracByName(Misc.templateData(this).carac, caracName);
 | 
			
		||||
  getCaracAndActuel() {
 | 
			
		||||
    let caracs = {
 | 
			
		||||
      'reve-actuel': { label: 'Rêve actuel', value: this.getReveActuel(), type: "number" },
 | 
			
		||||
      'chance-actuelle': { label: 'Chance actuelle', value: this.getChanceActuel(), type: "number" }
 | 
			
		||||
    };
 | 
			
		||||
    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,31 +3153,39 @@ 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)
 | 
			
		||||
 | 
			
		||||
    let draconique = Draconique.all().find(it => it.match(item));
 | 
			
		||||
    if (draconique) {
 | 
			
		||||
      draconique.onActorCreateOwned(this, item)
 | 
			
		||||
 | 
			
		||||
      this.notifyGestionTeteSouffleQueue(item, draconique.manualMessage());
 | 
			
		||||
        this.notifyGestionTeteSouffleQueue(item, draconique.manualMessage());
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async onDeleteOwnedDraconique(item, options, id) {
 | 
			
		||||
 | 
			
		||||
    let draconique = Draconique.all().find(it => it.match(item));
 | 
			
		||||
    if (draconique) {
 | 
			
		||||
      draconique.onActorDeleteOwned(this, item)
 | 
			
		||||
    if (Misc.isElectedUser()) {
 | 
			
		||||
      let draconique = Draconique.all().find(it => it.match(item));
 | 
			
		||||
      if (draconique) {
 | 
			
		||||
        draconique.onActorDeleteOwned(this, item)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async onDeleteOwnedCaseTmr(item, options, id) {
 | 
			
		||||
    let draconique = Draconique.all().find(it => it.isCase(item));
 | 
			
		||||
    if (draconique) {
 | 
			
		||||
      draconique.onActorDeleteCaseTmr(this, item)
 | 
			
		||||
    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,31 +8,27 @@ 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());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  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 }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -108,5 +105,5 @@ export class ChatUtility {
 | 
			
		||||
      ChatMessage.create(data);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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;
 | 
			
		||||
@@ -128,12 +131,12 @@ export class RdDItemCompetence extends Item {
 | 
			
		||||
  static computeEconomieXPTronc(competences) {
 | 
			
		||||
    return competenceTroncs.map(
 | 
			
		||||
      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);
 | 
			
		||||
          // 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(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.`
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
 
 | 
			
		||||
@@ -49,20 +49,13 @@ 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
 | 
			
		||||
      }
 | 
			
		||||
  static getDifficulte(aspects) {
 | 
			
		||||
    let elements = aspects.split('-');
 | 
			
		||||
    let composantes = elements.length;
 | 
			
		||||
    let distincts = Object.keys(Misc.classifyFirst(elements, it => it)).length;
 | 
			
		||||
    if (distincts == 1) {
 | 
			
		||||
      composantes--;
 | 
			
		||||
    }
 | 
			
		||||
    diff = diff - ((nbDifferent>1) ? nbDifferent : 0); // Ca doit marcher ....
 | 
			
		||||
    return Math.min(0, diff); // Pour être sur
 | 
			
		||||
    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,7 +22,15 @@ 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)
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
@@ -392,7 +402,7 @@ export class RdDCalendrier extends Application {
 | 
			
		||||
      }
 | 
			
		||||
      astrologieArray.push(duplicate(astralData));
 | 
			
		||||
    }
 | 
			
		||||
    //console.log("ASTRO", astrologieArray);
 | 
			
		||||
    //console.log("ASTRO", astrologieArray);    
 | 
			
		||||
    calendrierData.astrologieData = astrologieArray;
 | 
			
		||||
    let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/calendar-astrologie-template.html', calendrierData);
 | 
			
		||||
    let astrologieEditeur = new RdDAstrologieEditeur(html, this, calendrierData)
 | 
			
		||||
 
 | 
			
		||||
@@ -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,9 +195,11 @@ 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));
 | 
			
		||||
 | 
			
		||||
      actions.push({ name: "Draconic", data: { initOnly: true, competence: "Draconic" } });
 | 
			
		||||
      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" } });
 | 
			
		||||
@@ -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) {
 | 
			
		||||
    let turn = combat.turns.find(t => t.tokenId == combat.current.tokenId);
 | 
			
		||||
    if (game.user.isGM) {
 | 
			
		||||
      // seul le GM notifie le status
 | 
			
		||||
    if (Misc.isElectedUser()) {
 | 
			
		||||
      let turn = combat.turns.find(t => t.tokenId == combat.current.tokenId);
 | 
			
		||||
      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,36 +507,32 @@ export class RdDCombat {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static onMsgEncaisser(data) {
 | 
			
		||||
    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
 | 
			
		||||
    if (Misc.isElectedUser()) {
 | 
			
		||||
      let attackerRoll = RdDCombat._getAttaque(data.attackerId); // Retrieve the rolldata from the store
 | 
			
		||||
      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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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))) {
 | 
			
		||||
        const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
 | 
			
		||||
        if (rddCombat) {
 | 
			
		||||
          const defenderRoll = msg.defenderRoll;
 | 
			
		||||
          RdDCombat._storeAttaque(msg.attackerId, defenderRoll.attackerRoll);
 | 
			
		||||
          RdDCombat._storeDefense(defenderRoll);
 | 
			
		||||
          rddCombat.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
 | 
			
		||||
          rddCombat._chatMessageDefense(msg.paramChatDefense);
 | 
			
		||||
        }
 | 
			
		||||
    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 (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.passeArme, defenderRoll);
 | 
			
		||||
        rddCombat.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
 | 
			
		||||
        rddCombat._chatMessageDefense(msg.paramChatDefense);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@@ -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,15 +1,145 @@
 | 
			
		||||
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;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static async showDiceSoNice(roll, rollMode = undefined) {
 | 
			
		||||
    if (game.modules.get("dice-so-nice") && game.modules.get("dice-so-nice").active) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
@@ -269,23 +282,23 @@ export class RdDResolutionTable {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static buildHTMLResults(caracValue, levelValue) {
 | 
			
		||||
    if ( caracValue == undefined || isNaN(caracValue )) caracValue = 10;
 | 
			
		||||
    if ( levelValue == undefined || isNaN(levelValue )) levelValue = 0;
 | 
			
		||||
    
 | 
			
		||||
    if (caracValue == undefined || isNaN(caracValue)) caracValue = 10;
 | 
			
		||||
    if (levelValue == undefined || isNaN(levelValue)) levelValue = 0;
 | 
			
		||||
 | 
			
		||||
    let cell = this.computeChances(caracValue, levelValue);
 | 
			
		||||
    cell.epart = cell.epart > 99 ? 'N/A' : cell.epart;
 | 
			
		||||
    cell.etotal = cell.etotal > 100 ? 'N/A' : cell.etotal;
 | 
			
		||||
    cell.score = Math.min(cell.score, 99);
 | 
			
		||||
 | 
			
		||||
    return `
 | 
			
		||||
<span class="table-proba-reussite competence-label">
 | 
			
		||||
Particulière: <span class="rdd-roll-part">${cell.part}</span>
 | 
			
		||||
- Significative: <span class="rdd-roll-sign">${cell.sign}</span>
 | 
			
		||||
- Réussite: <span class="rdd-roll-norm">${cell.score}</span>
 | 
			
		||||
- Echec Particulier: <span class="rdd-roll-epart">${cell.epart}</span>
 | 
			
		||||
- Echec Total: <span class="rdd-roll-etotal">${cell.etotal}</span>
 | 
			
		||||
</span>
 | 
			
		||||
`
 | 
			
		||||
    <span class="table-proba-reussite competence-label">
 | 
			
		||||
    Particulière: <span class="rdd-roll-part">${cell.part}</span>
 | 
			
		||||
    - Significative: <span class="rdd-roll-sign">${cell.sign}</span>
 | 
			
		||||
    - Réussite: <span class="rdd-roll-norm">${cell.score}</span>
 | 
			
		||||
    - Echec Particulier: <span class="rdd-roll-epart">${cell.epart}</span>
 | 
			
		||||
    - Echec Total: <span class="rdd-roll-etotal">${cell.etotal}</span>
 | 
			
		||||
    </span>
 | 
			
		||||
    `
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -63,14 +64,33 @@ export class RdDRoll extends Dialog {
 | 
			
		||||
      surprise: actor.getSurprise(false),
 | 
			
		||||
      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,15 +700,19 @@ export class RdDUtility {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static afficherHeuresChanceMalchance(heureNaissance) {
 | 
			
		||||
    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")
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      ui.notifications.warn("Pas d'heure de naissance selectionnée")
 | 
			
		||||
    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("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;
 | 
			
		||||
    }
 | 
			
		||||
    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<72>es par le vent
 | 
			
		||||
des chemin<69>es de f<>es
 | 
			
		||||
des cristaux de neige <20>tincelants au soleil
 | 
			
		||||
des feux follets dans la nuit
 | 
			
		||||
des fumeroles s'<27>chappant de fissures dans le sol
 | 
			
		||||
des gr<67>lons de la taille d'un oeuf de pigeon
 | 
			
		||||
des lichens <20> l'assaut d'une souche
 | 
			
		||||
des mirages sur l'horizon
 | 
			
		||||
des nuages accroch<63>es aux flancs d'une montagne
 | 
			
		||||
des nu<6E>es dans le ciel nocturne
 | 
			
		||||
des plumes duveteuses accroch<63>es dans les foug<75>res
 | 
			
		||||
des roches sculpt<70>es par l'<27>rosion
 | 
			
		||||
des signes comme grav<61>s <20> m<>me la pierre <20>voquant la langue des Dragons
 | 
			
		||||
des silhouettes impr<70>cises dans la brume
 | 
			
		||||
des sons de fl<66>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<6F>ales tombant dans le ciel nocturne
 | 
			
		||||
des <20>clairs z<>brant le ciel <20> l'horizon
 | 
			
		||||
l'entrelacs des branches d'un arbre mill<6C>naire
 | 
			
		||||
l'<27>coulement d'une chute l'eau
 | 
			
		||||
l'<27>cume sur les vagues sal<61>es
 | 
			
		||||
la brillance d'<27>toiles align<67>es
 | 
			
		||||
la coloration verte des flammes
 | 
			
		||||
la course hypnotique des balles d'un jongleur
 | 
			
		||||
la formation de givre sur une <20>tendue d'eau
 | 
			
		||||
la lueur du cr<63>puscule sur les cimes <20> l'horizon
 | 
			
		||||
la lune rouge sang
 | 
			
		||||
la ros<6F>e dans une toile d'araign<67>e
 | 
			
		||||
la teinte rouge de la lune <20> travers les nuages
 | 
			
		||||
le faisceau d'ondes caus<75> par un insecte aquatique
 | 
			
		||||
le mouvement de grains de sable pouss<73>s par le vent
 | 
			
		||||
le mouvement de vagues battant le rivage
 | 
			
		||||
le mouvement r<>gulier des pales d'un moulin <20> vent
 | 
			
		||||
le rythme de l'eau qui emporte les aubes d'un moulin
 | 
			
		||||
le soleil masqu<71> 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<61>es et oranges du ciel matinal
 | 
			
		||||
les figures de la rouille sur un vieux casque
 | 
			
		||||
les filaments d'une fleur carnivore enla<6C>ant un insecte
 | 
			
		||||
les rayons du soleil couchant
 | 
			
		||||
les reflets d'eau <20> travers les plantes aquatiques
 | 
			
		||||
les remous cascadant d<>un torrent tels un liquide en <20>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<74>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<6E>me de poussi<73>re <20>tincellant au soleil
 | 
			
		||||
un geyser projetant eau et vapeur <20> la face des Dragons
 | 
			
		||||
un manche d'outil poli par l'usure
 | 
			
		||||
un moustique gorg<72> de sang
 | 
			
		||||
un nid d'oiseau inconnu
 | 
			
		||||
un nuage d'insectes assombrissant le ciel
 | 
			
		||||
un panache de fum<75>e volcaniques s'<27>levant <20> l'horizon
 | 
			
		||||
un parterre de fleurs
 | 
			
		||||
un prairie brumeuse
 | 
			
		||||
un rideau de pluie <20>clair<69> d'un rai de lumi<6D>re diffus
 | 
			
		||||
un tourbillon dans l'eau
 | 
			
		||||
un tourbillon de poussi<73>re
 | 
			
		||||
un vol d'oiseaux migrateurs align<67>s tra<72>ant des lettres dans le ciel
 | 
			
		||||
une braise attis<69>e par le vent
 | 
			
		||||
une coloration bleut<75>e de la lune
 | 
			
		||||
une concr<63>tion rocheuse <20>voquant une cascade fig<69>e
 | 
			
		||||
une fine couche de terre craquel<65>e par le soleil
 | 
			
		||||
une forme animale <20>voqu<71>e par les courbes d'une <20>corce
 | 
			
		||||
une gerbe d'<27>tincelles <20>chappant du feu
 | 
			
		||||
une mante religieuse d<>vorrant son male
 | 
			
		||||
une mue de l<>zard
 | 
			
		||||
une nu<6E>e chaotique d'oiseaux tourbillonnant dans le vent
 | 
			
		||||
une ond<6E>e illumin<69>e tombant tel un voile
 | 
			
		||||
une phosphorescence dans l'eau
 | 
			
		||||
une tornade dans le lointain
 | 
			
		||||
une <20>toile filante
 | 
			
		||||
une <20>trange disposition d'ossements sur le sol
 | 
			
		||||
@@ -20,10 +20,15 @@
 | 
			
		||||
    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 {
 | 
			
		||||
  /* =================== 1. ACTOR SHEET FONT STYLES =========== */
 | 
			
		||||
    --window-header-title-font-family: CaslonAntique;
 | 
			
		||||
@@ -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,101 +139,47 @@
 | 
			
		||||
      
 | 
			
		||||
    {{!-- 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>
 | 
			
		||||
      </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>
 | 
			
		||||
        {{#if options.isGM}}
 | 
			
		||||
        <span class="item-name"> - <a id="nettoyer-conteneurs">Vider tout les conteneurs</a></span>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
        <ul class="item-list alterne-list">
 | 
			
		||||
          <li class="competence-header flexrow">
 | 
			
		||||
            <span class="competence-title competence-label">Nom</span>
 | 
			
		||||
            <span class="competence-title competence-label">Q.</span>
 | 
			
		||||
            <span class="competence-title competence-value">Enc.</span>
 | 
			
		||||
            <span class="competence-title competence-value">Equiper</span>
 | 
			
		||||
            <span class="competence-title competence-value">Editer/Suppr.</span>
 | 
			
		||||
    {{!-- 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 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}}
 | 
			
		||||
      <ul class="item-list alterne-list">
 | 
			
		||||
        <li class="competence-header flexrow">
 | 
			
		||||
          <span class="competence-title competence-label">Nom</span>
 | 
			
		||||
          <span class="competence-title competence-label">Q.</span>
 | 
			
		||||
          <span class="competence-title competence-value">Enc.</span>
 | 
			
		||||
          <span class="competence-title competence-value">Equiper</span>
 | 
			
		||||
          <span class="competence-title competence-value">Editer/Suppr.</span>
 | 
			
		||||
        </li>
 | 
			
		||||
        {{#each data.objets as |item id|}}
 | 
			
		||||
          {{#unless item.estContenu}}
 | 
			
		||||
          {{#if (ne item.type 'conteneur')}}
 | 
			
		||||
          <li class="item flexrow list-item" data-item-id="{{item._id}}">
 | 
			
		||||
              <img class="sheet-competence-img" src="{{item.img}}" title="{{item.name}}"/>
 | 
			
		||||
              <span class="item-name">{{item.name}}</span>
 | 
			
		||||
              <span class="item-quantite">{{item.data.quantite}}</span>
 | 
			
		||||
              <span class="item-quantite">{{numberFormat item.data.encTotal decimals=2}}</span>
 | 
			
		||||
              <div class="item-controls">
 | 
			
		||||
                  <a class="item-control item-equip" title="Equiper">{{#if item.data.equipe}}<i class="fas fa-circle"></i>{{else}}<i class="fas fa-genderless"></i>{{/if}}</a>
 | 
			
		||||
                  <a class="item-control item-edit" title="Editer"><i class="fas fa-edit"></i></a>
 | 
			
		||||
                  <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
              </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{#each data.objets as |item id|}}
 | 
			
		||||
            {{#unless item.estContenu}}
 | 
			
		||||
            {{#if (ne item.type 'conteneur')}}
 | 
			
		||||
            <li class="item flexrow list-item" data-item-id="{{item._id}}">
 | 
			
		||||
                <img class="sheet-competence-img" src="{{item.img}}" title="{{item.name}}"/>
 | 
			
		||||
                <span class="item-name">{{item.name}}</span>
 | 
			
		||||
                <span class="item-quantite">{{item.data.quantite}}</span>
 | 
			
		||||
                <span class="item-quantite">{{numberFormat item.data.encTotal decimals=2}}</span>
 | 
			
		||||
                <div class="item-controls">
 | 
			
		||||
                    <a class="item-control item-equip" title="Equiper">{{#if item.data.equipe}}<i class="fas fa-circle"></i>{{else}}<i class="fas fa-genderless"></i>{{/if}}</a>
 | 
			
		||||
                    <a class="item-control item-edit" title="Editer"><i class="fas fa-edit"></i></a>
 | 
			
		||||
                    <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
            </li>
 | 
			
		||||
            {{/if}}
 | 
			
		||||
            {{/unless}}
 | 
			
		||||
          {{/if}}
 | 
			
		||||
          {{/unless}}
 | 
			
		||||
        {{/each}}
 | 
			
		||||
          {{#each data.conteneurs as |conteneur id|}}
 | 
			
		||||
          {{buildConteneur this}}
 | 
			
		||||
          {{/each}}
 | 
			
		||||
            {{#each data.conteneurs as |conteneur id|}}
 | 
			
		||||
            {{buildConteneur this}}
 | 
			
		||||
            {{/each}}
 | 
			
		||||
          </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
        </ul>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      {{!-- Biography Tab --}}
 | 
			
		||||
      <div class="tab description" data-group="primary" data-tab="description">
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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,15 +164,17 @@
 | 
			
		||||
                  </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')}}
 | 
			
		||||
                    {{#if (eq key 'protection')}}
 | 
			
		||||
                    <input id="attribut-protection-edit" type="text" name="{{key}}" value="{{attr.value}}" data-dtype="number"/><span/>
 | 
			
		||||
                  {{else}}
 | 
			
		||||
                    {{else}}
 | 
			
		||||
                    {{attr.value}}
 | 
			
		||||
                  {{/if}}
 | 
			
		||||
                    {{/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>
 | 
			
		||||
                <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>
 | 
			
		||||
        </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>
 | 
			
		||||
@@ -516,7 +438,7 @@
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        <h3>Recettes Alchimiques</h3>
 | 
			
		||||
          <ul class="item-list alterne-list">
 | 
			
		||||
        <ul class="item-list alterne-list">
 | 
			
		||||
          {{#each data.recettesAlchimiques as |recette id|}}
 | 
			
		||||
          <li class="item flexrow list-item" data-item-id="{{recette._id}}"><span class="competence-title recette-label item-edit"><a>{{recette.name}}</a></span>
 | 
			
		||||
            <div class="item-controls">
 | 
			
		||||
@@ -525,26 +447,22 @@
 | 
			
		||||
            </div>
 | 
			
		||||
          </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>
 | 
			
		||||
        </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>
 | 
			
		||||