Compare commits
	
		
			42 Commits
		
	
	
		
			foundryvtt
			...
			foundryvtt
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9c71827baa | |||
| fc9ef06e7b | |||
| 
						 | 
					9e63706de6 | ||
| 3958b1bdc2 | |||
| 6d6843223b | |||
| 
						 | 
					46f5cb67f6 | ||
| 
						 | 
					d51243d74f | ||
| 
						 | 
					34cc671f12 | ||
| 
						 | 
					16ce6a58dd | ||
| 89910e234d | |||
| f30df47d22 | |||
| 
						 | 
					c3c42bdb21 | ||
| 
						 | 
					14eb655382 | ||
| 
						 | 
					52e4375972 | ||
| 8aece9cad1 | |||
| ffd36a045e | |||
| 
						 | 
					bafc52a151 | ||
| 
						 | 
					940baad04c | ||
| 70c26ebfe0 | |||
| 782c6a8fe2 | |||
| 
						 | 
					b417fdfe32 | ||
| 11274c51d6 | |||
| 6377964d07 | |||
| 
						 | 
					8cf43d4e8a | ||
| 
						 | 
					5efb7d9be0 | ||
| 
						 | 
					f54804c071 | ||
| 
						 | 
					59ece09357 | ||
| 
						 | 
					5868bf16e0 | ||
| 6873cf0d41 | |||
| 2c73f5aa11 | |||
| 035da98aaa | |||
| 
						 | 
					2885ca1c8f | ||
| 
						 | 
					218c88a924 | ||
| 
						 | 
					e22b6c52f1 | ||
| 
						 | 
					9b8f694dda | ||
| 
						 | 
					75562b0af8 | ||
| 
						 | 
					3a684c3c54 | ||
| 
						 | 
					70354abacb | ||
| 
						 | 
					bdead49d01 | ||
| 60b6da5cd3 | |||
| 66218be14a | |||
| 
						 | 
					9aad57c00c | 
@@ -22,13 +22,6 @@ export class RdDActorEntiteSheet extends ActorSheet {
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */  
 | 
			
		||||
  _checkNull(items) {
 | 
			
		||||
    if (items && items.length) {
 | 
			
		||||
      return items;
 | 
			
		||||
    }
 | 
			
		||||
    return [];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async getData() {
 | 
			
		||||
 
 | 
			
		||||
@@ -94,7 +94,7 @@ export class RdDActorSheet extends ActorSheet {
 | 
			
		||||
    RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
 | 
			
		||||
    RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.data.carac);
 | 
			
		||||
    formData.esquives = this.actor.getCompetences("Esquive").map(i => foundry.utils.deepClone(i.data));
 | 
			
		||||
    formData.combat = RdDCombatManager.finalizeArmeList(formData.combat, formData.competences, formData.data.carac);
 | 
			
		||||
    formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.data.carac);
 | 
			
		||||
 | 
			
		||||
    this.armesList = formData.combat;
 | 
			
		||||
 | 
			
		||||
@@ -315,7 +315,7 @@ export class RdDActorSheet extends ActorSheet {
 | 
			
		||||
 | 
			
		||||
    // Boutons spéciaux MJs
 | 
			
		||||
    html.find('.forcer-tmr-aleatoire').click(async event => {
 | 
			
		||||
      this.actor.cacheTMRetMessage();
 | 
			
		||||
      this.actor.reinsertionAleatoire("Action MJ");
 | 
			
		||||
    });
 | 
			
		||||
    html.find('.afficher-tmr').click(async event => {
 | 
			
		||||
      this.actor.afficheTMRetMessage();
 | 
			
		||||
@@ -335,8 +335,8 @@ export class RdDActorSheet extends ActorSheet {
 | 
			
		||||
    html.find('.arme-initiative a').click(async event => {
 | 
			
		||||
      let combatant = game.combat.data.combatants.find(c => c.actor.data._id == this.actor.data._id);
 | 
			
		||||
      if (combatant) {
 | 
			
		||||
        let arme = this._getEventArmeCombat(event);
 | 
			
		||||
        RdDCombatManager.rollInitiativeCompetence(combatant._id, arme);
 | 
			
		||||
        let action = this._getEventArmeCombat(event);
 | 
			
		||||
        RdDCombatManager.rollInitiativeAction(combatant._id, action);
 | 
			
		||||
      } else {
 | 
			
		||||
        ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.");
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -25,14 +25,6 @@ export class RdDActorVehiculeSheet extends ActorSheet {
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  _checkNull(items) {
 | 
			
		||||
    if (items && items.length) {
 | 
			
		||||
      return items;
 | 
			
		||||
    }
 | 
			
		||||
    return [];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async getData() {
 | 
			
		||||
    const objectData = Misc.data(this.object);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										178
									
								
								module/actor.js
									
									
									
									
									
								
							
							
						
						
									
										178
									
								
								module/actor.js
									
									
									
									
									
								
							@@ -33,7 +33,8 @@ import { RollDataAjustements } from "./rolldata-ajustements.js";
 | 
			
		||||
import { DialogItemAchat } from "./dialog-item-achat.js";
 | 
			
		||||
import { RdDItem } from "./item.js";
 | 
			
		||||
import { RdDPossession } from "./rdd-possession.js";
 | 
			
		||||
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
 | 
			
		||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -------------------------------------------- */
 | 
			
		||||
/**
 | 
			
		||||
@@ -98,7 +99,6 @@ export class RdDActor extends Actor {
 | 
			
		||||
   * @param {Object} options     (Unused) Additional options which customize the creation workflow.
 | 
			
		||||
   *
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  static async create(actorData, options) {
 | 
			
		||||
    // Case of compendium global import
 | 
			
		||||
    if (actorData instanceof Array) {
 | 
			
		||||
@@ -115,11 +115,14 @@ export class RdDActor extends Actor {
 | 
			
		||||
      return actor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const competences = await RdDUtility.loadCompendium(RdDItemCompetence.actorCompendium(actorData.type));
 | 
			
		||||
    actorData.items = competences.map(i => i.toObject());
 | 
			
		||||
    if (isPersonnage) {
 | 
			
		||||
      const competences = await RdDUtility.loadCompendium(RdDItemCompetence.actorCompendium(actorData.type));
 | 
			
		||||
      actorData.items = competences.map(i => i.toObject());
 | 
			
		||||
      actorData.items = actorData.items.concat(Monnaie.monnaiesData());
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      actorData.items = [];
 | 
			
		||||
    }
 | 
			
		||||
    return super.create(actorData, options);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -132,13 +135,6 @@ export class RdDActor extends Actor {
 | 
			
		||||
    this.encTotal = 0;
 | 
			
		||||
    this.prixTotalEquipement = 0;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    // Auto-resize token
 | 
			
		||||
    if (this.isToken) {
 | 
			
		||||
      let tokenSize = actorData.data.carac.taille.value/10;
 | 
			
		||||
      this.token.update({height: tokenSize, width: tokenSize } );
 | 
			
		||||
    }*/
 | 
			
		||||
 | 
			
		||||
    // Make separate methods for each Actor type (character, npc, etc.) to keep
 | 
			
		||||
    // things organized.
 | 
			
		||||
    if (actorData.type === 'personnage') this._prepareCharacterData(actorData);
 | 
			
		||||
@@ -244,7 +240,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
  }
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  getForce() {
 | 
			
		||||
    if (this.isEntiteCauchemar()) {
 | 
			
		||||
    if (this.isEntite()) {
 | 
			
		||||
      return Misc.toInt(Misc.templateData(this).carac.reve?.value);
 | 
			
		||||
    }
 | 
			
		||||
    return Misc.toInt(Misc.templateData(this).carac.force?.value);
 | 
			
		||||
@@ -372,12 +368,30 @@ export class RdDActor extends Actor {
 | 
			
		||||
    const list = this.getDraconicList();
 | 
			
		||||
    return duplicate(list[0]);
 | 
			
		||||
  }
 | 
			
		||||
  getDraconicOrZero() {
 | 
			
		||||
    const list = this.getDraconicList().filter(it => Misc.data(it).data.niveau >= 0);
 | 
			
		||||
    if (list.length == 0) {
 | 
			
		||||
      return { name: "Aucun", data: { niveau: 0 } };
 | 
			
		||||
  getDraconicOuPossession() {
 | 
			
		||||
    const possessions = this.items.filter(it => Misc.data(it).type == 'competencecreature' && Misc.templateData(it).ispossession)
 | 
			
		||||
      .sort(Misc.descending(it => Misc.templateData(it).niveau));
 | 
			
		||||
    if (possessions.length>0) {
 | 
			
		||||
      return duplicate(possessions[0]);
 | 
			
		||||
    }
 | 
			
		||||
    return duplicate(list[0]);
 | 
			
		||||
    const draconics = this.getDraconicList().filter(it => Misc.data(it).data.niveau >= 0);
 | 
			
		||||
    if (draconics.length> 0) {
 | 
			
		||||
      return duplicate(draconics[0]);
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
 | 
			
		||||
      name: 'Sans draconic',
 | 
			
		||||
      data: {
 | 
			
		||||
        niveau: 0,
 | 
			
		||||
        defaut_carac: "reve",
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
  getPossession(possessionId) {
 | 
			
		||||
    return this.items.find(it => it.type == 'possession' && it.data.data.possessionid == possessionId);
 | 
			
		||||
  }
 | 
			
		||||
  getPossessions() {
 | 
			
		||||
    return this.items.filter(it => it.type == 'possession');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getDemiReve() {
 | 
			
		||||
@@ -599,7 +613,10 @@ export class RdDActor extends Actor {
 | 
			
		||||
      content: "Remise à neuf de " + this.name
 | 
			
		||||
    };
 | 
			
		||||
    const actorData = Misc.data(this);
 | 
			
		||||
    if (this.isEntiteCauchemar()) {
 | 
			
		||||
    if (this.isEntite([ENTITE_NONINCARNE])) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (this.isEntite([ENTITE_INCARNE, ENTITE_BLURETTE])) {
 | 
			
		||||
      await this.santeIncDec("endurance", actorData.data.sante.endurance.max - actorData.data.sante.endurance.value);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
@@ -783,7 +800,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
  async combattreReveDeDragon(force) {
 | 
			
		||||
    let rollData = {
 | 
			
		||||
      actor: this,
 | 
			
		||||
      competence: duplicate(this.getDraconicOrZero()),
 | 
			
		||||
      competence: duplicate(this.getDraconicOuPossession()),
 | 
			
		||||
      canClose: false,
 | 
			
		||||
      rencontre: duplicate(TMRRencontres.getRencontre('rdd')),
 | 
			
		||||
      tmr: true,
 | 
			
		||||
@@ -1472,10 +1489,8 @@ export class RdDActor extends Actor {
 | 
			
		||||
  isTMRCache() {
 | 
			
		||||
    return this.data.data.reve.tmrpos.cache;
 | 
			
		||||
  }
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async cacheTMRetMessage() {
 | 
			
		||||
    await this.reinsertionAleatoire("Action MJ");
 | 
			
		||||
    await this.cacheTMR();
 | 
			
		||||
 | 
			
		||||
  notifyRefreshTMR() {
 | 
			
		||||
    game.socket.emit(SYSTEM_SOCKET_ID, {
 | 
			
		||||
      msg: "msg_tmr_move", data: {
 | 
			
		||||
        actorId: this.data._id,
 | 
			
		||||
@@ -1487,27 +1502,27 @@ export class RdDActor extends Actor {
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async afficheTMRetMessage() {
 | 
			
		||||
    await this.montreTMR();
 | 
			
		||||
    game.socket.emit(SYSTEM_SOCKET_ID, {
 | 
			
		||||
      msg: "msg_tmr_move", data: {
 | 
			
		||||
        actorId: this.data._id,
 | 
			
		||||
        tmrPos: this.data.data.reve.tmrpos
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    this.notifyRefreshTMR();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async reinsertionAleatoire(raison) {
 | 
			
		||||
  async reinsertionAleatoire(raison, accessible = tmr => true) {
 | 
			
		||||
    const innaccessible = this.buildTMRInnaccessible();
 | 
			
		||||
    let tmr = await TMRUtility.getTMRAleatoire(tmr => accessible(tmr) && !innaccessible.includes(tmr.coord));
 | 
			
		||||
    ChatMessage.create({
 | 
			
		||||
      content: `${raison} : ré-insertion aléatoire.`,
 | 
			
		||||
      whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name)
 | 
			
		||||
    });
 | 
			
		||||
    const innaccessible = this.buildTMRInnaccessible();
 | 
			
		||||
    let tmr = await TMRUtility.getTMRAleatoire(tmr => !innaccessible.includes(tmr.coord));
 | 
			
		||||
    this.updateCoordTMR(tmr.coord);
 | 
			
		||||
    this.cacheTMR();
 | 
			
		||||
    await this.forcerPositionTMRInconnue(tmr);
 | 
			
		||||
    return tmr;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async forcerPositionTMRInconnue(tmr) {
 | 
			
		||||
    await this.cacheTMR();
 | 
			
		||||
    await this.updateCoordTMR(tmr.coord);
 | 
			
		||||
    this.notifyRefreshTMR();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  buildTMRInnaccessible() {
 | 
			
		||||
    const tmrInnaccessibles = this.filterItemsData(it => Draconique.isCaseTMR(it) &&
 | 
			
		||||
@@ -1611,7 +1626,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async setSonne(sonne = true) {
 | 
			
		||||
    if (this.isEntiteCauchemar()) {
 | 
			
		||||
    if (this.isEntite()) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!game.combat && sonne) {
 | 
			
		||||
@@ -1623,7 +1638,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  getSConst() {
 | 
			
		||||
    if (this.isEntiteCauchemar()) {
 | 
			
		||||
    if (this.isEntite()) {
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    return RdDCarac.calculSConst(Misc.templateData(this).carac.constitution.value);
 | 
			
		||||
@@ -1740,7 +1755,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
    result.newValue = Math.max(minValue, Math.min(compteur.value + inc, compteur.max));
 | 
			
		||||
    //console.log("New value ", inc, minValue, result.newValue);
 | 
			
		||||
    let fatigue = 0;
 | 
			
		||||
    if (name == "endurance" && !this.isEntiteCauchemar()) {
 | 
			
		||||
    if (name == "endurance" && !this.isEntite()) {
 | 
			
		||||
      if (result.newValue == 0 && inc < 0 && !isCritique) { // perte endurance et endurance devient 0 (sauf critique) -> -1 vie
 | 
			
		||||
        sante.vie.value--;
 | 
			
		||||
        result.perteVie = true;
 | 
			
		||||
@@ -1777,7 +1792,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  isDead() {
 | 
			
		||||
    return !this.isEntiteCauchemar() && Misc.templateData(this).sante.vie.value < -this.getSConst()
 | 
			
		||||
    return !this.isEntite() && Misc.templateData(this).sante.vie.value < -this.getSConst()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
@@ -2403,7 +2418,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async checkSoufflePeage(tmr) {
 | 
			
		||||
    if ((tmr.type == 'pont' || tmr.type == 'cite') && EffetsDraconiques.isPeage(actor)) {
 | 
			
		||||
    if ((tmr.type == 'pont' || tmr.type == 'cite') && EffetsDraconiques.isPeage(this)) {
 | 
			
		||||
      await this.reveActuelIncDec(-1);
 | 
			
		||||
      ChatMessage.create({
 | 
			
		||||
        content: "Vous êtes sous le coup d'un Péage : l'entrée sur cette case vous a coûté 1 Point de Rêve (déduit automatiquement).",
 | 
			
		||||
@@ -2540,9 +2555,9 @@ export class RdDActor extends Actor {
 | 
			
		||||
    if (rollData.competence.type == 'competencecreature') {
 | 
			
		||||
      if (rollData.competence.data.iscombat) {
 | 
			
		||||
        if (rollData.competence.data.ispossession) {
 | 
			
		||||
          RdDPossession.managePossession(this, rollData.competence)
 | 
			
		||||
          RdDPossession.onAttaquePossession(this, rollData.competence)
 | 
			
		||||
        } else {
 | 
			
		||||
          const arme = RdDItemCompetenceCreature.toArme(rollData.competence)
 | 
			
		||||
          const arme = RdDItemCompetenceCreature.toActionArme(rollData.competence)
 | 
			
		||||
          RdDCombat.createUsingTarget(this)?.attaque(competence, arme)
 | 
			
		||||
        }
 | 
			
		||||
        return
 | 
			
		||||
@@ -2568,8 +2583,8 @@ export class RdDActor extends Actor {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  conjurerPossession(possession) {
 | 
			
		||||
    let draconic = this.getBestDraconic()
 | 
			
		||||
    RdDPossession.managePossession(this, draconic, possession)
 | 
			
		||||
    let draconic = this.getDraconicOuPossession();
 | 
			
		||||
    RdDPossession.onAttaquePossession(this, draconic, possession)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
@@ -2838,20 +2853,19 @@ export class RdDActor extends Actor {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async _meditationResult(meditationData) {
 | 
			
		||||
  async _meditationResult(meditationRoll) {
 | 
			
		||||
    this.santeIncDec("fatigue", 2);
 | 
			
		||||
 | 
			
		||||
    const signeData = RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditationData.meditation, meditationData.rolled)
 | 
			
		||||
    if (signeData) {
 | 
			
		||||
      await this.createEmbeddedDocuments("Item", [signeData]);
 | 
			
		||||
    if (meditationRoll.rolled.isSuccess) {
 | 
			
		||||
      await this.createEmbeddedDocuments("Item", [RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditationRoll.meditation, meditationRoll.rolled)]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    await RdDResolutionTable.displayRollData(meditationData, this.name, 'chat-resultat-meditation.html');
 | 
			
		||||
    await RdDResolutionTable.displayRollData(meditationRoll, this.name, 'chat-resultat-meditation.html');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  _meditationEPart(meditationData) {
 | 
			
		||||
    this.updateEmbeddedDocuments('Item', [{ _id: meditationData._id, 'data.malus': meditationData.meditation.data.malus - 1 }]);
 | 
			
		||||
  _meditationEPart(meditationRoll) {
 | 
			
		||||
    this.updateEmbeddedDocuments('Item', [{ _id: meditationRoll.meditation._id, 'data.malus': meditationRoll.meditation.data.malus - 1 }]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -3133,7 +3147,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
        return carac.chance;
 | 
			
		||||
    }
 | 
			
		||||
    let entry = Misc.findFirstLike(name, Object.entries(carac), { mapper: it => it[1].label, description: 'caractéristique' });
 | 
			
		||||
    return entry.length > 0 ? carac[entry[0]] : undefined;
 | 
			
		||||
    return entry && entry.length > 0 ? carac[entry[0]] : undefined;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
@@ -3154,9 +3168,9 @@ export class RdDActor extends Actor {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  refreshTMRView(tmrData) {
 | 
			
		||||
  refreshTMRView() {
 | 
			
		||||
    if (this.currentTMR) {
 | 
			
		||||
      this.currentTMR.externalRefresh(tmrData)
 | 
			
		||||
      this.currentTMR.externalRefresh();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -3209,7 +3223,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
    let competence = Misc.data(this.getCompetence(arme.data.competence));
 | 
			
		||||
    if (arme || (competence.type == 'competencecreature' && competence.data.iscombat)) {
 | 
			
		||||
      if (competence.data.ispossession) {
 | 
			
		||||
        RdDPossession.managePossession(this, competence);
 | 
			
		||||
        RdDPossession.onAttaquePossession(this, competence);
 | 
			
		||||
      } else {
 | 
			
		||||
        RdDCombat.createUsingTarget(this)?.attaque(competence, arme);
 | 
			
		||||
      }
 | 
			
		||||
@@ -3278,11 +3292,11 @@ export class RdDActor extends Actor {
 | 
			
		||||
    protection = Math.max(protection - penetration, 0);
 | 
			
		||||
    protection += this.getProtectionNaturelle();
 | 
			
		||||
    // Gestion des cas particuliers sur la fenêtre d'encaissement
 | 
			
		||||
    if (attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "noarmure") {
 | 
			
		||||
    if (attackerRoll.dmg.encaisserSpecial == "noarmure") {
 | 
			
		||||
      protection = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (attackerRoll.dmg.encaisserSpecial && attackerRoll.dmg.encaisserSpecial == "chute" && Number(protection) > 2) {
 | 
			
		||||
      protection = 2;
 | 
			
		||||
    if (attackerRoll.dmg.encaisserSpecial == "chute") {
 | 
			
		||||
      protection = Math.min(protection, 2);
 | 
			
		||||
    }
 | 
			
		||||
    console.log("Final protect", protection, attackerRoll);
 | 
			
		||||
    return protection;
 | 
			
		||||
@@ -3290,20 +3304,25 @@ export class RdDActor extends Actor {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  _deteriorerArmure(item, dmg) {
 | 
			
		||||
    if (!ReglesOptionelles.isUsing('deteriorationArmure')) {
 | 
			
		||||
    let itemData = duplicate(Misc.data(item));
 | 
			
		||||
    if (!ReglesOptionelles.isUsing('deteriorationArmure') || itemData.data.protection == '0') {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    let itemData = duplicate(Misc.data(item));
 | 
			
		||||
    itemData.data.deterioration = (itemData.data.deterioration ?? 0) + dmg;
 | 
			
		||||
    if (itemData.data.deterioration >= 10) {
 | 
			
		||||
      itemData.data.deterioration = 0;
 | 
			
		||||
      let res = /\d+/.exec(itemData.data.protection);
 | 
			
		||||
      if (!res) {
 | 
			
		||||
        itemData.data.protection = "1d" + itemData.data.protection;
 | 
			
		||||
      itemData.data.deterioration -= 10;
 | 
			
		||||
      let res = /(\d+)?d(\d+)(\-\d+)?/.exec(itemData.data.protection);
 | 
			
		||||
      if (res) {
 | 
			
		||||
        let malus = Misc.toInt(res[3]) - 1;
 | 
			
		||||
        let armure = Misc.toInt(res[2]);
 | 
			
		||||
        if (armure+malus <= 0){
 | 
			
		||||
          itemData.data.protection = 0;
 | 
			
		||||
        } else {
 | 
			
		||||
          itemData.data.protection = '' + (res[1]??'1') + 'd' + armure + malus;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      else if (res = /(\d+d\d+)(\-\d+)?/.exec(itemData.data.protection)) {
 | 
			
		||||
        let malus = Misc.toInt(res[2]) - 1;
 | 
			
		||||
        itemData.data.protection = res[1] + malus;
 | 
			
		||||
      else if (/\d+/.exec(itemData.data.protection)) {
 | 
			
		||||
        itemData.data.protection = "1d" + itemData.data.protection;
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        ui.notifications.warn(`La valeur d'armure de votre ${item.name} est incorrecte`);
 | 
			
		||||
@@ -3332,7 +3351,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
    let encaissement = await this.jetEncaissement(rollData);
 | 
			
		||||
 | 
			
		||||
    this.ajouterBlessure(encaissement); // Will upate the result table
 | 
			
		||||
    const perteVie = this.isEntiteCauchemar()
 | 
			
		||||
    const perteVie = this.isEntite()
 | 
			
		||||
      ? { newValue: 0 }
 | 
			
		||||
      : await this.santeIncDec("vie", - encaissement.vie);
 | 
			
		||||
    const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, encaissement.critiques > 0);
 | 
			
		||||
@@ -3347,7 +3366,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
      sonne: perteEndurance.sonne,
 | 
			
		||||
      jetEndurance: perteEndurance.jetEndurance,
 | 
			
		||||
      endurance: santeOrig.endurance.value - perteEndurance.newValue,
 | 
			
		||||
      vie: this.isEntiteCauchemar() ? 0 : (santeOrig.vie.value - perteVie.newValue),
 | 
			
		||||
      vie: this.isEntite() ? 0 : (santeOrig.vie.value - perteVie.newValue),
 | 
			
		||||
      show: defenderRoll?.show ?? {}
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@@ -3537,8 +3556,8 @@ export class RdDActor extends Actor {
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async accorder(entite, when = 'avant-encaissement') {
 | 
			
		||||
    if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
 | 
			
		||||
      || !entite.isEntiteCauchemar()
 | 
			
		||||
      || entite.isEntiteCauchemarAccordee(this)) {
 | 
			
		||||
      || !entite.isEntite([ENTITE_INCARNE])
 | 
			
		||||
      || entite.isEntiteAccordee(this)) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    const tplData = Misc.templateData(this);
 | 
			
		||||
@@ -3562,29 +3581,30 @@ export class RdDActor extends Actor {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  isEntiteCauchemar() {
 | 
			
		||||
    return this.data.type == 'entite';
 | 
			
		||||
  isEntite(typeentite = [] ) {
 | 
			
		||||
    return this.data.type == 'entite' && (typeentite.length == 0 || typeentite.includes(this.data.data.typeentite));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  isEntiteCauchemarAccordee(attaquant) {
 | 
			
		||||
    if (!this.isEntiteCauchemar()) { return true; }
 | 
			
		||||
  isEntiteAccordee(attaquant) {
 | 
			
		||||
    if (!this.isEntite([ENTITE_INCARNE]))
 | 
			
		||||
    { return true; }
 | 
			
		||||
    let resonnance = Misc.templateData(this).sante.resonnance;
 | 
			
		||||
    return (resonnance.actors.find(it => it == attaquant._id));
 | 
			
		||||
    return (resonnance.actors.find(it => it == attaquant.id));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async setEntiteReveAccordee(attaquant) {
 | 
			
		||||
    if (!this.isEntiteCauchemar()) {
 | 
			
		||||
    if (!this.isEntite([ENTITE_INCARNE])) {
 | 
			
		||||
      ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entite de cauchemer/rêve");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    let resonnance = duplicate(Misc.templateData(this).sante.resonnance);
 | 
			
		||||
    if (resonnance.actors.find(it => it == attaquant._id)) {
 | 
			
		||||
    if (resonnance.actors.find(it => it == attaquant.id)) {
 | 
			
		||||
      // déjà accordé
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    resonnance.actors.push(attaquant._id);
 | 
			
		||||
    resonnance.actors.push(attaquant.id);
 | 
			
		||||
    await this.update({ "data.sante.resonnance": resonnance });
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
@@ -4138,7 +4158,7 @@ export class RdDActor extends Actor {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async setStatusEffect(label, status, updates = {}) {
 | 
			
		||||
    if (this.isEntiteCauchemar() || this.data.type == 'vehicule') {
 | 
			
		||||
    if (this.isEntite() || this.data.type == 'vehicule') {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    console.log("setStatusEffect", label, status, updates)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,3 +3,7 @@ export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon';
 | 
			
		||||
 | 
			
		||||
export const HIDE_DICE = 'hide';
 | 
			
		||||
export const SHOW_DICE = 'show';
 | 
			
		||||
 | 
			
		||||
export const ENTITE_INCARNE = 'incarne';
 | 
			
		||||
export const ENTITE_NONINCARNE = 'nonincarne';
 | 
			
		||||
export const ENTITE_BLURETTE = 'blurette';
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,7 @@ export class DialogItemAchat extends Dialog {
 | 
			
		||||
 | 
			
		||||
  static prepareVenteData(buttonAcheter, vendeurId, vendeur, acheteur) {
 | 
			
		||||
    const jsondata = buttonAcheter.attributes['data-jsondata']?.value;
 | 
			
		||||
    const prixLot = buttonAcheter.attributes['data-prixLot']?.value ?? 0;
 | 
			
		||||
    const prixLot = parseInt(buttonAcheter.attributes['data-prixLot']?.value ?? 0);
 | 
			
		||||
    let venteData = {
 | 
			
		||||
      item: JSON.parse(jsondata),
 | 
			
		||||
      vendeurId: vendeurId,
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ export class RdDItemArme extends Item {
 | 
			
		||||
    switch (armeData ? armeData.type : '') {
 | 
			
		||||
      case 'arme': return armeData;
 | 
			
		||||
      case 'competencecreature':
 | 
			
		||||
        return RdDItemCompetenceCreature.toArme(armeData);
 | 
			
		||||
        return RdDItemCompetenceCreature.toActionArme(armeData);
 | 
			
		||||
    }
 | 
			
		||||
    return RdDItemArme.mainsNues();
 | 
			
		||||
  }
 | 
			
		||||
@@ -189,7 +189,7 @@ export class RdDItemArme extends Item {
 | 
			
		||||
        categorie_parade: 'sans-armes'
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
    mergeObject(corpsACorps.data, actorData ??{}, { overwrite: false });
 | 
			
		||||
    mergeObject(corpsACorps.data, actorData ?? {}, { overwrite: false });
 | 
			
		||||
    return corpsACorps;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -212,8 +212,11 @@ export class RdDItemCompetence extends Item {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static findCompetence(list, idOrName, options = {}) {
 | 
			
		||||
    if (idOrName == undefined) {
 | 
			
		||||
      return undefined;
 | 
			
		||||
    }
 | 
			
		||||
    options = mergeObject(options, {
 | 
			
		||||
      filter: it => RdDItemCompetence.isCompetence(it),
 | 
			
		||||
      preFilter: it => RdDItemCompetence.isCompetence(it),
 | 
			
		||||
      description: 'compétence',
 | 
			
		||||
    });
 | 
			
		||||
    return list.find(it => it.id == idOrName && RdDItemCompetence.isCompetence(it))
 | 
			
		||||
 
 | 
			
		||||
@@ -11,14 +11,14 @@ export class RdDItemCompetenceCreature extends Item {
 | 
			
		||||
    rollData.competence.data.categorie = "creature"
 | 
			
		||||
    rollData.selectedCarac =  rollData.carac.carac_creature
 | 
			
		||||
    if (rollData.competence.data.iscombat) {
 | 
			
		||||
      rollData.arme = RdDItemCompetenceCreature.toArme(rollData.competence);
 | 
			
		||||
      rollData.arme = RdDItemCompetenceCreature.toActionArme(rollData.competence);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static toArme(item) {
 | 
			
		||||
  static toActionArme(item) {
 | 
			
		||||
    if (RdDItemCompetenceCreature.isCompetenceAttaque(item)) {
 | 
			
		||||
      // si c'est un Item compétence: cloner pour ne pas modifier lma compétence
 | 
			
		||||
      // si c'est un Item compétence: cloner pour ne pas modifier la compétence
 | 
			
		||||
      let arme = Misc.data( (item instanceof Item) ? item.clone():  item);
 | 
			
		||||
      mergeObject(arme.data,
 | 
			
		||||
        {
 | 
			
		||||
@@ -28,11 +28,12 @@ export class RdDItemCompetenceCreature extends Item {
 | 
			
		||||
          dommagesReels: arme.data.dommages,
 | 
			
		||||
          penetration: 0,
 | 
			
		||||
          force: 0,
 | 
			
		||||
          rapide: true
 | 
			
		||||
          rapide: true,
 | 
			
		||||
          action: 'attaque'
 | 
			
		||||
        });
 | 
			
		||||
      return arme;
 | 
			
		||||
    }
 | 
			
		||||
    console.error("RdDItemCompetenceCreature.toArme(", item, ") : impossible de transformer l'Item en arme");
 | 
			
		||||
    console.error("RdDItemCompetenceCreature.toActionArme(", item, ") : impossible de transformer l'Item en arme");
 | 
			
		||||
    return undefined;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ export class RdDItemMeditation {
 | 
			
		||||
  static calculDifficulte(rollData) {
 | 
			
		||||
    if (rollData.meditation) {
 | 
			
		||||
      // Malus permanent éventuel
 | 
			
		||||
      let diff = -rollData.meditation.data.malus ?? 0;
 | 
			
		||||
      let diff = rollData.meditation.data.malus ?? 0;
 | 
			
		||||
      if (!rollData.conditionMeditation.isHeure) diff -= 2;
 | 
			
		||||
      if (!rollData.conditionMeditation.isVeture) diff -= 2;
 | 
			
		||||
      if (!rollData.conditionMeditation.isComportement) diff -= 2;
 | 
			
		||||
 
 | 
			
		||||
@@ -13,25 +13,24 @@ const tableSignesIndicatifs = [
 | 
			
		||||
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const DIFFICULTE_LECTURE_SIGNE_MANQUE = +11;
 | 
			
		||||
 | 
			
		||||
export class RdDItemSigneDraconique {
 | 
			
		||||
 | 
			
		||||
  static prepareSigneDraconiqueMeditation(meditation, rolled) {
 | 
			
		||||
    if (rolled.isSuccess != undefined) {
 | 
			
		||||
      meditation = Misc.data(meditation);
 | 
			
		||||
      return {
 | 
			
		||||
        name: "de la " + meditation.name,
 | 
			
		||||
        type: "signedraconique",
 | 
			
		||||
        img: meditation.img,
 | 
			
		||||
        data: {
 | 
			
		||||
          typesTMR: [TMRUtility.typeTmrName(meditation.data.tmr)],
 | 
			
		||||
          difficulte: RdDItemSigneDraconique.getDiffSigneMeditation(rolled.code),
 | 
			
		||||
          ephemere: true,
 | 
			
		||||
          duree: "1 round",
 | 
			
		||||
          valeur: { "norm": 3, "sign": 5, "part": 10 }
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
    return undefined;
 | 
			
		||||
    meditation = Misc.data(meditation);
 | 
			
		||||
    return {
 | 
			
		||||
      name: "de la " + meditation.name,
 | 
			
		||||
      type: "signedraconique",
 | 
			
		||||
      img: meditation.img,
 | 
			
		||||
      data: {
 | 
			
		||||
        typesTMR: [TMRUtility.typeTmrName(meditation.data.tmr)],
 | 
			
		||||
        difficulte: rolled.isSuccess ? RdDItemSigneDraconique.getDiffSigneMeditation(rolled.code) : DIFFICULTE_LECTURE_SIGNE_MANQUE,
 | 
			
		||||
        ephemere: true,
 | 
			
		||||
        duree: "1 round",
 | 
			
		||||
        valeur: rolled.isSuccess ? { "norm": 3, "sign": 5, "part": 10 } : { "norm": 0, "sign": 0, "part": 0 }
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static getDiffSigneMeditation(code) {
 | 
			
		||||
@@ -44,7 +43,7 @@ export class RdDItemSigneDraconique {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static getXpSortSigneDraconique(code, signe) {
 | 
			
		||||
    return Misc.data(signe).data.valeur[code] ?? 0;
 | 
			
		||||
    return Misc.toInt(Misc.data(signe).data.valeur[code] ?? 0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static calculValeursXpSort(qualite, valeur, avant) {
 | 
			
		||||
 
 | 
			
		||||
@@ -192,7 +192,7 @@ export class Misc {
 | 
			
		||||
    if (!single) {
 | 
			
		||||
      single = subset[0];
 | 
			
		||||
      const choices = Misc.join(subset.map(it => options.mapper(it)), '<br>');
 | 
			
		||||
      options.info(`Plusieurs choix de ${options.description}s possibles:<br>${choices}<br>Le premier sera choisi: ${mapToValue(single)}`);
 | 
			
		||||
      options.onMessage(`Plusieurs choix de ${options.description}s possibles:<br>${choices}<br>Le premier sera choisi: ${options.mapper(single)}`);
 | 
			
		||||
    }
 | 
			
		||||
    return single;
 | 
			
		||||
  }
 | 
			
		||||
@@ -211,7 +211,7 @@ export class Misc {
 | 
			
		||||
    }
 | 
			
		||||
    value = Grammar.toLowerCaseNoAccent(value);
 | 
			
		||||
    const subset = elements.filter(options.preFilter)
 | 
			
		||||
      .filter(it => Grammar.toLowerCaseNoAccent(options.mapper(it)).includes(value));
 | 
			
		||||
      .filter(it => Grammar.toLowerCaseNoAccent(options.mapper(it))?.includes(value));
 | 
			
		||||
    if (subset.length == 0) {
 | 
			
		||||
      options.onMessage(`Pas de ${options.description} correspondant à ${value}`);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { ChatUtility } from "./chat-utility.js";
 | 
			
		||||
import { HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
 | 
			
		||||
import { ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
 | 
			
		||||
import { Grammar } from "./grammar.js";
 | 
			
		||||
import { RdDItemArme } from "./item-arme.js";
 | 
			
		||||
import { RdDItemCompetence } from "./item-competence.js";
 | 
			
		||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
 | 
			
		||||
@@ -26,7 +27,7 @@ const premierRoundInit = [
 | 
			
		||||
  { pattern: 'epeegnome', init: 5.35 },
 | 
			
		||||
  { pattern: 'masse', init: 5.30 },
 | 
			
		||||
  { pattern: 'gourdin', init: 5.25 },
 | 
			
		||||
  { pattern: 'fléau', init: 5.20 },
 | 
			
		||||
  { pattern: 'fleau', init: 5.20 },
 | 
			
		||||
  { pattern: 'dague', init: 5.15 },
 | 
			
		||||
  { pattern: 'autre', init: 5.10 },
 | 
			
		||||
];
 | 
			
		||||
@@ -84,28 +85,23 @@ export class RdDCombatManager extends Combat {
 | 
			
		||||
    // calculate initiative
 | 
			
		||||
    for (let cId = 0; cId < ids.length; cId++) {
 | 
			
		||||
      const combatant = this.combatants.get(ids[cId]);
 | 
			
		||||
      //if (!c) return results;
 | 
			
		||||
 | 
			
		||||
      let rollFormula = formula; // Init per default
 | 
			
		||||
      if (!rollFormula) {
 | 
			
		||||
        let armeCombat, competence;
 | 
			
		||||
      let rollFormula = formula ?? RdDCombatManager.formuleInitiative(2, 10, 0, 0);
 | 
			
		||||
      if (!formula) {
 | 
			
		||||
        if (combatant.actor.data.type == 'creature' || combatant.actor.data.type == 'entite') {
 | 
			
		||||
          for (const competenceItemData of combatant.actor.data.items) {
 | 
			
		||||
            if (competenceItemData.data.data.iscombat) {
 | 
			
		||||
              competence = duplicate(competenceItemData);
 | 
			
		||||
            }
 | 
			
		||||
          const competence = combatant.actor.data.items.find(it => it.data.data.iscombat)
 | 
			
		||||
          if (competence) {
 | 
			
		||||
            rollFormula = RdDCombatManager.formuleInitiative(2, competence.data.carac_value, competence.data.niveau, 0);
 | 
			
		||||
          }
 | 
			
		||||
          rollFormula = "2+( (" + RdDCombatManager.calculInitiative(competence.data.niveau, competence.data.carac_value) + ")/100)";
 | 
			
		||||
        } else {
 | 
			
		||||
          for (const itemData of combatant.actor.data.items) {
 | 
			
		||||
            if (itemData.type == "arme" && itemData.data.equipe) {
 | 
			
		||||
              armeCombat = duplicate(itemData);
 | 
			
		||||
            }
 | 
			
		||||
          const armeCombat = combatant.actor.data.items.find(it => it.type == 'arme' && itemData.data.equipe)
 | 
			
		||||
          const compName = (armeCombat == undefined) ? "Corps à corps" : armeCombat.data.competence;
 | 
			
		||||
          const competence = RdDItemCompetence.findCompetence(combatant.actor.data.items, compName);
 | 
			
		||||
          if (competence) {
 | 
			
		||||
            const carac = combatant.actor.data.data.carac[competence.data.defaut_carac].value;
 | 
			
		||||
            const niveau = competence.data.niveau;
 | 
			
		||||
            const bonusEcaille = (armeCombat?.data.magique) ? armeCombat.data.ecaille_efficacite : 0;
 | 
			
		||||
            rollFormula = RdDCombatManager.formuleInitiative(2,  carac, niveau, bonusEcaille);
 | 
			
		||||
          }
 | 
			
		||||
          let compName = (armeCombat == undefined) ? "Corps à corps" : armeCombat.data.competence;
 | 
			
		||||
          competence = RdDItemCompetence.findCompetence(combatant.actor.data.items, compName);
 | 
			
		||||
          let bonusEcaille = (armeCombat && armeCombat.data.magique) ? armeCombat.data.ecaille_efficacite : 0;
 | 
			
		||||
          rollFormula = "2+( (" + RdDCombatManager.calculInitiative(competence.data.niveau, Misc.data(combatant.actor).data.carac[competence.data.defaut_carac].value, bonusEcaille) + ")/100)";
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      //console.log("Combatat", c);
 | 
			
		||||
@@ -142,6 +138,10 @@ export class RdDCombatManager extends Combat {
 | 
			
		||||
    return this;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static formuleInitiative(rang, carac, niveau, bonusMalus) {
 | 
			
		||||
    return `${rang} +( (${RdDCombatManager.calculInitiative(niveau, carac, bonusMalus)} )/100)`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static calculInitiative(niveau, caracValue, bonusEcaille = 0) {
 | 
			
		||||
    let base = niveau + Math.floor(caracValue / 2);
 | 
			
		||||
@@ -150,63 +150,77 @@ export class RdDCombatManager extends Combat {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  /** Retourne une liste triée d'armes avec le split arme1 main / arme 2 main */
 | 
			
		||||
  static finalizeArmeList(armes, competences, carac) {
 | 
			
		||||
  /** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main */
 | 
			
		||||
  static listActionsArmes(armes, competences, carac) {
 | 
			
		||||
    // Gestion des armes 1/2 mains
 | 
			
		||||
    let armesEquipe = [];
 | 
			
		||||
    let actionsArme = [];
 | 
			
		||||
    for (const arme of armes) {
 | 
			
		||||
      let armeData = duplicate(Misc.data(arme));
 | 
			
		||||
      if (armeData.data.equipe) {
 | 
			
		||||
        let compData = competences.map(c => Misc.data(c)).find(c => c.name == armeData.data.competence);
 | 
			
		||||
      let action = duplicate(Misc.data(arme));
 | 
			
		||||
      if (action.data.equipe) {
 | 
			
		||||
        let compData = competences.map(c => Misc.data(c)).find(c => c.name == action.data.competence);
 | 
			
		||||
 | 
			
		||||
        armesEquipe.push(armeData);
 | 
			
		||||
        armeData.data.dommagesReels = Number(armeData.data.dommages);
 | 
			
		||||
        armeData.data.niveau = compData.data.niveau;
 | 
			
		||||
        armeData.data.initiative = RdDCombatManager.calculInitiative(compData.data.niveau, carac[compData.data.defaut_carac].value);
 | 
			
		||||
        actionsArme.push(action);
 | 
			
		||||
        action.action = 'attaque';
 | 
			
		||||
        action.data.dommagesReels = Number(action.data.dommages);
 | 
			
		||||
        action.data.niveau = compData.data.niveau;
 | 
			
		||||
        action.data.initiative = RdDCombatManager.calculInitiative(compData.data.niveau, carac[compData.data.defaut_carac].value);
 | 
			
		||||
        // Dupliquer les armes pouvant être à 1 main et 2 mains en patchant la compétence
 | 
			
		||||
        if (armeData.data.unemain && !armeData.data.deuxmains) {
 | 
			
		||||
          armeData.data.mainInfo = "(1m)";
 | 
			
		||||
        } else if (!armeData.data.unemain && armeData.data.deuxmains) {
 | 
			
		||||
          armeData.data.mainInfo = "(2m)";
 | 
			
		||||
        } else if (armeData.data.unemain && armeData.data.deuxmains) {
 | 
			
		||||
          armeData.data.mainInfo = "(1m)";
 | 
			
		||||
        if (action.data.unemain && !action.data.deuxmains) {
 | 
			
		||||
          action.data.mainInfo = "(1m)";
 | 
			
		||||
        } else if (!action.data.unemain && action.data.deuxmains) {
 | 
			
		||||
          action.data.mainInfo = "(2m)";
 | 
			
		||||
        } else if (action.data.unemain && action.data.deuxmains) {
 | 
			
		||||
          action.data.mainInfo = "(1m)";
 | 
			
		||||
 | 
			
		||||
          const comp2m = armeData.data.competence.replace(" 1 main", " 2 mains"); // Replace !
 | 
			
		||||
          const comp2m = action.data.competence.replace(" 1 main", " 2 mains"); // Replace !
 | 
			
		||||
          const comp = Misc.data(competences.find(c => c.name == comp2m));
 | 
			
		||||
 | 
			
		||||
          const arme2main = duplicate(armeData);
 | 
			
		||||
          const arme2main = duplicate(action);
 | 
			
		||||
          arme2main.data.mainInfo = "(2m)";
 | 
			
		||||
          arme2main.data.niveau = comp.data.niveau;
 | 
			
		||||
          arme2main.data.competence = comp2m;
 | 
			
		||||
          arme2main.data.initiative = RdDCombatManager.calculInitiative(arme2main.data.niveau, carac[comp.data.defaut_carac].value);
 | 
			
		||||
          armesEquipe.push(arme2main);
 | 
			
		||||
          const containsSlash = armeData.data.dommages.includes("/");
 | 
			
		||||
          actionsArme.push(arme2main);
 | 
			
		||||
          const containsSlash = action.data.dommages.includes("/");
 | 
			
		||||
          if (containsSlash) {
 | 
			
		||||
            const tableauDegats = armeData.data.dommages.split("/");
 | 
			
		||||
            armeData.data.dommagesReels = Number(tableauDegats[0]);
 | 
			
		||||
            const tableauDegats = action.data.dommages.split("/");
 | 
			
		||||
            action.data.dommagesReels = Number(tableauDegats[0]);
 | 
			
		||||
            arme2main.data.dommagesReels = Number(tableauDegats[1]);
 | 
			
		||||
          }
 | 
			
		||||
          else{
 | 
			
		||||
            ui.notifications.info("Les dommages de l'arme à 1/2 mains " + armeData.name + " ne sont pas corrects (ie sous la forme X/Y)");
 | 
			
		||||
            ui.notifications.info("Les dommages de l'arme à 1/2 mains " + action.name + " ne sont pas corrects (ie sous la forme X/Y)");
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return armesEquipe.sort(Misc.ascending(armeData => armeData.name + (armeData.data.mainInfo ?? '')));
 | 
			
		||||
    return actionsArme.sort(Misc.ascending(armeData => armeData.name + (armeData.data.mainInfo ?? '')));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static listActionsPossessions(actor) {
 | 
			
		||||
    return RdDCombatManager._indexActions(actor.getPossessions().map(p =>
 | 
			
		||||
      {
 | 
			
		||||
        return {
 | 
			
		||||
          name: p.name,
 | 
			
		||||
          action: 'conjurer',
 | 
			
		||||
          data: {
 | 
			
		||||
            competence: p.name,
 | 
			
		||||
            possessionid: p.data.data.possessionid,
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static buildListeActionsCombat(combatant) {
 | 
			
		||||
    if (combatant.actor == undefined) {
 | 
			
		||||
      ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
 | 
			
		||||
      return [];
 | 
			
		||||
  static listActionsCombat(combatant) {
 | 
			
		||||
    const actor = combatant.actor;
 | 
			
		||||
    let actions = RdDCombatManager.listActionsPossessions(actor);
 | 
			
		||||
    if (actions.length>0) {
 | 
			
		||||
      return actions;
 | 
			
		||||
    }
 | 
			
		||||
    const actorData = Misc.data(combatant.actor);
 | 
			
		||||
    let items = combatant.actor.data.items;
 | 
			
		||||
    let actions = []
 | 
			
		||||
    if (combatant.actor.isCreature()) {
 | 
			
		||||
    let items = actor.data.items;
 | 
			
		||||
    if (actor.isCreature()) {
 | 
			
		||||
      actions = actions.concat(items.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
 | 
			
		||||
        .map(competence => RdDItemCompetenceCreature.toArme(competence)));
 | 
			
		||||
        .map(competence => RdDItemCompetenceCreature.toActionArme(competence)));
 | 
			
		||||
    } else {
 | 
			
		||||
      // Recupération des items 'arme'
 | 
			
		||||
      let armes = items.filter(it => RdDItemArme.isArmeUtilisable(it))
 | 
			
		||||
@@ -214,14 +228,17 @@ export class RdDCombatManager extends Combat {
 | 
			
		||||
        .concat(RdDItemArme.mainsNues());
 | 
			
		||||
 | 
			
		||||
      let competences = items.filter(it => it.type == 'competence');
 | 
			
		||||
      actions = actions.concat(RdDCombatManager.finalizeArmeList(armes, competences, actorData.data.carac));
 | 
			
		||||
      actions = actions.concat(RdDCombatManager.listActionsArmes(armes, competences, actor.data.data.carac));
 | 
			
		||||
 | 
			
		||||
      if (actorData.data.attributs.hautrevant.value) {
 | 
			
		||||
        actions.push({ name: "Draconic", data: { initOnly: true, competence: "Draconic" } });
 | 
			
		||||
      if (actor.data.data.attributs.hautrevant.value) {
 | 
			
		||||
        actions.push({ name: "Draconic", action: 'haut-reve', data: { initOnly: true, competence: "Draconic" } });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actions.push({ name: "Autre action", data: { initOnly: true, competence: "Autre action" } });
 | 
			
		||||
    return RdDCombatManager._indexActions(actions);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static _indexActions(actions) {
 | 
			
		||||
    for (let index = 0; index < actions.length; index++) {
 | 
			
		||||
      actions[index].index = index;
 | 
			
		||||
    }
 | 
			
		||||
@@ -235,15 +252,15 @@ export class RdDCombatManager extends Combat {
 | 
			
		||||
      let initMissing = game.combat.data.combatants.find(it => !it.initiative);
 | 
			
		||||
      if (!initMissing) { // Premier round !
 | 
			
		||||
        for (let combatant of game.combat.data.combatants) {
 | 
			
		||||
          let arme = combatant.initiativeData?.arme;
 | 
			
		||||
          let action = combatant.initiativeData?.arme;
 | 
			
		||||
          //console.log("Parsed !!!", combatant, initDone, game.combat.current, arme);
 | 
			
		||||
          if (arme && arme.type == "arme") {
 | 
			
		||||
          if (action && action.type == "arme") {
 | 
			
		||||
            for (let initData of premierRoundInit) {
 | 
			
		||||
              if (arme.data.initpremierround.toLowerCase().includes(initData.pattern)) {
 | 
			
		||||
              if (Grammar.toLowerCaseNoAccentNoSpace(action.data.initpremierround).includes(initData.pattern)) {
 | 
			
		||||
                let msg = `<h4>L'initiative de ${combatant.actor.name} a été modifiée !</h4>
 | 
			
		||||
                      <hr>
 | 
			
		||||
                      <div>
 | 
			
		||||
                        Etant donné son ${arme.name}, son initative pour ce premier round est désormais de ${initData.init}.
 | 
			
		||||
                        Etant donné son ${action.name}, son initative pour ce premier round est désormais de ${initData.init}.
 | 
			
		||||
                      </div>`
 | 
			
		||||
                ChatMessage.create({ content: msg });
 | 
			
		||||
                game.combat.setInitiative(combatant._id, initData.init);
 | 
			
		||||
@@ -281,7 +298,7 @@ export class RdDCombatManager extends Combat {
 | 
			
		||||
    ].concat(options);
 | 
			
		||||
  }
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static rollInitiativeCompetence(combatantId, arme) {
 | 
			
		||||
  static rollInitiativeAction(combatantId, action) {
 | 
			
		||||
    const combatant = game.combat.combatants.get(combatantId);
 | 
			
		||||
    if (combatant.actor == undefined) {
 | 
			
		||||
      ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
 | 
			
		||||
@@ -299,34 +316,40 @@ export class RdDCombatManager extends Combat {
 | 
			
		||||
    } else if (combatant.actor.getSurprise() == "demi") {
 | 
			
		||||
      initOffset = 0;
 | 
			
		||||
      initInfo = "Demi Surprise"
 | 
			
		||||
    } else if (arme.name == "Autre action") {
 | 
			
		||||
    } else if (action.action == 'conjurer') {
 | 
			
		||||
      initOffset = 10;
 | 
			
		||||
      caracForInit = combatant.actor.getReveActuel();
 | 
			
		||||
      initInfo = "Possession"
 | 
			
		||||
    } else if (action.action == 'autre') {
 | 
			
		||||
      initOffset = 2;
 | 
			
		||||
      initInfo = "Autre Action"
 | 
			
		||||
    } else if (arme.name == "Draconic") {
 | 
			
		||||
    } else if (action.action == 'haut-reve') {
 | 
			
		||||
      initOffset = 9;
 | 
			
		||||
      initInfo = "Draconic"
 | 
			
		||||
    } else {
 | 
			
		||||
      compData = Misc.data(RdDItemCompetence.findCompetence(combatant.actor.data.items, arme.data.competence));
 | 
			
		||||
      compData = Misc.data(RdDItemCompetence.findCompetence(combatant.actor.data.items, action.data.competence));
 | 
			
		||||
      compNiveau = compData.data.niveau;
 | 
			
		||||
      initInfo = arme.name + " / " + arme.data.competence;
 | 
			
		||||
      if (combatant.actor.data.type == 'creature' || combatant.actor.data.type == 'entite') {
 | 
			
		||||
        caracForInit = compData.data.carac_value;
 | 
			
		||||
        if (compData.data.categorie == "lancer") {
 | 
			
		||||
          initOffset = 7;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          initOffset = 5;
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        caracForInit = Misc.data(combatant.actor).data.carac[compData.data.defaut_carac].value;
 | 
			
		||||
        initOffset = RdDCombatManager._baseInitOffset(compData.data.categorie, arme);
 | 
			
		||||
        initInfo = action.name + " / " + action.data.competence;
 | 
			
		||||
         
 | 
			
		||||
        if (combatant.actor.data.type == 'creature' || combatant.actor.data.type == 'entite') {
 | 
			
		||||
          caracForInit = compData.data.carac_value;
 | 
			
		||||
          if (compData.data.categorie == "lancer") {
 | 
			
		||||
            initOffset = 7;
 | 
			
		||||
          }
 | 
			
		||||
          else {
 | 
			
		||||
            initOffset = 5;
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          caracForInit = Misc.data(combatant.actor).data.carac[compData.data.defaut_carac].value;
 | 
			
		||||
          initOffset = RdDCombatManager._baseInitOffset(compData.data.categorie, action);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let malus = combatant.actor.getEtatGeneral(); // Prise en compte état général 
 | 
			
		||||
    // Cas des créatures et entités vs personnages
 | 
			
		||||
    let rollFormula = initOffset + "+ ( (" + RdDCombatManager.calculInitiative(compNiveau, caracForInit) + " + " + malus + ") /100)";
 | 
			
		||||
    let rollFormula = RdDCombatManager.formuleInitiative(initOffset, caracForInit, compNiveau, malus);
 | 
			
		||||
    // Garder la trace de l'arme/compétence utilisée pour l'iniative
 | 
			
		||||
    combatant.initiativeData = { arme: arme } // pour reclasser l'init au round 0
 | 
			
		||||
    combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0
 | 
			
		||||
    game.combat.rollInitiative(combatantId, rollFormula, { initInfo: initInfo });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -349,16 +372,21 @@ export class RdDCombatManager extends Combat {
 | 
			
		||||
  static displayInitiativeMenu(html, combatantId) {
 | 
			
		||||
    console.log("Combatant ; ", combatantId);
 | 
			
		||||
    const combatant = game.combat.combatants.get(combatantId);
 | 
			
		||||
    let armesList = RdDCombatManager.buildListeActionsCombat(combatant);
 | 
			
		||||
    if (! (combatant?.actor) ) {
 | 
			
		||||
      ui.notifications.warn(`Le combatant ${combatant.name ?? combatantId} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let actions = RdDCombatManager.listActionsCombat(combatant);
 | 
			
		||||
 | 
			
		||||
    // Build the relevant submenu
 | 
			
		||||
    if (armesList) {
 | 
			
		||||
    if (actions) {
 | 
			
		||||
      let menuItems = [];
 | 
			
		||||
      for (let arme of armesList) {
 | 
			
		||||
      for (let action of actions) {
 | 
			
		||||
        menuItems.push({
 | 
			
		||||
          name: arme.data.competence,
 | 
			
		||||
          name: action.data.competence,
 | 
			
		||||
          icon: "<i class='fas fa-dice-d6'></i>",
 | 
			
		||||
          callback: target => { RdDCombatManager.rollInitiativeCompetence(combatantId, arme) }
 | 
			
		||||
          callback: target => { RdDCombatManager.rollInitiativeAction(combatantId, action) }
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
      new ContextMenu(html, ".directory-list", menuItems).render();
 | 
			
		||||
@@ -429,7 +457,7 @@ export class RdDCombat {
 | 
			
		||||
    else {
 | 
			
		||||
      const defender = target?.actor;
 | 
			
		||||
      const defenderTokenId = target?.data._id;
 | 
			
		||||
      if ( defender.type == 'entite' && defender.data.data.definition.typeentite == 'nonincarne') {
 | 
			
		||||
      if ( defender.type == 'entite' && defender.data.data.definition.typeentite == ENTITE_NONINCARNE) {
 | 
			
		||||
        ui.notifications.warn("Vous ne pouvez pas cibler une entité non incarnée !!!!");
 | 
			
		||||
      } else {
 | 
			
		||||
        return this.create(attacker, defender, defenderTokenId, target)
 | 
			
		||||
@@ -465,15 +493,15 @@ export class RdDCombat {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static onMsgEncaisser(data) {
 | 
			
		||||
    let defender = canvas.tokens.get(data.defenderTokenId).actor;
 | 
			
		||||
  static onMsgEncaisser(msg) {
 | 
			
		||||
    let defender = canvas.tokens.get(msg.defenderTokenId).actor;
 | 
			
		||||
    if (Misc.isOwnerPlayerOrUniqueConnectedGM()) {
 | 
			
		||||
      let attackerRoll = data.attackerRoll;
 | 
			
		||||
      let attacker = data.attackerId ? game.actors.get(data.attackerId) : null;
 | 
			
		||||
      let attackerRoll = msg.attackerRoll;
 | 
			
		||||
      let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : null;
 | 
			
		||||
 | 
			
		||||
      defender.encaisserDommages(attackerRoll, attacker);
 | 
			
		||||
      RdDCombat._deleteDefense(attackerRoll.passeArme);
 | 
			
		||||
      RdDCombat._deleteAttaque(data.attackerId);
 | 
			
		||||
      const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
 | 
			
		||||
      rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -482,11 +510,8 @@ export class RdDCombat {
 | 
			
		||||
    let defenderToken = canvas.tokens.get(msg.defenderTokenId);
 | 
			
		||||
    if (defenderToken && Misc.isUniqueConnectedGM()) {
 | 
			
		||||
      const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
 | 
			
		||||
      if (rddCombat) {
 | 
			
		||||
        const defenderRoll = msg.defenderRoll;
 | 
			
		||||
        rddCombat.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
 | 
			
		||||
        rddCombat._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll);
 | 
			
		||||
      }
 | 
			
		||||
      rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme);
 | 
			
		||||
      rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -774,7 +799,7 @@ export class RdDCombat {
 | 
			
		||||
  async _onAttaqueNormale(attackerRoll) {
 | 
			
		||||
    console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll);
 | 
			
		||||
 | 
			
		||||
    attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntiteCauchemar());
 | 
			
		||||
    attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntite());
 | 
			
		||||
    let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
 | 
			
		||||
    attackerRoll.show = {
 | 
			
		||||
      cible: this.target ? this.defender.data.name : 'la cible',
 | 
			
		||||
@@ -1005,8 +1030,7 @@ export class RdDCombat {
 | 
			
		||||
    await this.computeRecul(defenderRoll);
 | 
			
		||||
    await this.computeDeteriorationArme(defenderRoll);
 | 
			
		||||
    await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.html');
 | 
			
		||||
 | 
			
		||||
    RdDCombat._deleteDefense(defenderRoll.passeArme);
 | 
			
		||||
    this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
@@ -1077,7 +1101,7 @@ export class RdDCombat {
 | 
			
		||||
  async _onEsquiveNormale(defenderRoll) {
 | 
			
		||||
    console.log("RdDCombat._onEsquiveNormal >>>", defenderRoll);
 | 
			
		||||
    await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html');
 | 
			
		||||
    RdDCombat._deleteDefense(defenderRoll.passeArme);
 | 
			
		||||
    this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
@@ -1217,7 +1241,6 @@ export class RdDCombat {
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    RdDCombat._deleteDefense(attackerRoll.passeArme);
 | 
			
		||||
    this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -1226,8 +1249,8 @@ export class RdDCombat {
 | 
			
		||||
  async accorderEntite(when = 'avant-encaissement') {
 | 
			
		||||
    if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
 | 
			
		||||
      || this.defender == undefined
 | 
			
		||||
      || !this.defender.isEntiteCauchemar()
 | 
			
		||||
      || this.defender.isEntiteCauchemarAccordee(this.attacker)) {
 | 
			
		||||
      || !this.defender.isEntite([ENTITE_INCARNE])
 | 
			
		||||
      || this.defender.isEntiteAccordee(this.attacker)) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import { RdDItemCompetence } from "./item-competence.js";
 | 
			
		||||
import { Misc } from "./misc.js";
 | 
			
		||||
import { RdDCarac } from "./rdd-carac.js";
 | 
			
		||||
import { RdDDice } from "./rdd-dice.js";
 | 
			
		||||
import { RdDMeteo } from "./rdd-meteo.js";
 | 
			
		||||
import { RdDNameGen } from "./rdd-namegen.js";
 | 
			
		||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
			
		||||
import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
 | 
			
		||||
@@ -34,6 +35,7 @@ export class RdDCommands {
 | 
			
		||||
      rddCommands.registerCommand({ path: ["/table", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle(true), descr: " Tire un Souffle de Dragon" });
 | 
			
		||||
      rddCommands.registerCommand({ path: ["/table", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence(true), descr: "Tire une compétence au hasard" });
 | 
			
		||||
      rddCommands.registerCommand({ path: ["/table", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot(true), descr: "Tire une carte du Tarot Draconique" });
 | 
			
		||||
      rddCommands.registerCommand({ path: ["/meteo"], func: (content, msg, params) => rddCommands.getMeteo(msg, params), descr: "Propose une météo marine" });
 | 
			
		||||
      rddCommands.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.getName(msg, params), descr: "Génère un nom aléatoire" });
 | 
			
		||||
 | 
			
		||||
      rddCommands.registerCommand({
 | 
			
		||||
@@ -274,9 +276,11 @@ export class RdDCommands {
 | 
			
		||||
          diff = 0;
 | 
			
		||||
        }
 | 
			
		||||
        const caracName = params[0];
 | 
			
		||||
        const compName = length > 1 ? Misc.join(params.slice(1, length), ' ') : undefined;
 | 
			
		||||
        for (let actor of actors) {
 | 
			
		||||
          await actor.rollCaracCompetence(caracName, compName, diff);
 | 
			
		||||
        let competence = length > 1 ? actors[0].getCompetence(Misc.join(params.slice(1, length), ' ')) : undefined;
 | 
			
		||||
        if (competence) {
 | 
			
		||||
          for (let actor of actors) {
 | 
			
		||||
            await actor.rollCaracCompetence(caracName, competence.name, diff);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
@@ -398,5 +402,8 @@ export class RdDCommands {
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  async getMeteo(msg, params) {
 | 
			
		||||
    return await RdDMeteo.getMeteo();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										134
									
								
								module/rdd-meteo.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								module/rdd-meteo.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
 | 
			
		||||
const vents = [
 | 
			
		||||
  { min: 0, max: 0, valeur: 'Calme' },
 | 
			
		||||
  { min: 1, max: 1, valeur: 'Légère brise' },
 | 
			
		||||
  { min: 2, max: 2, valeur: 'Jolie brise' },
 | 
			
		||||
  { min: 3, max: 3, valeur: 'Bonne brise' },
 | 
			
		||||
  { min: 4, max: 4, valeur: 'Vent frais' },
 | 
			
		||||
  { min: 5, max: 5, valeur: 'Coup de vent' },
 | 
			
		||||
  { min: 6, max: 6, valeur: 'Fort coup de vent' },
 | 
			
		||||
  { min: 7, max: 9, valeur: 'Tempête' },
 | 
			
		||||
  { min: 10, max: 13, valeur: 'Violente tempête' },
 | 
			
		||||
  { min: 14, valeur: 'Ouragan' },
 | 
			
		||||
]
 | 
			
		||||
const mers = [
 | 
			
		||||
  { min: 0, max: 0, valeur: 'Calme' },
 | 
			
		||||
  { min: 1, max: 1, valeur: 'Belle' },
 | 
			
		||||
  { min: 2, max: 2, valeur: 'Peu agitée' },
 | 
			
		||||
  { min: 3, max: 3, valeur: 'Agitée' },
 | 
			
		||||
  { min: 4, max: 4, valeur: 'Forte' },
 | 
			
		||||
  { min: 5, max: 6, valeur: 'Très forte' },
 | 
			
		||||
  { min: 7, max: 9, valeur: 'Grosse' },
 | 
			
		||||
  { min: 10, max: 13, valeur: 'Très grosse' },
 | 
			
		||||
  { min: 14, valeur: 'Énorme' },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const nuages = [
 | 
			
		||||
  { min: 0, max: 3, valeur: 'dégagé' },
 | 
			
		||||
  { min: 4, max: 6, valeur: 'passages nuageux' },
 | 
			
		||||
  { min: 7, max: 9, valeur: 'nuageux',  },
 | 
			
		||||
  { min: 10, max: 10, valeur: 'brouillard' },
 | 
			
		||||
  { min: 11, max: 12, valeur: 'bruine' },
 | 
			
		||||
  { min: 13, valeur: 'très nuageux' },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const pluies = [
 | 
			
		||||
  { min: 0, max: 4, valeur: 'aucune' },
 | 
			
		||||
  { min: 5, max: 5, valeur: 'bruine, crachin, éparse' },
 | 
			
		||||
  { min: 6, max: 7, valeur: 'averses' },
 | 
			
		||||
  { min: 8, max: 10, valeur: 'pluvieux', },
 | 
			
		||||
  { min: 11, max: 13, valeur: 'forte pluie' },
 | 
			
		||||
  { min: 14, valeur: 'déluge' },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const temperatures = [
 | 
			
		||||
  { max: -14, valeur: 'glaciale' },
 | 
			
		||||
  { min: -13, max: -10, valeur: 'Très froide' },
 | 
			
		||||
  { min: -9, max: -7, valeur: 'froide' },
 | 
			
		||||
  { min: -6, max: -4, valeur: 'fraîche' },
 | 
			
		||||
  { min: -3, max: 3, valeur: 'de saison' },
 | 
			
		||||
  { min: 4, max: 6, valeur: 'élevée' },
 | 
			
		||||
  { min: 7, max: 9, valeur: 'chaude' },
 | 
			
		||||
  { min: 10, max: 13, valeur: 'torride' },
 | 
			
		||||
  { min: 14, valeur: 'caniculaire' },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export class RdDMeteo {
 | 
			
		||||
  static async getForce() {
 | 
			
		||||
    const roll = new Roll(`1dr`);
 | 
			
		||||
    await roll.evaluate({ async: true });
 | 
			
		||||
    return roll.total;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static async getPluie(nuage) {
 | 
			
		||||
    return nuage <= 3 ? 0 : await RdDMeteo.getForce();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static async getTemperature() {
 | 
			
		||||
    const degre = await RdDMeteo.getForce();
 | 
			
		||||
    const rollChaudFroid = new Roll('1d2');
 | 
			
		||||
    await rollChaudFroid.evaluate({ async: true });
 | 
			
		||||
    const chaudFroid = rollChaudFroid.total == 1;
 | 
			
		||||
    return chaudFroid.total ? degre : -degre;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static async getDirection(direction) {
 | 
			
		||||
    const roll = new Roll(`1d16`);
 | 
			
		||||
    await roll.evaluate({ async: true });
 | 
			
		||||
    switch (roll.total % 16) {
 | 
			
		||||
      case 0: return 'Nord';
 | 
			
		||||
      case 1: return 'Nord Nord Est';
 | 
			
		||||
      case 2: return 'Nord Est';
 | 
			
		||||
      case 3: return 'Est Nord Est';
 | 
			
		||||
      case 4: return 'Est';
 | 
			
		||||
      case 5: return 'Est Sud Est';
 | 
			
		||||
      case 6: return 'Sud Est';
 | 
			
		||||
      case 7: return 'Sud Sud Est';
 | 
			
		||||
      case 8: return 'Sud';
 | 
			
		||||
      case 9: return 'Sud Sud Ouest';
 | 
			
		||||
      case 10: return 'Sud Ouest';
 | 
			
		||||
      case 11: return 'Ouest Sud Ouest';
 | 
			
		||||
      case 12: return 'Ouest';
 | 
			
		||||
      case 13: return 'Ouest Nord Ouest';
 | 
			
		||||
      case 14: return 'Nord Ouest';
 | 
			
		||||
      case 15: return 'Nord Nord Ouest';
 | 
			
		||||
    }
 | 
			
		||||
    return undefined;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static async getMeteo() {
 | 
			
		||||
    const vent = await RdDMeteo.getForce();
 | 
			
		||||
    const mer = await RdDMeteo.getForce();
 | 
			
		||||
    const nuage = await RdDMeteo.getForce();
 | 
			
		||||
    const pluie = await RdDMeteo.getPluie(nuage);
 | 
			
		||||
    const temperature = await RdDMeteo.getTemperature();
 | 
			
		||||
    const meteo = {
 | 
			
		||||
      vent: { force: vent, direction: await RdDMeteo.getDirection(), },
 | 
			
		||||
      mer: { force: mer, direction: await RdDMeteo.getDirection(), },
 | 
			
		||||
      temperature: { force: temperature },
 | 
			
		||||
      nuage: { force: nuage, },
 | 
			
		||||
      pluie: { force: pluie },
 | 
			
		||||
    }
 | 
			
		||||
    meteo.vent.description = RdDMeteo.vent(meteo.vent.force);
 | 
			
		||||
    meteo.mer.description = RdDMeteo.mer(meteo.mer.force),
 | 
			
		||||
    meteo.temperature.description = RdDMeteo.temperature(meteo.temperature.force);
 | 
			
		||||
    meteo.nuage.description = RdDMeteo.nuage(meteo.nuage.force);
 | 
			
		||||
    meteo.pluie.description = RdDMeteo.pluie(meteo.pluie.force);
 | 
			
		||||
 | 
			
		||||
    ChatMessage.create({
 | 
			
		||||
      content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-meteo.html', meteo),
 | 
			
		||||
      whisper: ChatMessage.getWhisperRecipients('GM')
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static description(liste, force, valeur = it => it.valeur) {
 | 
			
		||||
    let select = liste.find(it => (it.min == undefined || it.min <= force) && (it.max == undefined || force <= it.max));
 | 
			
		||||
    return valeur(select ?? liste[0]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static vent(force) { return this.description(vents, force); }
 | 
			
		||||
  static mer(force) { return this.description(mers, force); }
 | 
			
		||||
  static nuage(force) { return this.description(nuages, force); }
 | 
			
		||||
  static pluie(force) { return this.description(pluies, force); }
 | 
			
		||||
  static temperature(force) { return this.description(temperatures, force); }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +1,29 @@
 | 
			
		||||
import { RdDActor } from "./actor.js";
 | 
			
		||||
import { Misc } from "./misc.js";
 | 
			
		||||
import { RdDDice } from "./rdd-dice.js";
 | 
			
		||||
 | 
			
		||||
const words = [ 'pore', 'pre', 'flor', 'lane', 'turlu', 'pin', 'a', 'alph', 'i', 'onse', 'iane', 'ane', 'zach', 'arri', 'ba', 'bo', 'bi', 
 | 
			
		||||
              'alta', 'par', 'pir', 'zor', 'zir', 'de', 'pol', 'tran', 'no', 'la', 'al' , 'pul', 'one', 'ner', 'nur', 'mac', 'mery',
 | 
			
		||||
              'cat', 'do', 'di', 'der', 'er', 'el', 'far', 'fer', 'go', 'guer', 'hot', 'jor', 'jar', 'ji', 'kri', 'ket', 'lor', 'hur',
 | 
			
		||||
              'lar', 'lir', 'lu', 'pot', 'pro', 'pra', 'pit', 'qua', 'qui', 're', 'ral', 'sal', 'sen', 'ted', 'to', 'ta', 'lars', 'ver',
 | 
			
		||||
              'vin', 'ov', 'wal', 'ry', 'ly', '' ];
 | 
			
		||||
const words = ['pore', 'pre', 'flor', 'lane', 'turlu', 'pin', 'a', 'alph', 'i', 'onse', 'iane', 'ane', 'zach', 'arri', 'ba', 'bo', 'bi',
 | 
			
		||||
  'alta', 'par', 'pir', 'zor', 'zir', 'de', 'pol', 'tran', 'no', 'la', 'al', 'pul', 'one', 'ner', 'nur', 'mac', 'mery',
 | 
			
		||||
  'cat', 'do', 'di', 'der', 'er', 'el', 'far', 'fer', 'go', 'guer', 'hot', 'jor', 'jar', 'ji', 'kri', 'ket', 'lor', 'hur',
 | 
			
		||||
  'lar', 'lir', 'lu', 'pot', 'pro', 'pra', 'pit', 'qua', 'qui', 're', 'ral', 'sal', 'sen', 'ted', 'to', 'ta', 'lars', 'ver',
 | 
			
		||||
  'vin', 'ov', 'wal', 'ry', 'ly', ''];
 | 
			
		||||
 | 
			
		||||
/* -------------------------------------------- */
 | 
			
		||||
export class RdDNameGen {
 | 
			
		||||
 | 
			
		||||
  static async getName( msg, params ) {
 | 
			
		||||
    let name = Misc.upperFirst( await RdDDice.rollOneOf(words) + await RdDDice.rollOneOf(words) )
 | 
			
		||||
    //console.log(name);
 | 
			
		||||
    ChatMessage.create( { content: `Nom : ${name}`, whisper: ChatMessage.getWhisperRecipients("GM") } );
 | 
			
		||||
  static async getName(msg, params) {
 | 
			
		||||
    const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-command-nom.html`, {
 | 
			
		||||
      nom: Misc.upperFirst(await RdDDice.rollOneOf(words) + await RdDDice.rollOneOf(words))
 | 
			
		||||
    });
 | 
			
		||||
    ChatMessage.create({ content: html, whisper: ChatMessage.getWhisperRecipients("GM") });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static async onCreerActeur(event) {
 | 
			
		||||
    const button = event.currentTarget;
 | 
			
		||||
    await RdDActor.create({
 | 
			
		||||
        name: button.attributes['data-nom'].value,
 | 
			
		||||
        type: button.attributes['data-type'].value
 | 
			
		||||
      },
 | 
			
		||||
      {renderSheet: true});
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -14,44 +14,44 @@ Donc la compétence Possession ne peut être démarrée que par le MJ.
 | 
			
		||||
export class RdDPossession {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static init() {    
 | 
			
		||||
  static init() {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static searchPossessionFromEntite( attacker, defender) {
 | 
			
		||||
    let poss = attacker.data.items.find( poss => poss.type == 'possession' && poss.data.data.possedeid == defender.data._id);
 | 
			
		||||
  static searchPossessionFromEntite(attacker, defender) {
 | 
			
		||||
    let poss = attacker.data.items.find(poss => poss.type == 'possession' && poss.data.data.possedeid == defender.data._id);
 | 
			
		||||
    if (!poss) {
 | 
			
		||||
      poss = defender.data.items.find( poss => poss.type == 'possession' && poss.data.data.possedeid == defender.data._id);
 | 
			
		||||
      poss = defender.data.items.find(poss => poss.type == 'possession' && poss.data.data.possedeid == defender.data._id);
 | 
			
		||||
    }
 | 
			
		||||
    return poss && duplicate(poss) || undefined;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static updateEtatPossession( possession ) {
 | 
			
		||||
  static updateEtatPossession(possession) {
 | 
			
		||||
    possession.ptsConjuration = 0
 | 
			
		||||
    possession.ptsPossession = 0
 | 
			
		||||
    console.log("Possession", possession)
 | 
			
		||||
    if ( possession.data.compteur > 0) {
 | 
			
		||||
    if (possession.data.compteur > 0) {
 | 
			
		||||
      possession.ptsPossession = possession.data.compteur
 | 
			
		||||
    } 
 | 
			
		||||
    if ( possession.data.compteur < 0) {
 | 
			
		||||
    }
 | 
			
		||||
    if (possession.data.compteur < 0) {
 | 
			
		||||
      possession.ptsConjuration = Math.abs(possession.data.compteur)
 | 
			
		||||
    } 
 | 
			
		||||
    }
 | 
			
		||||
    possession.isPosseder = false
 | 
			
		||||
    possession.isConjurer = false
 | 
			
		||||
    if (possession.ptsPossession >= 2 ) {
 | 
			
		||||
    if (possession.ptsPossession >= 2) {
 | 
			
		||||
      possession.isPosseder = true
 | 
			
		||||
    }
 | 
			
		||||
    if (possession.ptsConjuration >= 2 ) {      
 | 
			
		||||
    if (possession.ptsConjuration >= 2) {
 | 
			
		||||
      possession.isConjurer = true
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static async resultConjuration( rollData) {
 | 
			
		||||
  static async resultConjuration(rollData) {
 | 
			
		||||
    let actor = game.actors.get(rollData.possession.data.possedeid)
 | 
			
		||||
    if ( !rollData.rolled.isSuccess ) {
 | 
			
		||||
      if( rollData.isECNIDefender) {
 | 
			
		||||
    if (!rollData.rolled.isSuccess) {
 | 
			
		||||
      if (rollData.isECNIDefender) {
 | 
			
		||||
        rollData.possession.data.compteur--
 | 
			
		||||
      } else {
 | 
			
		||||
        rollData.possession.data.compteur++
 | 
			
		||||
@@ -59,55 +59,41 @@ export class RdDPossession {
 | 
			
		||||
      let update = { _id: rollData.possession._id, "data.compteur": rollData.possession.data.compteur }
 | 
			
		||||
      await actor.updateEmbeddedDocuments('Item', [update])
 | 
			
		||||
    }
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
    this.updateEtatPossession(rollData.possession)
 | 
			
		||||
    await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-possession.html')
 | 
			
		||||
    if ( rollData.possession.isPosseder || rollData.possession.isConjurer) {
 | 
			
		||||
    if (rollData.possession.isPosseder || rollData.possession.isConjurer) {
 | 
			
		||||
      actor.deleteEmbeddedDocuments("Item", [rollData.possession._id])
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static async onDefensePossession( attackerId, defenderId, possessionId) {
 | 
			
		||||
  static async onDefensePossession(attackerId, defenderId, possessionId) {
 | 
			
		||||
    let attacker = game.actors.get(attackerId)
 | 
			
		||||
    let defender = game.actors.get(defenderId)
 | 
			
		||||
 | 
			
		||||
    let possession = attacker.items.find( item => item.type =='possession' && item.data.data.possessionid == possessionId)
 | 
			
		||||
    if ( !possession ) {    
 | 
			
		||||
      possession = defender.items.find( item => item.type =='possession' && item.data.data.possessionid == possessionId)
 | 
			
		||||
      if ( !possession) {
 | 
			
		||||
        ui.notifications.warn("Une erreur s'est produite : Aucune possession trouvée !!")
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
    let possession = attacker.getPossession(possessionId) ?? defender.getPossession(possessionId) ;
 | 
			
		||||
    if (!possession) {
 | 
			
		||||
      ui.notifications.warn("Une erreur s'est produite : Aucune possession trouvée !!")
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    possession = duplicate(possession)
 | 
			
		||||
 | 
			
		||||
    // Update for draconic roll
 | 
			
		||||
    let rollData = {
 | 
			
		||||
      possession: possession
 | 
			
		||||
      mode: "conjuration",
 | 
			
		||||
      isECNIDefender: defender.type == "entite",
 | 
			
		||||
      possession: duplicate(possession),
 | 
			
		||||
      attacker: attacker,
 | 
			
		||||
      defender: defender,
 | 
			
		||||
      competence: defender.getDraconicOuPossession(),
 | 
			
		||||
      selectedCarac: defender.data.data.carac.reve,
 | 
			
		||||
      forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: defender.getReveActuel() } }
 | 
			
		||||
    }
 | 
			
		||||
    rollData.actor = defender
 | 
			
		||||
    if ( defender.type == "personnage") {
 | 
			
		||||
      rollData.competence = duplicate(defender.getDraconicOrZero())
 | 
			
		||||
      rollData.competence.data.defaut_carac = 'reve-actuel'
 | 
			
		||||
      rollData.forceCarac = { 'reve-actuel': { label: "Rêve Actuel", value: defender.getReveActuel() } }
 | 
			
		||||
      rollData.selectedCarac = defender.data.data.carac.reve
 | 
			
		||||
      rollData.isECNIDefender = false
 | 
			
		||||
    } else {
 | 
			
		||||
      rollData.competence = duplicate(defender.getCompetence("Possession"))
 | 
			
		||||
      rollData.competence.data.defaut_carac = "reve"
 | 
			
		||||
      rollData.forceCarac = { 'reve': { label: "Rêve", value: defender.data.data.carac.reve.value } }
 | 
			
		||||
      rollData.selectedCarac = defender.data.data.carac.reve
 | 
			
		||||
      rollData.isECNIDefender = true
 | 
			
		||||
      //RdDItemCompetenceCreature.setRollDataCreature( rollData )
 | 
			
		||||
    }
 | 
			
		||||
    rollData.mode =  "conjuration"
 | 
			
		||||
    rollData.possesseur = attacker.name
 | 
			
		||||
    rollData.competence.data.defaut_carac = 'reve-actuel'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    const dialog = await RdDRoll.create(defender, rollData,
 | 
			
		||||
      {
 | 
			
		||||
        html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.html',
 | 
			
		||||
        options: { height: 400 }
 | 
			
		||||
        options: { height: 450 }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'conjurer',
 | 
			
		||||
@@ -121,54 +107,38 @@ export class RdDPossession {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static async _onRollPossession( rollData, isSuccess ) {
 | 
			
		||||
    let possession = rollData.possession
 | 
			
		||||
    possession.isSuccess = isSuccess
 | 
			
		||||
    this.updateEtatPossession( possession)
 | 
			
		||||
    await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-possession.html');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static async managePossession(attacker, competence, possession=undefined) {    
 | 
			
		||||
    
 | 
			
		||||
  static async onAttaquePossession(attacker, competence, possession = undefined) {
 | 
			
		||||
    const target = RdDCombat.getTarget()
 | 
			
		||||
    if (target == undefined) {
 | 
			
		||||
      ui.notifications.warn((game.user.targets?.size ?? 0) > 1
 | 
			
		||||
        ? "Vous devez choisir <strong>une seule</strong> cible à posséder!"
 | 
			
		||||
        : "Vous devez choisir une cible à posséder!");
 | 
			
		||||
      return;
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    const defender = target.actor
 | 
			
		||||
    if ( !possession) {
 | 
			
		||||
      possession = this.searchPossessionFromEntite( attacker, defender)
 | 
			
		||||
      if ( !possession) {
 | 
			
		||||
        possession = await this.createPossession(attacker, defender)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    possession = duplicate(possession)
 | 
			
		||||
 | 
			
		||||
    const defender = target.actor;
 | 
			
		||||
    possession = duplicate(possession ?? this.searchPossessionFromEntite(attacker, defender) ??(await this.createPossession(attacker, defender)));
 | 
			
		||||
    
 | 
			
		||||
    this.updateEtatPossession(possession)
 | 
			
		||||
    let rollData = {
 | 
			
		||||
      mode: "possession",
 | 
			
		||||
      isECNIDefender: defender.type == "entite",
 | 
			
		||||
      competence: competence,
 | 
			
		||||
      possession: possession,
 | 
			
		||||
      possede: defender.name,
 | 
			
		||||
      possesseur: attacker.name,
 | 
			
		||||
      attackerId: attacker.data._id,
 | 
			
		||||
      defenderId: defender.data._id,
 | 
			
		||||
      mode: "possession"
 | 
			
		||||
      attacker: attacker,
 | 
			
		||||
      defender: defender
 | 
			
		||||
    };
 | 
			
		||||
    if ( attacker.isCreature()) {
 | 
			
		||||
    if (attacker.isCreature()) {
 | 
			
		||||
      RdDItemCompetenceCreature.setRollDataCreature(rollData)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const dialog = await RdDRoll.create( attacker, rollData,
 | 
			
		||||
    const dialog = await RdDRoll.create(attacker, rollData,
 | 
			
		||||
      {
 | 
			
		||||
        html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
 | 
			
		||||
        options: { height: 540 }
 | 
			
		||||
      }, {
 | 
			
		||||
      name: 'jet-possession',
 | 
			
		||||
      label: 'Possession: ',
 | 
			
		||||
      label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession',
 | 
			
		||||
      callbacks: [
 | 
			
		||||
        { condition: r => (r.rolled.isSuccess), action: async r => await this._onRollPossession(r, true) },
 | 
			
		||||
        { condition: r => (r.rolled.isEchec), action: async r => await this._onRollPossession(r, false) },
 | 
			
		||||
@@ -178,7 +148,14 @@ export class RdDPossession {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static async createPossession( attacker, defender ) {
 | 
			
		||||
  static async _onRollPossession(rollData, isSuccess) {
 | 
			
		||||
    rollData.possession.isSuccess = isSuccess;
 | 
			
		||||
    this.updateEtatPossession(rollData.possession);
 | 
			
		||||
    await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-possession.html');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static async createPossession(attacker, defender) {
 | 
			
		||||
    let possessionData = {
 | 
			
		||||
      name: "Possession en cours de " + attacker.name, type: 'possession',
 | 
			
		||||
      img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "./constants";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extend the base Dialog entity by defining a custom window to perform roll.
 | 
			
		||||
 * @extends {Dialog}
 | 
			
		||||
@@ -7,15 +9,19 @@ export class RdDEncaisser extends Dialog {
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  constructor(html, actor) {
 | 
			
		||||
    // Common conf
 | 
			
		||||
    const buttonsCreatures = {
 | 
			
		||||
      "mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") },
 | 
			
		||||
      "non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") },
 | 
			
		||||
      "sonne": { label: "Sonné", callback: html => this.actor.setSonne() },
 | 
			
		||||
    };
 | 
			
		||||
    const buttonsEntitesCauchemar = {
 | 
			
		||||
      "cauchemar": { label: "cauchemar", callback: html => this.performEncaisser("cauchemar") }
 | 
			
		||||
    };
 | 
			
		||||
    const buttons = actor.isEntiteCauchemar() ? buttonsEntitesCauchemar : buttonsCreatures;
 | 
			
		||||
    let buttons = {};
 | 
			
		||||
    if (!actor.isEntite()){
 | 
			
		||||
      buttons = {
 | 
			
		||||
        "mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") },
 | 
			
		||||
        "non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") },
 | 
			
		||||
        "sonne": { label: "Sonné", callback: html => this.actor.setSonne() },
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
    else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])){
 | 
			
		||||
      buttons = {
 | 
			
		||||
        "cauchemar": { label: "cauchemar", callback: html => this.performEncaisser("cauchemar") }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let dialogConf = {
 | 
			
		||||
      title: "Jet d'Encaissement",
 | 
			
		||||
 
 | 
			
		||||
@@ -95,12 +95,15 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
  createPixiSprites() {
 | 
			
		||||
    EffetsDraconiques.carteTmr.createSprite(this.pixiTMR);
 | 
			
		||||
    this.updateTokens();
 | 
			
		||||
    this.demiReve = this._tokenDemiReve();
 | 
			
		||||
    this._updateDemiReve();
 | 
			
		||||
    this.forceDemiRevePositionView();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  _createTokens() {
 | 
			
		||||
    if (!this.isDemiReveCache()){
 | 
			
		||||
      this.demiReve = this._tokenDemiReve();
 | 
			
		||||
      this._trackToken(this.demiReve);
 | 
			
		||||
    }
 | 
			
		||||
    let tokens = this._getTokensCasesTmr()
 | 
			
		||||
      .concat(this._getTokensRencontres())
 | 
			
		||||
      .concat(this._getTokensSortsReserve());
 | 
			
		||||
@@ -154,9 +157,9 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
    return EffetsDraconiques.demiReve.token(this.pixiTMR, actorData, () => actorData.data.reve.tmrpos.coord);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _updateDemiReve() {
 | 
			
		||||
  forceDemiRevePositionView() {
 | 
			
		||||
    this.notifierResonanceSigneDraconique(this._getActorCoord());
 | 
			
		||||
    this._setTokenPosition(this.demiReve);
 | 
			
		||||
    this._trackToken(this.demiReve);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _getActorCoord() {
 | 
			
		||||
@@ -336,6 +339,10 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async choisirCasePortee(coord, portee) {
 | 
			
		||||
    if (this.actor.isTMRCache())
 | 
			
		||||
    {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    // Récupère la liste des cases à portées
 | 
			
		||||
    let locList = TMRUtility.getTMRPortee(coord, portee);
 | 
			
		||||
    this.colorierZoneRencontre(locList);
 | 
			
		||||
@@ -743,6 +750,7 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async _maitriserTMR(rollData, callbackMaitrise) {
 | 
			
		||||
    this.minimize(); // Hide
 | 
			
		||||
    rollData.isTMRCache = rollData.actor.isTMRCache();
 | 
			
		||||
    const dialog = await RdDRoll.create(this.actor, rollData,
 | 
			
		||||
      {
 | 
			
		||||
        html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html',
 | 
			
		||||
@@ -874,49 +882,62 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async _onClickTMRPos(clickOddq) {
 | 
			
		||||
    if (this.isDemiReveCache()) {
 | 
			
		||||
      ui.notifications.error(`Vous ne connaissez plus votre position dans les TMR.
 | 
			
		||||
      Vous devez utiliser les boutons de direction pour vous déplacer.
 | 
			
		||||
      Une fois que vous aurez retrouvé votre demi-rêve, demandez au gardien de vérifier et rendre les TMR visibles.
 | 
			
		||||
      `);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let currentOddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
 | 
			
		||||
 | 
			
		||||
    console.log("deplacerDemiReve >>>>", currentOddq, clickOddq);
 | 
			
		||||
 | 
			
		||||
    let targetCoord = TMRUtility.oddqToCoordTMR(clickOddq);
 | 
			
		||||
    let currentCoord = TMRUtility.oddqToCoordTMR(currentOddq);
 | 
			
		||||
 | 
			
		||||
    // Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter)
 | 
			
		||||
    let deplacementType = this._calculDeplacement(targetCoord, currentCoord, currentOddq, clickOddq);
 | 
			
		||||
 | 
			
		||||
    // Si le deplacement est valide
 | 
			
		||||
    if (deplacementType == 'normal' || deplacementType == 'saut') {
 | 
			
		||||
      await this._deplacerDemiReve(targetCoord, deplacementType);
 | 
			
		||||
    } else if (deplacementType == 'messager') { // Dans ce cas, ouverture du lancement de sort sur la case visée
 | 
			
		||||
      await this._messagerDemiReve(targetCoord);
 | 
			
		||||
    } else {
 | 
			
		||||
      ui.notifications.error("Vous ne pouvez pas vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre");
 | 
			
		||||
      console.log("STATUS :", this.rencontreState, this.currentRencontre);
 | 
			
		||||
    if (this.isDemiReveCache()) {
 | 
			
		||||
      if (this.isTerreAttache(targetCoord)
 | 
			
		||||
      || (this.isCaseHumide(currentCoord) && this.isCaseHumide(targetCoord))
 | 
			
		||||
      || deplacementType == 'changeur')
 | 
			
		||||
      {
 | 
			
		||||
        // déplacement possible
 | 
			
		||||
        await this.actor.montreTMR();
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        ui.notifications.error(`Vous ne connaissez plus votre position dans les TMR.
 | 
			
		||||
        Vous devez utiliser les boutons de direction pour vous déplacer.
 | 
			
		||||
        Une fois que vous aurez retrouvé votre demi-rêve, demandez au gardien de vérifier et rendre les TMR visibles.
 | 
			
		||||
        `);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (deplacementType){
 | 
			
		||||
      case 'normal':
 | 
			
		||||
        await this._deplacerDemiReve(targetCoord, deplacementType);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'messager':
 | 
			
		||||
        await this._messagerDemiReve(targetCoord);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'changeur':
 | 
			
		||||
      case 'passeur':
 | 
			
		||||
        await this._deplacerDemiReve(targetCoord, deplacementType);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
          ui.notifications.error("Vous ne pouvez pas vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre");
 | 
			
		||||
          console.log("STATUS :", this.rencontreState, this.currentRencontre);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.checkQuitterTMR();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  _calculDeplacement(targetCoord, currentCoord, fromOddq, toOddq) {
 | 
			
		||||
 | 
			
		||||
    const isInArea = this.rencontreState == 'aucune'
 | 
			
		||||
      ? (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1)
 | 
			
		||||
      : this.currentRencontre?.locList.find(coord => coord == targetCoord) ?? false
 | 
			
		||||
    if (isInArea) {
 | 
			
		||||
      switch (this.rencontreState) {
 | 
			
		||||
        case 'aucune': return 'normal';
 | 
			
		||||
        case 'messager': return 'messager';
 | 
			
		||||
        case 'passeur': case 'changeur': return 'saut';
 | 
			
		||||
        case 'passeur': case 'changeur': case 'messager': return this.rencontreState;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return 'erreur'
 | 
			
		||||
    return 'erreur';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
@@ -932,9 +953,8 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  externalRefresh(tmrData) {
 | 
			
		||||
  externalRefresh() {
 | 
			
		||||
    this.createPixiSprites();
 | 
			
		||||
    this.forceDemiRevePositionView();
 | 
			
		||||
    this.updateValuesDisplay();
 | 
			
		||||
    this.updateTokens();
 | 
			
		||||
    console.log("TMR REFRESHED !!!");
 | 
			
		||||
@@ -946,23 +966,17 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
      this.nettoyerRencontre();
 | 
			
		||||
    }
 | 
			
		||||
    let tmr = TMRUtility.getTMR(targetCoord);
 | 
			
		||||
    //console.log("deplacerDemiReve", tmr, this);
 | 
			
		||||
    // Gestion cases spéciales type Trou noir, etc
 | 
			
		||||
    tmr = await this.manageTmrInnaccessible(tmr);
 | 
			
		||||
 | 
			
		||||
    await this.actor.updateCoordTMR(tmr.coord);
 | 
			
		||||
 | 
			
		||||
    this._updateDemiReve();
 | 
			
		||||
    this.forceDemiRevePositionView();
 | 
			
		||||
    if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
 | 
			
		||||
      this.cumulFatigue += this.fatigueParCase;
 | 
			
		||||
    }
 | 
			
		||||
    this.updateValuesDisplay();
 | 
			
		||||
    game.socket.emit(SYSTEM_SOCKET_ID, {
 | 
			
		||||
      msg: "msg_tmr_move", data: {
 | 
			
		||||
        actorId: this.actor.data._id,
 | 
			
		||||
        tmrPos: Misc.data(this.actor).data.reve.tmrpos
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    this.actor.notifyRefreshTMR();
 | 
			
		||||
 | 
			
		||||
    if (deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
 | 
			
		||||
      await this.manageRencontre(tmr, () => this.postRencontre(tmr));
 | 
			
		||||
@@ -995,14 +1009,9 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async forceDemiRevePositionView() {
 | 
			
		||||
    this._updateDemiReve();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  async forceDemiRevePosition(coord) {
 | 
			
		||||
  async positionnerDemiReve(coord) {
 | 
			
		||||
    await this.actor.updateCoordTMR(coord);
 | 
			
		||||
    this._updateDemiReve();
 | 
			
		||||
    this.forceDemiRevePositionView();
 | 
			
		||||
    let tmr = TMRUtility.getTMR(coord);
 | 
			
		||||
    await this.postRencontre(tmr);
 | 
			
		||||
    return tmr;
 | 
			
		||||
@@ -1024,15 +1033,7 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
  _getCaseRectangleCoord(coord) {
 | 
			
		||||
    return this.pixiTMR.getCaseRectangle(TMRUtility.coordTMRToOddq(coord));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  _setTokenPosition(token) {
 | 
			
		||||
    if (this.isDemiReveCache() && this.demiReve === token ) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    this.pixiTMR.setPosition(token.sprite, TMRUtility.coordTMRToOddq(token.coordTMR()));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  _removeTokens(filter) {
 | 
			
		||||
    const tokensToRemove = this.allTokens.filter(filter);
 | 
			
		||||
@@ -1040,10 +1041,13 @@ export class RdDTMRDialog extends Dialog {
 | 
			
		||||
      this.pixiApp.stage.removeChild(token.sprite);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  _trackToken(token) {
 | 
			
		||||
    if (this.demiReve === token && this.isDemiReveCache()) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    this.pixiTMR.setPosition(token.sprite, TMRUtility.coordTMRToOddq(token.coordTMR()));
 | 
			
		||||
    this.allTokens.push(token);
 | 
			
		||||
    this._setTokenPosition(token);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,40 +23,63 @@ export class RdDTokenHud {
 | 
			
		||||
    let token = canvas.tokens.get(tokenId);
 | 
			
		||||
    let actor = token.actor;
 | 
			
		||||
    let combatant = game.combat.combatants.find(c => Misc.data(c).tokenId == tokenId);
 | 
			
		||||
    if (! (combatant?.actor) ) {
 | 
			
		||||
        ui.notifications.warn(`Le combatant ${token.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    app.hasExtension = true;
 | 
			
		||||
 | 
			
		||||
    let armesList = RdDCombatManager.buildListeActionsCombat(combatant);
 | 
			
		||||
    let actionsCombat = RdDCombatManager.listActionsCombat(combatant);
 | 
			
		||||
    const hudData = {
 | 
			
		||||
      combatant: combatant, armes: armesList,
 | 
			
		||||
      commandes: [{ name: 'Initiative +1', command: 'inc', value: 0.01 }, { name: 'Initiative -1', command: 'dec', value: -0.01 }]
 | 
			
		||||
      combatant: combatant,
 | 
			
		||||
      actions: actionsCombat,
 | 
			
		||||
      commandes: [
 | 
			
		||||
        { name: "Autre action", command: 'autre' },
 | 
			
		||||
        { name: 'Initiative +1', command: 'inc', value: 0.01 }, 
 | 
			
		||||
        { name: 'Initiative -1', command: 'dec', value: -0.01 }]
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const controlIconCombat = html.find('.control-icon[data-action=combat]');
 | 
			
		||||
    // initiative
 | 
			
		||||
    await RdDTokenHud._configureSubMenu(controlIconCombat, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html', hudData,
 | 
			
		||||
    await RdDTokenHud._configureSubMenu(controlIconCombat,
 | 
			
		||||
      'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html',
 | 
			
		||||
      hudData,
 | 
			
		||||
      (event) => {
 | 
			
		||||
        let initCommand = event.currentTarget.attributes['data-command'].value;
 | 
			
		||||
        let combatantId = event.currentTarget.attributes['data-combatant-id'].value;
 | 
			
		||||
        if (!initCommand) {
 | 
			
		||||
          let armeIndex = event.currentTarget.attributes['data-arme-id'].value;
 | 
			
		||||
          let arme = armesList[armeIndex];
 | 
			
		||||
          RdDCombatManager.rollInitiativeCompetence(combatantId, arme);
 | 
			
		||||
        } else if (initCommand == 'inc') {
 | 
			
		||||
          RdDCombatManager.incDecInit(combatantId, 0.01);
 | 
			
		||||
        } else if (initCommand == 'dec') {
 | 
			
		||||
          RdDCombatManager.incDecInit(combatantId, -0.01);
 | 
			
		||||
        }
 | 
			
		||||
        let initCommand = event.currentTarget.attributes['data-command']?.value;
 | 
			
		||||
        let combatantId = event.currentTarget.attributes['data-combatant-id']?.value;
 | 
			
		||||
        if (initCommand) {
 | 
			
		||||
          RdDTokenHud._initiativeCommand(initCommand, combatantId);
 | 
			
		||||
        } else {
 | 
			
		||||
          let index = event.currentTarget.attributes['data-action-index'].value;
 | 
			
		||||
          let action = actionsCombat[index];
 | 
			
		||||
          RdDCombatManager.rollInitiativeAction(combatantId, action);
 | 
			
		||||
        } 
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    const controlIconTarget = html.find('.control-icon[data-action=target]');
 | 
			
		||||
    // combat
 | 
			
		||||
    await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData,
 | 
			
		||||
      (event) => {
 | 
			
		||||
        let armeIndex = event.currentTarget.attributes['data-arme-id'].value;
 | 
			
		||||
        actor.rollArme(armesList[armeIndex]);
 | 
			
		||||
        const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
 | 
			
		||||
        const action = actionsCombat[actionIndex];
 | 
			
		||||
        if (action.action == 'conjurer') {
 | 
			
		||||
          actor.conjurerPossession(actor.getPossession(action.data.possessionid));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          actor.rollArme(action);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static _initiativeCommand(initCommand, combatantId) {
 | 
			
		||||
    switch (initCommand) {
 | 
			
		||||
      case 'inc': return RdDCombatManager.incDecInit(combatantId, 0.01);
 | 
			
		||||
      case 'dec': return RdDCombatManager.incDecInit(combatantId, -0.01);
 | 
			
		||||
      case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId, 
 | 
			
		||||
        { name: "Autre action", action: 'autre', data: { initOnly: true, competence: "Autre action" } });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static async addTokenHudExtensions(app, html, tokenId) {
 | 
			
		||||
    const controlIconCombat  = html.find('.control-icon[data-action=combat]');
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ import { RdDDice } from "./rdd-dice.js";
 | 
			
		||||
import { RdDItem } from "./item.js";
 | 
			
		||||
import { Monnaie } from "./item-monnaie.js";
 | 
			
		||||
import { RdDPossession } from "./rdd-possession.js";
 | 
			
		||||
import { RdDNameGen } from "./rdd-namegen.js";
 | 
			
		||||
 | 
			
		||||
/* -------------------------------------------- */
 | 
			
		||||
// This table starts at 0 -> niveau -10
 | 
			
		||||
@@ -221,8 +222,10 @@ export class RdDUtility {
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
 | 
			
		||||
    Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null'));
 | 
			
		||||
    Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? 'NULL');
 | 
			
		||||
    Handlebars.registerHelper('le', str => Grammar.articleDetermine(str));
 | 
			
		||||
    Handlebars.registerHelper('apostrophe', (article, str) => Grammar.apostrophe(article, str));
 | 
			
		||||
    Handlebars.registerHelper('un', str => Grammar.articleIndetermine(str));
 | 
			
		||||
    Handlebars.registerHelper('accord', (genre, ...args) => Grammar.accord(genre, args));
 | 
			
		||||
    Handlebars.registerHelper('buildConteneur', (objet) => { return new Handlebars.SafeString(RdDUtility.buildConteneur(objet)); });
 | 
			
		||||
@@ -326,8 +329,8 @@ export class RdDUtility {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
  static checkNull(items) {
 | 
			
		||||
    if (items && items.length) {
 | 
			
		||||
  static arrayOrEmpty(items) {
 | 
			
		||||
    if (items?.length) {
 | 
			
		||||
      return items;
 | 
			
		||||
    }
 | 
			
		||||
    return [];
 | 
			
		||||
@@ -360,44 +363,44 @@ export class RdDUtility {
 | 
			
		||||
 | 
			
		||||
    RdDUtility.filterEquipementParType(formData);
 | 
			
		||||
 | 
			
		||||
    formData.sorts = this.checkNull(formData.itemsByType['sort']);
 | 
			
		||||
    formData.signesdraconiques = this.checkNull(formData.itemsByType['signedraconique']);
 | 
			
		||||
    formData.queues = this.checkNull(formData.itemsByType['queue']);
 | 
			
		||||
    formData.souffles = this.checkNull(formData.itemsByType['souffle']);
 | 
			
		||||
    formData.ombres = this.checkNull(formData.itemsByType['ombre']);
 | 
			
		||||
    formData.tetes = this.checkNull(formData.itemsByType['tete']);
 | 
			
		||||
    formData.taches = this.checkNull(formData.itemsByType['tache']);
 | 
			
		||||
    formData.meditations = this.checkNull(formData.itemsByType['meditation']);
 | 
			
		||||
    formData.chants = this.checkNull(formData.itemsByType['chant']);
 | 
			
		||||
    formData.danses = this.checkNull(formData.itemsByType['danse']);
 | 
			
		||||
    formData.musiques = this.checkNull(formData.itemsByType['musique']);
 | 
			
		||||
    formData.oeuvres = this.checkNull(formData.itemsByType['oeuvre']);
 | 
			
		||||
    formData.jeux = this.checkNull(formData.itemsByType['jeu']);
 | 
			
		||||
    formData.sorts = this.arrayOrEmpty(formData.itemsByType['sort']);
 | 
			
		||||
    formData.signesdraconiques = this.arrayOrEmpty(formData.itemsByType['signedraconique']);
 | 
			
		||||
    formData.queues = this.arrayOrEmpty(formData.itemsByType['queue']);
 | 
			
		||||
    formData.souffles = this.arrayOrEmpty(formData.itemsByType['souffle']);
 | 
			
		||||
    formData.ombres = this.arrayOrEmpty(formData.itemsByType['ombre']);
 | 
			
		||||
    formData.tetes = this.arrayOrEmpty(formData.itemsByType['tete']);
 | 
			
		||||
    formData.taches = this.arrayOrEmpty(formData.itemsByType['tache']);
 | 
			
		||||
    formData.meditations = this.arrayOrEmpty(formData.itemsByType['meditation']);
 | 
			
		||||
    formData.chants = this.arrayOrEmpty(formData.itemsByType['chant']);
 | 
			
		||||
    formData.danses = this.arrayOrEmpty(formData.itemsByType['danse']);
 | 
			
		||||
    formData.musiques = this.arrayOrEmpty(formData.itemsByType['musique']);
 | 
			
		||||
    formData.oeuvres = this.arrayOrEmpty(formData.itemsByType['oeuvre']);
 | 
			
		||||
    formData.jeux = this.arrayOrEmpty(formData.itemsByType['jeu']);
 | 
			
		||||
 | 
			
		||||
    formData.recettescuisine = this.checkNull(formData.itemsByType['recettecuisine']);
 | 
			
		||||
    formData.recettesAlchimiques = this.checkNull(formData.itemsByType['recettealchimique']);
 | 
			
		||||
    formData.maladies = this.checkNull(formData.itemsByType['maladie']);
 | 
			
		||||
    formData.poisons = this.checkNull(formData.itemsByType['poison']);
 | 
			
		||||
    formData.possessions = this.checkNull(formData.itemsByType['possession']);
 | 
			
		||||
    formData.recettescuisine = this.arrayOrEmpty(formData.itemsByType['recettecuisine']);
 | 
			
		||||
    formData.recettesAlchimiques = this.arrayOrEmpty(formData.itemsByType['recettealchimique']);
 | 
			
		||||
    formData.maladies = this.arrayOrEmpty(formData.itemsByType['maladie']);
 | 
			
		||||
    formData.poisons = this.arrayOrEmpty(formData.itemsByType['poison']);
 | 
			
		||||
    formData.possessions = this.arrayOrEmpty(formData.itemsByType['possession']);
 | 
			
		||||
    formData.maladiesPoisons = formData.maladies.concat(formData.poisons);
 | 
			
		||||
    formData.competences = (formData.itemsByType.competence ?? []).concat(formData.itemsByType.competencecreature ?? []);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static filterEquipementParType(formData) {
 | 
			
		||||
    formData.conteneurs = this.checkNull(formData.itemsByType['conteneur']);
 | 
			
		||||
    formData.conteneurs = this.arrayOrEmpty(formData.itemsByType['conteneur']);
 | 
			
		||||
 | 
			
		||||
    formData.materiel = this.checkNull(formData.itemsByType['objet']);
 | 
			
		||||
    formData.armes = this.checkNull(formData.itemsByType['arme']);
 | 
			
		||||
    formData.armures = this.checkNull(formData.itemsByType['armure']);
 | 
			
		||||
    formData.munitions = this.checkNull(formData.itemsByType['munition']);
 | 
			
		||||
    formData.livres = this.checkNull(formData.itemsByType['livre']);
 | 
			
		||||
    formData.potions = this.checkNull(formData.itemsByType['potion']);
 | 
			
		||||
    formData.ingredients = this.checkNull(formData.itemsByType['ingredient']);
 | 
			
		||||
    formData.herbes = this.checkNull(formData.itemsByType['herbe']);
 | 
			
		||||
    formData.monnaie = this.checkNull(formData.itemsByType['monnaie']);
 | 
			
		||||
    formData.materiel = this.arrayOrEmpty(formData.itemsByType['objet']);
 | 
			
		||||
    formData.armes = this.arrayOrEmpty(formData.itemsByType['arme']);
 | 
			
		||||
    formData.armures = this.arrayOrEmpty(formData.itemsByType['armure']);
 | 
			
		||||
    formData.munitions = this.arrayOrEmpty(formData.itemsByType['munition']);
 | 
			
		||||
    formData.livres = this.arrayOrEmpty(formData.itemsByType['livre']);
 | 
			
		||||
    formData.potions = this.arrayOrEmpty(formData.itemsByType['potion']);
 | 
			
		||||
    formData.ingredients = this.arrayOrEmpty(formData.itemsByType['ingredient']);
 | 
			
		||||
    formData.herbes = this.arrayOrEmpty(formData.itemsByType['herbe']);
 | 
			
		||||
    formData.monnaie = this.arrayOrEmpty(formData.itemsByType['monnaie']);
 | 
			
		||||
    formData.monnaie.sort(Monnaie.triValeurDenier());
 | 
			
		||||
    formData.nourritureboissons = this.checkNull(formData.itemsByType['nourritureboisson']);
 | 
			
		||||
    formData.gemmes = this.checkNull(formData.itemsByType['gemme']);
 | 
			
		||||
    formData.nourritureboissons = this.arrayOrEmpty(formData.itemsByType['nourritureboisson']);
 | 
			
		||||
    formData.gemmes = this.arrayOrEmpty(formData.itemsByType['gemme']);
 | 
			
		||||
 | 
			
		||||
    formData.objets = formData.conteneurs
 | 
			
		||||
      .concat(formData.materiel)
 | 
			
		||||
@@ -666,7 +669,7 @@ export class RdDUtility {
 | 
			
		||||
      case "msg_tmr_move":
 | 
			
		||||
        let actor = game.actors.get(sockmsg.data.actorId);
 | 
			
		||||
        if (actor.isOwner || game.user.isGM) {
 | 
			
		||||
          actor.refreshTMRView(sockmsg.data.tmrPos);
 | 
			
		||||
          actor.refreshTMRView();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
@@ -681,7 +684,7 @@ export class RdDUtility {
 | 
			
		||||
      let coord = event.currentTarget.attributes['data-tmr-coord'].value;
 | 
			
		||||
      let actorId = event.currentTarget.attributes['data-actor-id'].value;
 | 
			
		||||
      let actor = game.actors.get(actorId);
 | 
			
		||||
      actor.tmrApp.forceDemiRevePosition(coord);
 | 
			
		||||
      actor.tmrApp.positionnerDemiReve(coord);
 | 
			
		||||
    });
 | 
			
		||||
    // Gestion spécifique des sorts en réserve multiples (ie têtes)
 | 
			
		||||
    html.on("click", '#sort-reserve', event => {
 | 
			
		||||
@@ -692,7 +695,7 @@ export class RdDUtility {
 | 
			
		||||
      actor.tmrApp.lancerSortEnReserve(coord, sortId);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // gestion bouton tchat Acheter
 | 
			
		||||
    // gestion bouton tchat Possession
 | 
			
		||||
    html.on("click", '.defense-possession', event => {
 | 
			
		||||
      let attackerId = event.currentTarget.attributes['data-attackerId'].value
 | 
			
		||||
      let defenderId = event.currentTarget.attributes['data-defenderId'].value
 | 
			
		||||
@@ -702,6 +705,7 @@ export class RdDUtility {
 | 
			
		||||
 | 
			
		||||
    // gestion bouton tchat Acheter
 | 
			
		||||
    html.on("click", '.button-acheter', event => DialogItemAchat.onButtonAcheter(event));
 | 
			
		||||
    html.on("click", '.button-creer-acteur', event => RdDNameGen.onCreerActeur(event));
 | 
			
		||||
 | 
			
		||||
    // Gestion du bouton payer
 | 
			
		||||
    html.on("click", '.payer-button', event => {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,14 @@ import { TMRType } from "./tmr-utility.js";
 | 
			
		||||
const typeRencontres = {
 | 
			
		||||
 | 
			
		||||
  messager: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} vous propose d'emmener le message de votre un sort à ${rencData.rencontre.force} cases ${rencData.tmr.label}.`,
 | 
			
		||||
    msgEchec: (rencData) => `Le ${rencData.rencontre.name} est pressé et continue son chemin d'une traite sans vous accorder un regard.`,
 | 
			
		||||
    postSucces: (tmrDialog, rencData) => {
 | 
			
		||||
    msgSucces: async (rencData) => {
 | 
			
		||||
      if (rencData.actor.isTMRCache()){
 | 
			
		||||
        return `Le ${rencData.rencontre.name} vous propose d'emmener le message de votre un sort,  mais vous ne savez pas où vous êtes.`;
 | 
			
		||||
      }
 | 
			
		||||
      return `Le ${rencData.rencontre.name} vous propose d'emmener le message de votre un sort à ${rencData.rencontre.force} cases ${rencData.tmr.label}.`;
 | 
			
		||||
    },
 | 
			
		||||
    msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} est pressé et continue son chemin d'une traite sans vous accorder un regard.`,
 | 
			
		||||
    postSucces: async (tmrDialog, rencData) => {
 | 
			
		||||
      tmrDialog.setStateRencontre(rencData.rencontre.type);
 | 
			
		||||
      tmrDialog.choisirCasePortee(rencData.tmr.coord, rencData.rencontre.force);
 | 
			
		||||
    },
 | 
			
		||||
@@ -28,9 +33,14 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  passeur: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} vous propose de vous transporter à ${rencData.rencontre.force} cases des ${rencData.tmr.label}.`,
 | 
			
		||||
    msgEchec: (rencData) => `Le prix que demande le ${rencData.rencontre.name} est trop élevé, vous êtes réduit à poursuivre votre chemin par vos propres moyens.`,
 | 
			
		||||
    postSucces: (tmrDialog, rencData) => {
 | 
			
		||||
    msgSucces: async (rencData) => {
 | 
			
		||||
      if (rencData.actor.isTMRCache()){
 | 
			
		||||
        return `Le ${rencData.rencontre.name} vous propose de vous transporter, mais vous ne savez pas où vous êtes.`;
 | 
			
		||||
      }
 | 
			
		||||
      return `Le ${rencData.rencontre.name} vous propose de vous transporter à ${rencData.rencontre.force} cases des ${rencData.tmr.label}.`;
 | 
			
		||||
    },
 | 
			
		||||
    msgEchec: async (rencData)=> `Le prix que demande le ${rencData.rencontre.name} est trop élevé, vous êtes réduit à poursuivre votre chemin par vos propres moyens.`,
 | 
			
		||||
    postSucces: async (tmrDialog, rencData) => {
 | 
			
		||||
      tmrDialog.setStateRencontre(rencData.rencontre.type);
 | 
			
		||||
      tmrDialog.choisirCasePortee(rencData.tmr.coord, rencData.rencontre.force);
 | 
			
		||||
    },
 | 
			
		||||
@@ -49,9 +59,9 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  fleur: {
 | 
			
		||||
    msgSucces: (rencData) => `Vous cueillez la ${rencData.rencontre.name}, son parfum vous apporte ${rencData.rencontre.force} points de Rêve.`,
 | 
			
		||||
    msgEchec: (rencData) => `La ${rencData.rencontre.name} se fâne et disparaît entre vos doigts.`,
 | 
			
		||||
    postSucces: (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(rencData.rencontre.force),
 | 
			
		||||
    msgSucces: async (rencData) => `Vous cueillez la ${rencData.rencontre.name}, son parfum vous apporte ${rencData.rencontre.force} points de Rêve.`,
 | 
			
		||||
    msgEchec: async (rencData)=> `La ${rencData.rencontre.name} se fâne et disparaît entre vos doigts.`,
 | 
			
		||||
    postSucces: async (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(rencData.rencontre.force),
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "L'Ennemi, Charles Baudelaire",
 | 
			
		||||
      extrait: `Et qui sait si les fleurs nouvelles que je rêve
 | 
			
		||||
@@ -66,9 +76,9 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  mangeur: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} claque de sa machoire dans le vide avant de fuir.`,
 | 
			
		||||
    msgEchec: (rencData) => `Le ${rencData.rencontre.name} croque votre Rêve ! Il emporte ${rencData.rencontre.force} de vos points de rêve actuels`,
 | 
			
		||||
    postEchec: (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(-rencData.rencontre.force),
 | 
			
		||||
    msgSucces: async (rencData) => `Le ${rencData.rencontre.name} claque de sa machoire dans le vide avant de fuir.`,
 | 
			
		||||
    msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} croque votre Rêve ! Il emporte ${rencData.rencontre.force} de vos points de rêve actuels`,
 | 
			
		||||
    postEchec: async (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(-rencData.rencontre.force),
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "Conseil, Victor Hugo",
 | 
			
		||||
      extrait: `Rois ! la bure est souvent jalouse du velours.
 | 
			
		||||
@@ -85,16 +95,17 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  changeur: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} vaincu accepte de vous déplacer sur une autre ${TMRType[rencData.tmr.type].name} de votre choix en échange de sa liberté.`,
 | 
			
		||||
    msgEchec: (rencData) => {
 | 
			
		||||
      rencData.newTMR = TMRUtility.getTMRAleatoire(it => it.type = rencData.tmr.type);
 | 
			
		||||
      return `Le ${rencData.rencontre.name} vous embobine avec des promesses, et vous transporte en ${rencData.newTMR.label} sans attendre votre avis.`;
 | 
			
		||||
    },
 | 
			
		||||
    postSucces: (tmrDialog, rencData) => {
 | 
			
		||||
    msgSucces: async (rencData) => `Le ${rencData.rencontre.name} vaincu accepte de vous déplacer sur une autre ${TMRType[rencData.tmr.type].name} de votre choix en échange de sa liberté.`,
 | 
			
		||||
    msgEchec: async (rencData) => `Le ${rencData.rencontre.name} vous embobine avec des promesses, et vous transporte sur une autre ${TMRType[rencData.tmr.type].name} sans attendre votre avis.`,
 | 
			
		||||
    postSucces: async (tmrDialog, rencData) => {
 | 
			
		||||
      tmrDialog.setStateRencontre(rencData.rencontre.type);
 | 
			
		||||
      tmrDialog.choisirCaseType(rencData.tmr.type);
 | 
			
		||||
    },
 | 
			
		||||
    postEchec: (tmrDialog, rencData) => tmrDialog.forceDemiRevePosition(rencData.newTMR.coord),
 | 
			
		||||
    postEchec: async (tmrDialog, rencData) => {
 | 
			
		||||
      const newTMR = await TMRUtility.getTMRAleatoire(it => it.type == rencData.tmr.type && it.coord != rencData.tmr.coord);
 | 
			
		||||
      await tmrDialog.actor.forcerPositionTMRInconnue(newTMR);
 | 
			
		||||
      tmrDialog.positionnerDemiReve(newTMR.coord);
 | 
			
		||||
    },
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "Caligula - IIIème chant, Gérard de Nerval",
 | 
			
		||||
      extrait: `Allez, que le caprice emporte
 | 
			
		||||
@@ -111,9 +122,9 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  briseur: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} tente vainement de vous déconcentrer, avant de fuir sans demander son reste.`,
 | 
			
		||||
    msgEchec: (rencData) => `Le ${rencData.rencontre.name} vous déconcentre au point de briser votre demi-rêve.`,
 | 
			
		||||
    postEchec: (tmrDialog, rencData) => tmrDialog.close(),
 | 
			
		||||
    msgSucces: async (rencData) => `Le ${rencData.rencontre.name} tente vainement de vous déconcentrer, avant de fuir sans demander son reste.`,
 | 
			
		||||
    msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} vous déconcentre au point de briser votre demi-rêve.`,
 | 
			
		||||
    postEchec: async (tmrDialog, rencData) => tmrDialog.close(),
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "Rêve de Dragon, Denis Gerfaud",
 | 
			
		||||
      extrait: `La légende affirme que ce sont les Gnomes qui furent
 | 
			
		||||
@@ -134,8 +145,8 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  reflet: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} s'estompe dans l'oubli.`,
 | 
			
		||||
    msgEchec: (rencData) => `Vous êtes submergé par un ${rencData.rencontre.name}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!`,
 | 
			
		||||
    msgSucces: async (rencData) => `Le ${rencData.rencontre.name} s'estompe dans l'oubli.`,
 | 
			
		||||
    msgEchec: async (rencData)=> `Vous êtes submergé par un ${rencData.rencontre.name}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!`,
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "Une charogne, Charles Baudelaire",
 | 
			
		||||
      extrait: `Les formes s'effaçaient et n'étaient plus qu'un rêve,
 | 
			
		||||
@@ -152,9 +163,9 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  passeurfou: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} tente vainement de découvrir où vous avez caché vos réserves. Vous le chassez, et en déroute il part harceler un autre voyageur du rêve.`,
 | 
			
		||||
    msgEchec: (rencData) => TMRRencontres.msgEchecPasseurFou(rencData),
 | 
			
		||||
    postEchec: (tmrDialog, rencData) => TMRRencontres.postEchecPasseurFou(tmrDialog, rencData),
 | 
			
		||||
    msgSucces: async (rencData) => `Le ${rencData.rencontre.name} tente vainement de découvrir où vous avez caché vos réserves. Vous le chassez, et en déroute il part harceler un autre voyageur du rêve.`,
 | 
			
		||||
    msgEchec: async (rencData)=> TMRRencontres.msgEchecPasseurFou(rencData),
 | 
			
		||||
    postEchec: async (tmrDialog, rencData) => TMRRencontres.postEchecPasseurFou(tmrDialog, rencData),
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "Un Fou et un Sage, Jean de La Fontaine",
 | 
			
		||||
      extrait: `Certain Fou poursuivait à coups de pierre un Sage.
 | 
			
		||||
@@ -174,9 +185,9 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  tbblanc: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.`,
 | 
			
		||||
    msgEchec: (rencData) => `Le souffle du ${rencData.rencontre.name} vous déstabilise et vous emmène dans un nuage de poussière.`,
 | 
			
		||||
    postEchec: (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 1),
 | 
			
		||||
    msgSucces: async (rencData) => `Le ${rencData.rencontre.name} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.`,
 | 
			
		||||
    msgEchec: async (rencData)=> `Le souffle du ${rencData.rencontre.name} vous déstabilise et vous emmène dans un nuage de poussière.`,
 | 
			
		||||
    postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 1),
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "Rêve de Dragon, Denis Gerfaud",
 | 
			
		||||
      extrait: `Le Premier Âge fut appelé l'Âge des Dragons. Ce fut le commencement
 | 
			
		||||
@@ -191,9 +202,9 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  tbnoir: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} orageux vous enveloppe de fureur et d'éclairs, vous tenez bon face à la tempête qui s'éloigne sans vous éloigner de votre chemin.`,
 | 
			
		||||
    msgEchec: (rencData) => `Le ${rencData.rencontre.name} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.`,
 | 
			
		||||
    postEchec: (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 2),
 | 
			
		||||
    msgSucces: async (rencData) => `Le ${rencData.rencontre.name} orageux vous enveloppe de fureur et d'éclairs, vous tenez bon face à la tempête qui s'éloigne sans vous éloigner de votre chemin.`,
 | 
			
		||||
    msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.`,
 | 
			
		||||
    postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 2),
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "Rêve de Dragon, Denis Gerfaud",
 | 
			
		||||
      extrait: `Car le Second Âge fut bel et bien celui des Magiciens. Durant cette période, les
 | 
			
		||||
@@ -207,9 +218,9 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  tbrouge: {
 | 
			
		||||
    msgSucces: (rencData) => `Le ${rencData.rencontre.name} s'abat avec violence mais vous êtes plus rapide et parvenez à lui échapper.`,
 | 
			
		||||
    msgEchec: (rencData) => `Le ${rencData.rencontre.name} vous frappe de milliers de morsure et vous malmène à travers les terres médianes.`,
 | 
			
		||||
    postEchec: (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillonRouge(tmrDialog, rencData),
 | 
			
		||||
    msgSucces: async (rencData) => `Le ${rencData.rencontre.name} s'abat avec violence mais vous êtes plus rapide et parvenez à lui échapper.`,
 | 
			
		||||
    msgEchec: async (rencData)=> `Le ${rencData.rencontre.name} vous frappe de milliers de morsure et vous malmène à travers les terres médianes.`,
 | 
			
		||||
    postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillonRouge(tmrDialog, rencData),
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "Qu'est-ce de votre vie ? une bouteille molle, Jean-Baptiste Chassignet",
 | 
			
		||||
      extrait: `Qu'est-ce de votre vie ? un tourbillon rouant
 | 
			
		||||
@@ -228,10 +239,10 @@ const typeRencontres = {
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  rdd: {
 | 
			
		||||
    msgSucces: (rencData) => `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. Vous le maîtrisez et récupérez ses rêves. Vous gagnez ses ${rencData.rencontre.force} points de rêve`,
 | 
			
		||||
    msgEchec: (rencData) => `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. La rencontre tourne au cauchemar, dans la lutte épique, vous subissez ${rencData.rolled.isETotal ? 'deux queues' : 'une queue'} de dragon!`,
 | 
			
		||||
    postSucces: (tmrDialog, rencData) => TMRRencontres.onPostSuccessReveDeDragon(tmrDialog, rencData),
 | 
			
		||||
    postEchec: (tmrDialog, rencData) => TMRRencontres.onPostEchecReveDeDragon(tmrDialog, rencData),
 | 
			
		||||
    msgSucces: async (rencData) => `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. Vous le maîtrisez et récupérez ses rêves. Vous gagnez ses ${rencData.rencontre.force} points de rêve`,
 | 
			
		||||
    msgEchec: async (rencData)=> `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. La rencontre tourne au cauchemar, dans la lutte épique, vous subissez ${rencData.rolled.isETotal ? 'deux queues' : 'une queue'} de dragon!`,
 | 
			
		||||
    postSucces: async (tmrDialog, rencData) => TMRRencontres.onPostSuccessReveDeDragon(tmrDialog, rencData),
 | 
			
		||||
    postEchec: async (tmrDialog, rencData) => TMRRencontres.onPostEchecReveDeDragon(tmrDialog, rencData),
 | 
			
		||||
    poesieSucces: {
 | 
			
		||||
      reference: "Rêve de Dragon, Denis Gerfaud",
 | 
			
		||||
      extrait: `Le monde est Rêve de Dragons, mais nous ne savons
 | 
			
		||||
@@ -404,7 +415,7 @@ export class TMRRencontres {
 | 
			
		||||
  static async gererRencontre(tmrDialog, rencData) {
 | 
			
		||||
    let gestion = TMRRencontres.getGestionRencontre(rencData.rencontre.type);
 | 
			
		||||
    if (rencData.rolled.isSuccess) {
 | 
			
		||||
      rencData.message = gestion.msgSucces(rencData);
 | 
			
		||||
      rencData.message = await gestion.msgSucces(rencData);
 | 
			
		||||
      if (rencData.nbRounds > 1) {
 | 
			
		||||
        rencData.message += ` Au total, vous avez passé ${rencData.nbRounds} rounds à vous battre!`;
 | 
			
		||||
      }
 | 
			
		||||
@@ -412,7 +423,7 @@ export class TMRRencontres {
 | 
			
		||||
      return gestion.postSucces;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rencData.message = gestion.msgEchec(rencData);
 | 
			
		||||
    rencData.message = await gestion.msgEchec(rencData);
 | 
			
		||||
    if (rencData.nbRounds > 1) {
 | 
			
		||||
      rencData.message += ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`;
 | 
			
		||||
    }
 | 
			
		||||
@@ -444,7 +455,7 @@ export class TMRRencontres {
 | 
			
		||||
    if (tmrData.sortReserve) {
 | 
			
		||||
      await tmrDialog.processSortReserve(tmrData.sortReserve);
 | 
			
		||||
    }
 | 
			
		||||
    await tmrDialog.forceDemiRevePosition(tmrData.newTMR.coord);
 | 
			
		||||
    await tmrDialog.positionnerDemiReve(tmrData.newTMR.coord);
 | 
			
		||||
    if (tmrData.sortReserve) {
 | 
			
		||||
      tmrDialog.close();
 | 
			
		||||
    }
 | 
			
		||||
@@ -469,7 +480,7 @@ export class TMRRencontres {
 | 
			
		||||
    for (let i = 0; i < cases; i++) {
 | 
			
		||||
      coord = await TMRUtility.deplaceTMRAleatoire(actor, coord).coord;
 | 
			
		||||
    }
 | 
			
		||||
    await tmrDialog.forceDemiRevePosition(coord)
 | 
			
		||||
    await tmrDialog.positionnerDemiReve(coord)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* -------------------------------------------- */
 | 
			
		||||
 
 | 
			
		||||
@@ -94,9 +94,8 @@ export class Draconique {
 | 
			
		||||
    token[type ?? this.code()] = linkData;
 | 
			
		||||
    pixiTMR.addTooltip(token.sprite, this.tooltip(linkData));
 | 
			
		||||
    return token;
 | 
			
		||||
 | 
			
		||||
    return sprite;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * factory d'élément graphique PIXI correpsondant à l'objet draconique
 | 
			
		||||
   * @param {*} pixiTMR instance de PixiTMR qui gère les tooltips, les méthodes de création de sprite standard, les clicks.
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ export class PixiTMR {
 | 
			
		||||
    for (const [name, img] of Object.entries(PixiTMR.textures)) {
 | 
			
		||||
      loader = loader.add(name, img);
 | 
			
		||||
    }
 | 
			
		||||
    loader.onLoad.add((error, resaon) => { console.log("ERROR", error, resaon) });
 | 
			
		||||
    loader.onLoad.add((error, reason) => { console.log("ERROR", error, reason) });
 | 
			
		||||
    loader.load( (loader, resources) =>  {
 | 
			
		||||
      onLoad(loader, resources);
 | 
			
		||||
      for (let onAnimate of this.callbacksOnAnimate) {
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -29,7 +29,7 @@
 | 
			
		||||
  "url": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/",
 | 
			
		||||
  "license": "LICENSE.txt",
 | 
			
		||||
  "flags": {},
 | 
			
		||||
  "version": "1.5.77",
 | 
			
		||||
  "version": "1.5.84",
 | 
			
		||||
  "minimumCoreVersion": "0.8.0",
 | 
			
		||||
  "compatibleCoreVersion": "9",
 | 
			
		||||
  "scripts": [],
 | 
			
		||||
@@ -500,7 +500,7 @@
 | 
			
		||||
  "dependencies": [],
 | 
			
		||||
  "socket": true,
 | 
			
		||||
  "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v1.5/system.json",
 | 
			
		||||
  "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-1.5.77.zip",
 | 
			
		||||
  "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-1.5.84.zip",
 | 
			
		||||
  "protected": false,
 | 
			
		||||
  "gridDistance": 1,
 | 
			
		||||
  "gridUnits": "m",
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,6 @@
 | 
			
		||||
            {{/each}}
 | 
			
		||||
            <li class="flexrow">
 | 
			
		||||
              <span class="carac-label" name="carac-total">Total Caractéristiques</span>
 | 
			
		||||
              {{log 'data-actor-creature' this}}
 | 
			
		||||
              <span class="competence-value" name="carac-total-value">{{calc.caracTotal}}</span>
 | 
			
		||||
            </li>
 | 
			
		||||
          </ol>
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
 | 
			
		||||
    {{!-- Carac Tab --}}
 | 
			
		||||
    <div class="tab items" data-group="primary" data-tab="carac">
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      <div class="grid grid-2col">
 | 
			
		||||
        <div class="flex-group-left flexcol">
 | 
			
		||||
          <ol class="carac-list alterne-list">
 | 
			
		||||
@@ -65,6 +65,7 @@
 | 
			
		||||
                {{#select data.definition.typeentite}}
 | 
			
		||||
                <option value="incarne">Incarnée</option>
 | 
			
		||||
                <option value="nonincarne">Non Incarnée</option>
 | 
			
		||||
                <option value="blurette">Blurete</option>
 | 
			
		||||
                {{/select}}
 | 
			
		||||
              </select>
 | 
			
		||||
            </li>
 | 
			
		||||
@@ -89,9 +90,7 @@
 | 
			
		||||
    
 | 
			
		||||
    {{!-- Compétences Tab --}}
 | 
			
		||||
    <div class="tab competences" data-group="primary" data-tab="competences">
 | 
			
		||||
 | 
			
		||||
      <div class="flexcol">
 | 
			
		||||
 | 
			
		||||
        <div class="flex-group-left flexcol competence-column">
 | 
			
		||||
          <ol class="item-list alterne-list">
 | 
			
		||||
            {{#each competences as |comp key|}}
 | 
			
		||||
@@ -111,25 +110,24 @@
 | 
			
		||||
            </li>
 | 
			
		||||
            {{/each}}
 | 
			
		||||
          </ol>
 | 
			
		||||
 | 
			
		||||
          <div class="flex-group-left flexcol competence-column">
 | 
			
		||||
            <ol class="item-list alterne-list">
 | 
			
		||||
              {{#each possessions as |possession key|}}
 | 
			
		||||
              <li class="item flexrow list-item" data-item-id="{{possession._id}}">
 | 
			
		||||
                <img class="sheet-competence-img" src="{{possession.img}}" />
 | 
			
		||||
                <span class="competence-label">{{possession.name}}</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}}
 | 
			
		||||
            </ol>
 | 
			
		||||
  
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="flex-group-left flexcol competence-column">
 | 
			
		||||
          <ol class="item-list alterne-list">
 | 
			
		||||
            {{#each possessions as |possession key|}}
 | 
			
		||||
            <li class="item flexrow list-item" data-item-id="{{possession._id}}">
 | 
			
		||||
              <img class="sheet-competence-img" src="{{possession.img}}" />
 | 
			
		||||
              <span class="competence-label">{{possession.name}}</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}}
 | 
			
		||||
          </ol>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
    {{!-- Biography Tab --}}
 | 
			
		||||
    <div class="tab description" data-group="primary" data-tab="description">
 | 
			
		||||
      <div class="form-group editor">
 | 
			
		||||
@@ -137,8 +135,6 @@
 | 
			
		||||
      </div>
 | 
			
		||||
      {{>"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-editor-notes-mj.html"}}
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
  </section>
 | 
			
		||||
</form>
 | 
			
		||||
@@ -307,7 +307,6 @@
 | 
			
		||||
                  <a class="competence-label" name="{{esq.name}}">
 | 
			
		||||
                    <img class="sheet-competence-img" src="{{esq.img}}"/>
 | 
			
		||||
                    <span>{{esq.name}}</span>
 | 
			
		||||
                    {{log esq}}
 | 
			
		||||
                  </a>
 | 
			
		||||
                </span>
 | 
			
		||||
                <span class="arme-initiative"></span>
 | 
			
		||||
@@ -322,6 +321,7 @@
 | 
			
		||||
        {{!-- Liste de blessures --}}
 | 
			
		||||
        {{> "systems/foundryvtt-reve-de-dragon/templates/actor-liste-blessures-partial.html" this}}
 | 
			
		||||
 | 
			
		||||
        {{#if maladiesPoisons.length}}
 | 
			
		||||
        {{!-- Maladies & Poison --}}
 | 
			
		||||
        <h3 class="blessures-title">Maladies & Poisons:</h3>
 | 
			
		||||
        <ul class="item-list alterne-list">
 | 
			
		||||
@@ -355,28 +355,30 @@
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
          </ul>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
 | 
			
		||||
          {{!-- Possession --}}
 | 
			
		||||
          <h3 class="blessures-title">Possession:</h3>
 | 
			
		||||
          <ul class="item-list alterne-list">
 | 
			
		||||
            <li class="competence-header flexrow">
 | 
			
		||||
              <span class="competence-title flex-grow competence-label">Nom</span>
 | 
			
		||||
              <span class="competence-title competence-label">Type</span>
 | 
			
		||||
            </li>
 | 
			
		||||
        {{#if possessions.length}}
 | 
			
		||||
        {{!-- Possession --}}
 | 
			
		||||
        <h3 class="blessures-title">Possession:</h3>
 | 
			
		||||
        <ul class="item-list alterne-list">
 | 
			
		||||
          <li class="competence-header flexrow">
 | 
			
		||||
            <span class="competence-title flex-grow competence-label">Nom</span>
 | 
			
		||||
            <span class="competence-title competence-label">Type</span>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{#each possessions as |possession  key|}}
 | 
			
		||||
            <li class="item flexrow list-item" data-item-id="{{possession._id}}">
 | 
			
		||||
                <span class="competence-label">
 | 
			
		||||
                  <a class="sheet-possession-attack">{{possession.name}} (Conjurer)</a>
 | 
			
		||||
                </span>
 | 
			
		||||
                <span class="competence-label">{{possession.data.type}}</span>
 | 
			
		||||
                <div class="item-controls">
 | 
			
		||||
                  <a class="item-control item-edit" title="Modifier"><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}}
 | 
			
		||||
            </ul>
 | 
			
		||||
  
 | 
			
		||||
          <li class="item flexrow list-item" data-item-id="{{possession._id}}">
 | 
			
		||||
              <span class="competence-label">
 | 
			
		||||
                <a class="sheet-possession-attack">{{possession.name}} (Conjurer)</a>
 | 
			
		||||
              </span>
 | 
			
		||||
              <span class="competence-label">{{possession.data.type}}</span>
 | 
			
		||||
              <div class="item-controls">
 | 
			
		||||
                <a class="item-control item-edit" title="Modifier"><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}}
 | 
			
		||||
          </ul>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      {{!-- Connaissances Tab --}}
 | 
			
		||||
@@ -509,65 +511,8 @@
 | 
			
		||||
          </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
        <hr>
 | 
			
		||||
        {{#if data.attributs.hautrevant.value}}
 | 
			
		||||
        {{#if options.isGM}}
 | 
			
		||||
        <h3>Signes draconiques</h3>
 | 
			
		||||
        <ul class="item-list alterne-list">
 | 
			
		||||
          {{#each signesdraconiques as |signe key|}}
 | 
			
		||||
          <li class="item list-item flexrow" data-item-id="{{signe._id}}" data-attribute="{{key}}">
 | 
			
		||||
            <span class="display-label flex-grow"> <a data-item-id="{{signe._id}}">{{signe.name}}</a></span> 
 | 
			
		||||
            <span class="flex-shrink">{{signe.data.difficulte}}</span>
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
        <h3>Sorts:</h3>
 | 
			
		||||
        <ul class="item-list alterne-list">
 | 
			
		||||
          {{#each sorts as |sort key|}}
 | 
			
		||||
          <li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
 | 
			
		||||
            <span class="display-label flex-grow"> <a data-item-id="{{sort._id}}">{{sort.name}}</a></span> 
 | 
			
		||||
            <span>{{sort.data.draconic}} / {{sort.data.difficulte}}</span>
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        
 | 
			
		||||
        <h3>Sorts en Réserve:</h3>
 | 
			
		||||
        <ul class="item-list alterne-list">
 | 
			
		||||
          {{#each hautreve.sortsReserve as |reserve key|}}
 | 
			
		||||
          <li class="item list-item flexrow" data-item-id="{{reserve._id}}" data-attribute="{{key}}">
 | 
			
		||||
            <img class="sheet-competence-img" src="{{reserve.sort.img}}" />
 | 
			
		||||
            <span class="display-label flex-grow">{{reserve.sort.name}}</span> 
 | 
			
		||||
            <span class="flex-shrink">r{{reserve.sort.data.ptreve_reel}}</span> 
 | 
			
		||||
            <span class="flex-shrink">{{reserve.coord}}</span> 
 | 
			
		||||
            <span>{{caseTmr-label reserve.coord}}</span> 
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <a class="item-control item-delete flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        
 | 
			
		||||
        <h3>Méditations:</h3>
 | 
			
		||||
        <ul class="item-list">
 | 
			
		||||
          {{#each meditations as |meditation key|}}
 | 
			
		||||
          <li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}">
 | 
			
		||||
            <span class="meditation-label flex-grow"><a data-item-id="{{meditation._id}}">{{meditation.name}} - {{meditation.data.competence}}</a></span> 
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <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}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        <hr>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
        {{!-- Queues, Souffles, Tetes, Ombre --}}
 | 
			
		||||
        {{#if queues.length}}
 | 
			
		||||
        <h3>Queues:</h3>
 | 
			
		||||
        <ul class="flex-group-left">
 | 
			
		||||
          {{#each queues as |queue key|}}
 | 
			
		||||
@@ -579,28 +524,8 @@
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        <h3>Souffles:</h3>
 | 
			
		||||
        <ul class="item-list">
 | 
			
		||||
          {{#each souffles as |souffle key|}}
 | 
			
		||||
          <li class="item flexrow" data-attribute={{key}} data-item-id="{{souffle._id}}">
 | 
			
		||||
            <span class="display-label flex-grow"><a data-item-id="{{souffle._id}}">{{souffle.name}}</a></span>
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}                 
 | 
			
		||||
        </ul>
 | 
			
		||||
        <h3>Tetes:</h3>
 | 
			
		||||
        <ul class="item-list">
 | 
			
		||||
          {{#each tetes as |tete key|}}
 | 
			
		||||
          <li class="item flexrow" data-attribute={{key}} data-item-id="{{tete._id}}">
 | 
			
		||||
            <span class="display-label flex-grow"><a data-item-id="{{tete._id}}">{{tete.name}}</a></span>
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
        {{#if ombres.length}}
 | 
			
		||||
        <h3>Ombres de Thanatos:</h3>
 | 
			
		||||
        <ul class="item-list">
 | 
			
		||||
          {{#each ombres as |ombre key|}}
 | 
			
		||||
@@ -612,35 +537,128 @@
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
        {{#if souffles.length}}
 | 
			
		||||
        <h3>Souffles:</h3>
 | 
			
		||||
        <ul class="item-list">
 | 
			
		||||
          {{#each souffles as |souffle key|}}
 | 
			
		||||
          <li class="item flexrow" data-attribute={{key}} data-item-id="{{souffle._id}}">
 | 
			
		||||
            <span class="display-label flex-grow"><a data-item-id="{{souffle._id}}">{{souffle.name}}</a></span>
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
        {{#if tetes.length}}
 | 
			
		||||
        <h3>Tetes:</h3>
 | 
			
		||||
        <ul class="item-list">
 | 
			
		||||
          {{#each tetes as |tete key|}}
 | 
			
		||||
          <li class="item flexrow" data-attribute={{key}} data-item-id="{{tete._id}}">
 | 
			
		||||
            <span class="display-label flex-grow"><a data-item-id="{{tete._id}}">{{tete.name}}</a></span>
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
        {{#if data.attributs.hautrevant.value}}
 | 
			
		||||
          {{#if (and options.isGM signesdraconiques.length)}}
 | 
			
		||||
            <h3>Signes draconiques</h3>
 | 
			
		||||
            <ul class="item-list alterne-list">
 | 
			
		||||
              {{#each signesdraconiques as |signe key|}}
 | 
			
		||||
              <li class="item list-item flexrow" data-item-id="{{signe._id}}" data-attribute="{{key}}">
 | 
			
		||||
                <span class="display-label flex-grow"> <a data-item-id="{{signe._id}}">{{signe.name}}</a></span> 
 | 
			
		||||
                <span class="flex-shrink">{{signe.data.difficulte}}</span>
 | 
			
		||||
                <div class="item-controls flex-shrink">
 | 
			
		||||
                  <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
              </li>
 | 
			
		||||
              {{/each}}
 | 
			
		||||
            </ul>
 | 
			
		||||
          {{/if}}
 | 
			
		||||
 | 
			
		||||
          {{#if hautreve.rencontres.length}}
 | 
			
		||||
            <h3>Rencontres présentes:</h3>
 | 
			
		||||
            <ul class="item-list">
 | 
			
		||||
              {{#each hautreve.rencontres as |rencontre key|}}
 | 
			
		||||
              <li class="item flexrow" data-item-id="{{key}}" data-attribute="{{key}}">
 | 
			
		||||
                <span class="display-label"><a data-item-id="{{key}}">{{rencontre.name}} r{{rencontre.force}}</a></span> 
 | 
			
		||||
                <span class="flex-shrink">{{rencontre.coord}} - {{caseTmr-label rencontre.coord}}</span> 
 | 
			
		||||
                {{#if rencontre.date}}
 | 
			
		||||
                <span>{{upperFirst rencontre.heure}}, le {{rencontre.date}}</span> 
 | 
			
		||||
                {{/if}}
 | 
			
		||||
                <div class="item-controls flex-shrink">
 | 
			
		||||
                  <a class="item-control rencontre-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
              </li>
 | 
			
		||||
              {{/each}}
 | 
			
		||||
            </ul>
 | 
			
		||||
          {{/if}}
 | 
			
		||||
          {{#if hautreve.sortsReserve.length}}
 | 
			
		||||
            <h3>Sorts en Réserve:</h3>
 | 
			
		||||
            <ul class="item-list alterne-list">
 | 
			
		||||
              {{#each hautreve.sortsReserve as |reserve key|}}
 | 
			
		||||
              <li class="item list-item flexrow" data-item-id="{{reserve._id}}" data-attribute="{{key}}">
 | 
			
		||||
                <img class="sheet-competence-img" src="{{reserve.sort.img}}" />
 | 
			
		||||
                <span class="display-label">{{reserve.sort.name}} r{{reserve.sort.data.ptreve_reel}}</span> 
 | 
			
		||||
                <span>{{reserve.coord}} - {{caseTmr-label reserve.coord}}</span> 
 | 
			
		||||
                <div class="item-controls flex-shrink">
 | 
			
		||||
                  <a class="item-control item-delete flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
              </li>
 | 
			
		||||
              {{/each}}
 | 
			
		||||
            </ul>
 | 
			
		||||
          {{/if}}
 | 
			
		||||
 | 
			
		||||
          <hr>
 | 
			
		||||
 | 
			
		||||
          <h3>Sorts:</h3>
 | 
			
		||||
          <ul class="item-list alterne-list">
 | 
			
		||||
            {{#each sorts as |sort key|}}
 | 
			
		||||
            <li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
 | 
			
		||||
              <span class="display-label flex-grow">
 | 
			
		||||
                <a data-item-id="{{sort._id}}">{{sort.name}}
 | 
			
		||||
                  - {{#if sort.data.caseTMRspeciale}}{{sort.data.caseTMRspeciale}}{{else}}{{upperFirst sort.data.caseTMR}}{{/if}}
 | 
			
		||||
                </a>
 | 
			
		||||
              </span> 
 | 
			
		||||
              <span>{{sort.data.draconic}} / {{sort.data.difficulte}}</span>
 | 
			
		||||
              <div class="item-controls flex-shrink">
 | 
			
		||||
                <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
              </div>
 | 
			
		||||
            </li>
 | 
			
		||||
            {{/each}}
 | 
			
		||||
          </ul>
 | 
			
		||||
 | 
			
		||||
          <h3>Méditations:</h3>
 | 
			
		||||
          <ul class="item-list">
 | 
			
		||||
            {{#each meditations as |meditation key|}}
 | 
			
		||||
            <li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}">
 | 
			
		||||
              <span class="meditation-label flex-grow"><a data-item-id="{{meditation._id}}">{{meditation.name}} - {{meditation.data.competence}}</a></span> 
 | 
			
		||||
              <div class="item-controls flex-shrink">
 | 
			
		||||
                <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}}
 | 
			
		||||
          </ul>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <h3>Rencontres présentes:</h3>
 | 
			
		||||
        <ul class="item-list">
 | 
			
		||||
          {{#each hautreve.rencontres as |rencontre key|}}
 | 
			
		||||
          <li class="item flexrow" data-item-id="{{key}}" data-attribute="{{key}}">
 | 
			
		||||
            <span class="display-label"><a data-item-id="{{key}}">{{rencontre.name}} - {{rencontre.coord}}</a></span> 
 | 
			
		||||
            <span class="flex-shrink">{{caseTmr-label rencontre.coord}}</span> 
 | 
			
		||||
            {{#if rencontre.date}}
 | 
			
		||||
            <span>Le {{rencontre.date}} à {{rencontre.heure}}</span> 
 | 
			
		||||
            {{/if}}
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <a class="item-control rencontre-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <h3>Cases Spéciales:</h3>
 | 
			
		||||
        <ul class="item-list">
 | 
			
		||||
          {{#each hautreve.casesTmr as |casetmr key|}}
 | 
			
		||||
          <li class="item flexrow" data-item-id="{{casetmr._id}}" data-attribute="{{key}}">
 | 
			
		||||
            <span class="display-label"><a data-item-id="{{casetmr._id}}">{{casetmr.name}}</a></span> 
 | 
			
		||||
            <div class="item-controls flex-shrink">
 | 
			
		||||
              <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          {{/each}}
 | 
			
		||||
        </ul>
 | 
			
		||||
          {{#if hautreve.casesTmr}}
 | 
			
		||||
            <h3>Cases Spéciales:</h3>
 | 
			
		||||
            <ul class="item-list">
 | 
			
		||||
              {{#each hautreve.casesTmr as |casetmr key|}}
 | 
			
		||||
              <li class="item flexrow" data-item-id="{{casetmr._id}}" data-attribute="{{key}}">
 | 
			
		||||
                <span class="display-label"><a data-item-id="{{casetmr._id}}">{{casetmr.name}}</a></span>
 | 
			
		||||
                <span>{{casetmr.data.coord}} - {{caseTmr-label casetmr.data.coord}}</span> 
 | 
			
		||||
                <div class="item-controls flex-shrink">
 | 
			
		||||
                  <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
 | 
			
		||||
                </div>
 | 
			
		||||
              </li>
 | 
			
		||||
              {{/each}}
 | 
			
		||||
            </ul>
 | 
			
		||||
          {{/if}}
 | 
			
		||||
        <br><br>
 | 
			
		||||
        {{/if}}
 | 
			
		||||
      </div>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								templates/chat-command-nom.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								templates/chat-command-nom.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
 | 
			
		||||
<h4>Proposition de nom: {{nom}}</h4>
 | 
			
		||||
<span class="chat-card-button-area">
 | 
			
		||||
  <a class="button-creer-acteur chat-card-button"
 | 
			
		||||
    data-nom='{{nom}}'
 | 
			
		||||
    data-type='personnage'
 | 
			
		||||
    >
 | 
			
		||||
  Créer un Personnage</a>
 | 
			
		||||
</span>
 | 
			
		||||
<span class="chat-card-button-area">
 | 
			
		||||
  <a class="button-creer-acteur chat-card-button"
 | 
			
		||||
    data-nom='{{nom}}'
 | 
			
		||||
    data-type='creature'>
 | 
			
		||||
  Créer une créature</a>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
@@ -1,6 +1,11 @@
 | 
			
		||||
<img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}"/>
 | 
			
		||||
<h4 data-categorie="tmr" data-actor-id="{{actor._id}}">
 | 
			
		||||
  {{alias}} tente de {{maitrise.verbe}} {{le tmr.genre}} {{tmr.label}} ({{tmr.coord}})
 | 
			
		||||
  {{alias}} tente de {{maitrise.verbe}} {{le tmr.genre}}
 | 
			
		||||
  {{#if isTMRCache}}
 | 
			
		||||
    {{caseTmr-type tmr.coord}}
 | 
			
		||||
  {{else}}
 | 
			
		||||
    {{tmr.label}} ({{tmr.coord}})
 | 
			
		||||
  {{/if}}
 | 
			
		||||
</h4>
 | 
			
		||||
{{#if previous}}
 | 
			
		||||
  {{#with previous}}
 | 
			
		||||
@@ -11,15 +16,20 @@
 | 
			
		||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
 | 
			
		||||
<hr>
 | 
			
		||||
<span>
 | 
			
		||||
{{#if rolled.isSuccess}}
 | 
			
		||||
  {{alias}} parvient à {{maitrise.verbe}} {{le tmr.genre}} {{tmr.label}} !
 | 
			
		||||
  {{alias}}
 | 
			
		||||
  {{#if rolled.isSuccess}}parvient à{{else}}échoue à{{/if}}
 | 
			
		||||
  {{maitrise.verbe}} {{le tmr.genre}}
 | 
			
		||||
  {{#if isTMRCache}}
 | 
			
		||||
    {{caseTmr-type tmr.coord}}
 | 
			
		||||
  {{else}}
 | 
			
		||||
  {{alias}} échoue à {{maitrise.verbe}} {{le tmr.genre}} {{tmr.label}}.
 | 
			
		||||
  {{alias}} <strong>quitte les Terres Médianes</strong> !
 | 
			
		||||
  {{#if souffle}}
 | 
			
		||||
    <br>De plus, son échec total lui fait subir un Souffle de Dragon : {{souffle.name}}
 | 
			
		||||
    {{tmr.label}} ({{tmr.coord}})
 | 
			
		||||
  {{/if}}!
 | 
			
		||||
  {{#if rolled.isEchec}}
 | 
			
		||||
    {{alias}} <strong>quitte les Terres Médianes</strong> !
 | 
			
		||||
    {{#if souffle}}
 | 
			
		||||
      <br>De plus, son échec total lui fait subir un Souffle de Dragon : {{souffle.name}}
 | 
			
		||||
    {{/if}}
 | 
			
		||||
  {{/if}}
 | 
			
		||||
{{/if}}
 | 
			
		||||
</span>
 | 
			
		||||
{{#if poesie}}
 | 
			
		||||
<hr>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								templates/chat-resultat-meteo.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								templates/chat-resultat-meteo.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<img class="chat-icon" src="icons/svg/lightning.svg" alt="Météo" />
 | 
			
		||||
<h4>Météo aléatoire</h4>
 | 
			
		||||
<ul>
 | 
			
		||||
  <li>Vent: {{lowerFirst vent.description}} {{apostrophe 'de' vent.direction}}, force {{vent.force}}</li>
 | 
			
		||||
  <li>Mer {{lowerFirst mer.description}}, {{apostrophe 'de' mer.direction}}, force {{mer.force}}</li>
 | 
			
		||||
  <li>Température {{lowerFirst temperature.description}} ({{numberFormat temperature.force decimals=0 sign=true}})</li>
 | 
			
		||||
  <li>Couverture nuageuse: {{lowerFirst nuage.description}}</li>
 | 
			
		||||
  <li>Pluie: {{lowerFirst pluie.description}}</li>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -1,31 +1,38 @@
 | 
			
		||||
<img class="chat-icon" src="{{competence.img}}" />
 | 
			
		||||
<h4>
 | 
			
		||||
  {{#if (eq mode "possession")}}
 | 
			
		||||
    {{alias}} tente de posséder {{possede}}
 | 
			
		||||
    {{attacker.name}} tente de {{#if isECNIDefender}}conjurer la possession de{{else}}posséder{{/if}} {{defender.name}}
 | 
			
		||||
  {{else}}
 | 
			
		||||
    {{alias}} tente de conjurer la possession de {{possesseur}}
 | 
			
		||||
    {{defender.name}} tente de {{#if isECNIDefender}}résister à{{else}}conjurer la possession de{{/if}} {{attacker.name}}
 | 
			
		||||
  {{/if}}
 | 
			
		||||
</h4>
 | 
			
		||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
<div>
 | 
			
		||||
  <span class='chat-card-button-area'>
 | 
			
		||||
    <br>
 | 
			
		||||
    {{#if (eq mode "possession")}}
 | 
			
		||||
      {{#if possession.isSuccess}}
 | 
			
		||||
        <a class='defense-possession chat-card-button' data-attackerId='{{attackerId}}'
 | 
			
		||||
                data-defenderId='{{defenderId}}' data-possessionId='{{possession.data.possessionid}}'>Résister à la possession</a>
 | 
			
		||||
              </a>
 | 
			
		||||
        <a class='defense-possession chat-card-button'
 | 
			
		||||
            data-attackerId='{{attacker.id}}'
 | 
			
		||||
            data-defenderId='{{defender.id}}'
 | 
			
		||||
            data-possessionId='{{possession.data.possessionid}}'>
 | 
			
		||||
            {{#if isECNIDefender}}
 | 
			
		||||
            Résister à la conjuration
 | 
			
		||||
            {{else}}
 | 
			
		||||
            Résister à la possession
 | 
			
		||||
            {{/if}}
 | 
			
		||||
        </a>
 | 
			
		||||
      {{else}}
 | 
			
		||||
        La Tentative de Possession a échouée !
 | 
			
		||||
        La Tentative de {{#if isECNIDefender}}conjuration{{else}}possession{{/if}} a échoué !
 | 
			
		||||
      {{/if}}
 | 
			
		||||
    {{else}}
 | 
			
		||||
      {{#if rolled.isSuccess}}
 | 
			
		||||
        La Tentative de Possession a été conjurée ! {{alias}} résiste à la tentative de possession.
 | 
			
		||||
      {{else}}
 | 
			
		||||
        La Tentative de Possession n'a pas pu être conjurée !
 | 
			
		||||
        La tentative de {{#if isECNIDefender}}conjuration a été repoussée{{else}}possession a été conjurée{{/if}}!
 | 
			
		||||
        {{defender.name}} a résisté.
 | 
			
		||||
        {{else}}
 | 
			
		||||
        La tentative de {{#if isECNIDefender}}conjuration a réussi{{else}}possession n'a pas pu être conjurée{{/if}}!
 | 
			
		||||
      {{/if}}
 | 
			
		||||
    {{/if}}
 | 
			
		||||
    <br>Points de Possession: {{possession.ptsPossession}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,9 @@
 | 
			
		||||
<form class="skill-roll-dialog">
 | 
			
		||||
  <h2>Conjuration d'une Possession {{possession.name}}!</h2>
 | 
			
		||||
  <h2>
 | 
			
		||||
    {{defender.name}} tente de
 | 
			
		||||
    {{#if isECNIDefender}}maintenir{{else}}résister à{{/if}}
 | 
			
		||||
    la possession de {{attacker.name}}
 | 
			
		||||
  </h2>
 | 
			
		||||
  <div class="grid grid-2col">
 | 
			
		||||
    <div class="flex-group-left">
 | 
			
		||||
      <img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,10 @@
 | 
			
		||||
<form class="skill-roll-dialog">
 | 
			
		||||
  <h2>Maîtrise {{tmr.label}} ({{tmr.coord}})</h2>
 | 
			
		||||
  <h2>Maîtrise {{#if isTMRCache}}
 | 
			
		||||
    {{tmr.type}}
 | 
			
		||||
  {{else}}
 | 
			
		||||
    {{tmr.label}} ({{tmr.coord}})
 | 
			
		||||
  {{/if}}
 | 
			
		||||
  </h2>
 | 
			
		||||
  <div class="grid grid-2col">
 | 
			
		||||
    <div class="flex-group-left">
 | 
			
		||||
      <img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
{{log 'lecture signe draconique' this}}
 | 
			
		||||
<form class="dialog-roll-sort">
 | 
			
		||||
  <h2>Lire le signe draconique
 | 
			
		||||
    <select name="signe-draconique" class="roll-signedraconique flex-grow" data-dtype="String">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,13 @@
 | 
			
		||||
<div class="control-icon rdd-combat ">
 | 
			
		||||
  <img class="rdd-hud-togglebutton" src="systems/foundryvtt-reve-de-dragon/icons/heures/hd06.svg" width="36" height="36" title="Attaque"/>
 | 
			
		||||
  <div class="rdd-hud-list tokenhudext left">
 | 
			
		||||
    {{#each armes as |arme key|}}
 | 
			
		||||
    {{#unless arme.data.initOnly}}
 | 
			
		||||
    <div class="control-icon tokenhudicon rdd-hud-menu rdd-attaque" data-combatant-id="{{../combatant.id}}" data-arme-id="{{arme.index}}"  title="{{arme.name}}">
 | 
			
		||||
      <label>C:{{arme.name}}  {{arme.data.mainInfo}}</label>
 | 
			
		||||
    {{#each actions as |action key|}}
 | 
			
		||||
    {{#unless action.data.initOnly}}
 | 
			
		||||
    <div class="control-icon tokenhudicon rdd-hud-menu rdd-attaque"
 | 
			
		||||
        data-combatant-id="{{../combatant.id}}"
 | 
			
		||||
        data-action-index="{{action.index}}"
 | 
			
		||||
        title="{{action.name}}">
 | 
			
		||||
      <label>{{action.name}}  {{action.data.mainInfo}}</label>
 | 
			
		||||
    </div>
 | 
			
		||||
    {{/unless}}
 | 
			
		||||
    {{/each}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,22 @@
 | 
			
		||||
<div class="control-icon rdd-initiative ">
 | 
			
		||||
  <img class="rdd-hud-togglebutton" src="icons/svg/sword.svg" width="36" height="36" title="Initiative" />
 | 
			
		||||
  <div class="rdd-hud-list tokenhudext right">
 | 
			
		||||
    {{#each armes as |arme key|}}
 | 
			
		||||
    <div class="control-icon tokenhudicon rdd-hud-menu" data-command="{{arme.command}}" data-combatant-id="{{../combatant.id}}" data-arme-id="{{arme.index}}" title="{{arme.name}}">
 | 
			
		||||
      <label>I:{{arme.name}} {{arme.data.mainInfo}}</label>
 | 
			
		||||
    {{#each actions as |action key|}}
 | 
			
		||||
    {{log 'action-hud-init' action}}
 | 
			
		||||
    <div class="control-icon tokenhudicon rdd-hud-menu"
 | 
			
		||||
        data-combatant-id="{{../combatant.id}}"
 | 
			
		||||
        data-action-index="{{action.index}}"
 | 
			
		||||
        title="{{action.name}}">
 | 
			
		||||
      <label>init: {{action.name}} {{action.data.mainInfo}}</label>
 | 
			
		||||
    </div>
 | 
			
		||||
    {{/each}}
 | 
			
		||||
    {{#each commandes as |commande key|}}
 | 
			
		||||
    <div class="control-icon tokenhudicon rdd-hud-menu" data-command="{{commande.command}}" data-combatant-id="{{../combatant.id}}" data-arme-id="{{commande.index}}" title="{{commande.name}}">
 | 
			
		||||
      <label>I:{{commande.name}}</label>
 | 
			
		||||
    <div class="control-icon tokenhudicon rdd-hud-menu"
 | 
			
		||||
        data-command="{{commande.command}}" 
 | 
			
		||||
        data-combatant-id="{{../combatant.id}}"
 | 
			
		||||
        data-action-index="{{commande.index}}"
 | 
			
		||||
        title="{{commande.name}}">
 | 
			
		||||
      <label>{{commande.name}}</label>
 | 
			
		||||
    </div>
 | 
			
		||||
    {{/each}}    
 | 
			
		||||
  </div>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user