Compare commits
	
		
			159 Commits
		
	
	
		
			foundryvtt
			...
			foundryvtt
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 57d52c1966 | |||
| e3a29cdab5 | |||
| 
						 | 
					10e4f14eb2 | ||
| 04273dfcf1 | |||
| 8c5c01114e | |||
| 
						 | 
					19e6124330 | ||
| 
						 | 
					1c908b50cb | ||
| 
						 | 
					969cedfc3d | ||
| 
						 | 
					830e66749d | ||
| 
						 | 
					df26e654ae | ||
| 
						 | 
					153bfe2e75 | ||
| 
						 | 
					f6d42875ae | ||
| 
						 | 
					450cb8e899 | ||
| 0202938910 | |||
| 512a056e59 | |||
| 
						 | 
					214377c66d | ||
| 752e534350 | |||
| c85a544cc9 | |||
| 3a90c693d9 | |||
| c04b179176 | |||
| 
						 | 
					63770790b9 | ||
| 
						 | 
					aefc7a434b | ||
| 
						 | 
					f02959adee | ||
| 
						 | 
					e652027b02 | ||
| 
						 | 
					2122a54db7 | ||
| f027e3318b | |||
| 
						 | 
					31b4d1cfcc | ||
| 
						 | 
					5056c35038 | ||
| 
						 | 
					7b58407634 | ||
| 
						 | 
					7efa7be1c0 | ||
| 
						 | 
					717bb6fc6e | ||
| 51273bcc3e | |||
| 
						 | 
					b8f3a9af27 | ||
| 
						 | 
					ab704c46d2 | ||
| 
						 | 
					db8fd6dbf8 | ||
| 
						 | 
					d998a4cb08 | ||
| 
						 | 
					b1e27a9597 | ||
| eaac9564b4 | |||
| 
						 | 
					0826c7e9e3 | ||
| 
						 | 
					bdd3802e72 | ||
| 
						 | 
					b07cea40e2 | ||
| 
						 | 
					bb7f4c42ad | ||
| 
						 | 
					ac15a022df | ||
| a43c725b06 | |||
| 
						 | 
					1276c64835 | ||
| 
						 | 
					4b4d778d9c | ||
| 
						 | 
					86f9c37b30 | ||
| 
						 | 
					ac77c6da9e | ||
| 344540ea8e | |||
| 
						 | 
					8a5cf3cb09 | ||
| 
						 | 
					3a29570bae | ||
| 
						 | 
					02c48f4796 | ||
| ee01878fae | |||
| 2e1005e909 | |||
| 
						 | 
					98c016696d | ||
| 
						 | 
					e67ac96e93 | ||
| 
						 | 
					979a48e4d9 | ||
| 
						 | 
					faff6e54ef | ||
| d493e99bcb | |||
| 
						 | 
					92ae0b7431 | ||
| 
						 | 
					13135ff2ca | ||
| 
						 | 
					453e7da848 | ||
| 
						 | 
					b7a0e5d034 | ||
| 
						 | 
					b7a8b0c08d | ||
| 
						 | 
					7557d33c73 | ||
| 
						 | 
					e35f77b5a8 | ||
| 
						 | 
					dd4484c17b | ||
| 
						 | 
					4bd2c1c2b4 | ||
| 
						 | 
					42c4fe0b29 | ||
| 
						 | 
					39c6478422 | ||
| 
						 | 
					c06491eb2f | ||
| 
						 | 
					e869d15b24 | ||
| 
						 | 
					7045b6d8e1 | ||
| 431d3199db | |||
| 
						 | 
					5555705912 | ||
| 
						 | 
					4a51f698ab | ||
| 
						 | 
					029bece877 | ||
| 
						 | 
					31eabbce23 | ||
| 
						 | 
					7200ff529f | ||
| 
						 | 
					0dacbefd6b | ||
| 970be67537 | |||
| 53aa9cd643 | |||
| 
						 | 
					c435bfa343 | ||
| 
						 | 
					8667d77169 | ||
| 
						 | 
					5e7fcf3c9b | ||
| 
						 | 
					e78ae3b292 | ||
| 
						 | 
					97ee5bc331 | ||
| 
						 | 
					c3c0bbc922 | ||
| 
						 | 
					9992b64cae | ||
| 
						 | 
					7698147e97 | ||
| 81aaf9e8d7 | |||
| 
						 | 
					8e1b33d964 | ||
| 
						 | 
					eca61fff57 | ||
| 
						 | 
					acc5ddac08 | ||
| 06024a0007 | |||
| da9158e718 | |||
| 
						 | 
					f57f03547a | ||
| 
						 | 
					5424763ad6 | ||
| 3543ce60cb | |||
| 5ba86f12df | |||
| 
						 | 
					424cdd3e65 | ||
| 
						 | 
					3362f2473a | ||
| 
						 | 
					5565bb7a48 | ||
| 
						 | 
					f953348f4e | ||
| 
						 | 
					702af37961 | ||
| 73718070cf | |||
| 091ce15dce | |||
| 
						 | 
					cdde7c5f2f | ||
| 
						 | 
					eb0afffbd6 | ||
| 6b0c7f4d38 | |||
| dd2109735d | |||
| 
						 | 
					0b192d66c3 | ||
| 
						 | 
					472cbb372e | ||
| 
						 | 
					8d2e7fd0c8 | ||
| 
						 | 
					c8526a2270 | ||
| 
						 | 
					8b6abcc8bb | ||
| 
						 | 
					468982b07b | ||
| 
						 | 
					95179ffff2 | ||
| 
						 | 
					884733e54b | ||
| a2d4b1049e | |||
| 3ce3898326 | |||
| 
						 | 
					32fc0019d5 | ||
| 
						 | 
					f3f928e43f | ||
| 
						 | 
					374a0e1846 | ||
| 
						 | 
					1e5a99e009 | ||
| 64320fc260 | |||
| ff923ebab2 | |||
| 
						 | 
					bcd25dd0ed | ||
| 
						 | 
					ccb6709f5b | ||
| 2fe6b472a2 | |||
| 01642ba495 | |||
| 
						 | 
					191d23e903 | ||
| 
						 | 
					be57a52f61 | ||
| 
						 | 
					c2e8621405 | ||
| 
						 | 
					d3533f5627 | ||
| 
						 | 
					db448028f9 | ||
| 
						 | 
					f659a7508a | ||
| 
						 | 
					d20a6a1506 | ||
| 
						 | 
					d724e9eb17 | ||
| 
						 | 
					2106e6ebef | ||
| 
						 | 
					dc07b60acf | ||
| 
						 | 
					d77f046a6a | ||
| 
						 | 
					73c490a91d | ||
| 
						 | 
					ce562b6b8a | ||
| 
						 | 
					9ea4c05199 | ||
| 
						 | 
					e198cb60b1 | ||
| 
						 | 
					d183ce505a | ||
| 
						 | 
					9d1dec4179 | ||
| e5e4ca75ea | |||
| adc8645453 | |||
| 
						 | 
					708d00e75c | ||
| 
						 | 
					ecd1652403 | ||
| 
						 | 
					42e4f5b391 | ||
| 
						 | 
					afb0f58ec1 | ||
| 
						 | 
					42e3caa448 | ||
| 
						 | 
					12a5cebc2d | ||
| 
						 | 
					65e7574106 | ||
| 
						 | 
					ca01bc2605 | ||
| 
						 | 
					ad9f04de4a | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1,5 +1,5 @@
 | 
				
			|||||||
.vscode/settings.json
 | 
					.vscode/settings.json
 | 
				
			||||||
.idea
 | 
					.idea
 | 
				
			||||||
todo.txt
 | 
					 | 
				
			||||||
todo.md
 | 
					todo.md
 | 
				
			||||||
/.vscode
 | 
					/.vscode
 | 
				
			||||||
 | 
					/ignored/
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								icons/faune/Escargot.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/andurak.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 15 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/barbon.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/brocart.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/cancre.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/cancrelas.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/cerf.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/chamois.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 16 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/chevre.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/colimace.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/coquillage-pointe.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/coquille.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/crabe.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/fretin.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/lapin.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/oie.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/oiseau.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/ours.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 16 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/padongre.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 15 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/poisson.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/raton-laveur.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/rongeur.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/sanglier.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 16 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/saumon.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/singe-vert.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/soldieze.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/ver.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								icons/faune/wolf-head.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 16 KiB  | 
@@ -15,11 +15,12 @@
 | 
				
			|||||||
    "TypeNombreastral": "Nombre astral",
 | 
					    "TypeNombreastral": "Nombre astral",
 | 
				
			||||||
    "TypeTarot": "Carte de tarot",
 | 
					    "TypeTarot": "Carte de tarot",
 | 
				
			||||||
    "TypeCasetmr": "TMR spéciale",
 | 
					    "TypeCasetmr": "TMR spéciale",
 | 
				
			||||||
    "TypeRencontrestmr": "Rencontre TMR",
 | 
					    "TypeRencontre": "Rencontre TMR",
 | 
				
			||||||
    "TypeMunition": "Munition",
 | 
					    "TypeMunition": "Munition",
 | 
				
			||||||
    "TypeMonnaie": "Monnaie",
 | 
					    "TypeMonnaie": "Monnaie",
 | 
				
			||||||
    "TypeHerbe": "Herbe ou plante",
 | 
					    "TypeHerbe": "Herbe ou plante",
 | 
				
			||||||
    "TypeIngredient": "Ingrédient",
 | 
					    "TypeIngredient": "Ingrédient",
 | 
				
			||||||
 | 
					    "TypeFaune": "Faune",
 | 
				
			||||||
    "TypeLivre": "Livre",
 | 
					    "TypeLivre": "Livre",
 | 
				
			||||||
    "TypePotion": "Potion",
 | 
					    "TypePotion": "Potion",
 | 
				
			||||||
    "TypeArme": "Arme",
 | 
					    "TypeArme": "Arme",
 | 
				
			||||||
@@ -42,7 +43,8 @@
 | 
				
			|||||||
    "TypeSouffle": "Souffle de Dragon",
 | 
					    "TypeSouffle": "Souffle de Dragon",
 | 
				
			||||||
    "TypeTete": "Tête de Dragon",
 | 
					    "TypeTete": "Tête de Dragon",
 | 
				
			||||||
    "TypePossession": "Possession",
 | 
					    "TypePossession": "Possession",
 | 
				
			||||||
    "TypeSortreserve": "Sort en réserve"
 | 
					    "TypeSortreserve": "Sort en réserve",
 | 
				
			||||||
 | 
					    "TypeExtraitpoetique": "Extrait poetique"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "EFFECT": {
 | 
					  "EFFECT": {
 | 
				
			||||||
    "StatusStunned": "Sonné",
 | 
					    "StatusStunned": "Sonné",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,9 @@
 | 
				
			|||||||
 | 
					import { RdDActorSheet } from "./actor-sheet.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Extend the basic ActorSheet with some very simple modifications
 | 
					 * Extend the basic ActorSheet with some very simple modifications
 | 
				
			||||||
 * @extends {ActorSheet}
 | 
					 * @extends {ActorSheet}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					 | 
				
			||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					 | 
				
			||||||
import { RdDActorSheet } from "./actor-sheet.js";
 | 
					 | 
				
			||||||
import { RdDCarac } from "./rdd-carac.js";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* -------------------------------------------- */
 | 
					 | 
				
			||||||
export class RdDActorCreatureSheet extends RdDActorSheet {
 | 
					export class RdDActorCreatureSheet extends RdDActorSheet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @override */
 | 
					  /** @override */
 | 
				
			||||||
@@ -19,7 +14,7 @@ export class RdDActorCreatureSheet extends RdDActorSheet {
 | 
				
			|||||||
      width: 640,
 | 
					      width: 640,
 | 
				
			||||||
      height: 720,
 | 
					      height: 720,
 | 
				
			||||||
      tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
 | 
					      tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
 | 
				
			||||||
      dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }]
 | 
					      dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,15 +27,15 @@ export class RdDActorCreatureSheet extends RdDActorSheet {
 | 
				
			|||||||
    if (!this.options.editable) return;
 | 
					    if (!this.options.editable) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // On competence change
 | 
					    // On competence change
 | 
				
			||||||
    html.find('.creature-carac').change(async event => {
 | 
					    this.html.find('.creature-carac').change(async event => {
 | 
				
			||||||
      let compName = event.currentTarget.attributes.compname.value;
 | 
					      let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
      this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value));
 | 
					      this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.creature-niveau').change(async event => {
 | 
					    this.html.find('.creature-niveau').change(async event => {
 | 
				
			||||||
      let compName = event.currentTarget.attributes.compname.value;
 | 
					      let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
      this.actor.updateCreatureCompetence(compName, "niveau", parseInt(event.target.value));
 | 
					      this.actor.updateCreatureCompetence(compName, "niveau", parseInt(event.target.value));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.creature-dommages').change(async event => {
 | 
					    this.html.find('.creature-dommages').change(async event => {
 | 
				
			||||||
      let compName = event.currentTarget.attributes.compname.value;
 | 
					      let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
      this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value));
 | 
					      this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,4 @@
 | 
				
			|||||||
import { RdDActorSheet } from "./actor-sheet.js";
 | 
					import { RdDActorSheet } from "./actor-sheet.js";
 | 
				
			||||||
import { HtmlUtility } from "./html-utility.js";
 | 
					 | 
				
			||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class RdDActorEntiteSheet extends RdDActorSheet {
 | 
					export class RdDActorEntiteSheet extends RdDActorSheet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -12,7 +10,7 @@ export class RdDActorEntiteSheet extends RdDActorSheet {
 | 
				
			|||||||
      width: 640,
 | 
					      width: 640,
 | 
				
			||||||
      height: 720,
 | 
					      height: 720,
 | 
				
			||||||
      tabs: [{navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac"}],
 | 
					      tabs: [{navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac"}],
 | 
				
			||||||
      dragDrop: [{dragSelector: ".item-list .item", dropSelector: null}]
 | 
					      dragDrop: [{dragSelector: ".item-list .item", dropSelector: undefined}]
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,15 +23,15 @@ export class RdDActorEntiteSheet extends RdDActorSheet {
 | 
				
			|||||||
    if (!this.options.editable) return;
 | 
					    if (!this.options.editable) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // On competence change
 | 
					    // On competence change
 | 
				
			||||||
    html.find('.creature-carac').change(async event => {
 | 
					    this.html.find('.creature-carac').change(async event => {
 | 
				
			||||||
        let compName = event.currentTarget.attributes.compname.value;
 | 
					        let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
        this.actor.updateCreatureCompetence( compName, "carac_value", parseInt(event.target.value) );
 | 
					        this.actor.updateCreatureCompetence( compName, "carac_value", parseInt(event.target.value) );
 | 
				
			||||||
      } );    
 | 
					      } );    
 | 
				
			||||||
    html.find('.creature-niveau').change(async event => {
 | 
					    this.html.find('.creature-niveau').change(async event => {
 | 
				
			||||||
        let compName = event.currentTarget.attributes.compname.value;
 | 
					        let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
        this.actor.updateCreatureCompetence( compName, "niveau", parseInt(event.target.value) );
 | 
					        this.actor.updateCreatureCompetence( compName, "niveau", parseInt(event.target.value) );
 | 
				
			||||||
      } );    
 | 
					      } );    
 | 
				
			||||||
      html.find('.creature-dommages').change(async event => {
 | 
					      this.html.find('.creature-dommages').change(async event => {
 | 
				
			||||||
        let compName = event.currentTarget.attributes.compname.value;
 | 
					        let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
        this.actor.updateCreatureCompetence( compName, "dommages", parseInt(event.target.value) );
 | 
					        this.actor.updateCreatureCompetence( compName, "dommages", parseInt(event.target.value) );
 | 
				
			||||||
      } );    
 | 
					      } );    
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,3 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Extend the basic ActorSheet with some very simple modifications
 | 
					 | 
				
			||||||
 * @extends {ActorSheet}
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
import { HtmlUtility } from "./html-utility.js";
 | 
					import { HtmlUtility } from "./html-utility.js";
 | 
				
			||||||
import { RdDItemArme } from "./item-arme.js";
 | 
					import { RdDItemArme } from "./item-arme.js";
 | 
				
			||||||
@@ -12,12 +7,16 @@ import { Misc } from "./misc.js";
 | 
				
			|||||||
import { RdDCombatManager } from "./rdd-combat.js";
 | 
					import { RdDCombatManager } from "./rdd-combat.js";
 | 
				
			||||||
import { RdDCarac } from "./rdd-carac.js";
 | 
					import { RdDCarac } from "./rdd-carac.js";
 | 
				
			||||||
import { DialogSplitItem } from "./dialog-split-item.js";
 | 
					import { DialogSplitItem } from "./dialog-split-item.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
import { DialogRepos } from "./dialog-repos.js";
 | 
					import { DialogRepos } from "./dialog-repos.js";
 | 
				
			||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
 | 
					import { RdDSheetUtility } from "./rdd-sheet-utility.js";
 | 
				
			||||||
import { STATUSES } from "./status-effects.js";
 | 
					import { STATUSES } from "./settings/status-effects.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Extend the basic ActorSheet with some very simple modifications
 | 
				
			||||||
 | 
					 * @extends {ActorSheet}
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export class RdDActorSheet extends ActorSheet {
 | 
					export class RdDActorSheet extends ActorSheet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @override */
 | 
					  /** @override */
 | 
				
			||||||
@@ -26,9 +25,9 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
    return mergeObject(super.defaultOptions, {
 | 
					    return mergeObject(super.defaultOptions, {
 | 
				
			||||||
      classes: ["rdd", "sheet", "actor"],
 | 
					      classes: ["rdd", "sheet", "actor"],
 | 
				
			||||||
      template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html",
 | 
					      template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html",
 | 
				
			||||||
      width: 640,
 | 
					      width: 550,
 | 
				
			||||||
      tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
 | 
					      tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
 | 
				
			||||||
      dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
 | 
					      dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
 | 
				
			||||||
      showCompNiveauBase: false,
 | 
					      showCompNiveauBase: false,
 | 
				
			||||||
      vueDetaillee: false
 | 
					      vueDetaillee: false
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@@ -37,6 +36,7 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async getData() {
 | 
					  async getData() {
 | 
				
			||||||
    this.timerRecherche = undefined;
 | 
					    this.timerRecherche = undefined;
 | 
				
			||||||
 | 
					    this.actor.computeEtatGeneral();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let formData = {
 | 
					    let formData = {
 | 
				
			||||||
      title: this.title,
 | 
					      title: this.title,
 | 
				
			||||||
@@ -102,7 +102,6 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      formData.hautreve = {
 | 
					      formData.hautreve = {
 | 
				
			||||||
        isDemiReve: this.actor.getEffect(STATUSES.StatusDemiReve),
 | 
					        isDemiReve: this.actor.getEffect(STATUSES.StatusDemiReve),
 | 
				
			||||||
        rencontres: duplicate(formData.system.reve.rencontre.list),
 | 
					 | 
				
			||||||
        cacheTMR: this.actor.isTMRCache()
 | 
					        cacheTMR: this.actor.isTMRCache()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -119,79 +118,26 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
    return formData;
 | 
					    return formData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  isCompetenceAffichable(competence) {
 | 
					 | 
				
			||||||
    return !this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(competence);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  async _onDropActor(event, dragData) {
 | 
					 | 
				
			||||||
    const dropActor = fromUuidSync(dragData.uuid);
 | 
					 | 
				
			||||||
    this.actor.addSubActeur(dropActor);
 | 
					 | 
				
			||||||
    super._onDropActor(event, dragData);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  async _onDropItem(event, dragData) {
 | 
					 | 
				
			||||||
    const destItemId = $(event.target)?.closest('.item').attr('data-item-id')
 | 
					 | 
				
			||||||
    const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor.id, dragData, this.objetVersConteneur)
 | 
					 | 
				
			||||||
    const callSuper = await this.actor.processDropItem(dropParams)
 | 
					 | 
				
			||||||
    if (callSuper) {
 | 
					 | 
				
			||||||
      await super._onDropItem(event, dragData)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  async createItem(name, type) {
 | 
					 | 
				
			||||||
    await this.actor.createEmbeddedDocuments('Item', [{ name: name, type: type }], { renderSheet: true });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  async createEmptyTache() {
 | 
					 | 
				
			||||||
    await this.createItem('Nouvelle tache', 'tache');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */  /** @override */
 | 
					  /* -------------------------------------------- */  /** @override */
 | 
				
			||||||
  activateListeners(html) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    super.activateListeners(html);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
 | 
					    HtmlUtility._showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Everything below here is only needed if the sheet is editable
 | 
					    // Everything below here is only needed if the sheet is editable
 | 
				
			||||||
    if (!this.options.editable) return;
 | 
					    if (!this.options.editable) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.item-split').click(async event => {
 | 
					    this.html.find('.item-split').click(async event => {
 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
					      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
				
			||||||
      RdDSheetUtility.splitItem(item, this.actor);
 | 
					      RdDSheetUtility.splitItem(item, this.actor);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.item-edit').click(async event => {
 | 
					    this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true))
 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor)
 | 
					    this.html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor)));
 | 
				
			||||||
      item.sheet.render(true)
 | 
					    this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente());
 | 
				
			||||||
    })
 | 
					    this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem());
 | 
				
			||||||
    html.find('.display-label a').click(async event => {
 | 
					    this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor));
 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
					    this.html.find('.subacteur-delete').click(async event => {
 | 
				
			||||||
      item.sheet.render(true);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.rencontre-delete').click(async event => {
 | 
					 | 
				
			||||||
      this.actor.deleteTMRRencontre(RdDSheetUtility.getItemId(event));
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.item-delete').click(async event => {
 | 
					 | 
				
			||||||
      const li = RdDSheetUtility.getEventElement(event);
 | 
					 | 
				
			||||||
      const item = this.actor.getObjet(li.data("item-id"));
 | 
					 | 
				
			||||||
      RdDUtility.confirmerSuppressionItem(this, item, li);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.item-vendre').click(async event => {
 | 
					 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
					 | 
				
			||||||
      item?.proposerVente();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.item-montrer').click(async event => {
 | 
					 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
					 | 
				
			||||||
      item?.postItem();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.item-action').click(async event => {
 | 
					 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor)
 | 
					 | 
				
			||||||
      this.actor.actionItem(item);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.subacteur-delete').click(async event => {
 | 
					 | 
				
			||||||
      const li = RdDSheetUtility.getEventElement(event);
 | 
					      const li = RdDSheetUtility.getEventElement(event);
 | 
				
			||||||
      const actorId = li.data("actor-id");
 | 
					      const actorId = li.data("actor-id");
 | 
				
			||||||
      if (actorId) {
 | 
					      if (actorId) {
 | 
				
			||||||
@@ -199,54 +145,54 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
        RdDUtility.confirmerSuppressionSubacteur(this, subActor, li);
 | 
					        RdDUtility.confirmerSuppressionSubacteur(this, subActor, li);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.experiencelog-delete').click(async event => {
 | 
					    this.html.find('.experiencelog-delete').click(async event => {
 | 
				
			||||||
      const li = $(event.currentTarget)?.parents(".experiencelog");
 | 
					      const li = this.html.find(event.currentTarget)?.parents(".experiencelog");
 | 
				
			||||||
      const key = Number(li.data("key") ?? -1);
 | 
					      const key = Number(li.data("key") ?? -1);
 | 
				
			||||||
      await this.actor.deleteExperienceLog(key, 1);
 | 
					      await this.actor.deleteExperienceLog(key, 1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.experiencelog-delete-previous').click(async event => {
 | 
					    this.html.find('.experiencelog-delete-previous').click(async event => {
 | 
				
			||||||
      const li = $(event.currentTarget)?.parents(".experiencelog");
 | 
					      const li = this.html.find(event.currentTarget)?.parents(".experiencelog");
 | 
				
			||||||
      const key = Number(li.data("key") ?? -1);
 | 
					      const key = Number(li.data("key") ?? -1);
 | 
				
			||||||
      await this.actor.deleteExperienceLog(0, key + 1);
 | 
					      await this.actor.deleteExperienceLog(0, key + 1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.encaisser-direct').click(async event => {
 | 
					    this.html.find('.encaisser-direct').click(async event => {
 | 
				
			||||||
      this.actor.encaisser();
 | 
					      this.actor.encaisser();
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    html.find('.sheet-possession-attack').click(async event => {
 | 
					    this.html.find('.sheet-possession-attack').click(async event => {
 | 
				
			||||||
      const poss = RdDSheetUtility.getItem(event, this.actor)
 | 
					      const poss = RdDSheetUtility.getItem(event, this.actor)
 | 
				
			||||||
      this.actor.conjurerPossession(poss)
 | 
					      this.actor.conjurerPossession(poss)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    html.find('.remise-a-neuf').click(async event => {
 | 
					    this.html.find('.remise-a-neuf').click(async event => {
 | 
				
			||||||
      if (game.user.isGM) {
 | 
					      if (game.user.isGM) {
 | 
				
			||||||
        this.actor.remiseANeuf();
 | 
					        this.actor.remiseANeuf();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.creer-tache').click(async event => {
 | 
					    this.html.find('.creer-tache').click(async event => {
 | 
				
			||||||
      this.createEmptyTache();
 | 
					      this.createEmptyTache();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.creer-un-objet').click(async event => {
 | 
					    this.html.find('.creer-un-objet').click(async event => {
 | 
				
			||||||
      RdDUtility.selectObjetType(this);
 | 
					      RdDUtility.selectObjetType(this);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.creer-une-oeuvre').click(async event => {
 | 
					    this.html.find('.creer-une-oeuvre').click(async event => {
 | 
				
			||||||
      RdDUtility.selectTypeOeuvre(this);
 | 
					      RdDUtility.selectTypeOeuvre(this);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.nettoyer-conteneurs').click(async event => {
 | 
					    this.html.find('.nettoyer-conteneurs').click(async event => {
 | 
				
			||||||
      this.actor.nettoyerConteneurs();
 | 
					      this.actor.nettoyerConteneurs();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Blessure control
 | 
					    // Blessure control
 | 
				
			||||||
    html.find('.blessure-control').click(async event => {
 | 
					    this.html.find('.blessure-control').click(async event => {
 | 
				
			||||||
      const tr = $(event.currentTarget).parents(".item");
 | 
					      const tr = this.html.find(event.currentTarget).parents(".item");
 | 
				
			||||||
      let btype = tr.data("blessure-type");
 | 
					      let btype = tr.data("blessure-type");
 | 
				
			||||||
      let index = tr.data('blessure-index');
 | 
					      let index = tr.data('blessure-index');
 | 
				
			||||||
      let active = $(event.currentTarget).data('blessure-active');
 | 
					      let active = this.html.find(event.currentTarget).data('blessure-active');
 | 
				
			||||||
      //console.log(btype, index, active);
 | 
					      //console.log(btype, index, active);
 | 
				
			||||||
      await this.actor.manageBlessureFromSheet(btype, index, active);
 | 
					      await this.actor.manageBlessureFromSheet(btype, index, active);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Blessure data
 | 
					    // Blessure data
 | 
				
			||||||
    html.find('.blessure-soins').change(async event => {
 | 
					    this.html.find('.blessure-soins').change(async event => {
 | 
				
			||||||
      const tr = $(event.currentTarget).parents(".item");
 | 
					      const tr = this.html.find(event.currentTarget).parents(".item");
 | 
				
			||||||
      let btype = tr.data('blessure-type');
 | 
					      let btype = tr.data('blessure-type');
 | 
				
			||||||
      let index = tr.data('blessure-index');
 | 
					      let index = tr.data('blessure-index');
 | 
				
			||||||
      let psoins = tr.find('.blessure-premiers_soins').val();
 | 
					      let psoins = tr.find('.blessure-premiers_soins').val();
 | 
				
			||||||
@@ -260,57 +206,57 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Equip Inventory Item
 | 
					    // Equip Inventory Item
 | 
				
			||||||
    html.find('.item-equip').click(async event => {
 | 
					    this.html.find('.item-equip').click(async event => {
 | 
				
			||||||
      this.actor.equiperObjet(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.equiperObjet(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Roll Carac
 | 
					    // Roll Carac
 | 
				
			||||||
    html.find('.carac-label a').click(async event => {
 | 
					    this.html.find('.carac-label a').click(async event => {
 | 
				
			||||||
      let caracName = event.currentTarget.attributes.name.value;
 | 
					      let caracName = event.currentTarget.attributes.name.value;
 | 
				
			||||||
      this.actor.rollCarac(caracName.toLowerCase());
 | 
					      this.actor.rollCarac(caracName.toLowerCase());
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.chance-actuelle').click(async event => {
 | 
					    this.html.find('.chance-actuelle').click(async event => {
 | 
				
			||||||
      this.actor.rollCarac('chance-actuelle');
 | 
					      this.actor.rollCarac('chance-actuelle');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.chance-appel').click(async event => {
 | 
					    this.html.find('.chance-appel').click(async event => {
 | 
				
			||||||
      this.actor.rollAppelChance();
 | 
					      this.actor.rollAppelChance();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('#jet-astrologie').click(async event => {
 | 
					    this.html.find('[name="jet-astrologie"]').click(async event => {
 | 
				
			||||||
      this.actor.astrologieNombresAstraux();
 | 
					      this.actor.astrologieNombresAstraux();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Roll Skill
 | 
					    // Roll Skill
 | 
				
			||||||
    html.find('a.competence-label').click(async event => {
 | 
					    this.html.find('a.competence-label').click(async event => {
 | 
				
			||||||
      this.actor.rollCompetence(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.rollCompetence(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.tache-label a').click(async event => {
 | 
					    this.html.find('.tache-label a').click(async event => {
 | 
				
			||||||
      this.actor.rollTache(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.rollTache(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.meditation-label a').click(async event => {
 | 
					    this.html.find('.meditation-label a').click(async event => {
 | 
				
			||||||
      this.actor.rollMeditation(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.rollMeditation(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.chant-label a').click(async event => {
 | 
					    this.html.find('.chant-label a').click(async event => {
 | 
				
			||||||
      this.actor.rollChant(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.rollChant(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.danse-label a').click(async event => {
 | 
					    this.html.find('.danse-label a').click(async event => {
 | 
				
			||||||
      this.actor.rollDanse(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.rollDanse(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.musique-label a').click(async event => {
 | 
					    this.html.find('.musique-label a').click(async event => {
 | 
				
			||||||
      this.actor.rollMusique(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.rollMusique(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.oeuvre-label a').click(async event => {
 | 
					    this.html.find('.oeuvre-label a').click(async event => {
 | 
				
			||||||
      this.actor.rollOeuvre(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.rollOeuvre(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.jeu-label a').click(async event => {
 | 
					    this.html.find('.jeu-label a').click(async event => {
 | 
				
			||||||
      this.actor.rollJeu(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.rollJeu(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.recettecuisine-label a').click(async event => {
 | 
					    this.html.find('.recettecuisine-label a').click(async event => {
 | 
				
			||||||
      this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.subacteur-label a').click(async event => {
 | 
					    this.html.find('.subacteur-label a').click(async event => {
 | 
				
			||||||
      let actorId = RdDSheetUtility.getEventItemData(event, 'actor-id');
 | 
					      let actorId = RdDSheetUtility.getEventItemData(event, 'actor-id');
 | 
				
			||||||
      let actor = game.actors.get(actorId);
 | 
					      let actor = game.actors.get(actorId);
 | 
				
			||||||
      if (actor) {
 | 
					      if (actor) {
 | 
				
			||||||
@@ -319,25 +265,25 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Boutons spéciaux MJs
 | 
					    // Boutons spéciaux MJs
 | 
				
			||||||
    html.find('.forcer-tmr-aleatoire').click(async event => {
 | 
					    this.html.find('.forcer-tmr-aleatoire').click(async event => {
 | 
				
			||||||
      this.actor.reinsertionAleatoire("Action MJ");
 | 
					      this.actor.reinsertionAleatoire("Action MJ");
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.afficher-tmr').click(async event => {
 | 
					    this.html.find('.afficher-tmr').click(async event => {
 | 
				
			||||||
      this.actor.changeTMRVisible();
 | 
					      this.actor.changeTMRVisible();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Points de reve actuel
 | 
					    // Points de reve actuel
 | 
				
			||||||
    html.find('.ptreve-actuel a').click(async event => {
 | 
					    this.html.find('.ptreve-actuel a').click(async event => {
 | 
				
			||||||
      this.actor.rollCarac('reve-actuel');
 | 
					      this.actor.rollCarac('reve-actuel');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Roll Weapon1
 | 
					    // Roll Weapon1
 | 
				
			||||||
    html.find('.arme-label a').click(async event => {
 | 
					    this.html.find('.arme-label a').click(async event => {
 | 
				
			||||||
      let arme = this._getEventArmeCombat(event);
 | 
					      let arme = this._getEventArmeCombat(event);
 | 
				
			||||||
      this.actor.rollArme(duplicate(arme));
 | 
					      this.actor.rollArme(duplicate(arme));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    // Initiative pour l'arme
 | 
					    // Initiative pour l'arme
 | 
				
			||||||
    html.find('.arme-initiative a').click(async event => {
 | 
					    this.html.find('.arme-initiative a').click(async event => {
 | 
				
			||||||
      let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id);
 | 
					      let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id);
 | 
				
			||||||
      if (combatant) {
 | 
					      if (combatant) {
 | 
				
			||||||
        let action = this._getEventArmeCombat(event);
 | 
					        let action = this._getEventArmeCombat(event);
 | 
				
			||||||
@@ -347,88 +293,88 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    // Display TMR, visualisation
 | 
					    // Display TMR, visualisation
 | 
				
			||||||
    html.find('.visu-tmr').click(async event => {
 | 
					    this.html.find('.visu-tmr').click(async event => {
 | 
				
			||||||
      this.actor.displayTMR("visu");
 | 
					      this.actor.displayTMR("visu");
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Display TMR, normal
 | 
					    // Display TMR, normal
 | 
				
			||||||
    html.find('.monte-tmr').click(async event => {
 | 
					    this.html.find('.monte-tmr').click(async event => {
 | 
				
			||||||
      this.actor.displayTMR("normal");
 | 
					      this.actor.displayTMR("normal");
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Display TMR, fast 
 | 
					    // Display TMR, fast 
 | 
				
			||||||
    html.find('.monte-tmr-rapide').click(async event => {
 | 
					    this.html.find('.monte-tmr-rapide').click(async event => {
 | 
				
			||||||
      this.actor.displayTMR("rapide");
 | 
					      this.actor.displayTMR("rapide");
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.repos').click(async event => {
 | 
					    this.html.find('.repos').click(async event => {
 | 
				
			||||||
      await DialogRepos.create(this.actor);
 | 
					      await DialogRepos.create(this.actor);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.delete-active-effect').click(async event => {
 | 
					    this.html.find('.delete-active-effect').click(async event => {
 | 
				
			||||||
      if (game.user.isGM) {
 | 
					      if (game.user.isGM) {
 | 
				
			||||||
        let effect = $(event.currentTarget).parents(".active-effect").data('effect');
 | 
					        let effect = this.html.find(event.currentTarget).parents(".active-effect").data('effect');
 | 
				
			||||||
        this.actor.removeEffect(effect);
 | 
					        this.actor.removeEffect(effect);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.enlever-tous-effets').click(async event => {
 | 
					    this.html.find('.enlever-tous-effets').click(async event => {
 | 
				
			||||||
      if (game.user.isGM) {
 | 
					      if (game.user.isGM) {
 | 
				
			||||||
        await this.actor.removeEffects();
 | 
					        await this.actor.removeEffects();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.conteneur-name a').click(async event => {
 | 
					    this.html.find('.conteneur-name a').click(async event => {
 | 
				
			||||||
      RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
 | 
					      RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
      this.render(true);
 | 
					      this.render(true);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.carac-xp-augmenter').click(async event => {
 | 
					    this.html.find('.carac-xp-augmenter').click(async event => {
 | 
				
			||||||
      let caracName = event.currentTarget.name.replace("augmenter.", "");
 | 
					      let caracName = event.currentTarget.name.replace("augmenter.", "");
 | 
				
			||||||
      this.actor.updateCaracXPAuto(caracName);
 | 
					      this.actor.updateCaracXPAuto(caracName);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.competence-xp-augmenter').click(async event => {
 | 
					    this.html.find('.competence-xp-augmenter').click(async event => {
 | 
				
			||||||
      this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.competence-stress-augmenter').click(async event => {
 | 
					    this.html.find('.competence-stress-augmenter').click(async event => {
 | 
				
			||||||
      this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event));
 | 
					      this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.options.vueDetaillee) {
 | 
					    if (this.options.vueDetaillee) {
 | 
				
			||||||
      // On carac change
 | 
					      // On carac change
 | 
				
			||||||
      html.find('.carac-value').change(async event => {
 | 
					      this.html.find('.carac-value').change(async event => {
 | 
				
			||||||
        let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
 | 
					        let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
 | 
				
			||||||
        this.actor.updateCarac(caracName, parseInt(event.target.value));
 | 
					        this.actor.updateCarac(caracName, parseInt(event.target.value));
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      html.find('input.carac-xp').change(async event => {
 | 
					      this.html.find('input.carac-xp').change(async event => {
 | 
				
			||||||
        let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "");
 | 
					        let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "");
 | 
				
			||||||
        this.actor.updateCaracXP(caracName, parseInt(event.target.value));
 | 
					        this.actor.updateCaracXP(caracName, parseInt(event.target.value));
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      // On competence change
 | 
					      // On competence change
 | 
				
			||||||
      html.find('.competence-value').change(async event => {
 | 
					      this.html.find('.competence-value').change(async event => {
 | 
				
			||||||
        let compName = event.currentTarget.attributes.compname.value;
 | 
					        let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
        //console.log("Competence changed :", compName);
 | 
					        //console.log("Competence changed :", compName);
 | 
				
			||||||
        this.actor.updateCompetence(compName, parseInt(event.target.value));
 | 
					        this.actor.updateCompetence(compName, parseInt(event.target.value));
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      // On competence xp change
 | 
					      // On competence xp change
 | 
				
			||||||
      html.find('input.competence-xp').change(async event => {
 | 
					      this.html.find('input.competence-xp').change(async event => {
 | 
				
			||||||
        let compName = event.currentTarget.attributes.compname.value;
 | 
					        let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
        this.actor.updateCompetenceXP(compName, parseInt(event.target.value));
 | 
					        this.actor.updateCompetenceXP(compName, parseInt(event.target.value));
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      // On competence xp change
 | 
					      // On competence xp change
 | 
				
			||||||
      html.find('input.competence-xp-sort').change(async event => {
 | 
					      this.html.find('input.competence-xp-sort').change(async event => {
 | 
				
			||||||
        let compName = event.currentTarget.attributes.compname.value;
 | 
					        let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
        this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value));
 | 
					        this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value));
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      // On competence archetype change
 | 
					      // On competence archetype change
 | 
				
			||||||
      html.find('.competence-archetype').change(async event => {
 | 
					      this.html.find('.competence-archetype').change(async event => {
 | 
				
			||||||
        let compName = event.currentTarget.attributes.compname.value;
 | 
					        let compName = event.currentTarget.attributes.compname.value;
 | 
				
			||||||
        this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value));
 | 
					        this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value));
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.show-hide-competences').click(async event => {
 | 
					    this.html.find('.show-hide-competences').click(async event => {
 | 
				
			||||||
      this.options.showCompNiveauBase = !this.options.showCompNiveauBase;
 | 
					      this.options.showCompNiveauBase = !this.options.showCompNiveauBase;
 | 
				
			||||||
      this.render(true);
 | 
					      this.render(true);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.recherche')
 | 
					    this.html.find('.recherche')
 | 
				
			||||||
      .each((index, field) => {
 | 
					      .each((index, field) => {
 | 
				
			||||||
        if (this.options.recherche) {
 | 
					        if (this.options.recherche) {
 | 
				
			||||||
          field.focus();
 | 
					          field.focus();
 | 
				
			||||||
@@ -451,92 +397,125 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
      .change(async event =>
 | 
					      .change(async event =>
 | 
				
			||||||
        this.options.recherche = this._optionRecherche(event.currentTarget)
 | 
					        this.options.recherche = this._optionRecherche(event.currentTarget)
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    html.find('.vue-detaillee').click(async event => {
 | 
					    this.html.find('.vue-detaillee').click(async event => {
 | 
				
			||||||
      this.options.vueDetaillee = !this.options.vueDetaillee;
 | 
					      this.options.vueDetaillee = !this.options.vueDetaillee;
 | 
				
			||||||
      this.render(true);
 | 
					      this.render(true);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // On pts de reve change
 | 
					    // On pts de reve change
 | 
				
			||||||
    html.find('.pointsreve-value').change(async event => {
 | 
					    this.html.find('.pointsreve-value').change(async event => {
 | 
				
			||||||
      let reveValue = event.currentTarget.value;
 | 
					      let reveValue = event.currentTarget.value;
 | 
				
			||||||
      this.actor.update({ "system.reve.reve.value": reveValue });
 | 
					      this.actor.update({ "system.reve.reve.value": reveValue });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // On seuil de reve change
 | 
					    // On seuil de reve change
 | 
				
			||||||
    html.find('.seuil-reve-value').change(async event => {
 | 
					    this.html.find('.seuil-reve-value').change(async event => {
 | 
				
			||||||
      console.log("seuil-reve-value", event.currentTarget)
 | 
					      console.log("seuil-reve-value", event.currentTarget)
 | 
				
			||||||
      this.actor.setPointsDeSeuil(event.currentTarget.value);
 | 
					      this.actor.setPointsDeSeuil(event.currentTarget.value);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('#attribut-protection-edit').change(async event => {
 | 
					    this.html.find('#attribut-protection-edit').change(async event => {
 | 
				
			||||||
      this.actor.updateAttributeValue(event.currentTarget.attributes.name.value, parseInt(event.target.value));
 | 
					      this.actor.updateAttributeValue(event.currentTarget.attributes.name.value, parseInt(event.target.value));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // On stress change
 | 
					    // On stress change
 | 
				
			||||||
    html.find('.compteur-edit').change(async event => {
 | 
					    this.html.find('.compteur-edit').change(async event => {
 | 
				
			||||||
      let fieldName = event.currentTarget.attributes.name.value;
 | 
					      let fieldName = event.currentTarget.attributes.name.value;
 | 
				
			||||||
      this.actor.updateCompteurValue(fieldName, parseInt(event.target.value));
 | 
					      this.actor.updateCompteurValue(fieldName, parseInt(event.target.value));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('#ethylisme').change(async event => {
 | 
					    this.html.find('#ethylisme').change(async event => {
 | 
				
			||||||
      this.actor.setEthylisme(parseInt(event.target.value));
 | 
					      this.actor.setEthylisme(parseInt(event.target.value));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.stress-test').click(async event => {
 | 
					    this.html.find('.stress-test').click(async event => {
 | 
				
			||||||
      this.actor.transformerStress();
 | 
					      this.actor.transformerStress();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.moral-malheureux').click(async event => {
 | 
					    this.html.find('.moral-malheureux').click(async event => {
 | 
				
			||||||
      this.actor.jetDeMoral('malheureuse');
 | 
					      this.actor.jetDeMoral('malheureuse');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.moral-neutre').click(async event => {
 | 
					    this.html.find('.moral-neutre').click(async event => {
 | 
				
			||||||
      this.actor.jetDeMoral('neutre');
 | 
					      this.actor.jetDeMoral('neutre');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.moral-heureux').click(async event => {
 | 
					    this.html.find('.moral-heureux').click(async event => {
 | 
				
			||||||
      this.actor.jetDeMoral('heureuse');
 | 
					      this.actor.jetDeMoral('heureuse');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.ethylisme-test').click(async event => {
 | 
					    this.html.find('.ethylisme-test').click(async event => {
 | 
				
			||||||
      this.actor.jetEthylisme();
 | 
					      this.actor.jetEthylisme();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.jet-vie').click(async event => {
 | 
					    this.html.find('.jet-vie').click(async event => {
 | 
				
			||||||
      this.actor.jetVie();
 | 
					      this.actor.jetVie();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.jet-endurance').click(async event => {
 | 
					    this.html.find('.jet-endurance').click(async event => {
 | 
				
			||||||
      this.actor.jetEndurance();
 | 
					      this.actor.jetEndurance();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.monnaie-plus').click(async event => {
 | 
					    this.html.find('.monnaie-plus').click(async event => {
 | 
				
			||||||
      this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), 1);
 | 
					      this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), 1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.monnaie-moins').click(async event => {
 | 
					    this.html.find('.monnaie-moins').click(async event => {
 | 
				
			||||||
      this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), -1);
 | 
					      this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), -1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.vie-plus').click(async event => {
 | 
					    this.html.find('.vie-plus').click(async event => {
 | 
				
			||||||
      this.actor.santeIncDec("vie", 1);
 | 
					      this.actor.santeIncDec("vie", 1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.vie-moins').click(async event => {
 | 
					    this.html.find('.vie-moins').click(async event => {
 | 
				
			||||||
      this.actor.santeIncDec("vie", -1);
 | 
					      this.actor.santeIncDec("vie", -1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.endurance-plus').click(async event => {
 | 
					    this.html.find('.endurance-plus').click(async event => {
 | 
				
			||||||
      this.actor.santeIncDec("endurance", 1);
 | 
					      this.actor.santeIncDec("endurance", 1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.endurance-moins').click(async event => {
 | 
					    this.html.find('.endurance-moins').click(async event => {
 | 
				
			||||||
      this.actor.santeIncDec("endurance", -1);
 | 
					      this.actor.santeIncDec("endurance", -1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.ptreve-actuel-plus').click(async event => {
 | 
					    this.html.find('.ptreve-actuel-plus').click(async event => {
 | 
				
			||||||
      this.actor.reveActuelIncDec(1);
 | 
					      this.actor.reveActuelIncDec(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.ptreve-actuel-moins').click(async event => {
 | 
					    this.html.find('.ptreve-actuel-moins').click(async event => {
 | 
				
			||||||
      this.actor.reveActuelIncDec(-1);
 | 
					      this.actor.reveActuelIncDec(-1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.fatigue-plus').click(async event => {
 | 
					    this.html.find('.fatigue-plus').click(async event => {
 | 
				
			||||||
      this.actor.santeIncDec("fatigue", 1);
 | 
					      this.actor.santeIncDec("fatigue", 1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.fatigue-moins').click(async event => {
 | 
					    this.html.find('.fatigue-moins').click(async event => {
 | 
				
			||||||
      this.actor.santeIncDec("fatigue", -1);
 | 
					      this.actor.santeIncDec("fatigue", -1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  isCompetenceAffichable(competence) {
 | 
				
			||||||
 | 
					    return !this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(competence);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async _onDropActor(event, dragData) {
 | 
				
			||||||
 | 
					    const dropActor = fromUuidSync(dragData.uuid);
 | 
				
			||||||
 | 
					    this.actor.addSubActeur(dropActor);
 | 
				
			||||||
 | 
					    super._onDropActor(event, dragData);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async _onDropItem(event, dragData) {
 | 
				
			||||||
 | 
					    const destItemId = this.html.find(event.target)?.closest('.item').attr('data-item-id')
 | 
				
			||||||
 | 
					    const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur)
 | 
				
			||||||
 | 
					    if (dropParams) {
 | 
				
			||||||
 | 
					      const callSuper = await this.actor.processDropItem(dropParams)
 | 
				
			||||||
 | 
					      if (callSuper) {
 | 
				
			||||||
 | 
					        await super._onDropItem(event, dragData)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async createItem(name, type) {
 | 
				
			||||||
 | 
					    await this.actor.createEmbeddedDocuments('Item', [{ name: name, type: type }], { renderSheet: true });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async createEmptyTache() {
 | 
				
			||||||
 | 
					    await this.createItem('Nouvelle tache', 'tache');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _optionRecherche(target) {
 | 
					  _optionRecherche(target) {
 | 
				
			||||||
    if (!target.value?.length){
 | 
					    if (!target.value?.length){
 | 
				
			||||||
      return undefined;
 | 
					      return undefined;
 | 
				
			||||||
@@ -549,7 +528,7 @@ export class RdDActorSheet extends ActorSheet {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _getEventArmeCombat(event) {
 | 
					  _getEventArmeCombat(event) {
 | 
				
			||||||
    const li = $(event.currentTarget)?.parents(".item");
 | 
					    const li = this.html.find(event.currentTarget)?.parents(".item");
 | 
				
			||||||
    let armeName = li.data("arme-name");
 | 
					    let armeName = li.data("arme-name");
 | 
				
			||||||
    let compName = li.data('competence-name');
 | 
					    let compName = li.data('competence-name');
 | 
				
			||||||
    const arme = this.armesList.find(a => a.name == armeName && a.system.competence == compName);
 | 
					    const arme = this.armesList.find(a => a.name == armeName && a.system.competence == compName);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
 | 
					 | 
				
			||||||
import { RdDActorSheet } from "./actor-sheet.js";
 | 
					import { RdDActorSheet } from "./actor-sheet.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
@@ -15,9 +14,26 @@ export class RdDActorVehiculeSheet extends RdDActorSheet {
 | 
				
			|||||||
      width: 640,
 | 
					      width: 640,
 | 
				
			||||||
      height: 720,
 | 
					      height: 720,
 | 
				
			||||||
      tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
 | 
					      tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
 | 
				
			||||||
      dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }]
 | 
					      dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    if (!this.options.editable) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('.resistance-moins').click(async event => {
 | 
				
			||||||
 | 
					      this.actor.vehicleIncDec("resistance", -1);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.html.find('.resistance-plus').click(async event => {
 | 
				
			||||||
 | 
					      this.actor.vehicleIncDec("resistance", 1);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.html.find('.structure-moins').click(async event => {
 | 
				
			||||||
 | 
					      this.actor.vehicleIncDec("structure", -1);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.html.find('.structure-plus').click(async event => {
 | 
				
			||||||
 | 
					      this.actor.vehicleIncDec("structure", 1);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										732
									
								
								module/actor.js
									
									
									
									
									
								
							
							
						
						
							
								
								
									
										127
									
								
								module/dialog-chronologie.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,127 @@
 | 
				
			|||||||
 | 
					import { SYSTEM_RDD } from "./constants.js";
 | 
				
			||||||
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const LATEST_USED_JOURNAL_ID = "chronologie-dernier-journal";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class DialogChronologie extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static init() {
 | 
				
			||||||
 | 
					    game.settings.register(SYSTEM_RDD, LATEST_USED_JOURNAL_ID, {
 | 
				
			||||||
 | 
					      name: "Dernier article de journal utilisé pour enregistrer la chronologie",
 | 
				
			||||||
 | 
					      scope: "client",
 | 
				
			||||||
 | 
					      config: false,
 | 
				
			||||||
 | 
					      default: "",
 | 
				
			||||||
 | 
					      type: String
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  static async create() {
 | 
				
			||||||
 | 
					    const dateRdD = game.system.rdd.calendrier.getCalendrier();
 | 
				
			||||||
 | 
					    const dialogData = {
 | 
				
			||||||
 | 
					      auteur: game.user.name,
 | 
				
			||||||
 | 
					      isGM: game.user.isGM,
 | 
				
			||||||
 | 
					      information: "",
 | 
				
			||||||
 | 
					      journalId: game.settings.get(SYSTEM_RDD, LATEST_USED_JOURNAL_ID),
 | 
				
			||||||
 | 
					      journaux: game.journal.filter(it => it.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)),
 | 
				
			||||||
 | 
					      dateRdD: dateRdD,
 | 
				
			||||||
 | 
					      jourRdD: dateRdD.jour +1,
 | 
				
			||||||
 | 
					      heureRdD: game.system.rdd.calendrier.getCurrentHeure(),
 | 
				
			||||||
 | 
					      dateReel: DialogChronologie.getCurrentDateTime()
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.html", dialogData);
 | 
				
			||||||
 | 
					    const dialog = new DialogChronologie(html);
 | 
				
			||||||
 | 
					    dialog.render(true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(html) {
 | 
				
			||||||
 | 
					    const options = {
 | 
				
			||||||
 | 
					      classes: ["DialogChronologie"],
 | 
				
			||||||
 | 
					      width: 500,
 | 
				
			||||||
 | 
					      height: 'fit-content',
 | 
				
			||||||
 | 
					      'z-index': 99999
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    const conf = {
 | 
				
			||||||
 | 
					      title: "Chronologie",
 | 
				
			||||||
 | 
					      content: html,
 | 
				
			||||||
 | 
					      buttons: {
 | 
				
			||||||
 | 
					        ajout: { label: "Ajouter", callback: it => this.ajouter() },
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    super(conf, options);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getCurrentDateTime() {
 | 
				
			||||||
 | 
					    return new Date().toLocaleString("sv-SE", {
 | 
				
			||||||
 | 
					      year: "numeric",
 | 
				
			||||||
 | 
					      month: "2-digit",
 | 
				
			||||||
 | 
					      day: "2-digit",
 | 
				
			||||||
 | 
					      hour: "2-digit",
 | 
				
			||||||
 | 
					      minute: "2-digit"
 | 
				
			||||||
 | 
					    }).replace(" ", "T");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async ajouter() {
 | 
				
			||||||
 | 
					    await this.forceValidation();
 | 
				
			||||||
 | 
					    const { journalId, journalEntry } = this.findJournal();
 | 
				
			||||||
 | 
					    // ajouter à la page ou créer une page
 | 
				
			||||||
 | 
					    this.addContentToJournal(journalEntry, await this.prepareChronologieEntry());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.storeLatestUsedJournalEntry(journalId);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async forceValidation() {
 | 
				
			||||||
 | 
					    await this.html.find("form.rdddialogchrono :input").change();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  findJournal() {
 | 
				
			||||||
 | 
					    const journalId = this.html.find("form.rdddialogchrono :input[name='journalId']").val();
 | 
				
			||||||
 | 
					    const journalEntry = game.journal.get(journalId);
 | 
				
			||||||
 | 
					    return { journalId, journalEntry };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async prepareChronologieEntry() {
 | 
				
			||||||
 | 
					    return await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chronologie-entry.html", this.extractJournalParameters());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  extractJournalParameters() {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      auteur: this.html.find("form.rdddialogchrono :input[name='auteur']").val(),
 | 
				
			||||||
 | 
					      information: this.html.find("form.rdddialogchrono :input[name='information']").val(),
 | 
				
			||||||
 | 
					      dateRdD: {
 | 
				
			||||||
 | 
					        jour: this.html.find("form.rdddialogchrono :input[name='jourRdD']").val(),
 | 
				
			||||||
 | 
					        moisRdD: this.html.find("form.rdddialogchrono :input[name='dateRdD.moisRdD.key']").val(),
 | 
				
			||||||
 | 
					        annee: this.html.find("form.rdddialogchrono :input[name='dateRdD.annee']").val()
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      heureRdD: this.html.find("form.rdddialogchrono :input[name='heureRdD']").val(),
 | 
				
			||||||
 | 
					      dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val().replace('T', ' ')
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  addContentToJournal(journalEntry, content) {
 | 
				
			||||||
 | 
					    let page = journalEntry.pages.find(p => p.type == 'text' && Grammar.equalsInsensitive(p.name, 'Chronologie'));
 | 
				
			||||||
 | 
					    if (page) {
 | 
				
			||||||
 | 
					      page.update({ 'text.content': content + '\n' + page.text.content });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      journalEntry.createEmbeddedDocuments('JournalEntryPage', [this.newPageChronologie(content)]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  newPageChronologie(content) {
 | 
				
			||||||
 | 
					    return new JournalEntryPage({
 | 
				
			||||||
 | 
					      name: 'Chronologie',
 | 
				
			||||||
 | 
					      type: 'text',
 | 
				
			||||||
 | 
					      title: { show: true, level: 1 },
 | 
				
			||||||
 | 
					      text: { content: content, format: 1 }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  storeLatestUsedJournalEntry(journalId) {
 | 
				
			||||||
 | 
					    game.settings.set(SYSTEM_RDD, LATEST_USED_JOURNAL_ID, journalId);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -35,16 +35,16 @@ export class DialogCreateSigneDraconique extends Dialog {
 | 
				
			|||||||
    super(conf, options);
 | 
					    super(conf, options);
 | 
				
			||||||
    this.dialogData = dialogData;
 | 
					    this.dialogData = dialogData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  async _onCreerSigneActeurs() {
 | 
					  async _onCreerSigneActeurs() {
 | 
				
			||||||
    await $("[name='signe.system.ephemere']").change();
 | 
					    await this.html.find("[name='signe.system.ephemere']").change();
 | 
				
			||||||
    await $(".signe-xp-sort").change();
 | 
					    await this.html.find(".signe-xp-sort").change();
 | 
				
			||||||
    this.validerSigne();
 | 
					    this.validerSigne();
 | 
				
			||||||
    this.dialogData.actors.filter(it => it.selected)
 | 
					    this.dialogData.actors.filter(it => it.selected)
 | 
				
			||||||
      .map(it => game.actors.get(it.id))
 | 
					    .map(it => game.actors.get(it.id))
 | 
				
			||||||
      .forEach(actor => this._createSigneForActor(actor, this.dialogData.signe));
 | 
					    .forEach(actor => this._createSigneForActor(actor, this.dialogData.signe));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  async _createSigneForActor(actor, signe) {
 | 
					  async _createSigneForActor(actor, signe) {
 | 
				
			||||||
    actor.createEmbeddedDocuments("Item", [signe]);
 | 
					    actor.createEmbeddedDocuments("Item", [signe]);
 | 
				
			||||||
    ChatMessage.create({
 | 
					    ChatMessage.create({
 | 
				
			||||||
@@ -57,19 +57,20 @@ export class DialogCreateSigneDraconique extends Dialog {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  validerSigne() {
 | 
					  validerSigne() {
 | 
				
			||||||
    this.dialogData.signe.name = $("[name='signe.name']").val();
 | 
					    this.dialogData.signe.name = this.html.find("[name='signe.name']").val();
 | 
				
			||||||
    this.dialogData.signe.system.valeur.norm = $("[name='signe.system.valeur.norm']").val();
 | 
					    this.dialogData.signe.system.valeur.norm = this.html.find("[name='signe.system.valeur.norm']").val();
 | 
				
			||||||
    this.dialogData.signe.system.valeur.sign = $("[name='signe.system.valeur.sign']").val();
 | 
					    this.dialogData.signe.system.valeur.sign = this.html.find("[name='signe.system.valeur.sign']").val();
 | 
				
			||||||
    this.dialogData.signe.system.valeur.part = $("[name='signe.system.valeur.part']").val();
 | 
					    this.dialogData.signe.system.valeur.part = this.html.find("[name='signe.system.valeur.part']").val();
 | 
				
			||||||
    this.dialogData.signe.system.difficulte = $("[name='signe.system.difficulte']").val();
 | 
					    this.dialogData.signe.system.difficulte = this.html.find("[name='signe.system.difficulte']").val();
 | 
				
			||||||
    this.dialogData.signe.system.ephemere = $("[name='signe.system.ephemere']").prop("checked");
 | 
					    this.dialogData.signe.system.ephemere = this.html.find("[name='signe.system.ephemere']").prop("checked");
 | 
				
			||||||
    this.dialogData.signe.system.duree = $("[name='signe.system.duree']").val();
 | 
					    this.dialogData.signe.system.duree = this.html.find("[name='signe.system.duree']").val();
 | 
				
			||||||
    this.dialogData.signe.system.typesTMR = TMRUtility.buildListTypesTMRSelection(this.dialogData.tmrs);
 | 
					    this.dialogData.signe.system.typesTMR = TMRUtility.buildListTypesTMRSelection(this.dialogData.tmrs);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  activateListeners(html) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    super.activateListeners(html);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
    this.setEphemere(this.dialogData.signe.system.ephemere);
 | 
					    this.setEphemere(this.dialogData.signe.system.ephemere);
 | 
				
			||||||
    html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
 | 
					    html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
 | 
				
			||||||
    html.find("[name='signe.system.ephemere']").change((event) => this.setEphemere(event.currentTarget.checked));
 | 
					    html.find("[name='signe.system.ephemere']").change((event) => this.setEphemere(event.currentTarget.checked));
 | 
				
			||||||
@@ -81,27 +82,27 @@ export class DialogCreateSigneDraconique extends Dialog {
 | 
				
			|||||||
  async setSigneAleatoire() {
 | 
					  async setSigneAleatoire() {
 | 
				
			||||||
    const newSigne = await RdDItemSigneDraconique.randomSigneDraconique({ephemere: true});
 | 
					    const newSigne = await RdDItemSigneDraconique.randomSigneDraconique({ephemere: true});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $("[name='signe.name']").val(newSigne.name);
 | 
					    this.html.find("[name='signe.name']").val(newSigne.name);
 | 
				
			||||||
    $("[name='signe.system.valeur.norm']").val(newSigne.system.valeur.norm);
 | 
					    this.html.find("[name='signe.system.valeur.norm']").val(newSigne.system.valeur.norm);
 | 
				
			||||||
    $("[name='signe.system.valeur.sign']").val(newSigne.system.valeur.sign);
 | 
					    this.html.find("[name='signe.system.valeur.sign']").val(newSigne.system.valeur.sign);
 | 
				
			||||||
    $("[name='signe.system.valeur.part']").val(newSigne.system.valeur.part);
 | 
					    this.html.find("[name='signe.system.valeur.part']").val(newSigne.system.valeur.part);
 | 
				
			||||||
    $("[name='signe.system.difficulte']").val(newSigne.system.difficulte);
 | 
					    this.html.find("[name='signe.system.difficulte']").val(newSigne.system.difficulte);
 | 
				
			||||||
    $("[name='signe.system.duree']").val(newSigne.system.duree);
 | 
					    this.html.find("[name='signe.system.duree']").val(newSigne.system.duree);
 | 
				
			||||||
    $("[name='signe.system.ephemere']").prop("checked", newSigne.system.ephemere);
 | 
					    this.html.find("[name='signe.system.ephemere']").prop("checked", newSigne.system.ephemere);
 | 
				
			||||||
    this.dialogData.tmrs = TMRUtility.buildSelectionTypesTMR(newSigne.system.typesTMR);
 | 
					    this.dialogData.tmrs = TMRUtility.buildSelectionTypesTMR(newSigne.system.typesTMR);
 | 
				
			||||||
    this.dialogData.tmrs.forEach(t => {
 | 
					    this.dialogData.tmrs.forEach(t => {
 | 
				
			||||||
      $(`[data-tmr-name='${t.name}']`).prop( "checked", t.selected);
 | 
					      this.html.find(`[data-tmr-name='${t.name}']`).prop( "checked", t.selected);
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    this.setEphemere(newSigne.system.ephemere);
 | 
					    this.setEphemere(newSigne.system.ephemere);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async setEphemere(ephemere) {
 | 
					  async setEphemere(ephemere) {
 | 
				
			||||||
    this.dialogData.signe.system.ephemere = ephemere;
 | 
					    this.dialogData.signe.system.ephemere = ephemere;
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".signe-system-duree"), ephemere);
 | 
					    HtmlUtility._showControlWhen(this.html.find(".signe-system-duree"), ephemere);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async onSelectActor(event) {
 | 
					  async onSelectActor(event) {
 | 
				
			||||||
    const actorId = $(event.currentTarget)?.data("actor-id");
 | 
					    const actorId = this.html.find(event.currentTarget)?.data("actor-id");
 | 
				
			||||||
    const actor = this.dialogData.actors.find(it => it.id == actorId);
 | 
					    const actor = this.dialogData.actors.find(it => it.id == actorId);
 | 
				
			||||||
    if (actor) {
 | 
					    if (actor) {
 | 
				
			||||||
      actor.selected = event.currentTarget.checked;
 | 
					      actor.selected = event.currentTarget.checked;
 | 
				
			||||||
@@ -109,7 +110,7 @@ export class DialogCreateSigneDraconique extends Dialog {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onSelectTmr(event) {
 | 
					  onSelectTmr(event) {
 | 
				
			||||||
    const tmrName = $(event.currentTarget)?.data("tmr-name");
 | 
					    const tmrName = this.html.find(event.currentTarget)?.data("tmr-name");
 | 
				
			||||||
    const onTmr = this.tmrs.find(it => it.name == tmrName);
 | 
					    const onTmr = this.tmrs.find(it => it.name == tmrName);
 | 
				
			||||||
    if (onTmr){
 | 
					    if (onTmr){
 | 
				
			||||||
      onTmr.selected = event.currentTarget.checked;
 | 
					      onTmr.selected = event.currentTarget.checked;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,18 +13,12 @@ export class DialogFabriquerPotion extends Dialog {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    let potionData = DialogFabriquerPotion.prepareData(actor, item);
 | 
					    let potionData = DialogFabriquerPotion.prepareData(actor, item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let conf = {
 | 
					    const html = await renderTemplate(dialogConfig.html, potionData);
 | 
				
			||||||
      title: `Fabriquer une potion de ${potionData.system.categorie}`,
 | 
					 | 
				
			||||||
      content: await renderTemplate(dialogConfig.html, potionData),
 | 
					 | 
				
			||||||
      default: potionData.buttonName,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let options = { classes: ["dialogfabriquerpotion"], width: 600, height: 160, 'z-index': 99999 };
 | 
					    let options = { classes: ["dialogfabriquerpotion"], width: 600, height: 160, 'z-index': 99999 };
 | 
				
			||||||
    mergeObject(options, dialogConfig.options ?? {}, { overwrite: true })
 | 
					    mergeObject(options, dialogConfig.options ?? {}, { overwrite: true })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const dialog = new DialogFabriquerPotion(actor, potionData, conf, options);
 | 
					    new DialogFabriquerPotion(actor, potionData, html, options).render(true);
 | 
				
			||||||
    dialog.render(true);
 | 
					 | 
				
			||||||
    return dialog;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -40,10 +34,15 @@ export class DialogFabriquerPotion extends Dialog {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  constructor(actor, potionData, conf, options) {
 | 
					  constructor(actor, potionData, html, options) {
 | 
				
			||||||
    conf.buttons = {
 | 
					    const conf = {
 | 
				
			||||||
      [potionData.buttonName]: {
 | 
					      title: `Fabriquer une potion de ${potionData.system.categorie}`,
 | 
				
			||||||
        label: potionData.buttonName, callback: it => this.onFabriquer(it)
 | 
					      content: html,
 | 
				
			||||||
 | 
					      default: 'fabriquer',
 | 
				
			||||||
 | 
					      buttons: {
 | 
				
			||||||
 | 
					        'fabriquer': {
 | 
				
			||||||
 | 
					          label: potionData.buttonName, callback: it => this.onFabriquer(html)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,6 +52,24 @@ export class DialogFabriquerPotion extends Dialog {
 | 
				
			|||||||
    this.potionData = potionData;
 | 
					    this.potionData = potionData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					    this.html.find("[name='nbBrins']").change(event => {
 | 
				
			||||||
 | 
					      this.potionData.nbBrins = Misc.toInt(event.currentTarget.value);
 | 
				
			||||||
 | 
					      const brinsManquants = Math.max(0, DialogFabriquerPotion.nombreBrinsOptimal(this.potionData) - this.potionData.nbBrins);
 | 
				
			||||||
 | 
					      this.potionData.herbebonus = Math.max(0, this.potionData.system.niveau - brinsManquants)
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async onFabriquer(html) {
 | 
				
			||||||
 | 
					    await this.html.find("[name='nbBrins']").change();
 | 
				
			||||||
 | 
					    this.actor.fabriquerPotion(this.potionData);
 | 
				
			||||||
 | 
					    this.close();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static nombreBrinsMinimum(herbeData) {
 | 
					  static nombreBrinsMinimum(herbeData) {
 | 
				
			||||||
    switch (herbeData.system.categorie ?? '') {
 | 
					    switch (herbeData.system.categorie ?? '') {
 | 
				
			||||||
      case "Soin": return 1 + Math.max(0, 12 - 2 * herbeData.system.niveau);
 | 
					      case "Soin": return 1 + Math.max(0, 12 - 2 * herbeData.system.niveau);
 | 
				
			||||||
@@ -68,22 +85,4 @@ export class DialogFabriquerPotion extends Dialog {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    html.find("#nbBrins").change(event => {
 | 
					 | 
				
			||||||
      this.potionData.nbBrins = Misc.toInt(event.currentTarget.value);
 | 
					 | 
				
			||||||
      const brinsManquants = Math.max(0, DialogFabriquerPotion.nombreBrinsOptimal(this.potionData) - this.potionData.nbBrins);
 | 
					 | 
				
			||||||
      this.potionData.herbebonus = Math.max(0, this.potionData.system.niveau - brinsManquants)
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  async onFabriquer(it) {
 | 
					 | 
				
			||||||
    await $("#nbBrins").change();
 | 
					 | 
				
			||||||
    this.actor.fabriquerPotion(this.potionData);
 | 
					 | 
				
			||||||
    this.close();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { Monnaie } from "./item-monnaie.js";
 | 
					import { Monnaie } from "./item-monnaie.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					 | 
				
			||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class DialogItemAchat extends Dialog {
 | 
					export class DialogItemAchat extends Dialog {
 | 
				
			||||||
@@ -19,9 +18,10 @@ export class DialogItemAchat extends Dialog {
 | 
				
			|||||||
      return undefined;
 | 
					      return undefined;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const prixLot = Monnaie.arrondiDeniers(button.attributes['data-prixLot']?.value ?? 0);
 | 
					    const prixLot = Number(button.attributes['data-prixLot']?.value ?? 0);
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      item: json ? JSON.parse(json) : undefined,
 | 
					      item: json ? JSON.parse(json) : undefined,
 | 
				
			||||||
 | 
					      actingUserId: game.user.id,
 | 
				
			||||||
      vendeurId: vendeurId,
 | 
					      vendeurId: vendeurId,
 | 
				
			||||||
      vendeur: vendeur,
 | 
					      vendeur: vendeur,
 | 
				
			||||||
      acheteur: acheteur,
 | 
					      acheteur: acheteur,
 | 
				
			||||||
@@ -39,20 +39,20 @@ export class DialogItemAchat extends Dialog {
 | 
				
			|||||||
      chatMessageIdVente: RdDUtility.findChatMessageId(button)
 | 
					      chatMessageIdVente: RdDUtility.findChatMessageId(button)
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async onAcheter(venteData) {
 | 
					  static async onAcheter(venteData) {
 | 
				
			||||||
    const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
 | 
					    const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
 | 
				
			||||||
    const dialog = new DialogItemAchat(html, venteData);
 | 
					    new DialogItemAchat(html, venteData).render(true);
 | 
				
			||||||
    dialog.render(true);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(html, venteData) {
 | 
					  constructor(html, venteData) {
 | 
				
			||||||
    const isConsommable = venteData.item.type == 'nourritureboisson' && venteData.acheteur?.isPersonnage();
 | 
					    const isConsommable = venteData.item.type == 'nourritureboisson' && venteData.acheteur?.isPersonnage();
 | 
				
			||||||
    let options = { classes: ["dialogachat"], width: 400, height: isConsommable ? 450 : 350, 'z-index': 99999 };
 | 
					    let options = { classes: ["dialogachat"], width: 400, height: 'fit-content', 'z-index': 99999 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
 | 
					    const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
 | 
				
			||||||
    const buttons = {};
 | 
					    const buttons = {};
 | 
				
			||||||
    if (isConsommable) {
 | 
					    if (isConsommable) {
 | 
				
			||||||
      buttons["consommer"] = { label: venteData.item.system.boisson ? "Boire" : "Manger", callback: it => { this.onAchatConsommer(); } }
 | 
					      buttons["consommer"] = { label: venteData.item.system.boisson ? "Boire" : "Manger", callback: it => this.onAchatConsommer() }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
 | 
					    buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
 | 
				
			||||||
    buttons["decliner"] = { label: "Décliner", callback: it => { } };
 | 
					    buttons["decliner"] = { label: "Décliner", callback: it => { } };
 | 
				
			||||||
@@ -64,19 +64,19 @@ export class DialogItemAchat extends Dialog {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    super(conf, options);
 | 
					    super(conf, options);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.venteData = venteData;
 | 
					    this.venteData = venteData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async onAchat() {
 | 
					  async onAchat() {
 | 
				
			||||||
    await $(".nombreLots").change();
 | 
					    await this.html.find(".nombreLots").change();
 | 
				
			||||||
    (this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
 | 
					    (this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
 | 
				
			||||||
      userId: game.user.id,
 | 
					      userId: game.user.id,
 | 
				
			||||||
      vendeurId: this.venteData.vendeur?.id,
 | 
					      vendeurId: this.venteData.vendeur?.id,
 | 
				
			||||||
      acheteurId: this.venteData.acheteur?.id,
 | 
					      acheteurId: this.venteData.acheteur?.id,
 | 
				
			||||||
      prixTotal: this.venteData.prixTotal,
 | 
					      prixTotal: this.venteData.prixTotal,
 | 
				
			||||||
      chatMessageIdVente: this.venteData.chatMessageIdVente,
 | 
					      chatMessageIdVente: this.venteData.chatMessageIdVente,
 | 
				
			||||||
      choix: this.venteData.choix
 | 
					      choix: this.venteData.choix,
 | 
				
			||||||
 | 
					      vente: this.venteData
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -88,9 +88,9 @@ export class DialogItemAchat extends Dialog {
 | 
				
			|||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  activateListeners(html) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    super.activateListeners(html);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
    html.find(".nombreLots").change(event => this.setNombreLots(Number(event.currentTarget.value)));
 | 
					    this.html.find(".nombreLots").change(event => this.setNombreLots(Number(event.currentTarget.value)));
 | 
				
			||||||
    html.find(".se-forcer").change(event => this.setSeForcer(event));
 | 
					    this.html.find(".se-forcer").change(event => this.setSeForcer(event));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setSeForcer(event) {
 | 
					  setSeForcer(event) {
 | 
				
			||||||
@@ -103,8 +103,8 @@ export class DialogItemAchat extends Dialog {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    this.venteData.choix.nombreLots = Math.min(nombreLots, this.venteData.quantiteNbLots);
 | 
					    this.venteData.choix.nombreLots = Math.min(nombreLots, this.venteData.quantiteNbLots);
 | 
				
			||||||
    this.venteData.prixTotal = (nombreLots * this.venteData.prixLot).toFixed(2);
 | 
					    this.venteData.prixTotal = (nombreLots * this.venteData.prixLot).toFixed(2);
 | 
				
			||||||
    $(".nombreLots").val(this.venteData.choix.nombreLots);
 | 
					    this.html.find(".nombreLots").val(this.venteData.choix.nombreLots);
 | 
				
			||||||
    $(".prixTotal").text(this.venteData.prixTotal);
 | 
					    this.html.find(".prixTotal").text(this.venteData.prixTotal);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -2,14 +2,14 @@ import { Misc } from "./misc.js";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export class DialogConsommer extends Dialog {
 | 
					export class DialogConsommer extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async create(actor, item, onActionItem = async ()=>{}) {
 | 
					  static async create(actor, item, onActionItem = async () => { }) {
 | 
				
			||||||
    const consommerData = DialogConsommer.prepareData(actor, item);
 | 
					    const consommerData = DialogConsommer.prepareData(actor, item);
 | 
				
			||||||
    const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-item-consommer.html', consommerData);
 | 
					    const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-item-consommer.html', consommerData);
 | 
				
			||||||
    return new DialogConsommer(actor, item, consommerData, html, onActionItem)
 | 
					    return new DialogConsommer(actor, item, consommerData, html, onActionItem)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(actor, item, consommerData, html, onActionItem = async ()=>{}) {
 | 
					  constructor(actor, item, consommerData, html, onActionItem = async () => { }) {
 | 
				
			||||||
    const options = { classes: ["dialogconsommer"], width: 350, height: 450, 'z-index': 99999 };
 | 
					    const options = { classes: ["dialogconsommer"], width: 350, height: 'fit-content', 'z-index': 99999 };
 | 
				
			||||||
    let conf = {
 | 
					    let conf = {
 | 
				
			||||||
      title: consommerData.title,
 | 
					      title: consommerData.title,
 | 
				
			||||||
      content: html,
 | 
					      content: html,
 | 
				
			||||||
@@ -17,8 +17,9 @@ export class DialogConsommer extends Dialog {
 | 
				
			|||||||
      buttons: {
 | 
					      buttons: {
 | 
				
			||||||
        [consommerData.buttonName]: {
 | 
					        [consommerData.buttonName]: {
 | 
				
			||||||
          label: consommerData.buttonName, callback: async it => {
 | 
					          label: consommerData.buttonName, callback: async it => {
 | 
				
			||||||
            await this.onConsommer(it);
 | 
					            await this.onConsommer();
 | 
				
			||||||
            await onActionItem();}
 | 
					            await onActionItem();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@@ -30,17 +31,23 @@ export class DialogConsommer extends Dialog {
 | 
				
			|||||||
    this.consommerData = consommerData;
 | 
					    this.consommerData = consommerData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async onConsommer(event) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    await $(".se-forcer").change();
 | 
					    super.activateListeners(html);
 | 
				
			||||||
    await $(".consommer-doses").change();
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					    this.html.find(".se-forcer").change(event => this.setSeForcer(event));
 | 
				
			||||||
 | 
					    this.html.find(".consommer-doses").change(event => this.selectDoses(event));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async onConsommer() {
 | 
				
			||||||
 | 
					    await this.html.find(".se-forcer").change();
 | 
				
			||||||
 | 
					    await this.html.find(".consommer-doses").change();
 | 
				
			||||||
    await this.actor.consommer(this.item, this.consommerData.choix);
 | 
					    await this.actor.consommer(this.item, this.consommerData.choix);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static prepareData(actor, item) {
 | 
					  static prepareData(actor, item) {
 | 
				
			||||||
    item = duplicate(item);
 | 
					 | 
				
			||||||
    let consommerData = {
 | 
					    let consommerData = {
 | 
				
			||||||
      item: item,
 | 
					      item: duplicate(item),
 | 
				
			||||||
      cuisine: actor.getCompetence('cuisine'),
 | 
					      cuisine: actor.getCompetence('cuisine'),
 | 
				
			||||||
      choix: {
 | 
					      choix: {
 | 
				
			||||||
        doses: 1,
 | 
					        doses: 1,
 | 
				
			||||||
@@ -48,33 +55,47 @@ export class DialogConsommer extends Dialog {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    switch (item.type) {
 | 
					    switch (item.type) {
 | 
				
			||||||
 | 
					      case 'herbe': case 'faune':
 | 
				
			||||||
 | 
					        consommerData.title = 'Manger une portion crue: ';
 | 
				
			||||||
 | 
					        consommerData.buttonName = "Manger";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
      case 'nourritureboisson':
 | 
					      case 'nourritureboisson':
 | 
				
			||||||
        consommerData.title = item.system.boisson ? `${item.name}: boire une dose` : `${item.name}: manger une portion`;
 | 
					        consommerData.title = item.system.boisson ? 'Boire une dose: ' : 'Manger une portion: ';
 | 
				
			||||||
        consommerData.buttonName = item.system.boisson ? "Boire" : "Manger";
 | 
					        consommerData.buttonName = item.system.boisson ? "Boire" : "Manger";
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case 'potion':
 | 
					      case 'potion':
 | 
				
			||||||
        consommerData.title = `${item.name}: boire la potion`;
 | 
					        consommerData.title = 'Boire la potion: ';
 | 
				
			||||||
        consommerData.buttonName = "Boire";
 | 
					        consommerData.buttonName = "Boire";
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    DialogConsommer.calculDoses(consommerData, consommerData.choix.doses)
 | 
					    consommerData.title += item.name;
 | 
				
			||||||
 | 
					    DialogConsommer.calculDoses(consommerData, item)
 | 
				
			||||||
    return consommerData;
 | 
					    return consommerData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static calculDoses(consommer) {
 | 
					  static calculDoses(consommer, item) {
 | 
				
			||||||
    const doses = consommer.choix.doses;
 | 
					    const doses = consommer.choix.doses;
 | 
				
			||||||
    consommer.totalSust = Misc.keepDecimals(doses * (consommer.item.system.sust ?? 0), 2);
 | 
					    switch (item.type) {
 | 
				
			||||||
    consommer.totalDesaltere = consommer.item.system.boisson
 | 
					      case 'herbe': case 'faune':
 | 
				
			||||||
      ? Misc.keepDecimals(doses * (consommer.item.system.desaltere ?? 0), 2)
 | 
					        consommer.totalSust = doses;
 | 
				
			||||||
      : 0;
 | 
					        consommer.totalDesaltere = 0;
 | 
				
			||||||
  }
 | 
					        consommer.choix.sust = 1;
 | 
				
			||||||
 | 
					        consommer.choix.quantite = 0;
 | 
				
			||||||
 | 
					        consommer.choix.encombrement = Misc.keepDecimals(consommer.item.system.encombrement / item.system.sust, 2);
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					        return;
 | 
				
			||||||
  activateListeners(html) {
 | 
					      case 'nourritureboisson':
 | 
				
			||||||
    super.activateListeners(html);
 | 
					        consommer.choix.sust = consommer.item.system.sust;
 | 
				
			||||||
    html.find(".se-forcer").change(event => this.setSeForcer(event));
 | 
					        consommer.choix.quantite = doses;
 | 
				
			||||||
    html.find(".consommer-doses").change(event => this.selectDoses(event));
 | 
					        consommer.choix.encombrement = 0
 | 
				
			||||||
 | 
					        consommer.totalSust = Misc.keepDecimals(doses * (consommer.item.system.sust ?? 0), 2);
 | 
				
			||||||
 | 
					        consommer.totalDesaltere = consommer.item.system.boisson
 | 
				
			||||||
 | 
					          ? Misc.keepDecimals(doses * (consommer.item.system.desaltere ?? 0), 2)
 | 
				
			||||||
 | 
					          : 0;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'potion':
 | 
				
			||||||
 | 
					        consommer.totalSust = 0
 | 
				
			||||||
 | 
					        consommer.totalDesaltere = 0
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,8 +105,8 @@ export class DialogConsommer extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  selectDoses(event) {
 | 
					  selectDoses(event) {
 | 
				
			||||||
    this.consommerData.choix.doses = Number(event.currentTarget.value);
 | 
					    this.consommerData.choix.doses = Number(event.currentTarget.value);
 | 
				
			||||||
    DialogConsommer.calculDoses(this.consommerData);
 | 
					    DialogConsommer.calculDoses(this.consommerData, this.item);
 | 
				
			||||||
    $(".total-sust").text(this.consommerData.totalSust);
 | 
					    this.html.find(".total-sust").text(this.consommerData.totalSust);
 | 
				
			||||||
    $(".total-desaltere").text(this.consommerData.totalDesaltere);
 | 
					    this.html.find(".total-desaltere").text(this.consommerData.totalDesaltere);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
import { HtmlUtility } from "./html-utility.js";
 | 
					import { HtmlUtility } from "./html-utility.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class DialogItemVente extends Dialog {
 | 
					export class DialogItemVente extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,7 +23,7 @@ export class DialogItemVente extends Dialog {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(venteData, html, callback) {
 | 
					  constructor(venteData, html, callback) {
 | 
				
			||||||
    let options = { classes: ["dialogvente"], width: 400, height: 300, 'z-index': 99999 };
 | 
					    let options = { classes: ["dialogvente"], width: 400, height: 'fit-content', 'z-index': 99999 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let conf = {
 | 
					    let conf = {
 | 
				
			||||||
      title: "Proposer",
 | 
					      title: "Proposer",
 | 
				
			||||||
@@ -38,26 +37,26 @@ export class DialogItemVente extends Dialog {
 | 
				
			|||||||
    this.venteData = venteData;
 | 
					    this.venteData = venteData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async onProposer(it) {
 | 
					 | 
				
			||||||
    await $(".tailleLot").change();
 | 
					 | 
				
			||||||
    await $(".quantiteNbLots").change();
 | 
					 | 
				
			||||||
    await $(".quantiteIllimite").change();
 | 
					 | 
				
			||||||
    await $(".prixLot").change();
 | 
					 | 
				
			||||||
    this.callback(this.venteData);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    super.activateListeners(html);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					    HtmlUtility._showControlWhen(this.html.find(".quantiteNbLots"), !this.venteData.quantiteIllimite)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".quantiteNbLots"), !this.venteData.quantiteIllimite)
 | 
					    this.html.find(".tailleLot").change(event => this.setTailleLot(Number(event.currentTarget.value)));
 | 
				
			||||||
 | 
					    this.html.find(".quantiteNbLots").change(event => this.setNbLots(Number(event.currentTarget.value)));
 | 
				
			||||||
    html.find(".tailleLot").change(event => this.setTailleLot(Number(event.currentTarget.value)));
 | 
					    this.html.find(".quantiteIllimite").change(event => this.setQuantiteIllimite(event.currentTarget.checked));
 | 
				
			||||||
    html.find(".quantiteNbLots").change(event => this.setNbLots(Number(event.currentTarget.value)));
 | 
					    this.html.find(".prixLot").change(event => this.setPrixLot(Number(event.currentTarget.value)));
 | 
				
			||||||
    html.find(".quantiteIllimite").change(event => this.setQuantiteIllimite(event.currentTarget.checked));
 | 
					 | 
				
			||||||
    html.find(".prixLot").change(event => this.setPrixLot(Number(event.currentTarget.value)));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async onProposer(it) {
 | 
				
			||||||
 | 
					    await this.html.find(".tailleLot").change();
 | 
				
			||||||
 | 
					    await this.html.find(".quantiteNbLots").change();
 | 
				
			||||||
 | 
					    await this.html.find(".quantiteIllimite").change();
 | 
				
			||||||
 | 
					    await this.html.find(".prixLot").change();
 | 
				
			||||||
 | 
					    this.callback(this.venteData);
 | 
				
			||||||
 | 
					  }  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  setPrixLot(prixLot) {
 | 
					  setPrixLot(prixLot) {
 | 
				
			||||||
    this.venteData.prixLot = prixLot;
 | 
					    this.venteData.prixLot = prixLot;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -66,15 +65,15 @@ export class DialogItemVente extends Dialog {
 | 
				
			|||||||
    // recalculer le prix du lot
 | 
					    // recalculer le prix du lot
 | 
				
			||||||
    if (tailleLot != this.venteData.tailleLot) {
 | 
					    if (tailleLot != this.venteData.tailleLot) {
 | 
				
			||||||
      this.venteData.prixLot = (tailleLot * this.venteData.prixOrigine).toFixed(2);
 | 
					      this.venteData.prixLot = (tailleLot * this.venteData.prixOrigine).toFixed(2);
 | 
				
			||||||
      $(".prixLot").val(this.venteData.prixLot);
 | 
					      this.html.find(".prixLot").val(this.venteData.prixLot);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this.venteData.tailleLot = tailleLot;
 | 
					    this.venteData.tailleLot = tailleLot;
 | 
				
			||||||
    if (this.venteData.isOwned) {
 | 
					    if (this.venteData.isOwned) {
 | 
				
			||||||
      // recalculer le nombre de lots max
 | 
					      // recalculer le nombre de lots max
 | 
				
			||||||
      this.venteData.quantiteMaxLots = Math.floor(this.venteData.quantiteMax / tailleLot);
 | 
					      this.venteData.quantiteMaxLots = Math.floor(this.venteData.quantiteMax / tailleLot);
 | 
				
			||||||
      this.venteData.quantiteNbLots = Math.min(this.venteData.quantiteMaxLots, this.venteData.quantiteNbLots);
 | 
					      this.venteData.quantiteNbLots = Math.min(this.venteData.quantiteMaxLots, this.venteData.quantiteNbLots);
 | 
				
			||||||
      $(".quantiteNbLots").val(this.venteData.quantiteNbLots);
 | 
					      this.html.find(".quantiteNbLots").val(this.venteData.quantiteNbLots);
 | 
				
			||||||
      $(".quantiteNbLots").attr("max", this.venteData.quantiteMaxLots)
 | 
					      this.html.find(".quantiteNbLots").attr("max", this.venteData.quantiteMaxLots)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -83,12 +82,12 @@ export class DialogItemVente extends Dialog {
 | 
				
			|||||||
      nbLots = Math.max(0, Math.min(nbLots, this.venteData.quantiteMaxLots));
 | 
					      nbLots = Math.max(0, Math.min(nbLots, this.venteData.quantiteMaxLots));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this.venteData.quantiteNbLots = nbLots;
 | 
					    this.venteData.quantiteNbLots = nbLots;
 | 
				
			||||||
    $(".quantiteNbLots").val(this.venteData.quantiteNbLots);
 | 
					    this.html.find(".quantiteNbLots").val(this.venteData.quantiteNbLots);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setQuantiteIllimite(checked) {
 | 
					  setQuantiteIllimite(checked) {
 | 
				
			||||||
    this.venteData.quantiteIllimite = checked;
 | 
					    this.venteData.quantiteIllimite = checked;
 | 
				
			||||||
    $(".label-quantiteIllimite").text(this.venteData.quantiteIllimite ? "Illimités" : "disponibles");
 | 
					    this.html.find(".label-quantiteIllimite").text(this.venteData.quantiteIllimite ? "Illimités" : "disponibles");
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".quantiteNbLots"), !this.venteData.quantiteIllimite)
 | 
					    HtmlUtility._showControlWhen(this.html.find(".quantiteNbLots"), !this.venteData.quantiteIllimite)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -3,13 +3,13 @@ import { Misc } from "./misc.js";
 | 
				
			|||||||
export class DialogRepos extends Dialog {
 | 
					export class DialogRepos extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async create(actor) {
 | 
					  static async create(actor) {
 | 
				
			||||||
    let actorData = actor
 | 
					    const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-repos.html", actor);
 | 
				
			||||||
    const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-repos.html", actorData);
 | 
					    const dialog = new DialogRepos(html, actor);
 | 
				
			||||||
    new DialogRepos(html, actor).render(true);
 | 
					    dialog.render(true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(html, actor) {
 | 
					  constructor(html, actor) {
 | 
				
			||||||
    let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 400, 'z-index': 99999 };
 | 
					    let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 400, height: 'fit-content', 'z-index': 99999 };
 | 
				
			||||||
    let conf = {
 | 
					    let conf = {
 | 
				
			||||||
      title: "Se reposer",
 | 
					      title: "Se reposer",
 | 
				
			||||||
      content: html,
 | 
					      content: html,
 | 
				
			||||||
@@ -21,13 +21,18 @@ export class DialogRepos extends Dialog {
 | 
				
			|||||||
    super(conf, options);
 | 
					    super(conf, options);
 | 
				
			||||||
    this.actor = actor;
 | 
					    this.actor = actor;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async repos() {
 | 
					  async repos() {
 | 
				
			||||||
    await $("[name='nb-heures']").change();
 | 
					    await this.html.find("[name='nb-heures']").change();
 | 
				
			||||||
    await $("[name='nb-jours']").change();
 | 
					    await this.html.find("[name='nb-jours']").change();
 | 
				
			||||||
    const selection = await $("[name='repos']:checked").val();
 | 
					    const selection = await this.html.find("[name='repos']:checked").val();
 | 
				
			||||||
    const nbHeures = Number.parseInt(await $("[name='nb-heures']").val());
 | 
					    const nbHeures = Number.parseInt(await this.html.find("[name='nb-heures']").val());
 | 
				
			||||||
    const nbJours = Number.parseInt(await $("[name='nb-jours']").val());
 | 
					    const nbJours = Number.parseInt(await this.html.find("[name='nb-jours']").val());
 | 
				
			||||||
    switch (selection) {
 | 
					    switch (selection) {
 | 
				
			||||||
      case "sieste": {
 | 
					      case "sieste": {
 | 
				
			||||||
        await this.actor.dormir(nbHeures);
 | 
					        await this.actor.dormir(nbHeures);
 | 
				
			||||||
@@ -35,7 +40,7 @@ export class DialogRepos extends Dialog {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      case "nuit": {
 | 
					      case "nuit": {
 | 
				
			||||||
        let heuresDormies = await this.actor.dormir(nbHeures);
 | 
					        let heuresDormies = await this.actor.dormir(nbHeures);
 | 
				
			||||||
        if (heuresDormies == nbHeures){
 | 
					        if (heuresDormies == nbHeures) {
 | 
				
			||||||
          await this.actor.dormirChateauDormant();
 | 
					          await this.actor.dormirChateauDormant();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
@@ -49,8 +54,4 @@ export class DialogRepos extends Dialog {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								module/dialog-select-target.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					export class DialogSelectTarget extends Dialog {
 | 
				
			||||||
 | 
					  constructor(html, onSelectTarget, targets) {
 | 
				
			||||||
 | 
					    const options = {
 | 
				
			||||||
 | 
					      classes: ["rdd-dialog-select-target"],
 | 
				
			||||||
 | 
					      width: 'fit-content',
 | 
				
			||||||
 | 
					      height: 'fit-content',
 | 
				
			||||||
 | 
					      'max-height': 600,
 | 
				
			||||||
 | 
					      'z-index': 99999
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    const conf = {
 | 
				
			||||||
 | 
					      title: "Choisir une cible",
 | 
				
			||||||
 | 
					      content: html,
 | 
				
			||||||
 | 
					      buttons: {}
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    super(conf, options);
 | 
				
			||||||
 | 
					    this.onSelectTarget = onSelectTarget;
 | 
				
			||||||
 | 
					    this.targets = targets;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					    this.html.find("li.select-target").click((event) => {
 | 
				
			||||||
 | 
					      this.targetSelected(this.html.find(event.currentTarget)?.data("token-id"));
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  targetSelected(tokenId) {
 | 
				
			||||||
 | 
					    const target = this.targets.find(it => it.id == tokenId);
 | 
				
			||||||
 | 
					    this.close();
 | 
				
			||||||
 | 
					    if (target) {
 | 
				
			||||||
 | 
					      this.onSelectTarget(target);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -13,39 +13,33 @@ export class DialogSplitItem extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  constructor(item, splitData, html, callback) {
 | 
					  constructor(item, splitData, html, callback) {
 | 
				
			||||||
    let options = { classes: ["dialogsplit"], width: 300, height: 160, 'z-index': 99999 };
 | 
					    let options = { classes: ["dialogsplit"], width: 300, height: 160, 'z-index': 99999 };
 | 
				
			||||||
 | 
					 | 
				
			||||||
    let conf = {
 | 
					    let conf = {
 | 
				
			||||||
      title: "Séparer en deux",
 | 
					      title: "Séparer en deux",
 | 
				
			||||||
      content: html,
 | 
					      content: html,
 | 
				
			||||||
      default: "separer",
 | 
					      default: "separer",
 | 
				
			||||||
      buttons: {
 | 
					      buttons: {
 | 
				
			||||||
        "separer": {
 | 
					        "separer": { label: "Séparer", callback: it => this.onSplit() }
 | 
				
			||||||
          label: "Séparer", callback: it => {
 | 
					 | 
				
			||||||
            this.onSplit();
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    super(conf, options);
 | 
					    super(conf, options);
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    this.callback = callback;
 | 
					    this.callback = callback;
 | 
				
			||||||
    this.item = item;
 | 
					    this.item = item;
 | 
				
			||||||
    this.splitData = splitData;
 | 
					    this.splitData = splitData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async onSplit(){
 | 
					 | 
				
			||||||
    await $(".choix-quantite").change();
 | 
					 | 
				
			||||||
    this.callback(this.item, this.splitData.choix.quantite);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    super.activateListeners(html);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
    html.find(".choix-quantite").change(event => {
 | 
					    this.html.find(".choix-quantite").change(event => {
 | 
				
			||||||
      this.splitData.choix.quantite = Number(event.currentTarget.value);
 | 
					      this.splitData.choix.quantite = Number(event.currentTarget.value);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async onSplit() {
 | 
				
			||||||
 | 
					    await this.html.find(".choix-quantite").change();
 | 
				
			||||||
 | 
					    this.callback(this.item, this.splitData.choix.quantite);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class DialogStress extends Dialog {
 | 
					export class DialogStress extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,7 +23,7 @@ export class DialogStress extends Dialog {
 | 
				
			|||||||
  constructor(dialogData, html) {
 | 
					  constructor(dialogData, html) {
 | 
				
			||||||
    const options = { classes: ["DialogStress"],
 | 
					    const options = { classes: ["DialogStress"],
 | 
				
			||||||
      width: 400,
 | 
					      width: 400,
 | 
				
			||||||
      height: 205+dialogData.actors.length*25,
 | 
					      height: 'fit-content',
 | 
				
			||||||
      'z-index': 99999
 | 
					      'z-index': 99999
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    const conf = {
 | 
					    const conf = {
 | 
				
			||||||
@@ -32,31 +31,30 @@ export class DialogStress extends Dialog {
 | 
				
			|||||||
      content: html,
 | 
					      content: html,
 | 
				
			||||||
      buttons: {
 | 
					      buttons: {
 | 
				
			||||||
        stress: { label: "Stress !", callback: it => { this.onStress(); } }
 | 
					        stress: { label: "Stress !", callback: it => { this.onStress(); } }
 | 
				
			||||||
      },
 | 
					      }
 | 
				
			||||||
      default: "stress"
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    super(conf, options);
 | 
					    super(conf, options);
 | 
				
			||||||
    this.dialogData = dialogData;
 | 
					    this.dialogData = dialogData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					    this.html.find("input.select-actor").change((event) => this.onSelectActor(event));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async onStress() {
 | 
					  async onStress() {
 | 
				
			||||||
    const motif = $("form.rdddialogstress input[name='motif']").val();
 | 
					    const motif = this.html.find("form.rdddialogstress input[name='motif']").val();
 | 
				
			||||||
    const stress = Number($("form.rdddialogstress input[name='stress']").val());
 | 
					    const stress = Number(this.html.find("form.rdddialogstress input[name='stress']").val());
 | 
				
			||||||
    const compteur = ($("form.rdddialogstress input[name='immediat']").prop("checked")) ? 'experience' : 'stress';
 | 
					    const compteur = (this.html.find("form.rdddialogstress input[name='immediat']").prop("checked")) ? 'experience' : 'stress';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.dialogData.actors.filter(it => it.selected)
 | 
					    this.dialogData.actors.filter(it => it.selected)
 | 
				
			||||||
      .map(it => game.actors.get(it.id))
 | 
					      .map(it => game.actors.get(it.id))
 | 
				
			||||||
      .forEach(actor => actor.distribuerStress(compteur, stress, motif));
 | 
					      .forEach(actor => actor.distribuerStress(compteur, stress, motif));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
    html.find("input.select-actor").change((event) => this.onSelectActor(event));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async onSelectActor(event) {
 | 
					  async onSelectActor(event) {
 | 
				
			||||||
    const actorId = $(event.currentTarget)?.data("actor-id");
 | 
					    const actorId = this.html.find(event.currentTarget)?.data("actor-id");
 | 
				
			||||||
    const actor = this.dialogData.actors.find(it => it.id == actorId);
 | 
					    const actor = this.dialogData.actors.find(it => it.id == actorId);
 | 
				
			||||||
    if (actor) {
 | 
					    if (actor) {
 | 
				
			||||||
      actor.selected = event.currentTarget.checked;
 | 
					      actor.selected = event.currentTarget.checked;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ export class DialogValidationEncaissement extends Dialog {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let dialogOptions = {
 | 
					    let dialogOptions = {
 | 
				
			||||||
      classes: ["rdddialog"],
 | 
					      classes: ["rdd-roll-dialog"],
 | 
				
			||||||
      width: 350,
 | 
					      width: 350,
 | 
				
			||||||
      height: 290
 | 
					      height: 290
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -55,11 +55,12 @@ export class DialogValidationEncaissement extends Dialog {
 | 
				
			|||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  activateListeners(html) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    super.activateListeners(html);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
    html.find('input.encaissement-roll-result').keyup(async event => {
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					    this.html.find('input.encaissement-roll-result').keyup(async event => {
 | 
				
			||||||
      this.forceDiceResult.total = event.currentTarget.value;
 | 
					      this.forceDiceResult.total = event.currentTarget.value;
 | 
				
			||||||
      this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult});
 | 
					      this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult});
 | 
				
			||||||
      $('label.encaissement-total').text(this.encaissement.total);
 | 
					      this.html.find('label.encaissement-total').text(this.encaissement.total);
 | 
				
			||||||
      $('label.encaissement-blessure').text(this.encaissement.blessures)
 | 
					      this.html.find('label.encaissement-blessure').text(this.encaissement.blessures)
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										137
									
								
								module/effets-rencontres.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,137 @@
 | 
				
			|||||||
 | 
					import { ChatUtility } from "./chat-utility.js";
 | 
				
			||||||
 | 
					import { Poetique } from "./poetique.js";
 | 
				
			||||||
 | 
					import { RdDDice } from "./rdd-dice.js";
 | 
				
			||||||
 | 
					import { TMRUtility } from "./tmr-utility.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class EffetsRencontre {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static messager = async (dialog, context) => {
 | 
				
			||||||
 | 
					    dialog.setRencontreState('messager', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static passeur = async (dialog, context) => {
 | 
				
			||||||
 | 
					    dialog.setRencontreState('passeur', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static teleportation_typecase = async (dialog, context) => {
 | 
				
			||||||
 | 
					    dialog.setRencontreState('changeur', TMRUtility.getCasesType(context.tmr.type));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static rencontre_persistante = async (dialog, context) => {
 | 
				
			||||||
 | 
					    dialog.setRencontreState('persistant', []);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static reve_plus_force = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, context.rencontre.system.force) }
 | 
				
			||||||
 | 
					  static reve_plus_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, 1) }
 | 
				
			||||||
 | 
					  static reve_moins_force = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -context.rencontre.system.force) }
 | 
				
			||||||
 | 
					  static reve_moins_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -1) }
 | 
				
			||||||
 | 
					  static $reve_plus = async (actor, valeur) => { await actor.reveActuelIncDec(valeur) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static vie_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
 | 
				
			||||||
 | 
					  static vie_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) }
 | 
				
			||||||
 | 
					  static $vie_plus = async (actor, valeur) => { await actor.santeIncDec("vie", valeur) }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static moral_plus_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, 1) }
 | 
				
			||||||
 | 
					  static moral_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
 | 
				
			||||||
 | 
					  static $moral_plus = async (actor, valeur) => { await actor.moralIncDec(valeur) }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static end_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
 | 
				
			||||||
 | 
					  static end_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) }
 | 
				
			||||||
 | 
					  static $end_plus = async (actor, valeur) => { await actor.santeIncDec("endurance", valeur) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static fatigue_plus_1 = async (dialog, context) => { await EffetsRencontre.$fatigue_plus(context.actor, 1) }
 | 
				
			||||||
 | 
					  static fatigue_plus_force = async (dialog, context) => { await EffetsRencontre.$fatigue_plus(context.actor, context.rencontre.system.force) }
 | 
				
			||||||
 | 
					  static fatigue_moins_1 = async (dialog, context) => { await EffetsRencontre.$fatigue_plus(context.actor, -1) }
 | 
				
			||||||
 | 
					  static fatigue_moins_force = async (dialog, context) => { await EffetsRencontre.$fatigue_plus(context.actor, -context.rencontre.system.force) }
 | 
				
			||||||
 | 
					  static $fatigue_plus = async (actor, valeur) => { await actor.santeIncDec("fatigue", valeur) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static perte_chance = async (dialog, context) => {
 | 
				
			||||||
 | 
					    const perte = context.rolled.isETotal ? context.rencontre.system.force : 1;
 | 
				
			||||||
 | 
					    await context.actor.chanceActuelleIncDec("fatigue", -perte);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static xp_sort_force = async (dialog, context) => { 
 | 
				
			||||||
 | 
					    let competence = context.competence;
 | 
				
			||||||
 | 
					    if (competence) {
 | 
				
			||||||
 | 
					      const xpSort = Misc.toInt(competence.system.xp_sort) + context.rencontre.system.force;
 | 
				
			||||||
 | 
					      await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': xpSort }]);
 | 
				
			||||||
 | 
					      await this.updateExperienceLog("XP Sort", xpSort, `Rencontre d'un ${context.rencontre.name} en TMR`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static stress_plus_1 = async (dialog, context) => {
 | 
				
			||||||
 | 
					    await context.actor.addCompteurValue('stress', 1, `Rencontre d'un ${context.rencontre.name} en TMR`);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static reinsertion = async (dialog, context) => {
 | 
				
			||||||
 | 
					    await EffetsRencontre.$reinsertion(dialog, context.actor, it => true)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static teleportation_aleatoire_typecase = async (dialog, context) => {
 | 
				
			||||||
 | 
					    await EffetsRencontre.$reinsertion(dialog, context.actor, it => it.type == context.tmr.type && it.coord != context.tmr.coord)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static demireve_rompu = async (dialog, context) => {
 | 
				
			||||||
 | 
					    dialog.close()
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static sort_aleatoire = async (dialog, context) => {
 | 
				
			||||||
 | 
					    context.sortReserve = await RdDDice.rollOneOf(context.actor.itemTypes['sortreserve']);
 | 
				
			||||||
 | 
					    if (context.sortReserve) {
 | 
				
			||||||
 | 
					      context.newTMR = TMRUtility.getTMR(context.sortReserve.system.coord);
 | 
				
			||||||
 | 
					      await dialog.positionnerDemiReve(context.newTMR.coord);
 | 
				
			||||||
 | 
					      await dialog.processSortReserve(context.sortReserve);
 | 
				
			||||||
 | 
					      dialog.close();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      await EffetsRencontre.$reinsertion(dialog, context.actor, it => true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static deplacement_aleatoire = async (dialog, context) => {
 | 
				
			||||||
 | 
					    const oldCoord = context.actor.system.reve.tmrpos.coord;
 | 
				
			||||||
 | 
					    const newTmr = await TMRUtility.deplaceTMRAleatoire(context.actor, oldCoord);
 | 
				
			||||||
 | 
					    await dialog.positionnerDemiReve(newTmr.coord)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static rdd_part_tete = async (dialog, context) => {
 | 
				
			||||||
 | 
					    mergeObject(context, {
 | 
				
			||||||
 | 
					      tete: context.rolled.isPart,
 | 
				
			||||||
 | 
					      poesie: await Poetique.getExtrait()
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    ChatMessage.create({
 | 
				
			||||||
 | 
					      whisper: ChatUtility.getWhisperRecipientsAndGMs(context.actor.name),
 | 
				
			||||||
 | 
					      content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context)
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static rdd_echec_queue = async (dialog, context) => {
 | 
				
			||||||
 | 
					    mergeObject(context, {
 | 
				
			||||||
 | 
					      queues: [await context.actor.ajouterQueue()],
 | 
				
			||||||
 | 
					      poesie: await Poetique.getExtrait()
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    if (context.rolled.isETotal) {
 | 
				
			||||||
 | 
					      context.queues.push(await context.actor.ajouterQueue());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ChatMessage.create({
 | 
				
			||||||
 | 
					      whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
 | 
				
			||||||
 | 
					      content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context)
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static experience_particuliere = async (dialog, context) => {
 | 
				
			||||||
 | 
					    await context.actor.appliquerAjoutExperience(context)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static regain_seuil = async (dialog, context) => {
 | 
				
			||||||
 | 
					    await context.actor.regainPointDeSeuil()
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async $reinsertion(dialog, actor, filter) {
 | 
				
			||||||
 | 
					    const newTMR = await TMRUtility.getTMRAleatoire(filter);
 | 
				
			||||||
 | 
					    await actor.forcerPositionTMRInconnue(newTMR);
 | 
				
			||||||
 | 
					    await dialog.positionnerDemiReve(newTMR.coord);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										223
									
								
								module/environnement.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,223 @@
 | 
				
			|||||||
 | 
					import { SYSTEM_RDD } from "./constants.js";
 | 
				
			||||||
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
 | 
					import { CompendiumTableHelpers, CompendiumTable } from "./settings/system-compendiums.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const RARETES = [
 | 
				
			||||||
 | 
					  { name: 'Commune', frequence: 54, min: 27, max: 108 },
 | 
				
			||||||
 | 
					  { name: 'Frequente', frequence: 18, min: 9, max: 36 },
 | 
				
			||||||
 | 
					  { name: 'Rare', frequence: 6, min: 3, max: 12 },
 | 
				
			||||||
 | 
					  { name: 'Rarissime', frequence: 2, min: 1, max: 4 }]
 | 
				
			||||||
 | 
					const DEFAULT_RARETE = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const SETTINGS_LISTE_MILIEUX = "liste-milieux";
 | 
				
			||||||
 | 
					const MILIEUX = [
 | 
				
			||||||
 | 
					  "Collines",
 | 
				
			||||||
 | 
					  "Cours d'eau",
 | 
				
			||||||
 | 
					  "Déserts",
 | 
				
			||||||
 | 
					  "Forêts",
 | 
				
			||||||
 | 
					  "Marais",
 | 
				
			||||||
 | 
					  "Maritimes",
 | 
				
			||||||
 | 
					  "Montagnes",
 | 
				
			||||||
 | 
					  "Plaines",
 | 
				
			||||||
 | 
					  "Sous-sols"
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					const ITEM_ENVIRONNEMENT_TYPES = [
 | 
				
			||||||
 | 
					  'herbe', 'ingredient', 'faune'
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Environnement {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static init() {
 | 
				
			||||||
 | 
					    game.settings.register(SYSTEM_RDD, SETTINGS_LISTE_MILIEUX, {
 | 
				
			||||||
 | 
					      name: "Liste des milieux proposés",
 | 
				
			||||||
 | 
					      hint: "Liste des milieux proposés pour la faune&flore, séparés par des virgules",
 | 
				
			||||||
 | 
					      scope: "world",
 | 
				
			||||||
 | 
					      config: true,
 | 
				
			||||||
 | 
					      default: MILIEUX.reduce(Misc.joining(',')),
 | 
				
			||||||
 | 
					      type: String
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    game.system.rdd.environnement = new Environnement();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    this.table = new CompendiumTable('faune-flore-mineraux', 'Item', ITEM_ENVIRONNEMENT_TYPES)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getRarete(name = undefined) {
 | 
				
			||||||
 | 
					    return RARETES.find(it => it.name == name) ?? RARETES[DEFAULT_RARETE];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getFrequenceRarete(rarete, field = undefined) {
 | 
				
			||||||
 | 
					    const selected = this.getRarete(rarete);
 | 
				
			||||||
 | 
					    return selected[field];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async milieux() {
 | 
				
			||||||
 | 
					    return Object.values(await this.mapMilieux());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async mapMilieux() {
 | 
				
			||||||
 | 
					    const compendiumItems = await this.getElements(it => 1, it => ITEM_ENVIRONNEMENT_TYPES.includes(it.type));
 | 
				
			||||||
 | 
					    return Misc.indexLowercase(this.getMilieuxSettings().concat(Environnement.listMilieux(compendiumItems)));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static listMilieux(items) {
 | 
				
			||||||
 | 
					    return Misc.concat(items.map(it => Environnement.$itemToMilieux(it).filter(m => m)));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async autresMilieux(item) {
 | 
				
			||||||
 | 
					    const mapMilieux = await this.mapMilieux();
 | 
				
			||||||
 | 
					    const milieuxExistants = Environnement.$itemToMilieux(item).map(it => Grammar.toLowerCaseNoAccent(it));
 | 
				
			||||||
 | 
					    return Object.keys(mapMilieux)
 | 
				
			||||||
 | 
					      .filter(it => !milieuxExistants.includes(it))
 | 
				
			||||||
 | 
					      .map(it => mapMilieux[it]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static $itemToMilieux(item) {
 | 
				
			||||||
 | 
					    return item.system.environnement.map(env => env.milieu);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getMilieuxSettings() {
 | 
				
			||||||
 | 
					    return game.settings.get(SYSTEM_RDD, SETTINGS_LISTE_MILIEUX).split(',').map(it => it.trim()).filter(it => it != '');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async findEnvironnementsLike(search) {
 | 
				
			||||||
 | 
					    const milieux = await this.mapMilieux();
 | 
				
			||||||
 | 
					    const searchLower = Grammar.toLowerCaseNoAccent(search);
 | 
				
			||||||
 | 
					    const keys = Object.keys(milieux).filter(it => it.includes(searchLower));
 | 
				
			||||||
 | 
					    if (keys.length > 1) {
 | 
				
			||||||
 | 
					      const milieuExact = milieux[searchLower];
 | 
				
			||||||
 | 
					      if (milieuExact) {
 | 
				
			||||||
 | 
					        return [milieuExact];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return keys.map(k => milieux[k]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async searchToChatMessage(milieux, typeName) {
 | 
				
			||||||
 | 
					    const table = await this.buildEnvironnementTable(milieux);
 | 
				
			||||||
 | 
					    await CompendiumTableHelpers.tableToChatMessage(table, 'Item', ITEM_ENVIRONNEMENT_TYPES, typeName);
 | 
				
			||||||
 | 
					    return true
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getRandom(milieux, typeName) {
 | 
				
			||||||
 | 
					    const table = await this.buildEnvironnementTable(milieux);
 | 
				
			||||||
 | 
					    return await CompendiumTableHelpers.getRandom(table, 'Item', ITEM_ENVIRONNEMENT_TYPES, undefined, typeName);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async buildEnvironnementTable(milieux) {
 | 
				
			||||||
 | 
					    const filterMilieux = item => item.system?.environnement.filter(env => milieux.includes(env.milieu));
 | 
				
			||||||
 | 
					    const itemRareteEnMilieu = item => {
 | 
				
			||||||
 | 
					      const raretes = filterMilieux(item);
 | 
				
			||||||
 | 
					      const frequenceMax = Math.max(raretes.map(env => env.frequence));
 | 
				
			||||||
 | 
					      return raretes.find(env => env.frequence == frequenceMax);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const itemFrequenceEnMilieu = item => itemRareteEnMilieu(item)?.frequence ?? 0;
 | 
				
			||||||
 | 
					    const isPresentEnMilieu = item => itemFrequenceEnMilieu(item) > 0;
 | 
				
			||||||
 | 
					    return await this.table.buildTable(itemFrequenceEnMilieu, isPresentEnMilieu);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getElements(itemFrequence, filter) {
 | 
				
			||||||
 | 
					    return await this.table.getContent(itemFrequence, filter);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class EnvironmentSheetHelper {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static defaultOptions(defaultOptions) {
 | 
				
			||||||
 | 
					    return mergeObject(defaultOptions, {
 | 
				
			||||||
 | 
					      tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "informations" }]
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static setPosition(sheet, superPosition) {
 | 
				
			||||||
 | 
					    const position = superPosition;
 | 
				
			||||||
 | 
					    const sheetHeader = sheet.element.find(".sheet-header");
 | 
				
			||||||
 | 
					    const sheetBody = sheet.element.find(".sheet-body");
 | 
				
			||||||
 | 
					    sheetBody.css("height", position.height - sheetHeader[0].clientHeight)
 | 
				
			||||||
 | 
					    return position;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async getData(sheet, formData) {
 | 
				
			||||||
 | 
					    return mergeObject(formData, {
 | 
				
			||||||
 | 
					      milieux: await game.system.rdd.environnement.autresMilieux(sheet.item)
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static activateListeners(sheet) {
 | 
				
			||||||
 | 
					    if (!sheet.options.editable) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sheet.html.find("input.input-selection-milieu").keypress(event => {
 | 
				
			||||||
 | 
					      if (event.keyCode == '13') {
 | 
				
			||||||
 | 
					        EnvironmentSheetHelper.onAddMilieu(sheet, event);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      event.stopPropagation();
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    sheet.html.find("a.milieu-add").click(event => EnvironmentSheetHelper.onAddMilieu(sheet, event));
 | 
				
			||||||
 | 
					    sheet.html.find("div.environnement-milieu a.milieu-delete").click(event => EnvironmentSheetHelper.onDeleteMilieu(sheet, event));
 | 
				
			||||||
 | 
					    sheet.html.find("div.environnement-milieu select.environnement-rarete").change(event => EnvironmentSheetHelper.onChange(sheet, event,
 | 
				
			||||||
 | 
					      updated => EnvironmentSheetHelper.$changeRarete(sheet, event, updated)));
 | 
				
			||||||
 | 
					    sheet.html.find("div.environnement-milieu input[name='environnement-frequence']").change(event => EnvironmentSheetHelper.onChange(sheet, event,
 | 
				
			||||||
 | 
					      updated => EnvironmentSheetHelper.$changeFrequence(sheet, event, updated)));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static $changeFrequence(sheet, event, updated) {
 | 
				
			||||||
 | 
					    updated.frequence = Number(sheet.html.find(event.currentTarget).val());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static $changeRarete(sheet, event, updated) {
 | 
				
			||||||
 | 
					    const name = sheet.html.find(event.currentTarget).val();
 | 
				
			||||||
 | 
					    const rarete = Environnement.getRarete(name);
 | 
				
			||||||
 | 
					    updated.rarete = rarete.name;
 | 
				
			||||||
 | 
					    updated.frequence = rarete.frequence;
 | 
				
			||||||
 | 
					    // updated.frequence = Math.min(
 | 
				
			||||||
 | 
					    //   Math.max(rarete.min, updated.frequence ?? rarete.frequence),
 | 
				
			||||||
 | 
					    //   rarete.max);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async onAddMilieu(sheet, event) {
 | 
				
			||||||
 | 
					    const milieu = sheet.html.find('input.input-selection-milieu').val();
 | 
				
			||||||
 | 
					    if (!milieu) {
 | 
				
			||||||
 | 
					      ui.notifications.warn(`Choisissez le milieu dans lequel se trouve le/la ${sheet.item.name}`);
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const list = sheet.item.system.environnement;
 | 
				
			||||||
 | 
					    const exists = list.find(it => it.milieu == milieu);
 | 
				
			||||||
 | 
					    if (exists) {
 | 
				
			||||||
 | 
					      ui.notifications.warn(`${sheet.item.name} a déjà une rareté ${exists.rarete} en ${milieu} (fréquence: ${exists.frequence})`);
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const rarete = Environnement.getRarete();
 | 
				
			||||||
 | 
					    const newList = [...list, { milieu, rarete: rarete.name, frequence: rarete.frequence }].sort(Misc.ascending(it => it.milieu))
 | 
				
			||||||
 | 
					    await sheet.item.update({ 'system.environnement': newList })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async onDeleteMilieu(sheet, event) {
 | 
				
			||||||
 | 
					    const milieu = EnvironmentSheetHelper.$getEventMilieu(sheet, event);
 | 
				
			||||||
 | 
					    if (milieu != undefined) {
 | 
				
			||||||
 | 
					      const newList = sheet.item.system.environnement.filter(it => it.milieu != milieu)
 | 
				
			||||||
 | 
					        .sort(Misc.ascending(it => it.milieu));
 | 
				
			||||||
 | 
					      await sheet.item.update({ 'system.environnement': newList });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async onChange(sheet, event, doMutation) {
 | 
				
			||||||
 | 
					    const list = sheet.item.system.environnement;
 | 
				
			||||||
 | 
					    const milieu = EnvironmentSheetHelper.$getEventMilieu(sheet, event);
 | 
				
			||||||
 | 
					    const updated = list.find(it => it.milieu == milieu);
 | 
				
			||||||
 | 
					    if (updated) {
 | 
				
			||||||
 | 
					      doMutation(updated);
 | 
				
			||||||
 | 
					      const newList = [...list.filter(it => it.milieu != milieu), updated]
 | 
				
			||||||
 | 
					        .sort(Misc.ascending(it => it.milieu));
 | 
				
			||||||
 | 
					      await sheet.item.update({ 'system.environnement': newList });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static $getEventMilieu(sheet, event) {
 | 
				
			||||||
 | 
					    return sheet.html.find(event.currentTarget)?.parents("div.environnement-milieu").data("milieu");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -19,10 +19,14 @@ export class Grammar {
 | 
				
			|||||||
    return word.match(/^[aeiouy]/i)
 | 
					    return word.match(/^[aeiouy]/i)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static equalsInsensitive(a, b) {
 | 
				
			||||||
 | 
					    return Grammar.toLowerCaseNoAccent(a) == Grammar.toLowerCaseNoAccent(b)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  static includesLowerCaseNoAccent(value, content) {
 | 
					  static includesLowerCaseNoAccent(value, content) {
 | 
				
			||||||
    return Grammar.toLowerCaseNoAccent(value).includes(Grammar.toLowerCaseNoAccent(content));
 | 
					    return Grammar.toLowerCaseNoAccent(value).includes(Grammar.toLowerCaseNoAccent(content));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static toLowerCaseNoAccent(words) {
 | 
					  static toLowerCaseNoAccent(words) {
 | 
				
			||||||
    return words?.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "") ?? words;
 | 
					    return words?.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "") ?? words;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
export class HtmlUtility{
 | 
					export class HtmlUtility{
 | 
				
			||||||
  static _showControlWhen(control, condition) {
 | 
					  static _showControlWhen(jQuerySelector, condition) {
 | 
				
			||||||
    if (condition) {
 | 
					    if (condition) {
 | 
				
			||||||
      control.show();
 | 
					      jQuerySelector.show();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      control.hide();
 | 
					      jQuerySelector.hide();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -28,7 +28,7 @@ export class RdDItemArme extends Item {
 | 
				
			|||||||
    switch (arme ? arme.type : '') {
 | 
					    switch (arme ? arme.type : '') {
 | 
				
			||||||
      case 'arme': return arme;
 | 
					      case 'arme': return arme;
 | 
				
			||||||
      case 'competencecreature':
 | 
					      case 'competencecreature':
 | 
				
			||||||
        return RdDItemCompetenceCreature.toActionArme(arme);
 | 
					        return RdDItemCompetenceCreature.armeNaturelle(arme);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return RdDItemArme.mainsNues();
 | 
					    return RdDItemArme.mainsNues();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -177,7 +177,7 @@ export class RdDItemArme extends Item {
 | 
				
			|||||||
        equipe: true,
 | 
					        equipe: true,
 | 
				
			||||||
        rapide: true,
 | 
					        rapide: true,
 | 
				
			||||||
        force: 0,
 | 
					        force: 0,
 | 
				
			||||||
        dommages: 0,
 | 
					        dommages: "0",
 | 
				
			||||||
        dommagesReels: 0,
 | 
					        dommagesReels: 0,
 | 
				
			||||||
        mortalite: 'non-mortel',
 | 
					        mortalite: 'non-mortel',
 | 
				
			||||||
        competence: 'Corps à corps',
 | 
					        competence: 'Corps à corps',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,18 +8,18 @@ const xp_par_niveau = [5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, 20, 20, 20,
 | 
				
			|||||||
const niveau_max = xp_par_niveau.length - 10;
 | 
					const niveau_max = xp_par_niveau.length - 10;
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
const limitesArchetypes = [
 | 
					const limitesArchetypes = [
 | 
				
			||||||
  { "niveau": 0, "nombreMax": 100, "nombre": 0 },
 | 
					  { "niveau": 0, "nombreMax": 100, "reste": 100 },
 | 
				
			||||||
  { "niveau": 1, "nombreMax": 10, "nombre": 0 },
 | 
					  { "niveau": 1, "nombreMax": 10, "reste": 10 },
 | 
				
			||||||
  { "niveau": 2, "nombreMax": 9, "nombre": 0 },
 | 
					  { "niveau": 2, "nombreMax": 9, "reste": 9 },
 | 
				
			||||||
  { "niveau": 3, "nombreMax": 8, "nombre": 0 },
 | 
					  { "niveau": 3, "nombreMax": 8, "reste": 8 },
 | 
				
			||||||
  { "niveau": 4, "nombreMax": 7, "nombre": 0 },
 | 
					  { "niveau": 4, "nombreMax": 7, "reste": 7 },
 | 
				
			||||||
  { "niveau": 5, "nombreMax": 6, "nombre": 0 },
 | 
					  { "niveau": 5, "nombreMax": 6, "reste": 6 },
 | 
				
			||||||
  { "niveau": 6, "nombreMax": 5, "nombre": 0 },
 | 
					  { "niveau": 6, "nombreMax": 5, "reste": 5 },
 | 
				
			||||||
  { "niveau": 7, "nombreMax": 4, "nombre": 0 },
 | 
					  { "niveau": 7, "nombreMax": 4, "reste": 4 },
 | 
				
			||||||
  { "niveau": 8, "nombreMax": 3, "nombre": 0 },
 | 
					  { "niveau": 8, "nombreMax": 3, "reste": 3 },
 | 
				
			||||||
  { "niveau": 9, "nombreMax": 2, "nombre": 0 },
 | 
					  { "niveau": 9, "nombreMax": 2, "reste": 2 },
 | 
				
			||||||
  { "niveau": 10, "nombreMax": 1, "nombre": 0 },
 | 
					  { "niveau": 10, "nombreMax": 1, "reste": 1 },
 | 
				
			||||||
  { "niveau": 11, "nombreMax": 1, "nombre": 0 }
 | 
					  { "niveau": 11, "nombreMax": 1, "reste": 1 }
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
@@ -34,13 +34,6 @@ const categorieCompetences = {
 | 
				
			|||||||
  "lancer": { base: -8, label: "Lancer" }
 | 
					  "lancer": { base: -8, label: "Lancer" }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const compendiumCompetences = {
 | 
					 | 
				
			||||||
  "personnage": "foundryvtt-reve-de-dragon.competences",
 | 
					 | 
				
			||||||
  "creature": "foundryvtt-reve-de-dragon.competences-creatures",
 | 
					 | 
				
			||||||
  "entite": "foundryvtt-reve-de-dragon.competences-entites"
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function _buildCumulXP() {
 | 
					function _buildCumulXP() {
 | 
				
			||||||
  let cumulXP = { "-11": 0 };
 | 
					  let cumulXP = { "-11": 0 };
 | 
				
			||||||
  let cumul = 0;
 | 
					  let cumul = 0;
 | 
				
			||||||
@@ -55,12 +48,6 @@ function _buildCumulXP() {
 | 
				
			|||||||
const competence_xp_cumul = _buildCumulXP();
 | 
					const competence_xp_cumul = _buildCumulXP();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class RdDItemCompetence extends Item {
 | 
					export class RdDItemCompetence extends Item {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static actorCompendium(actorType = undefined) {
 | 
					 | 
				
			||||||
    return compendiumCompetences[actorType ?? 'personnage'];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static getCategorieCompetences() {
 | 
					  static getCategorieCompetences() {
 | 
				
			||||||
    return categorieCompetences;
 | 
					    return categorieCompetences;
 | 
				
			||||||
@@ -280,18 +267,47 @@ export class RdDItemCompetence extends Item {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static computeResumeArchetype(competences) {
 | 
					  static computeResumeArchetype(competences) {
 | 
				
			||||||
    const archetype = RdDItemCompetence.getLimitesArchetypes();
 | 
					    const computed = duplicate(limitesArchetypes);
 | 
				
			||||||
    competences.map(it => Math.max(0, it.system.niveau_archetype))
 | 
					    competences.map(it => Math.max(0, it.system.niveau_archetype))
 | 
				
			||||||
      .forEach(niveau => {
 | 
					      .filter(n => n > 0)
 | 
				
			||||||
        archetype[niveau] = archetype[niveau] ?? { "niveau": niveau, "nombreMax": 0, "nombre": 0 };
 | 
					      .forEach(n => {
 | 
				
			||||||
        archetype[niveau].nombre = (archetype[niveau]?.nombre ?? 0) + 1;
 | 
					        computed[n] = computed[n] ?? { niveau: n, nombreMax: 0, reste: 0 };
 | 
				
			||||||
 | 
					        computed[n].reste = computed[n].reste - 1;
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    return archetype;
 | 
					      return computed.filter(it => it.reste > 0 && it.niveau > 0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static getLimitesArchetypes() {
 | 
					  static triVisible(competences) {
 | 
				
			||||||
    return duplicate(limitesArchetypes);
 | 
					    return competences.filter(it => it.system.isVisible)
 | 
				
			||||||
 | 
					      .sort((a, b) => RdDItemCompetence.compare(a, b))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static $positionTri(comp) {
 | 
				
			||||||
 | 
					    if (comp.name.startsWith("Survie")) {
 | 
				
			||||||
 | 
					      if (comp.name.includes("Cité")) return 0;
 | 
				
			||||||
 | 
					      if (comp.name.includes("Extérieur")) return 1;
 | 
				
			||||||
 | 
					      return 2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (comp.system.categorie.startsWith("melee")) {
 | 
				
			||||||
 | 
					      if (comp.name.includes("Corps")) return 0;
 | 
				
			||||||
 | 
					      if (comp.name.includes("Dague")) return 1;
 | 
				
			||||||
 | 
					      if (comp.name.includes("Esquive")) return 2;
 | 
				
			||||||
 | 
					      return 3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (comp.system.categorie.startsWith("draconic")) {
 | 
				
			||||||
 | 
					      if (comp.name.includes("Oniros")) return 0;
 | 
				
			||||||
 | 
					      if (comp.name.includes("Hypnos")) return 1;
 | 
				
			||||||
 | 
					      if (comp.name.includes("Narcos")) return 2;
 | 
				
			||||||
 | 
					      if (comp.name.includes("Thanatos")) return 3;
 | 
				
			||||||
 | 
					      return 4;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static compare(a, b) {
 | 
				
			||||||
 | 
					    const diff = RdDItemCompetence.$positionTri(a) - RdDItemCompetence.$positionTri(b);
 | 
				
			||||||
 | 
					    return diff ? diff : a.name.localeCompare(b.name);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { Misc } from "./misc.js";
 | 
					
 | 
				
			||||||
import { RdDCombatManager } from "./rdd-combat.js";
 | 
					import { RdDCombatManager } from "./rdd-combat.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
@@ -12,12 +12,12 @@ export class RdDItemCompetenceCreature extends Item {
 | 
				
			|||||||
    rollData.competence.system.categorie = "creature"
 | 
					    rollData.competence.system.categorie = "creature"
 | 
				
			||||||
    rollData.selectedCarac =  rollData.carac.carac_creature
 | 
					    rollData.selectedCarac =  rollData.carac.carac_creature
 | 
				
			||||||
    if (rollData.competence.system.iscombat) {
 | 
					    if (rollData.competence.system.iscombat) {
 | 
				
			||||||
      rollData.arme = RdDItemCompetenceCreature.toActionArme(rollData.competence);
 | 
					      rollData.arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static toActionArme(competencecreature) {
 | 
					  static armeNaturelle(competencecreature) {
 | 
				
			||||||
    if (RdDItemCompetenceCreature.isCompetenceAttaque(competencecreature)) {
 | 
					    if (RdDItemCompetenceCreature.isCompetenceAttaque(competencecreature)) {
 | 
				
			||||||
      // 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 lma compétence
 | 
				
			||||||
      let arme = (competencecreature instanceof Item) ? competencecreature.clone():  competencecreature;
 | 
					      let arme = (competencecreature instanceof Item) ? competencecreature.clone():  competencecreature;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										60
									
								
								module/item-conteneur-sheet.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					import { RdDItemSheet } from "./item-sheet.js";
 | 
				
			||||||
 | 
					import { RdDSheetUtility } from "./rdd-sheet-utility.js";
 | 
				
			||||||
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class RdDConteneurItemSheet extends RdDItemSheet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get ITEM_TYPE() { return "conteneur" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getData() {
 | 
				
			||||||
 | 
					    const formData = await super.getData();
 | 
				
			||||||
 | 
					    if (this.actor) {
 | 
				
			||||||
 | 
					      this.prepareConteneurData(formData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return formData;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!this.options.editable) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('.conteneur-name a').click(async event => {
 | 
				
			||||||
 | 
					      RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
 | 
				
			||||||
 | 
					      this.render(true);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  prepareConteneurData(formData) {
 | 
				
			||||||
 | 
					    RdDUtility.filterEquipementParType(formData, this.actor.itemTypes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
 | 
				
			||||||
 | 
					    formData.subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async _onDragStart(event) {
 | 
				
			||||||
 | 
					    console.log("_onDragStart", event);
 | 
				
			||||||
 | 
					    if (event.target.classList.contains("entity-link")) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const itemId = event.srcElement?.attributes["data-item-id"].value;
 | 
				
			||||||
 | 
					    const item = this.actor.items.get(itemId);
 | 
				
			||||||
 | 
					    // Create drag data
 | 
				
			||||||
 | 
					    const dragData = {
 | 
				
			||||||
 | 
					      actorId: this.actor.id,
 | 
				
			||||||
 | 
					      type: "Item",
 | 
				
			||||||
 | 
					      data: item.system
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    event.dataTransfer.setData("text/plain", JSON.stringify(dragData));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async _onDropItem(event, dragData) {
 | 
				
			||||||
 | 
					    if (this.actor) {
 | 
				
			||||||
 | 
					      const dropParams = RdDSheetUtility.prepareItemDropParameters(this.item.id, this.actor, dragData, this.objetVersConteneur);
 | 
				
			||||||
 | 
					      await this.actor.processDropItem(dropParams);
 | 
				
			||||||
 | 
					      await this.render(true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										67
									
								
								module/item-faune-sheet.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					import { EnvironmentSheetHelper } from "./environnement.js";
 | 
				
			||||||
 | 
					import { RdDItemSheet } from "./item-sheet.js";
 | 
				
			||||||
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class RdDFauneItemSheet extends RdDItemSheet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get ITEM_TYPE() { return "faune" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get defaultOptions() {
 | 
				
			||||||
 | 
					    return EnvironmentSheetHelper.defaultOptions(super.defaultOptions);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setPosition(options = {}) {
 | 
				
			||||||
 | 
					    return EnvironmentSheetHelper.setPosition(this, super.setPosition(options));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getData() {
 | 
				
			||||||
 | 
					    const formData = await super.getData();
 | 
				
			||||||
 | 
					    return await EnvironmentSheetHelper.getData(this, formData);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    if (!this.options.editable) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EnvironmentSheetHelper.activateListeners(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    html.find("a.linked-actor-delete").click(event => this.onDeleteLinkedActor());
 | 
				
			||||||
 | 
					    html.find("a.preparer-nourriture").click(event => this.preparerNourriture(event));
 | 
				
			||||||
 | 
					    html.find("a.manger-nourriture").click(event => this.mangerNourriture(event));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async _onDropActor(event, dragData) {
 | 
				
			||||||
 | 
					    console.log('faune:dropActor', event, dragData)
 | 
				
			||||||
 | 
					    const linkedActor = fromUuidSync(dragData.uuid);
 | 
				
			||||||
 | 
					    if (linkedActor?.pack) {
 | 
				
			||||||
 | 
					      this.item.update({
 | 
				
			||||||
 | 
					        'system.actor.pack': linkedActor.pack,
 | 
				
			||||||
 | 
					        'system.actor.id': linkedActor._id,
 | 
				
			||||||
 | 
					        'system.actor.name': linkedActor.name
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      ui.notifications.warn(`${linkedActor.name} ne provient pas d'un compendium.
 | 
				
			||||||
 | 
					        <br>Choisissez une créature du compendium pour représenter un élément de faune générique`)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  async onDeleteLinkedActor() {
 | 
				
			||||||
 | 
					    this.item.update({
 | 
				
			||||||
 | 
					      'system.actor.pack': '',
 | 
				
			||||||
 | 
					      'system.actor.id': '',
 | 
				
			||||||
 | 
					      'system.actor.name': ''
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async preparerNourriture(event) {
 | 
				
			||||||
 | 
					    if (this.actor) {
 | 
				
			||||||
 | 
					      await this.actor.preparerNourriture(this.item);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  async mangerNourriture(event) {
 | 
				
			||||||
 | 
					    if (this.actor) {
 | 
				
			||||||
 | 
					      await this.actor.mangerNourriture(this.item);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								module/item-herbe-sheet.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					import { EnvironmentSheetHelper } from "./environnement.js";
 | 
				
			||||||
 | 
					import { RdDItemSheet } from "./item-sheet.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class RdDHerbeItemSheet extends RdDItemSheet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get ITEM_TYPE() { return "herbe" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get defaultOptions() {
 | 
				
			||||||
 | 
					    return EnvironmentSheetHelper.defaultOptions(super.defaultOptions);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setPosition(options = {}) {
 | 
				
			||||||
 | 
					    return EnvironmentSheetHelper.setPosition(this, super.setPosition(options));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getData() {
 | 
				
			||||||
 | 
					    const formData = await super.getData();
 | 
				
			||||||
 | 
					    return await EnvironmentSheetHelper.getData(this, formData);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    EnvironmentSheetHelper.activateListeners(this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								module/item-ingredient-sheet.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					import { EnvironmentSheetHelper } from "./environnement.js";
 | 
				
			||||||
 | 
					import { RdDItemSheet } from "./item-sheet.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class RdDIngredientItemSheet extends RdDItemSheet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get ITEM_TYPE() { return "ingredient" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get defaultOptions() {
 | 
				
			||||||
 | 
					    return EnvironmentSheetHelper.defaultOptions(super.defaultOptions);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setPosition(options = {}) {
 | 
				
			||||||
 | 
					    return EnvironmentSheetHelper.setPosition(this, super.setPosition(options));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getData() {
 | 
				
			||||||
 | 
					    const formData = await super.getData();
 | 
				
			||||||
 | 
					    return await EnvironmentSheetHelper.getData(this, formData);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    EnvironmentSheetHelper.activateListeners(this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -4,22 +4,22 @@ import { LOG_HEAD } from "./constants.js";
 | 
				
			|||||||
const MONNAIE_ETAIN = {
 | 
					const MONNAIE_ETAIN = {
 | 
				
			||||||
  name: "Etain (1 denier)", type: 'monnaie',
 | 
					  name: "Etain (1 denier)", type: 'monnaie',
 | 
				
			||||||
  img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
 | 
					  img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
 | 
				
			||||||
  system: { quantite: 0, valeur_deniers: 1, encombrement: 0.001, description: "" }
 | 
					  system: { quantite: 0, cout: 0.01, encombrement: 0.001, description: "" }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const MONNAIE_BRONZE = {
 | 
					const MONNAIE_BRONZE = {
 | 
				
			||||||
  name: "Bronze (10 deniers)", type: 'monnaie',
 | 
					  name: "Bronze (10 deniers)", type: 'monnaie',
 | 
				
			||||||
  img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
 | 
					  img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
 | 
				
			||||||
  system: { quantite: 0, valeur_deniers: 10, encombrement: 0.002, description: "" }
 | 
					  system: { quantite: 0, cout: 0.10, encombrement: 0.002, description: "" }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const MONNAIE_ARGENT = {
 | 
					const MONNAIE_ARGENT = {
 | 
				
			||||||
  name: "Argent (1 sol)", type: 'monnaie',
 | 
					  name: "Argent (1 sol)", type: 'monnaie',
 | 
				
			||||||
  img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
 | 
					  img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
 | 
				
			||||||
  system: { quantite: 0, valeur_deniers: 100, encombrement: 0.003, description: "" }
 | 
					  system: { quantite: 0, cout: 1, encombrement: 0.003, description: "" }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const MONNAIE_OR = {
 | 
					const MONNAIE_OR = {
 | 
				
			||||||
  name: "Or (10 sols)", type: 'monnaie',
 | 
					  name: "Or (10 sols)", type: 'monnaie',
 | 
				
			||||||
  img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
 | 
					  img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
 | 
				
			||||||
  system: { quantite: 0, valeur_deniers: 1000, encombrement: 0.004, description: "" }
 | 
					  system: { quantite: 0, cout: 10, encombrement: 0.004, description: "" }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MONNAIES_STANDARD = [MONNAIE_ETAIN, MONNAIE_BRONZE, MONNAIE_ARGENT, MONNAIE_OR];
 | 
					const MONNAIES_STANDARD = [MONNAIE_ETAIN, MONNAIE_BRONZE, MONNAIE_ARGENT, MONNAIE_OR];
 | 
				
			||||||
@@ -32,7 +32,7 @@ export class Monnaie {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  static monnaiesManquantes(actor) {
 | 
					  static monnaiesManquantes(actor) {
 | 
				
			||||||
    const disponibles = actor.itemTypes['monnaie'];
 | 
					    const disponibles = actor.itemTypes['monnaie'];
 | 
				
			||||||
    const manquantes = MONNAIES_STANDARD.filter(standard => !disponibles.find(disponible => Monnaie.deValeur(disponible, standard.system?.valeur_deniers)));
 | 
					    const manquantes = MONNAIES_STANDARD.filter(standard => !disponibles.find(disponible => Monnaie.deValeur(disponible, standard.system?.cout)));
 | 
				
			||||||
    if (manquantes.length > 0) {
 | 
					    if (manquantes.length > 0) {
 | 
				
			||||||
      console.error(`${LOG_HEAD} monnaiesManquantes pour ${actor.name}`, manquantes, ' avec monnaies', disponibles, MONNAIES_STANDARD);
 | 
					      console.error(`${LOG_HEAD} monnaiesManquantes pour ${actor.name}`, manquantes, ' avec monnaies', disponibles, MONNAIES_STANDARD);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -40,15 +40,15 @@ export class Monnaie {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static deValeur(monnaie, valeur) {
 | 
					  static deValeur(monnaie, valeur) {
 | 
				
			||||||
    return valeur == monnaie.system.valeur_deniers
 | 
					    return Monnaie.valEntiere(valeur) == Monnaie.valEntiere(monnaie.system.cout)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static arrondiDeniers(sols) {
 | 
					  static valEntiere(sols) {
 | 
				
			||||||
    return Number(sols).toFixed(2);
 | 
					    return Math.max(Math.floor((sols??0)*100), 0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static triValeurDenier() {
 | 
					  static triValeurEntiere() {
 | 
				
			||||||
    return Misc.ascending(item => item.system.valeur_deniers)
 | 
					    return Misc.ascending(item => Monnaie.valEntiere(item.system.cout))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async creerMonnaiesStandard(actor) {
 | 
					  static async creerMonnaiesStandard(actor) {
 | 
				
			||||||
@@ -65,28 +65,28 @@ export class Monnaie {
 | 
				
			|||||||
    return deniers;
 | 
					    return deniers;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async optimiser(actor, fortune) {
 | 
					  static async optimiserFortune(actor, fortune) {
 | 
				
			||||||
    let reste = fortune;
 | 
					    let resteEnDeniers = Math.round(fortune*100);
 | 
				
			||||||
    let monnaies = actor.itemTypes['monnaie'];
 | 
					    let monnaies = actor.itemTypes['monnaie'];
 | 
				
			||||||
    let updates = [];
 | 
					    let updates = [];
 | 
				
			||||||
    let parValeur = Misc.classifyFirst(monnaies, it => it.system.valeur_deniers);
 | 
					    let parValeur = Misc.classifyFirst(monnaies, it => Monnaie.valEntiere(it.system.cout));
 | 
				
			||||||
    for (let valeur of  [1000, 100, 10, 1]) {
 | 
					    for (let valeurDeniers of  [1000, 100, 10, 1]) {
 | 
				
			||||||
      const itemPiece = parValeur[valeur];
 | 
					      const itemPiece = parValeur[valeurDeniers];
 | 
				
			||||||
      const piecesDeCetteValeur = Math.floor(reste / valeur);
 | 
					 | 
				
			||||||
      if (itemPiece) {
 | 
					      if (itemPiece) {
 | 
				
			||||||
        if (piecesDeCetteValeur != itemPiece.system.quantite) {
 | 
					        const quantite = Math.floor(resteEnDeniers / valeurDeniers);
 | 
				
			||||||
          updates.push({ _id: parValeur[valeur].id, 'system.quantite': piecesDeCetteValeur });
 | 
					        if (quantite != itemPiece.system.quantite) {
 | 
				
			||||||
 | 
					          updates.push({ _id: parValeur[valeurDeniers].id, 'system.quantite': quantite });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        reste -= piecesDeCetteValeur*valeur;
 | 
					        resteEnDeniers -= quantite*valeurDeniers;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    console.log('Monnaie.optimiser', actor.name, 'total', fortune, 'parValeur', parValeur, 'updates', updates, 'reste', reste);
 | 
					    console.log('Monnaie.optimiserFortune', actor.name, 'total', fortune, 'parValeur', parValeur, 'updates', updates, 'reste', resteEnDeniers);
 | 
				
			||||||
    if (updates.length > 0) {
 | 
					    if (updates.length > 0) {
 | 
				
			||||||
      await actor.updateEmbeddedDocuments('Item', updates);
 | 
					      await actor.updateEmbeddedDocuments('Item', updates);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (reste>0){
 | 
					    if (resteEnDeniers > 0){
 | 
				
			||||||
      // créer le reste en deniers fortune en deniers
 | 
					      // créer le reste en deniers fortune en deniers
 | 
				
			||||||
      await Monnaie.creerMonnaiesDeniers(actor, reste);
 | 
					      await Monnaie.creerMonnaiesDeniers(actor, resteEnDeniers);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										85
									
								
								module/item-rencontre-sheet.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					import { RdDRencontre } from "./item-rencontre.js";
 | 
				
			||||||
 | 
					import { RdDItemSheet } from "./item-sheet.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class RdDRencontreItemSheet extends RdDItemSheet {
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static get ITEM_TYPE() { return "rencontre" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get defaultOptions() {
 | 
				
			||||||
 | 
					    return mergeObject(super.defaultOptions, {
 | 
				
			||||||
 | 
					      tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }]
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  /** @override */
 | 
				
			||||||
 | 
					  setPosition(options = {}) {
 | 
				
			||||||
 | 
					    const position = super.setPosition(options);
 | 
				
			||||||
 | 
					    const sheetHeader = this.element.find(".sheet-header");
 | 
				
			||||||
 | 
					    const sheetBody = this.element.find(".sheet-body");
 | 
				
			||||||
 | 
					    sheetBody.css("height", position.height - sheetHeader[0].clientHeight)
 | 
				
			||||||
 | 
					    return position;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async getData() {
 | 
				
			||||||
 | 
					    const formData = duplicate(this.item);
 | 
				
			||||||
 | 
					    mergeObject(formData, {
 | 
				
			||||||
 | 
					      title: formData.name,
 | 
				
			||||||
 | 
					      isGM: game.user.isGM,
 | 
				
			||||||
 | 
					      owner: this.actor?.isOwner,
 | 
				
			||||||
 | 
					      isOwned: this.actor ? true : false,
 | 
				
			||||||
 | 
					      actorId: this.actor?.id,
 | 
				
			||||||
 | 
					      editable: this.isEditable,
 | 
				
			||||||
 | 
					      cssClass: this.isEditable ? "editable" : "locked",
 | 
				
			||||||
 | 
					      effets: {
 | 
				
			||||||
 | 
					        succes: {
 | 
				
			||||||
 | 
					          liste: RdDRencontre.getEffetsSucces(),
 | 
				
			||||||
 | 
					          select: RdDRencontre.mapEffets(this.item.system.succes.effets)
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        echec: {
 | 
				
			||||||
 | 
					          liste: RdDRencontre.getEffetsEchec(),
 | 
				
			||||||
 | 
					          select: RdDRencontre.mapEffets(this.item.system.echec.effets)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return formData;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  /** @override */
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    if (!this.options.editable) return;
 | 
				
			||||||
 | 
					    this.html.find("a.effet-add").click(event => this.onAddEffet(event));
 | 
				
			||||||
 | 
					    this.html.find("a.effet-delete").click(event => this.onDeleteEffet(event));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async onAddEffet(event) {
 | 
				
			||||||
 | 
					    const resultat = this.html.find(event.currentTarget)?.data("effet-resultat");
 | 
				
			||||||
 | 
					    const keyEffets = `system.${resultat}.effets`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const code = this.html.find(event.currentTarget)?.data("effet-code");
 | 
				
			||||||
 | 
					    const liste = RdDRencontre.getListeEffets(this.item, resultat);
 | 
				
			||||||
 | 
					    liste.push(code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await this._updateEffetsRencontre(keyEffets, liste);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async onDeleteEffet(event) {
 | 
				
			||||||
 | 
					    const resultat = this.html.find(event.currentTarget)?.data("effet-resultat");
 | 
				
			||||||
 | 
					    const keyEffets = `system.${resultat}.effets`;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    const pos = this.html.find(event.currentTarget)?.data("effet-pos");
 | 
				
			||||||
 | 
					    const liste = RdDRencontre.getListeEffets(this.item, resultat);
 | 
				
			||||||
 | 
					    liste.splice(pos, 1);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    await this._updateEffetsRencontre(keyEffets, liste);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  async _updateEffetsRencontre(key, liste) {
 | 
				
			||||||
 | 
					    const updates = {};
 | 
				
			||||||
 | 
					    updates[key] = liste;
 | 
				
			||||||
 | 
					    this.item.update(updates);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										71
									
								
								module/item-rencontre.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					import { EffetsRencontre } from "./effets-rencontres.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const tableEffets = [
 | 
				
			||||||
 | 
					  { code: "messager", resultat: "succes", description: "Envoie un message à (force) cases", method: EffetsRencontre.messager },
 | 
				
			||||||
 | 
					  { code: "passeur", resultat: "succes", description: "Déplacer le demi-rêve à (force) cases", method: EffetsRencontre.passeur},
 | 
				
			||||||
 | 
					  { code: "reve+f", resultat: "succes", description: "Gain de (force) points de rêve" , method: EffetsRencontre.reve_plus_force},
 | 
				
			||||||
 | 
					  { code: "teleport", resultat: "succes", description: "Déplacer le demi-rêve (même type)", method: EffetsRencontre.teleportation_typecase },
 | 
				
			||||||
 | 
					  { code: "part+tete", resultat: "succes", description: "Tête de dragon sur réussite particulière", method: EffetsRencontre.rdd_part_tete },
 | 
				
			||||||
 | 
					  { code: "part+xp", resultat: "succes", description: "Expérience sur réussite particulière", method: EffetsRencontre.experience_particuliere },
 | 
				
			||||||
 | 
					  { code: "seuil", resultat: "succes", description: "Récupération de seuil de rêve", method: EffetsRencontre.regain_seuil },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  { code: "reve-1", resultat: "echec", description: "Perte de 1 point de rêve", method: EffetsRencontre.reve_moins_1 },
 | 
				
			||||||
 | 
					  { code: "reve-f", resultat: "echec", description: "Perte de (force) points de rêve", method: EffetsRencontre.reve_moins_force },
 | 
				
			||||||
 | 
					  { code: "vie-1", resultat: "echec", description: "Perte de 1 point de vie", method: EffetsRencontre.vie_moins_1 },
 | 
				
			||||||
 | 
					  { code: "reinsere", resultat: "echec", description: "Réinsertion aléatoire", method: EffetsRencontre.reinsertion },
 | 
				
			||||||
 | 
					  { code: "persistant", resultat: "echec", description: "Bloque le demi-rêve", method: EffetsRencontre.rencontre_persistante },
 | 
				
			||||||
 | 
					  { code: "teleport-aleatoire", resultat: "echec", description: "Déplacement aléatoire (même type)", method: EffetsRencontre.teleportation_aleatoire_typecase },
 | 
				
			||||||
 | 
					  { code: "aleatoire", resultat: "echec", description: "Déplacement aléatoire", method: EffetsRencontre.deplacement_aleatoire },
 | 
				
			||||||
 | 
					  { code: "sort-aleatoire", resultat: "echec", description: "Déclenche un sort en réserve aléatoire", method: EffetsRencontre.sort_aleatoire },
 | 
				
			||||||
 | 
					  { code: "rompu", resultat: "echec", description: "Demi-rêve interrompu", method: EffetsRencontre.demireve_rompu },
 | 
				
			||||||
 | 
					  { code: "echec-queue", resultat: "echec", description: "Queue(s) de dragon sur échec", method: EffetsRencontre.rdd_echec_queue },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  { code: "reve+1", resultat: "succes", description: "Gain de 1 point de rêve", method: EffetsRencontre.reve_plus_1 },
 | 
				
			||||||
 | 
					  { code: "vie-f", resultat: "echec", description: "Perte de (force) points de vie", method: EffetsRencontre.vie_moins_force },
 | 
				
			||||||
 | 
					  { code: "moral+1", resultat: "succes", description: "Gain de 1 point de moral", method: EffetsRencontre.moral_plus_1 },
 | 
				
			||||||
 | 
					  { code: "moral-1", resultat: "echec", description: "Perte de 1 point de moral", method: EffetsRencontre.moral_moins_1 },
 | 
				
			||||||
 | 
					  { code: "xpsort+f", resultat: "succes", description: "Gain de (force) xp sort", method: EffetsRencontre.xp_sort_force },
 | 
				
			||||||
 | 
					  { code: "endurance-1", resultat: "echec", description: "Perte de 1 point d'endurance", method: EffetsRencontre.end_moins_1 },
 | 
				
			||||||
 | 
					  { code: "endurance-f", resultat: "echec", description: "Perte de (force) points d'endurance", method: EffetsRencontre.end_moins_force },
 | 
				
			||||||
 | 
					  { code: "fatigue+1", resultat: "echec", description: "Coup de fatigue de 1 point", method: EffetsRencontre.fatigue_plus_1},
 | 
				
			||||||
 | 
					  { code: "fatigue+f", resultat: "echec", description: "Coup de fatigue de 1 (force) points", method: EffetsRencontre.fatigue_plus_force },
 | 
				
			||||||
 | 
					  { code: "fatigue-1", resultat: "succes", description: "Récupération de 1 point de fatigue", method: EffetsRencontre.fatigue_moins_1},
 | 
				
			||||||
 | 
					  { code: "fatigue-f", resultat: "succes", description: "Récupération de 1 (force) points de fatigue", method: EffetsRencontre.fatigue_moins_force },
 | 
				
			||||||
 | 
					  { code: "perte-chance", resultat: "echec", description: "Perte de chance actuelle", method: EffetsRencontre.perte_chance },
 | 
				
			||||||
 | 
					  { code: "stress+1", resultat: "succes", description: "Gain de 1 point de stress", method: EffetsRencontre.stress_plus_1 },
 | 
				
			||||||
 | 
					  // { code: "epart-souffle", resultat: "echec", description: "Souffle de dragon sur échec particulier" },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class RdDRencontre {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getEffetsSucces() { return RdDRencontre.getEffets("succes"); }
 | 
				
			||||||
 | 
					  static getEffetsEchec() { return RdDRencontre.getEffets("echec"); }
 | 
				
			||||||
 | 
					  static getEffets(resultat) {
 | 
				
			||||||
 | 
					    return tableEffets.filter(e => resultat == e.resultat);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static mapEffets(liste) {
 | 
				
			||||||
 | 
					    return liste.map(it => RdDRencontre.getEffet(it));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static getListeEffets(item, reussite) {
 | 
				
			||||||
 | 
					    if (reussite == 'echec') {
 | 
				
			||||||
 | 
					      return [...item.system.echec.effets];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (reussite == 'succes') {
 | 
				
			||||||
 | 
					      return [...item.system.succes.effets];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return [];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getEffet(code) {
 | 
				
			||||||
 | 
					    return tableEffets.find(it => code == it.code)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async appliquer(codes, tmrDialog, rencData) {
 | 
				
			||||||
 | 
					    for(const effet of RdDRencontre.mapEffets(codes)){
 | 
				
			||||||
 | 
					      await effet.method(tmrDialog, rencData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -4,35 +4,59 @@ import { RdDAlchimie } from "./rdd-alchimie.js";
 | 
				
			|||||||
import { RdDItemCompetence } from "./item-competence.js";
 | 
					import { RdDItemCompetence } from "./item-competence.js";
 | 
				
			||||||
import { RdDHerbes } from "./rdd-herbes.js";
 | 
					import { RdDHerbes } from "./rdd-herbes.js";
 | 
				
			||||||
import { RdDGemme } from "./rdd-gemme.js";
 | 
					import { RdDGemme } from "./rdd-gemme.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					 | 
				
			||||||
import { HtmlUtility } from "./html-utility.js";
 | 
					import { HtmlUtility } from "./html-utility.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
import { SYSTEM_RDD } from "./constants.js";
 | 
					import { SYSTEM_RDD } from "./constants.js";
 | 
				
			||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
 | 
					import { RdDSheetUtility } from "./rdd-sheet-utility.js";
 | 
				
			||||||
 | 
					import { SystemCompendiums } from "./settings/system-compendiums.js";
 | 
				
			||||||
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Extend the basic ItemSheet with some very simple modifications
 | 
					 * Extend the basic ItemSheet for RdD specific items
 | 
				
			||||||
 * @extends {ItemSheet}
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export class RdDItemSheet extends ItemSheet {
 | 
					export class RdDItemSheet extends ItemSheet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get ITEM_TYPE() {
 | 
				
			||||||
 | 
					    return undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static defaultTemplate(type) {
 | 
				
			||||||
 | 
					    return type ?
 | 
				
			||||||
 | 
					      `systems/foundryvtt-reve-de-dragon/templates/item-${type}-sheet.html` :
 | 
				
			||||||
 | 
					      "systems/foundryvtt-reve-de-dragon/templates/item-sheet.html";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static register(sheetClass) {
 | 
				
			||||||
 | 
					    Items.registerSheet(SYSTEM_RDD, sheetClass, {
 | 
				
			||||||
 | 
					      label: Misc.typeName('Item', sheetClass.ITEM_TYPE),
 | 
				
			||||||
 | 
					      types: [sheetClass.ITEM_TYPE],
 | 
				
			||||||
 | 
					      makeDefault: true
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @override */
 | 
					  /** @override */
 | 
				
			||||||
  static get defaultOptions() {
 | 
					  static get defaultOptions() {
 | 
				
			||||||
    return mergeObject(super.defaultOptions, {
 | 
					    return mergeObject(super.defaultOptions, {
 | 
				
			||||||
      classes: [SYSTEM_RDD, "sheet", "item"],
 | 
					      classes: [SYSTEM_RDD, "sheet", "item"],
 | 
				
			||||||
      template: "systems/foundryvtt-reve-de-dragon/templates/item-sheet.html",
 | 
					      template: RdDItemSheet.defaultTemplate(RdDItemSheet.ITEM_TYPE),
 | 
				
			||||||
      width: 550,
 | 
					      width: 550,
 | 
				
			||||||
      height: 550
 | 
					      height: 550
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  get template() {
 | 
				
			||||||
 | 
					    return RdDItemSheet.defaultTemplate(this.item.type);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get title() {
 | 
				
			||||||
 | 
					    return `${Misc.typeName('Item', this.item.type)}: ${this.item.name}`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _getHeaderButtons() {
 | 
					  _getHeaderButtons() {
 | 
				
			||||||
    let buttons = super._getHeaderButtons();
 | 
					    let buttons = super._getHeaderButtons();
 | 
				
			||||||
    // Add "Post to chat" button
 | 
					    if (this.item.isInventaire() && this.item.isVideOuNonConteneur()) {
 | 
				
			||||||
    // We previously restricted this to GM and editable items only. If you ever find this comment because it broke something: eh, sorry!
 | 
					 | 
				
			||||||
    if ("cout" in this.item.system && this.item.isVideOuNonConteneur()) {
 | 
					 | 
				
			||||||
      buttons.unshift({
 | 
					      buttons.unshift({
 | 
				
			||||||
        class: "vendre",
 | 
					        class: "vendre",
 | 
				
			||||||
        icon: "fas fa-comments-dollar",
 | 
					        icon: "fas fa-comments-dollar",
 | 
				
			||||||
@@ -67,43 +91,44 @@ export class RdDItemSheet extends ItemSheet {
 | 
				
			|||||||
      img: this.item.img,
 | 
					      img: this.item.img,
 | 
				
			||||||
      name: this.item.name,
 | 
					      name: this.item.name,
 | 
				
			||||||
      system: this.item.system,
 | 
					      system: this.item.system,
 | 
				
			||||||
      // TODO: v10 remove
 | 
					 | 
				
			||||||
      data: this.item.system,
 | 
					 | 
				
			||||||
      isGM: game.user.isGM,
 | 
					      isGM: game.user.isGM,
 | 
				
			||||||
      actorId: this.actor?.id,
 | 
					      actorId: this.actor?.id,
 | 
				
			||||||
 | 
					      isOwned: this.actor ? true : false,
 | 
				
			||||||
      owner: this.item.isOwner,
 | 
					      owner: this.item.isOwner,
 | 
				
			||||||
      editable: this.isEditable,
 | 
					      editable: this.isEditable,
 | 
				
			||||||
      cssClass: this.isEditable ? "editable" : "locked",
 | 
					      cssClass: this.isEditable ? "editable" : "locked",
 | 
				
			||||||
      isSoins: false,
 | 
					      isSoins: false,
 | 
				
			||||||
      description:  await TextEditor.enrichHTML(this.object.system.description, {async: true}),
 | 
					      description: await TextEditor.enrichHTML(this.item.system.description, { async: true }),
 | 
				
			||||||
      descriptionmj:  await TextEditor.enrichHTML(this.object.system.descriptionmj, {async: true})
 | 
					      descriptionmj: await TextEditor.enrichHTML(this.item.system.descriptionmj, { async: true }),
 | 
				
			||||||
 | 
					      isComestible: this.item.isComestible()
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (this.actor) {
 | 
					 | 
				
			||||||
      formData.isOwned = true;
 | 
					 | 
				
			||||||
      if (this.item.type == 'conteneur') {
 | 
					 | 
				
			||||||
        this.prepareConteneurData(formData);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const competences = await SystemCompendiums.getCompetences(this.actor?.type);
 | 
				
			||||||
    formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences()
 | 
					    formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences()
 | 
				
			||||||
    if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') {
 | 
					    if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') {
 | 
				
			||||||
      formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
 | 
					      formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
 | 
				
			||||||
      formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
 | 
					      formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
 | 
				
			||||||
      formData.competences = await RdDUtility.loadItems(it => it.isCompetencePersonnage(), RdDItemCompetence.actorCompendium(this.actor?.type))
 | 
					      formData.competences = competences;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (this.item.type == 'arme') {
 | 
					    if (this.item.type == 'arme') {
 | 
				
			||||||
      formData.competences = await RdDUtility.loadItems(it => RdDItemCompetence.isCompetenceArme(it),  RdDItemCompetence.actorCompendium(this.actor?.type))
 | 
					      formData.competences = competences.filter(it => RdDItemCompetence.isCompetenceArme(it));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (['sort', 'sortreserve'].includes(this.item.type)) {
 | 
				
			||||||
 | 
					      formData.competences = competences.filter(it => RdDItemCompetence.isDraconic(it));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (this.item.type == 'recettecuisine') {
 | 
					    if (this.item.type == 'recettecuisine') {
 | 
				
			||||||
      formData.ingredients =  await TextEditor.enrichHTML(this.object.system.ingredients, {async: true})
 | 
					      formData.ingredients = await TextEditor.enrichHTML(this.object.system.ingredients, { async: true })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (this.item.type == 'extraitpoetique') {
 | 
				
			||||||
 | 
					      formData.extrait = await TextEditor.enrichHTML(this.object.system.extrait, { async: true })
 | 
				
			||||||
 | 
					      formData.texte = await TextEditor.enrichHTML(this.object.system.texte, { async: true })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (this.item.type == 'recettealchimique') {
 | 
					    if (this.item.type == 'recettealchimique') {
 | 
				
			||||||
      RdDAlchimie.processManipulation(this.item, this.actor && this.actor.id);
 | 
					      RdDAlchimie.processManipulation(this.item, this.actor && this.actor.id);
 | 
				
			||||||
      formData.manipulation_update =  await TextEditor.enrichHTML(this.object.system.manipulation_update, {async: true})
 | 
					      formData.manipulation_update = await TextEditor.enrichHTML(this.object.system.manipulation_update, { async: true })
 | 
				
			||||||
      formData.utilisation =  await TextEditor.enrichHTML(this.object.system.utilisation, {async: true})
 | 
					      formData.utilisation = await TextEditor.enrichHTML(this.object.system.utilisation, { async: true })
 | 
				
			||||||
      formData.enchantement =  await TextEditor.enrichHTML(this.object.system.enchantement, {async: true})
 | 
					      formData.enchantement = await TextEditor.enrichHTML(this.object.system.enchantement, { async: true })
 | 
				
			||||||
      formData.sureffet =  await TextEditor.enrichHTML(this.object.system.sureffet, {async: true})
 | 
					      formData.sureffet = await TextEditor.enrichHTML(this.object.system.sureffet, { async: true })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (this.item.type == 'gemme') {
 | 
					    if (this.item.type == 'gemme') {
 | 
				
			||||||
      formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList();
 | 
					      formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList();
 | 
				
			||||||
@@ -128,106 +153,66 @@ export class RdDItemSheet extends ItemSheet {
 | 
				
			|||||||
    return formData;
 | 
					    return formData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  prepareConteneurData(formData) {
 | 
					 | 
				
			||||||
    RdDUtility.filterEquipementParType(formData, this.actor.itemTypes);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
 | 
					 | 
				
			||||||
    formData.subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  /** @override */
 | 
					  /** @override */
 | 
				
			||||||
  activateListeners(html) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    super.activateListeners(html);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
    if (this.item.type == 'conteneur') {
 | 
					 | 
				
			||||||
      this.form.ondragstart = (event) => this._onDragStart(event);
 | 
					 | 
				
			||||||
      this.form.ondrop = (event) => this._onDrop(event);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let itemSheetDialog = this;
 | 
					    let itemSheetDialog = this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".item-cout"), ReglesOptionelles.isUsing('afficher-prix-joueurs') || game.user.isGM || !this.item.isOwned);
 | 
					    HtmlUtility._showControlWhen(this.html.find(".item-cout"), ReglesOptionelles.isUsing('afficher-prix-joueurs') || game.user.isGM || !this.item.isOwned);
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".item-magique"), this.item.isMagique());
 | 
					    HtmlUtility._showControlWhen(this.html.find(".item-magique"), this.item.isMagique());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Everything below here is only needed if the sheet is editable
 | 
					    // Everything below here is only needed if the sheet is editable
 | 
				
			||||||
    if (!this.options.editable) return;
 | 
					    if (!this.options.editable) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Select competence categorie
 | 
					    this.form.ondragstart = (event) => this._onDragStart(event);
 | 
				
			||||||
    html.find(".categorie").change(event => this._onSelectCategorie(event));
 | 
					    this.form.ondrop = (event) => this._onDrop(event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.sheet-competence-xp').change((event) => {
 | 
					    // Select competence categorie
 | 
				
			||||||
 | 
					    this.html.find(".categorie").change(event => this._onSelectCategorie(event));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('.sheet-competence-xp').change((event) => {
 | 
				
			||||||
      if (this.item.isCompetencePersonnage()) {
 | 
					      if (this.item.isCompetencePersonnage()) {
 | 
				
			||||||
        RdDUtility.checkThanatosXP(this.item.name);
 | 
					        RdDUtility.checkThanatosXP(this.item.name);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.enchanteDate').change((event) => {
 | 
					    this.html.find('.enchanteDate').change((event) => {
 | 
				
			||||||
      let jour = Number($('#jourMois').val());
 | 
					      let jour = Number(this.html.find('[name="splitDate.day"]').val());
 | 
				
			||||||
      let mois = $('#nomMois').val();
 | 
					      let mois = this.html.find('[name="splitDate.month"]').val();
 | 
				
			||||||
      this.dateUpdated = game.system.rdd.calendrier.getIndexFromDate(jour, mois);
 | 
					      this.dateUpdated = game.system.rdd.calendrier.getIndexFromDate(jour, mois);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.creer-tache-livre').click((event) => {
 | 
					    this.html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item));
 | 
				
			||||||
      let actorId = event.currentTarget.attributes['data-actor-id'].value;
 | 
					    this.html.find('.consommer-potion').click((event) => this._getEventActor(event).consommerPotion(this.item));
 | 
				
			||||||
      let actor = game.actors.get(actorId);
 | 
					    this.html.find('.creer-potion-base').click((event) => this._getEventActor(event).dialogFabriquerPotion(this.item));
 | 
				
			||||||
      actor.creerTacheDepuisLivre(this.item);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.consommer-potion').click((event) => {
 | 
					 | 
				
			||||||
      let actorId = event.currentTarget.attributes['data-actor-id'].value;
 | 
					 | 
				
			||||||
      let actor = game.actors.get(actorId);
 | 
					 | 
				
			||||||
      actor.consommerPotion(this.item);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.creer-potion-base').click((event) => {
 | 
					 | 
				
			||||||
      let actorId = event.currentTarget.attributes['data-actor-id'].value;
 | 
					 | 
				
			||||||
      let actor = game.actors.get(actorId);
 | 
					 | 
				
			||||||
      actor.dialogFabriquerPotion(this.item);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.alchimie-tache a').click((event) => {
 | 
					    this.html.find('.alchimie-tache a').click((event) => {
 | 
				
			||||||
      let actorId = event.currentTarget.attributes['data-actor-id'].value;
 | 
					      let actor = this._getEventActor(event);
 | 
				
			||||||
      let recetteId = event.currentTarget.attributes['data-recette-id'].value;
 | 
					 | 
				
			||||||
      let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value;
 | 
					 | 
				
			||||||
      let tacheData = event.currentTarget.attributes['data-alchimie-data'].value;
 | 
					 | 
				
			||||||
      let actor = game.actors.get(actorId);
 | 
					 | 
				
			||||||
      if (actor) {
 | 
					      if (actor) {
 | 
				
			||||||
 | 
					        let recetteId = event.currentTarget.attributes['data-recette-id'].value;
 | 
				
			||||||
 | 
					        let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value;
 | 
				
			||||||
 | 
					        let tacheData = event.currentTarget.attributes['data-alchimie-data'].value;
 | 
				
			||||||
        actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData);
 | 
					        actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData);
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        ui.notifications.info("Impossible trouver un acteur pour réaliser cette tache Alchimique.");
 | 
					        ui.notifications.info("Impossible trouver un acteur pour réaliser cette tache Alchimique.");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('.item-split').click(async event => {
 | 
					    this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, async () => itemSheetDialog.render(true)));
 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
					    this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true));
 | 
				
			||||||
      await RdDSheetUtility.splitItem(item, this.actor, async () => itemSheetDialog.render(true));
 | 
					    this.html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor)));
 | 
				
			||||||
    });
 | 
					    this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente());
 | 
				
			||||||
    html.find('.item-edit').click(async event => {
 | 
					    this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem());
 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
					    this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, async () => itemSheetDialog.render(true)));
 | 
				
			||||||
      item.sheet.render(true);
 | 
					  }
 | 
				
			||||||
    });
 | 
					
 | 
				
			||||||
    html.find('.item-delete').click(async event => {
 | 
					  _getEventActor(event) {
 | 
				
			||||||
      const li = RdDSheetUtility.getEventElement(event);
 | 
					    let actorId = event.currentTarget.attributes['data-actor-id'].value;
 | 
				
			||||||
      const item = this.actor.getObjet(li.data("item-id"));
 | 
					    let actor = game.actors.get(actorId);
 | 
				
			||||||
      RdDUtility.confirmerSuppressionItem(this, item, li);
 | 
					    return actor;
 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.item-vendre').click(async event => {
 | 
					 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
					 | 
				
			||||||
      item?.proposerVente();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.item-montrer').click(async event => {
 | 
					 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
					 | 
				
			||||||
      item?.postItem();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.item-action').click(async event => {
 | 
					 | 
				
			||||||
      const item = RdDSheetUtility.getItem(event, this.actor);
 | 
					 | 
				
			||||||
      this.actor.actionItem(item, async () => itemSheetDialog.render(true));
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('.conteneur-name a').click(async event => {
 | 
					 | 
				
			||||||
      RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
 | 
					 | 
				
			||||||
      this.render(true);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -237,70 +222,56 @@ export class RdDItemSheet extends ItemSheet {
 | 
				
			|||||||
    if (this.item.isCompetence()) {
 | 
					    if (this.item.isCompetence()) {
 | 
				
			||||||
      let level = RdDItemCompetence.getNiveauBase(event.currentTarget.value);
 | 
					      let level = RdDItemCompetence.getNiveauBase(event.currentTarget.value);
 | 
				
			||||||
      this.item.system.base = level;
 | 
					      this.item.system.base = level;
 | 
				
			||||||
      $("#base").val(level);
 | 
					      this.html.find('[name="system.base"]').val(level);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  get template() {
 | 
					 | 
				
			||||||
    let type = this.item.type
 | 
					 | 
				
			||||||
    return `systems/foundryvtt-reve-de-dragon/templates/item-${type}-sheet.html`;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** @override */
 | 
					  /** @override */
 | 
				
			||||||
  _updateObject(event, formData) {
 | 
					  _updateObject(event, formData) {
 | 
				
			||||||
    // Données de bonus de cases ?
 | 
					    if (this.item.type == 'sort') {
 | 
				
			||||||
    formData['system.bonuscase'] = RdDItemSort.buildBonusCaseStringFromFormData(formData.bonusValue, formData.caseValue);
 | 
					      // Données de bonus de cases ?
 | 
				
			||||||
 | 
					      formData['system.bonuscase'] = RdDItemSort.buildBonusCaseStringFromFormData(formData.bonusValue, formData.caseValue);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return this.item.update(formData);
 | 
					    return this.item.update(formData);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async _onDragStart(event) {
 | 
					  async _onDragStart(event) {
 | 
				
			||||||
    console.log("_onDragStart", event);
 | 
					 | 
				
			||||||
    if (event.target.classList.contains("entity-link")) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const itemId = event.srcElement?.attributes["data-item-id"].value;
 | 
					 | 
				
			||||||
    const item = this.actor.items.get(itemId);
 | 
					 | 
				
			||||||
    // Create drag data
 | 
					 | 
				
			||||||
    const dragData = {
 | 
					 | 
				
			||||||
      actorId: this.actor.id,
 | 
					 | 
				
			||||||
      type: "Item",
 | 
					 | 
				
			||||||
      data: item.system
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event.dataTransfer.setData("text/plain", JSON.stringify(dragData));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async _onDrop(event) {
 | 
					  async _onDrop(event) {
 | 
				
			||||||
    // Try to extract the dragData
 | 
					    // Try to extract the dragData
 | 
				
			||||||
    let dragData;
 | 
					    let dragData = RdDItemSheet.$extractDragData(event);
 | 
				
			||||||
    try {
 | 
					    if (!dragData) return false;
 | 
				
			||||||
      dragData = JSON.parse(event.dataTransfer.getData('text/plain'));
 | 
					 | 
				
			||||||
    } catch (err) {
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const allowed = Hooks.call("dropActorSheetData", this.actor, this, dragData);
 | 
					    const allowed = Hooks.call("dropActorSheetData", this.actor, this, dragData);
 | 
				
			||||||
    if (allowed === false) return;
 | 
					    if (allowed === false) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Handle different dragData types
 | 
					    // Handle different dragData types
 | 
				
			||||||
    switch (dragData.type) {
 | 
					    switch (dragData.type) {
 | 
				
			||||||
      case "Item":
 | 
					      case "Item":
 | 
				
			||||||
        return this._onDropItem(event, dragData);
 | 
					        return this._onDropItem(event, dragData);
 | 
				
			||||||
 | 
					      case "Actor":
 | 
				
			||||||
 | 
					        return this._onDropActor(event, dragData);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return super._onDrop(event);
 | 
					    return super._onDrop(event);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  static $extractDragData(event) {
 | 
				
			||||||
  async _onDropItem(event, dragData) {
 | 
					    try {
 | 
				
			||||||
    if (this.actor) {
 | 
					      const eventData = event?.dataTransfer?.getData('text/plain');
 | 
				
			||||||
      const dropParams = RdDSheetUtility.prepareItemDropParameters(this.item.id, this.actor.id, dragData, this.objetVersConteneur);
 | 
					      if (eventData) {
 | 
				
			||||||
      await this.actor.processDropItem(dropParams);
 | 
					        return JSON.parse(eventData);
 | 
				
			||||||
      await this.render(true);
 | 
					      }
 | 
				
			||||||
    }
 | 
					    } catch (err) { }
 | 
				
			||||||
 | 
					    return undefined;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async _onDropItem(event, dragData) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async _onDropActor(event, dragData) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,30 +1,14 @@
 | 
				
			|||||||
import { SYSTEM_RDD } from "./constants.js";
 | 
					import { RdDItemSheet } from "./item-sheet.js";
 | 
				
			||||||
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
 | 
					import { RdDItemSigneDraconique } from "./item-signedraconique.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					import { TMRUtility } from "./tmr-utility.js";
 | 
				
			||||||
import { TMRType, TMRUtility } from "./tmr-utility.js";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Item sheet pour signes draconiques
 | 
					 * Item sheet pour signes draconiques
 | 
				
			||||||
 * @extends {ItemSheet}
 | 
					 * @extends {RdDItemSheet}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export class RdDSigneDraconiqueItemSheet extends ItemSheet {
 | 
					export class RdDSigneDraconiqueItemSheet extends RdDItemSheet {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @override */
 | 
					  static get ITEM_TYPE() { return "signedraconique" }
 | 
				
			||||||
  static get defaultOptions() {
 | 
					 | 
				
			||||||
    return mergeObject(super.defaultOptions, {
 | 
					 | 
				
			||||||
      classes: [SYSTEM_RDD, "sheet", "item"],
 | 
					 | 
				
			||||||
      template: "systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html",
 | 
					 | 
				
			||||||
      width: 550,
 | 
					 | 
				
			||||||
      height: 550
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  _getHeaderButtons() {
 | 
					 | 
				
			||||||
    let buttons = super._getHeaderButtons();
 | 
					 | 
				
			||||||
    buttons.unshift({ class: "post", icon: "fas fa-comment", onclick: ev => this.item.postItem() });
 | 
					 | 
				
			||||||
    return buttons;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  /** @override */
 | 
					  /** @override */
 | 
				
			||||||
@@ -62,12 +46,13 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
 | 
				
			|||||||
    if (!this.options.editable) return;
 | 
					    if (!this.options.editable) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
 | 
					    html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
 | 
				
			||||||
    html.find("input.select-tmr").change((event) => this.onSelectTmr(event));
 | 
					    html.find("input.select-tmr").change(event => this.onSelectTmr(event));
 | 
				
			||||||
    html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value)));
 | 
					    html.find(".signe-xp-sort").change(event => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value)));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async setSigneAleatoire() {
 | 
					  async setSigneAleatoire() {
 | 
				
			||||||
    const newSigne = await RdDItemSigneDraconique.randomSigneDraconique();
 | 
					    const newSigne = await RdDItemSigneDraconique.randomSigneDraconique();
 | 
				
			||||||
 | 
					    newSigne.name = this.item.name;
 | 
				
			||||||
    this.item.update(newSigne);
 | 
					    this.item.update(newSigne);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -89,12 +74,4 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
 | 
				
			|||||||
    await this.item.update({ 'system.valeur': newValeur });
 | 
					    await this.item.update({ 'system.valeur': newValeur });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  get template() {
 | 
					 | 
				
			||||||
    return `systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html`;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  get title() {
 | 
					 | 
				
			||||||
    return `Signe draconique: ${this.object.name}`;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										528
									
								
								module/item.js
									
									
									
									
									
								
							
							
						
						@@ -1,15 +1,17 @@
 | 
				
			|||||||
import { DialogItemVente } from "./dialog-item-vente.js";
 | 
					import { DialogItemVente } from "./dialog-item-vente.js";
 | 
				
			||||||
import { Grammar } from "./grammar.js";
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
import { RdDHerbes } from "./rdd-herbes.js";
 | 
					import { RdDHerbes } from "./rdd-herbes.js";
 | 
				
			||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const typesObjetsEquipement = [
 | 
					const typesObjetsInventaire = [
 | 
				
			||||||
  "arme",
 | 
					  "arme",
 | 
				
			||||||
  "armure",
 | 
					  "armure",
 | 
				
			||||||
  "conteneur",
 | 
					  "conteneur",
 | 
				
			||||||
  "gemme",
 | 
					  "gemme",
 | 
				
			||||||
  "herbe",
 | 
					  "herbe",
 | 
				
			||||||
  "ingredient",
 | 
					  "ingredient",
 | 
				
			||||||
 | 
					  "faune",
 | 
				
			||||||
  "livre",
 | 
					  "livre",
 | 
				
			||||||
  "monnaie",
 | 
					  "monnaie",
 | 
				
			||||||
  "munition",
 | 
					  "munition",
 | 
				
			||||||
@@ -18,7 +20,7 @@ const typesObjetsEquipement = [
 | 
				
			|||||||
  "potion",
 | 
					  "potion",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
 | 
					const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
 | 
				
			||||||
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve"]
 | 
					const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve", "rencontre"]
 | 
				
			||||||
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
 | 
					const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
 | 
				
			||||||
const typesObjetsEffet = ["possession", "poison", "maladie"]
 | 
					const typesObjetsEffet = ["possession", "poison", "maladie"]
 | 
				
			||||||
const typesObjetsCompetence = ["competence", "competencecreature"]
 | 
					const typesObjetsCompetence = ["competence", "competencecreature"]
 | 
				
			||||||
@@ -35,9 +37,11 @@ export const defaultItemImg = {
 | 
				
			|||||||
  conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp",
 | 
					  conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp",
 | 
				
			||||||
  sort: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
 | 
					  sort: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
 | 
				
			||||||
  herbe: "systems/foundryvtt-reve-de-dragon/icons/botanique/Endorlotte.webp",
 | 
					  herbe: "systems/foundryvtt-reve-de-dragon/icons/botanique/Endorlotte.webp",
 | 
				
			||||||
 | 
					  faune: "systems/foundryvtt-reve-de-dragon/icons/faune/rongeur.webp",
 | 
				
			||||||
  ingredient: "systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp",
 | 
					  ingredient: "systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp",
 | 
				
			||||||
  livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp",
 | 
					  livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp",
 | 
				
			||||||
  potion: "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp",
 | 
					  potion: "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp",
 | 
				
			||||||
 | 
					  rencontre: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp",
 | 
				
			||||||
  queue: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
 | 
					  queue: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
 | 
				
			||||||
  ombre: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
 | 
					  ombre: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp",
 | 
				
			||||||
  souffle: "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp",
 | 
					  souffle: "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp",
 | 
				
			||||||
@@ -57,20 +61,61 @@ export const defaultItemImg = {
 | 
				
			|||||||
  gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp",
 | 
					  gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp",
 | 
				
			||||||
  possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
 | 
					  possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
 | 
				
			||||||
  sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
 | 
					  sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
 | 
				
			||||||
 | 
					  extraitpoetique: "systems/foundryvtt-reve-de-dragon/icons/competence_ecriture.webp",
 | 
				
			||||||
 | 
					  tarot: "systems/foundryvtt-reve-de-dragon/icons/tarots/dos-tarot.webp",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
export class RdDItem extends Item {
 | 
					export class RdDItem extends Item {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getDefaultImg(itemType) {
 | 
				
			||||||
 | 
					    return defaultItemImg[itemType];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static isItemInventaire(newLocal) {
 | 
				
			||||||
 | 
					    return typesObjetsInventaire.includes(newLocal.type);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static isFieldInventaireModifiable(type, field) {
 | 
				
			||||||
 | 
					    switch (field) {
 | 
				
			||||||
 | 
					      case 'quantite':
 | 
				
			||||||
 | 
					        if (['conteneur'].includes(type)) {
 | 
				
			||||||
 | 
					          return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'cout':
 | 
				
			||||||
 | 
					        if (['monnaie'].includes(type)) {
 | 
				
			||||||
 | 
					          return game.user.isGM;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getUniteQuantite() {
 | 
				
			||||||
 | 
					    switch (this.type) {
 | 
				
			||||||
 | 
					      case "monnaie": return "(Pièces)"
 | 
				
			||||||
 | 
					      case "herbe":
 | 
				
			||||||
 | 
					        switch (this.system.categorie) {
 | 
				
			||||||
 | 
					          case 'Alchimie': case 'Repos': case 'Soin':
 | 
				
			||||||
 | 
					            return "(Brins)"
 | 
				
			||||||
 | 
					          case 'Cuisine': return '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return '';
 | 
				
			||||||
 | 
					      case "ingredient": return "(Pépins ou Brins)"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return '';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(itemData, context) {
 | 
					  constructor(itemData, context) {
 | 
				
			||||||
    if (!itemData.img) {
 | 
					    if (!itemData.img) {
 | 
				
			||||||
      itemData.img = defaultItemImg[itemData.type];
 | 
					      itemData.img = RdDItem.getDefaultImg(itemData.type);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    super(itemData, context);
 | 
					    super(itemData, context);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static getTypesObjetsEquipement() {
 | 
					  static getItemTypesInventaire() {
 | 
				
			||||||
    return typesObjetsEquipement
 | 
					    return typesObjetsInventaire
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static getTypesOeuvres() {
 | 
					  static getTypesOeuvres() {
 | 
				
			||||||
@@ -80,11 +125,14 @@ export class RdDItem extends Item {
 | 
				
			|||||||
  isCompetencePersonnage() {
 | 
					  isCompetencePersonnage() {
 | 
				
			||||||
    return this.type == 'competence'
 | 
					    return this.type == 'competence'
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  isCompetenceCreature() {
 | 
				
			||||||
 | 
					    return this.type == 'competencecreature'
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  isCompetence() {
 | 
					  isCompetence() {
 | 
				
			||||||
    return typesObjetsCompetence.includes(this.type)
 | 
					    return typesObjetsCompetence.includes(this.type)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  isEquipement() {
 | 
					  isInventaire() {
 | 
				
			||||||
    return typesObjetsEquipement.includes(this.type)
 | 
					    return RdDItem.isItemInventaire(this)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  isOeuvre() {
 | 
					  isOeuvre() {
 | 
				
			||||||
    return typesObjetsOeuvres.includes(this.type)
 | 
					    return typesObjetsOeuvres.includes(this.type)
 | 
				
			||||||
@@ -103,7 +151,7 @@ export class RdDItem extends Item {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getItemGroup() {
 | 
					  getItemGroup() {
 | 
				
			||||||
    if (this.isEquipement()) return "equipement";
 | 
					    if (this.isInventaire()) return "equipement";
 | 
				
			||||||
    if (this.isOeuvre()) return "oeuvre";
 | 
					    if (this.isOeuvre()) return "oeuvre";
 | 
				
			||||||
    if (this.isDraconique()) return "draconique";
 | 
					    if (this.isDraconique()) return "draconique";
 | 
				
			||||||
    if (this.isConnaissance()) return "connaissance";
 | 
					    if (this.isConnaissance()) return "connaissance";
 | 
				
			||||||
@@ -124,9 +172,25 @@ export class RdDItem extends Item {
 | 
				
			|||||||
    return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0;
 | 
					    return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  isAlcool() {
 | 
					  isNourritureBoisson() {
 | 
				
			||||||
    return this.type == 'nourritureboisson' && this.system.boisson && this.system.alcoolise;
 | 
					    return this.type == 'nourritureboisson';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  isComestible() {
 | 
				
			||||||
 | 
					    switch (this.type) {
 | 
				
			||||||
 | 
					      case 'nourritureboisson': return 'pret';
 | 
				
			||||||
 | 
					      case 'herbe':
 | 
				
			||||||
 | 
					        return this.system.categorie == 'Cuisine' && this.system.sust > 0 ? 'brut' : '';
 | 
				
			||||||
 | 
					      case 'faune':
 | 
				
			||||||
 | 
					        return this.system.sust > 0 ? 'brut' : '';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return '';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  isAlcool() {
 | 
				
			||||||
 | 
					    return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  isHerbeAPotion() {
 | 
					  isHerbeAPotion() {
 | 
				
			||||||
    return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos');
 | 
					    return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -147,29 +211,38 @@ export class RdDItem extends Item {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  getEncTotal() {
 | 
					  getEncTotal() {
 | 
				
			||||||
    return this.getEnc() * this.getQuantite();
 | 
					    return this.getEnc() * this.getQuantite();
 | 
				
			||||||
  }  
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getEnc() {
 | 
					  getEnc() {
 | 
				
			||||||
    switch (this.type) {
 | 
					    switch (this.type) {
 | 
				
			||||||
      case 'herbe':
 | 
					      case 'herbe':
 | 
				
			||||||
        return encBrin;
 | 
					        return this.getEncHerbe();
 | 
				
			||||||
      case 'gemme':
 | 
					      case 'gemme':
 | 
				
			||||||
        return encPepin * this.system.taille;
 | 
					        return encPepin * this.system.taille;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return Math.max(this.system.encombrement ?? 0, 0);
 | 
					    return Math.max(this.system.encombrement ?? 0, 0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  prixTotalDeniers() {
 | 
					  getEncHerbe() {
 | 
				
			||||||
    return this.getQuantite() * this.valeurDeniers()
 | 
					    switch (this.system.categorie) {
 | 
				
			||||||
 | 
					      case 'Repos': case 'Soin': case 'Alchimie':
 | 
				
			||||||
 | 
					        return encBrin;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return this.system.encombrement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  valeurDeniers() {
 | 
					  valeurTotale() {
 | 
				
			||||||
    return Math.max(Math.round(this.system.cout ? (this.system.cout * 100) : (this.system.valeur_deniers ?? 0)), 0) 
 | 
					    return this.getQuantite() * this.valeur()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  valeur() {
 | 
				
			||||||
 | 
					    return this.system.cout ?? 0
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  prepareDerivedData() {
 | 
					  prepareDerivedData() {
 | 
				
			||||||
    super.prepareDerivedData();
 | 
					    super.prepareDerivedData();
 | 
				
			||||||
    if (this.isEquipement()) {
 | 
					    if (this.isInventaire()) {
 | 
				
			||||||
      this.system.encTotal = this.getEncTotal();
 | 
					      this.system.encTotal = this.getEncTotal();
 | 
				
			||||||
      if (this.isPotion()) {
 | 
					      if (this.isPotion()) {
 | 
				
			||||||
        this.prepareDataPotion()
 | 
					        this.prepareDataPotion()
 | 
				
			||||||
@@ -190,19 +263,43 @@ export class RdDItem extends Item {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getActionPrincipale(options = { warnIfNot: true }) {
 | 
					  getActionPrincipale(options = { warnIfNot: true }) {
 | 
				
			||||||
    const warn = options.warnIfNot;
 | 
					 | 
				
			||||||
    switch (this.type) {
 | 
					    switch (this.type) {
 | 
				
			||||||
      case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
 | 
					 | 
				
			||||||
      case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn);
 | 
					 | 
				
			||||||
      case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn);
 | 
					 | 
				
			||||||
      case 'conteneur': return 'Ouvrir';
 | 
					      case 'conteneur': return 'Ouvrir';
 | 
				
			||||||
      case 'herbe':  return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
 | 
					    }
 | 
				
			||||||
      case 'queue': case 'ombre': return this.system.refoulement>0 ? 'Refouler' : undefined;
 | 
					    if (this.actor?.isPersonnage()) {
 | 
				
			||||||
 | 
					      const warn = options.warnIfNot;
 | 
				
			||||||
 | 
					      if (this.isComestible() == 'brut') {
 | 
				
			||||||
 | 
					        return 'Utiliser';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      switch (this.type) {
 | 
				
			||||||
 | 
					        case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
 | 
				
			||||||
 | 
					        case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn);
 | 
				
			||||||
 | 
					        case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn);
 | 
				
			||||||
 | 
					        case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
 | 
				
			||||||
 | 
					        case 'queue': case 'ombre': return this.system.refoulement > 0 ? 'Refouler' : undefined;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return undefined;
 | 
					    return undefined;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async actionPrincipale(actor, onActionItem = async () => { }) {
 | 
				
			||||||
 | 
					    if (!this.getActionPrincipale()) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (await actor.actionNourritureboisson(this, onActionItem)) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    switch (this.type) {
 | 
				
			||||||
 | 
					      case 'potion': return await actor.consommerPotion(this, onActionItem);
 | 
				
			||||||
 | 
					      case 'livre': return await actor.actionLire(this);
 | 
				
			||||||
 | 
					      case 'conteneur': return await this.sheet.render(true);
 | 
				
			||||||
 | 
					      case 'herbe': return await actor.actionHerbe(this);
 | 
				
			||||||
 | 
					      case 'queue': case 'ombre': return await actor.actionRefoulement(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _actionOrWarnQuantiteZero(actionName, warn){
 | 
					  _actionOrWarnQuantiteZero(actionName, warn) {
 | 
				
			||||||
    if ((this.system.quantite ?? 0) <= 0) {
 | 
					    if ((this.system.quantite ?? 0) <= 0) {
 | 
				
			||||||
      if (warn) {
 | 
					      if (warn) {
 | 
				
			||||||
        ui.notifications.warn(`Vous n'avez plus de ${this.name}.`);
 | 
					        ui.notifications.warn(`Vous n'avez plus de ${this.name}.`);
 | 
				
			||||||
@@ -219,6 +316,42 @@ export class RdDItem extends Item {
 | 
				
			|||||||
    await this.quantiteIncDec(-nombre, options);
 | 
					    await this.quantiteIncDec(-nombre, options);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async onCreateDecoupeComestible(actor) {
 | 
				
			||||||
 | 
					    if (actor && this.isComestible() == 'brut' && this.system.sust != 1) {
 | 
				
			||||||
 | 
					      if (this.system.sust < 1) {
 | 
				
			||||||
 | 
					        await actor.updateEmbeddedDocuments('Item', [{
 | 
				
			||||||
 | 
					          _id: this.id,
 | 
				
			||||||
 | 
					          'system.sust': 0
 | 
				
			||||||
 | 
					        }])
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else {
 | 
				
			||||||
 | 
					        const sust = Math.floor(this.system.sust);
 | 
				
			||||||
 | 
					        await actor.updateEmbeddedDocuments('Item', [{
 | 
				
			||||||
 | 
					          _id: this.id,
 | 
				
			||||||
 | 
					          'system.quantite': this.system.quantite * sust,
 | 
				
			||||||
 | 
					          'system.encombrement': Misc.keepDecimals(this.system.encombrement / sust, 2),
 | 
				
			||||||
 | 
					          'system.cout': Misc.keepDecimals(this.system.cout / sust, 2),
 | 
				
			||||||
 | 
					          'system.sust': 1
 | 
				
			||||||
 | 
					        }])
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async empiler(item) {
 | 
				
			||||||
 | 
					    if (this.isComestible() == 'brut') {
 | 
				
			||||||
 | 
					      const sust = this.system.sust + item.system.sust;
 | 
				
			||||||
 | 
					      const encombrement = this.system.encombrement + item.system.encombrement;
 | 
				
			||||||
 | 
					      await this.update({
 | 
				
			||||||
 | 
					        "system.sust": sust,
 | 
				
			||||||
 | 
					        "system.encombrement": encombrement
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      await this.quantiteIncDec(item.system.quantite);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    await item.delete();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async quantiteIncDec(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) {
 | 
					  async quantiteIncDec(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) {
 | 
				
			||||||
    const quantite = Number(this.system.quantite ?? -1);
 | 
					    const quantite = Number(this.system.quantite ?? -1);
 | 
				
			||||||
    if (quantite >= 0) {
 | 
					    if (quantite >= 0) {
 | 
				
			||||||
@@ -242,14 +375,13 @@ export class RdDItem extends Item {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  // détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité
 | 
					  // détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité
 | 
				
			||||||
  isEquipementEmpilable(other) {
 | 
					  isInventaireEmpilable(other) {
 | 
				
			||||||
    if (!other || !this.isEquipement()) {
 | 
					    if (!other || !this.isInventaire()) {
 | 
				
			||||||
      return [false, undefined];
 | 
					      return [false, undefined];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (this.system.quantite == undefined) {
 | 
					    if (this.system.quantite == undefined) {
 | 
				
			||||||
      return [false, `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`];
 | 
					      return [false, `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`];
 | 
				
			||||||
    } 
 | 
					    }
 | 
				
			||||||
    else if (this.type != other.type) {
 | 
					    else if (this.type != other.type) {
 | 
				
			||||||
      return [false, `Impossible de regrouper des ${this.type} avec des ${other.type}`];
 | 
					      return [false, `Impossible de regrouper des ${this.type} avec des ${other.type}`];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -257,8 +389,13 @@ export class RdDItem extends Item {
 | 
				
			|||||||
      return [false, `Impossible de regrouper ${this.name} avec ${other.name}`];
 | 
					      return [false, `Impossible de regrouper ${this.name} avec ${other.name}`];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      const differences = Object.entries(this.system)
 | 
					      const excludedProperties = ['quantite', 'cout', 'encTotal'];
 | 
				
			||||||
        .filter(([key, value]) => !['quantite', 'cout', 'encTotal'].includes(key) && value != other.system[key]);
 | 
					      if (this.isComestible()) {
 | 
				
			||||||
 | 
					        excludedProperties.push('sust', 'encombrement');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      let differences = Object.entries(this.system)
 | 
				
			||||||
 | 
					        .filter(([key, value]) => !excludedProperties.includes(key))
 | 
				
			||||||
 | 
					        .filter(([key, value]) => value != other.system[key])
 | 
				
			||||||
      if (differences.length > 0) {
 | 
					      if (differences.length > 0) {
 | 
				
			||||||
        let message = `Impossible de regrouper les ${this.type} ${this.name}: `;
 | 
					        let message = `Impossible de regrouper les ${this.type} ${this.name}: `;
 | 
				
			||||||
        for (const [key, value] of differences) {
 | 
					        for (const [key, value] of differences) {
 | 
				
			||||||
@@ -276,7 +413,7 @@ export class RdDItem extends Item {
 | 
				
			|||||||
      ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
 | 
					      ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    await DialogItemVente.display(this, async (vente) =>  {
 | 
					    await DialogItemVente.display(this, async (vente) => {
 | 
				
			||||||
      vente["properties"] = this.getProprietes();
 | 
					      vente["properties"] = this.getProprietes();
 | 
				
			||||||
      if (vente.isOwned) {
 | 
					      if (vente.isOwned) {
 | 
				
			||||||
        if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) {
 | 
					        if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) {
 | 
				
			||||||
@@ -285,7 +422,7 @@ export class RdDItem extends Item {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      vente.jsondata = JSON.stringify(vente.item);
 | 
					      vente.jsondata = JSON.stringify(vente.item);
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
      console.log(vente);
 | 
					      console.log(vente);
 | 
				
			||||||
      let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
 | 
					      let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
 | 
				
			||||||
      ChatMessage.create(RdDUtility.chatDataSetup(html));
 | 
					      ChatMessage.create(RdDUtility.chatDataSetup(html));
 | 
				
			||||||
@@ -294,15 +431,14 @@ export class RdDItem extends Item {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  getProprietes() {
 | 
					  getProprietes() {
 | 
				
			||||||
    return this[`_${this.type}ChatData`]();
 | 
					    return this[`_${this.type}ChatData`]().filter(it => it != undefined);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async postItem(modeOverride) {
 | 
					  async postItem(modeOverride) {
 | 
				
			||||||
    console.log(this);
 | 
					    console.log(this);
 | 
				
			||||||
    let chatData = duplicate(this);
 | 
					    let chatData = duplicate(this);
 | 
				
			||||||
    const properties = this.getProprietes();
 | 
					    chatData["properties"] = this.getProprietes();
 | 
				
			||||||
    chatData["properties"] = properties
 | 
					 | 
				
			||||||
    if (this.actor) {
 | 
					    if (this.actor) {
 | 
				
			||||||
      chatData.actor = { id: this.actor.id };
 | 
					      chatData.actor = { id: this.actor.id };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -319,262 +455,237 @@ export class RdDItem extends Item {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static propertyIfDefined(name, val, condition = (it) => true) {
 | 
					  static propertyIfDefined(name, val, condition = true) {
 | 
				
			||||||
    return condition ? [`<b>${name}</b>: ${val}`] : [];
 | 
					    return condition ? `<b>${name}</b>: ${val}` : undefined;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _inventaireTemplateChatData() {
 | 
				
			||||||
 | 
					    return [
 | 
				
			||||||
 | 
					      RdDItem.propertyIfDefined('Qualité', this.system.qualite, this.system.qualite != 0),
 | 
				
			||||||
 | 
					      RdDItem.propertyIfDefined('Encombrement', this.system.encombrement)
 | 
				
			||||||
 | 
					      // cout et quantité masqués
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _objetChatData() {
 | 
					  _objetChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return this._inventaireTemplateChatData()
 | 
				
			||||||
    let properties = [].concat(
 | 
					 | 
				
			||||||
      RdDItem.propertyIfDefined('Résistance', tplData.resistance, tplData.resistance),
 | 
					 | 
				
			||||||
      RdDItem.propertyIfDefined('Qualité', tplData.qualite, tplData.qualite),
 | 
					 | 
				
			||||||
      RdDItem.propertyIfDefined('Encombrement', tplData.encombrement),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _nourritureboissonChatData() {
 | 
					  _nourritureboissonChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [].concat(
 | 
					      RdDItem.propertyIfDefined('Sustentation', this.system.sust, this.system.sust > 0),
 | 
				
			||||||
      RdDItem.propertyIfDefined('Sustentation', tplData.sust, tplData.sust > 0),
 | 
					      RdDItem.propertyIfDefined('Désaltère', this.system.desaltere, this.system.boisson),
 | 
				
			||||||
      RdDItem.propertyIfDefined('Désaltère', tplData.desaltere, tplData.boisson),
 | 
					      RdDItem.propertyIfDefined('Force alcool', this.system.force, this.system.boisson && this.system.alcoolise),
 | 
				
			||||||
      RdDItem.propertyIfDefined('Force alcool', tplData.force, tplData.boisson && tplData.alcoolise),
 | 
					      RdDItem.propertyIfDefined('Exotisme', this.system.exotisme, this.system.exotisme < 0),
 | 
				
			||||||
      RdDItem.propertyIfDefined('Exotisme', tplData.exotisme, tplData.exotisme < 0),
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
      RdDItem.propertyIfDefined('Qualité', tplData.qualite, tplData.qualite),
 | 
					    ]
 | 
				
			||||||
      RdDItem.propertyIfDefined('Encombrement', tplData.encombrement),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _armeChatData() {
 | 
					  _armeChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Compétence</b>: ${this.system.competence}`,
 | 
				
			||||||
      `<b>Compétence</b>: ${tplData.competence}`,
 | 
					      `<b>Dommages</b>: ${this.system.dommages}`,
 | 
				
			||||||
      `<b>Dommages</b>: ${tplData.dommages}`,
 | 
					      `<b>Force minimum</b>: ${this.system.force}`,
 | 
				
			||||||
      `<b>Force minimum</b>: ${tplData.force}`,
 | 
					      `<b>Resistance</b>: ${this.system.resistance}`,
 | 
				
			||||||
      `<b>Resistance</b>: ${tplData.resistance}`,
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
      `<b>Encombrement</b>: ${tplData.encombrement}`
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _conteneurChatData() {
 | 
					  _conteneurChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Capacité</b>: ${this.system.capacite} Enc.`,
 | 
				
			||||||
      `<b>Capacité</b>: ${tplData.capacite} Enc.`,
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
      `<b>Encombrement</b>: ${tplData.encombrement}`
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _munitionChatData() {
 | 
					  _munitionChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return this._inventaireTemplateChatData()
 | 
				
			||||||
    let properties = [
 | 
					 | 
				
			||||||
      `<b>Encombrement</b>: ${tplData.encombrement}`
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _armureChatData() {
 | 
					  _armureChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Protection</b>: ${this.system.protection}`,
 | 
				
			||||||
      `<b>Protection</b>: ${tplData.protection}`,
 | 
					      `<b>Détérioration</b>: ${this.system.deterioration}`,
 | 
				
			||||||
      `<b>Détérioration</b>: ${tplData.deterioration}`,
 | 
					      `<b>Malus armure</b>: ${this.system.malus}`,
 | 
				
			||||||
      `<b>Malus armure</b>: ${tplData.malus}`,
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
      `<b>Encombrement</b>: ${tplData.encombrement}`
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _competenceChatData() {
 | 
					  _competenceChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Catégorie</b>: ${this.system.categorie}`,
 | 
				
			||||||
      `<b>Catégorie</b>: ${tplData.categorie}`,
 | 
					      `<b>Niveau</b>: ${this.system.niveau}`,
 | 
				
			||||||
      `<b>Niveau</b>: ${tplData.niveau}`,
 | 
					      `<b>Caractéristique par défaut</b>: ${this.system.carac_defaut}`,
 | 
				
			||||||
      `<b>Caractéristique par défaut</b>: ${tplData.carac_defaut}`,
 | 
					      `<b>XP</b>: ${this.system.xp}`
 | 
				
			||||||
      `<b>XP</b>: ${tplData.xp}`
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _competencecreatureChatData() {
 | 
					  _competencecreatureChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Catégorie</b>: ${this.system.categorie}`,
 | 
				
			||||||
      `<b>Catégorie</b>: ${tplData.categorie}`,
 | 
					      `<b>Niveau</b>: ${this.system.niveau}`,
 | 
				
			||||||
      `<b>Niveau</b>: ${tplData.niveau}`,
 | 
					      `<b>Caractéristique</b>: ${this.system.carac_value}`,
 | 
				
			||||||
      `<b>Caractéristique</b>: ${tplData.carac_value}`,
 | 
					      `<b>XP</b>: ${this.system.xp}`
 | 
				
			||||||
      `<b>XP</b>: ${tplData.xp}`
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _sortChatData() {
 | 
					  _sortChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Draconic</b>: ${this.system.draconic}`,
 | 
				
			||||||
      `<b>Draconic</b>: ${tplData.draconic}`,
 | 
					      `<b>Difficulté</b>: ${this.system.difficulte}`,
 | 
				
			||||||
      `<b>Difficulté</b>: ${tplData.difficulte}`,
 | 
					      `<b>Case TMR</b>: ${this.system.caseTMR}`,
 | 
				
			||||||
      `<b>Case TMR</b>: ${tplData.caseTMR}`,
 | 
					      `<b>Points de Rêve</b>: ${this.system.ptreve}`
 | 
				
			||||||
      `<b>Points de Rêve</b>: ${tplData.ptreve}`
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _herbeChatData() {
 | 
					  _herbeChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Milieu</b>: ${this.system.milieu}`,
 | 
				
			||||||
      `<b>Milieu</b>: ${tplData.milieu}`,
 | 
					      `<b>Catégorie</b>: ${this.system.categorie}`,
 | 
				
			||||||
      `<b>Rareté</b>: ${tplData.rarete}`,
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
      `<b>Catégorie</b>: ${tplData.categorie}`,
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _ingredientChatData() {
 | 
					  _ingredientChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Milieu</b>: ${this.system.milieu}`,
 | 
				
			||||||
      `<b>Milieu</b>: ${tplData.milieu}`,
 | 
					      `<b>Catégorie</b>: ${this.system.categorie}`,
 | 
				
			||||||
      `<b>Rareté</b>: ${tplData.rarete}`,
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
      `<b>Catégorie</b>: ${tplData.categorie}`,
 | 
					    ]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  _fauneChatData() {
 | 
				
			||||||
 | 
					    return [
 | 
				
			||||||
 | 
					      `<b>Sustentation</b>: ${this.system.sust}`,
 | 
				
			||||||
 | 
					      `<b>Milieu</b>: ${this.system.milieu}`,
 | 
				
			||||||
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _tacheChatData() {
 | 
					  _tacheChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Caractéristique</b>: ${this.system.carac}`,
 | 
				
			||||||
      `<b>Caractéristique</b>: ${tplData.carac}`,
 | 
					      `<b>Compétence</b>: ${this.system.competence}`,
 | 
				
			||||||
      `<b>Compétence</b>: ${tplData.competence}`,
 | 
					      `<b>Périodicité</b>: ${this.system.periodicite}`,
 | 
				
			||||||
      `<b>Périodicité</b>: ${tplData.periodicite}`,
 | 
					      `<b>Fatigue</b>: ${this.system.fatigue}`,
 | 
				
			||||||
      `<b>Fatigue</b>: ${tplData.fatigue}`,
 | 
					      `<b>Difficulté</b>: ${this.system.difficulte}`,
 | 
				
			||||||
      `<b>Difficulté</b>: ${tplData.difficulte}`
 | 
					      RdDItem.propertyIfDefined('Points de Tâche', this.system.points_de_tache, this.system.cacher_points_de_tache),
 | 
				
			||||||
    ].concat([
 | 
					      `<b>Points de Tâche atteints</b>: ${this.system.points_de_tache_courant}`]
 | 
				
			||||||
      tplData.cacher_points_de_tache ? [] :`<b>Points de Tâche</b>: ${tplData.points_de_tache}`
 | 
					 | 
				
			||||||
    ]).concat([
 | 
					 | 
				
			||||||
      `<b>Points de Tâche atteints</b>: ${tplData.points_de_tache_courant}`]
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _livreChatData() {
 | 
					  _livreChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Compétence</b>: ${this.system.competence}`,
 | 
				
			||||||
      `<b>Compétence</b>: ${tplData.competence}`,
 | 
					      `<b>Auteur</b>: ${this.system.auteur}`,
 | 
				
			||||||
      `<b>Auteur</b>: ${tplData.auteur}`,
 | 
					      `<b>Difficulté</b>: ${this.system.difficulte}`,
 | 
				
			||||||
      `<b>Difficulté</b>: ${tplData.difficulte}`,
 | 
					      RdDItem.propertyIfDefined('Points de Tâche', this.system.points_de_tache, this.system.cacher_points_de_tache),
 | 
				
			||||||
      `<b>Points de Tâche</b>: ${tplData.points_de_tache}`,
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
      `<b>Encombrement</b>: ${tplData.encombrement}`
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _potionChatData() {
 | 
					  _potionChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Rareté</b>: ${this.system.rarete}`,
 | 
				
			||||||
      `<b>Rareté</b>: ${tplData.rarete}`,
 | 
					      `<b>Catégorie</b>: ${this.system.categorie}`,
 | 
				
			||||||
      `<b>Catégorie</b>: ${tplData.categorie}`,
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
      `<b>Encombrement</b>: ${tplData.encombrement}`,
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _queueChatData() {
 | 
					  _queueChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    function label(categorie) {
 | 
				
			||||||
    let properties = [
 | 
					      switch (categorie) {
 | 
				
			||||||
      `<b>Refoulement</b>: ${tplData.refoulement}`
 | 
					        case 'ideefixe': return 'Idée fixe';
 | 
				
			||||||
 | 
					        case 'lancinant': return 'Désir lancinant';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return ''
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return [
 | 
				
			||||||
 | 
					      `<b>Refoulement</b>: ${this.system.refoulement}`,
 | 
				
			||||||
 | 
					      `<b>Catégorie</b>: ${label(this.system.categorie)}`,
 | 
				
			||||||
 | 
					      `<b>Affecte</b>: ${this.system.hautrevant ? 'les haut-rêvants' : 'tout le monde'}`,
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _ombreChatData() {
 | 
					  _ombreChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return this._queueChatData()
 | 
				
			||||||
    let properties = [
 | 
					 | 
				
			||||||
      `<b>Refoulement</b>: ${tplData.refoulement}`
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _souffleChatData() {
 | 
					  _souffleChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [];
 | 
					      `<b>Affecte</b>: ${this.system.hautrevant ? 'les haut-rêvants' : 'tout le monde'}`,
 | 
				
			||||||
    return properties;
 | 
					    ];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _teteChatData() {
 | 
					  _teteChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [];
 | 
					      `<b>Affecte</b>: ${this.system.hautrevant ? 'les haut-rêvants' : 'tout le monde'}`,
 | 
				
			||||||
    return properties;
 | 
					    ];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _tarotChatData() {
 | 
					  _tarotChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      RdDItem.propertyIfDefined('Carte', RdDUtility.linkCompendium(this.pack, this.id, this.name), this.pack),
 | 
				
			||||||
      `<b>Concept</b>: ${tplData.concept}`,
 | 
					      `<b>Concept</b>: ${this.system.concept}`,
 | 
				
			||||||
      `<b>Aspect</b>: ${tplData.aspect}`,
 | 
					      `<b>Aspect</b>: ${this.system.aspect}`,
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _nombreastralChatData() {
 | 
					  _nombreastralChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Valeur</b>: ${this.system.value}`,
 | 
				
			||||||
      `<b>Valeur</b>: ${tplData.value}`,
 | 
					      `<b>Jour</b>: ${this.system.jourlabel}`,
 | 
				
			||||||
      `<b>Jour</b>: ${tplData.jourlabel}`,
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _monnaieChatData() {
 | 
					  _monnaieChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return this._inventaireTemplateChatData()
 | 
				
			||||||
    let properties = [
 | 
					 | 
				
			||||||
      `<b>Valeur en Deniers</b>: ${tplData.valeur_deniers}`,
 | 
					 | 
				
			||||||
      `<b>Encombrement</b>: ${tplData.encombrement}`
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _meditationChatData() {
 | 
					  _meditationChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Thème</b>: ${this.system.theme}`,
 | 
				
			||||||
      `<b>Thème</b>: ${tplData.theme}`,
 | 
					      `<b>Compétence</b>: ${this.system.competence}`,
 | 
				
			||||||
      `<b>Compétence</b>: ${tplData.competence}`,
 | 
					      `<b>Support</b>: ${this.system.support}`,
 | 
				
			||||||
      `<b>Support</b>: ${tplData.support}`,
 | 
					      `<b>Heure</b>: ${this.system.heure}`,
 | 
				
			||||||
      `<b>Heure</b>: ${tplData.heure}`,
 | 
					      `<b>Purification</b>: ${this.system.purification}`,
 | 
				
			||||||
      `<b>Purification</b>: ${tplData.purification}`,
 | 
					      `<b>Vêture</b>: ${this.system.veture}`,
 | 
				
			||||||
      `<b>Vêture</b>: ${tplData.veture}`,
 | 
					      `<b>Comportement</b>: ${this.system.comportement}`,
 | 
				
			||||||
      `<b>Comportement</b>: ${tplData.comportement}`,
 | 
					      `<b>Case TMR</b>: ${this.system.tmr}`
 | 
				
			||||||
      `<b>Case TMR</b>: ${tplData.tmr}`
 | 
					    ]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  _rencontreChatData() {
 | 
				
			||||||
 | 
					    if (this.system.coord) {
 | 
				
			||||||
 | 
					      return [
 | 
				
			||||||
 | 
					        `<b>Force</b>: ${this.system.force}`,
 | 
				
			||||||
 | 
					        `<b>Coordonnées</b>: ${this.system.coord}`,
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return [
 | 
				
			||||||
 | 
					      `<b>Force</b>: ${this.system.formule}`,
 | 
				
			||||||
 | 
					      `<b>Refoulement</b>: ${this.system.refoulement}`,
 | 
				
			||||||
 | 
					      RdDItem.propertyIfDefined('<b>Présent de cités</b>', '', this.system.presentCite),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _casetmrChatData() {
 | 
					  _casetmrChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Coordonnée</b>: ${this.system.coord}`,
 | 
				
			||||||
      `<b>Coordonnée</b>: ${tplData.coord}`,
 | 
					      `<b>Spécificité</b>: ${this.system.specific}`
 | 
				
			||||||
      `<b>Spécificité</b>: ${tplData.specific}`
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _maladieChatData() {
 | 
					  _maladieChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    if (!this.system.identifie) {
 | 
				
			||||||
    let properties
 | 
					      return [`<b>Inconnue</b>`]
 | 
				
			||||||
    if (tplData.identifie) {
 | 
					 | 
				
			||||||
      properties = [
 | 
					 | 
				
			||||||
        `<b>Malignité</b>: ${tplData.malignite}`,
 | 
					 | 
				
			||||||
        `<b>Périodicité</b>: ${tplData.periodicite}`,
 | 
					 | 
				
			||||||
        `<b>Dommages</b>: ${tplData.dommages}`
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
      if (tplData.remedesconnus) {
 | 
					 | 
				
			||||||
        properties.push(`<b>Remedes</b>: ${tplData.remedes}`)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      properties = [
 | 
					 | 
				
			||||||
        `<b>Inconnue</b>`]
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return properties;
 | 
					    return [
 | 
				
			||||||
 | 
					      `<b>Malignité</b>: ${this.system.malignite}`,
 | 
				
			||||||
 | 
					      `<b>Périodicité</b>: ${this.system.periodicite}`,
 | 
				
			||||||
 | 
					      `<b>Dommages</b>: ${this.system.dommages}`,
 | 
				
			||||||
 | 
					      RdDItem.propertyIfDefined('<b>Remedes</b>', this.system.remedes, this.system.remedesconnus),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -584,16 +695,13 @@ export class RdDItem extends Item {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _gemmeChatData() {
 | 
					  _gemmeChatData() {
 | 
				
			||||||
    const tplData = this.system
 | 
					    return [
 | 
				
			||||||
    let properties = [
 | 
					      `<b>Pureté</b>: ${this.system.purete}`,
 | 
				
			||||||
      `<b>Pureté</b>: ${tplData.purete}`,
 | 
					      `<b>Taille</b>: ${this.system.taille}`,
 | 
				
			||||||
      `<b>Taille</b>: ${tplData.taille}`,
 | 
					      `<b>Inertie</b>: ${this.system.inertie}`,
 | 
				
			||||||
      `<b>Inertie</b>: ${tplData.inertie}`,
 | 
					      `<b>Enchantabilité</b>: ${this.system.enchantabilite}`,
 | 
				
			||||||
      `<b>Enchantabilité</b>: ${tplData.enchantabilite}`,
 | 
					      ...this._inventaireTemplateChatData()
 | 
				
			||||||
      `<b>Prix</b>: ${tplData.cout}`,
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    return properties;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
 | 
					import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
 | 
				
			||||||
 | 
					import { Environnement } from "./environnement.js";
 | 
				
			||||||
import { Grammar } from "./grammar.js";
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Migration {
 | 
					class Migration {
 | 
				
			||||||
@@ -42,7 +43,7 @@ class _10_0_16_MigrationSortsReserve extends Migration {
 | 
				
			|||||||
        await actor.createEmbeddedDocuments("Item", sortsReserve, {
 | 
					        await actor.createEmbeddedDocuments("Item", sortsReserve, {
 | 
				
			||||||
          renderSheet: false,
 | 
					          renderSheet: false,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        await actor.update({ 'system.reve.reserve.list': [] })
 | 
					        await actor.update({ 'system.reve.reserve': undefined })
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,12 +99,177 @@ class _10_0_21_VehiculeStructureResistanceMax extends Migration {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _10_0_33_MigrationNomsDraconic extends Migration {
 | 
				
			||||||
 | 
					  get code() { return "competences-creature-parade"; }
 | 
				
			||||||
 | 
					  get version() { return "10.0.33"; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  migrationNomDraconic(ancien) {
 | 
				
			||||||
 | 
					    if (typeof ancien == 'string') {
 | 
				
			||||||
 | 
					      switch (ancien) {
 | 
				
			||||||
 | 
					        case 'oniros': case "Voie d'Oniros": return "Voie d'Oniros";
 | 
				
			||||||
 | 
					        case 'hypnos': case "Voie d'Hypnos": return "Voie d'Hypnos";
 | 
				
			||||||
 | 
					        case 'narcos': case "Voie de Narcos": return "Voie de Narcos";
 | 
				
			||||||
 | 
					        case 'thanatos': case "Voie de Thanatos": return "Voie de Thanatos";
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return ancien;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (typeof ancien.name == 'string') {
 | 
				
			||||||
 | 
					      return this.migrationNomDraconic(ancien.name)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return ancien;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  async migrate() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await this.applyItemsUpdates(items => items
 | 
				
			||||||
 | 
					      .filter(it => ["sort", "sortreserve"].includes(it.type)
 | 
				
			||||||
 | 
					        && (typeof it.system.draconic == 'string') || (typeof it.system.draconic?.name == 'string'))
 | 
				
			||||||
 | 
					      .map(it => { return { _id: it.id, "system.draconic": this.migrationNomDraconic(it.system.draconic) } }));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _10_2_5_ArmesTirLancer extends Migration {
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    super();
 | 
				
			||||||
 | 
					    this.dagues = { "system.competence": 'Dague', "system.lancer": 'Dague de jet', "system.portee_courte": 3, "system.portee_moyenne": 8, "system.portee_extreme": 15 }
 | 
				
			||||||
 | 
					    this.javelot = { "system.competence": 'Lance', "system.lancer": 'Javelot', "system.portee_courte": 6, "system.portee_moyenne": 12, "system.portee_extreme": 20 }
 | 
				
			||||||
 | 
					    this.fouet = { "system.competence": '', "system.lancer": 'Fouet', "system.portee_courte": 2, "system.portee_moyenne": 2, "system.portee_extreme": 3, "system.penetration": -1 }
 | 
				
			||||||
 | 
					    this.arc = { "system.competence": '', "system.tir": 'Arc' }
 | 
				
			||||||
 | 
					    this.arbalete = { "system.competence": '', "system.tir": 'Arbalète' }
 | 
				
			||||||
 | 
					    this.fronde = { "system.competence": '', "system.tir": 'Fronde' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.mappings = {
 | 
				
			||||||
 | 
					      'dague': { filter: it => true, updates: this.dagues },
 | 
				
			||||||
 | 
					      'dague de jet': { filter: it => true, updates: this.dagues },
 | 
				
			||||||
 | 
					      'javelot': { filter: it => true, updates: this.javelot },
 | 
				
			||||||
 | 
					      'lance': { filter: it => it.name == 'Javeline', updates: this.javelot },
 | 
				
			||||||
 | 
					      'fouet': { filter: it => true, updates: this.fouet },
 | 
				
			||||||
 | 
					      'arc': { filter: it => true, updates: this.arc },
 | 
				
			||||||
 | 
					      'arbalete': { filter: it => true, updates: this.arbalete },
 | 
				
			||||||
 | 
					      'fronde': { filter: it => true, updates: this.fronde },
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get code() { return "separation-competences-tir-lancer"; }
 | 
				
			||||||
 | 
					  get version() { return "10.2.5"; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  migrateArmeTirLancer(it) {
 | 
				
			||||||
 | 
					    let updates = mergeObject({ _id: it.id }, this.getMapping(it).updates);
 | 
				
			||||||
 | 
					    console.log(it.name, updates);
 | 
				
			||||||
 | 
					    return updates;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async migrate() {
 | 
				
			||||||
 | 
					    await this.applyItemsUpdates(items => items
 | 
				
			||||||
 | 
					      .filter(it => "arme" == it.type)
 | 
				
			||||||
 | 
					      .filter(it => this.isTirLancer(it))
 | 
				
			||||||
 | 
					      .filter(it => this.getMapping(it).filter(it))
 | 
				
			||||||
 | 
					      .map(it => this.migrateArmeTirLancer(it)));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  isTirLancer(it) {
 | 
				
			||||||
 | 
					    return Object.keys(this.mappings).includes(this.getCompKey(it));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getMapping(it) {
 | 
				
			||||||
 | 
					    return this.mappings[this.getCompKey(it)];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getCompKey(it) {
 | 
				
			||||||
 | 
					    return Grammar.toLowerCaseNoAccent(it.system.competence);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _10_2_10_DesirLancinant_IdeeFixe extends Migration {
 | 
				
			||||||
 | 
					  get code() { return "desir-lancinat-idee-fixe"; }
 | 
				
			||||||
 | 
					  get version() { return "10.2.10"; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  migrateQueue(it) {
 | 
				
			||||||
 | 
					    let categorie = undefined
 | 
				
			||||||
 | 
					    let name = it.name
 | 
				
			||||||
 | 
					    if (Grammar.toLowerCaseNoAccent(name).includes('desir')) {
 | 
				
			||||||
 | 
					      categorie = 'lancinant';
 | 
				
			||||||
 | 
					      name = it.name.replace('Désir lancinant : ', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (Grammar.toLowerCaseNoAccent(name).includes('idee fixe')) {
 | 
				
			||||||
 | 
					      categorie = 'ideefixe';
 | 
				
			||||||
 | 
					      name = it.name.replace('Idée fixe : ', '')
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      _id: it.id, name: name,
 | 
				
			||||||
 | 
					      'system.ideefixe': undefined,
 | 
				
			||||||
 | 
					      'system.lancinant': undefined,
 | 
				
			||||||
 | 
					      'system.categorie': categorie
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async migrate() {
 | 
				
			||||||
 | 
					    await this.applyItemsUpdates(items => items
 | 
				
			||||||
 | 
					      .filter(it => ['queue', 'ombre'].includes(it.type))
 | 
				
			||||||
 | 
					      .map(it => this.migrateQueue(it))
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _10_3_0_Inventaire extends Migration {
 | 
				
			||||||
 | 
					  get code() { return "migration-equipement-inventaire"; }
 | 
				
			||||||
 | 
					  get version() { return "10.3.0"; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async migrate() {
 | 
				
			||||||
 | 
					    await this.applyItemsUpdates(items => {
 | 
				
			||||||
 | 
					      return this._updatesMonnaies(items)
 | 
				
			||||||
 | 
					        .concat(this._updatesNonEquipe(items))
 | 
				
			||||||
 | 
					        .concat(this._updatesObjets(items))
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _updatesNonEquipe(items) {
 | 
				
			||||||
 | 
					    return items
 | 
				
			||||||
 | 
					      .filter(it => ['munition'].includes(it.type))
 | 
				
			||||||
 | 
					      .map(it => { return { _id: it.id, 'system.equipe': undefined } });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  _updatesObjets(items) {
 | 
				
			||||||
 | 
					    return items
 | 
				
			||||||
 | 
					      .filter(it => ['objet'].includes(it.type))
 | 
				
			||||||
 | 
					      .map(it => { return { _id: it.id, 'system.resistance': undefined, 'system.equipe': undefined } });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  _updatesMonnaies(items) {
 | 
				
			||||||
 | 
					    return items
 | 
				
			||||||
 | 
					      .filter(it => ['monnaie'].includes(it.type) && it.system.cout == undefined)
 | 
				
			||||||
 | 
					      .map(it => { return { _id: it.id, 'system.cout': it.system.valeur_deniers / 100, 'system.valeur_deniers': undefined } });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _10_3_0_FrequenceEnvironnement extends Migration {
 | 
				
			||||||
 | 
					  get code() { return "migration-frequence-resources"; }
 | 
				
			||||||
 | 
					  get version() { return "10.3.0"; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async migrate() {
 | 
				
			||||||
 | 
					    await this.applyItemsUpdates(items => items.filter(it => ['herbe', 'ingredient'].includes(it.type))
 | 
				
			||||||
 | 
					      .map(it => this._updatesFrequences(it)));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _updatesFrequences(it) {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      _id: it.id,
 | 
				
			||||||
 | 
					      'system.rarete': undefined,
 | 
				
			||||||
 | 
					      'system.environnement': [{ milieu: it.system.milieu, rarete: it.system.rarete, frequence: Environnement.getFrequenceRarete(it.system.rarete, 'frequence') }]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class Migrations {
 | 
					export class Migrations {
 | 
				
			||||||
  static getMigrations() {
 | 
					  static getMigrations() {
 | 
				
			||||||
    return [
 | 
					    return [
 | 
				
			||||||
      new _10_0_16_MigrationSortsReserve(),
 | 
					      new _10_0_16_MigrationSortsReserve(),
 | 
				
			||||||
      new _10_0_17_MigrationCompetenceCreature(),
 | 
					      new _10_0_17_MigrationCompetenceCreature(),
 | 
				
			||||||
      new _10_0_21_VehiculeStructureResistanceMax(),
 | 
					      new _10_0_21_VehiculeStructureResistanceMax(),
 | 
				
			||||||
 | 
					      new _10_0_33_MigrationNomsDraconic(),
 | 
				
			||||||
 | 
					      new _10_2_5_ArmesTirLancer(),
 | 
				
			||||||
 | 
					      new _10_2_10_DesirLancinant_IdeeFixe(),
 | 
				
			||||||
 | 
					      new _10_3_0_Inventaire(),
 | 
				
			||||||
 | 
					      new _10_3_0_FrequenceEnvironnement()
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -118,11 +284,9 @@ export class Migrations {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  migrate() {
 | 
					  migrate() {
 | 
				
			||||||
    const currentVersion = game.settings.get(
 | 
					    const currentVersion = game.settings.get(SYSTEM_RDD,"systemMigrationVersion");
 | 
				
			||||||
      SYSTEM_RDD,
 | 
					    //if (isNewerVersion(game.system.version, currentVersion)) {
 | 
				
			||||||
      "systemMigrationVersion"
 | 
					    if (true) { /* comment previous and uncomment here to test before upgrade  */
 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    if (isNewerVersion(game.system.version, currentVersion)) {
 | 
					 | 
				
			||||||
      const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
 | 
					      const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
 | 
				
			||||||
      if (migrations.length > 0) {
 | 
					      if (migrations.length > 0) {
 | 
				
			||||||
        migrations.sort((a, b) =>
 | 
					        migrations.sort((a, b) =>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@ export class Misc {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static sum() {
 | 
					  static sum() {
 | 
				
			||||||
    return (a, b) => a + b;
 | 
					    return (a, b) => Number(a) + Number(b);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static ascending(orderFunction = x => x) {
 | 
					  static ascending(orderFunction = x => x) {
 | 
				
			||||||
@@ -41,6 +41,11 @@ export class Misc {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static typeName(type, subType) {
 | 
				
			||||||
 | 
					    return subType ? game.i18n.localize(`${type.toUpperCase()}.Type${Misc.upperFirst(subType)}`)
 | 
				
			||||||
 | 
					      : '';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Converts the value to an integer, or to 0 if undefined/null/not representing integer
 | 
					   * Converts the value to an integer, or to 0 if undefined/null/not representing integer
 | 
				
			||||||
   * @param {*} value value to convert to an integer using parseInt
 | 
					   * @param {*} value value to convert to an integer using parseInt
 | 
				
			||||||
@@ -68,6 +73,19 @@ export class Misc {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static indexLowercase(list) {
 | 
				
			||||||
 | 
					    const obj = {};
 | 
				
			||||||
 | 
					    const addToObj = (map, val) => {
 | 
				
			||||||
 | 
					      const key = Grammar.toLowerCaseNoAccent(val);
 | 
				
			||||||
 | 
					      if (key && !map[key]) map[key] = val
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    list.forEach(it => addToObj(obj, it))
 | 
				
			||||||
 | 
					    return obj;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  static concat(lists) {
 | 
				
			||||||
 | 
					    return lists.reduce((a, b) => a.concat(b), []);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static classify(items, classifier = it => it.type) {
 | 
					  static classify(items, classifier = it => it.type) {
 | 
				
			||||||
    let itemsBy = {}
 | 
					    let itemsBy = {}
 | 
				
			||||||
    Misc.classifyInto(itemsBy, items, classifier)
 | 
					    Misc.classifyInto(itemsBy, items, classifier)
 | 
				
			||||||
@@ -102,7 +120,11 @@ export class Misc {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static join(params, separator = '') {
 | 
					  static join(params, separator = '') {
 | 
				
			||||||
    return params.reduce((a, b) => a + separator + b);
 | 
					    return params?.reduce(Misc.joining(separator)) ?? '';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static joining(separator = '') {
 | 
				
			||||||
 | 
					    return (a, b) => a + separator + b;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static connectedGMOrUser(ownerId = undefined) {
 | 
					  static connectedGMOrUser(ownerId = undefined) {
 | 
				
			||||||
@@ -112,13 +134,20 @@ export class Misc {
 | 
				
			|||||||
    return Misc.firstConnectedGM()?.id ?? game.user.id;
 | 
					    return Misc.firstConnectedGM()?.id ?? game.user.id;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static isRollModeHiddenToPlayer() {
 | 
				
			||||||
 | 
					      switch (game.settings.get("core", "rollMode")) {
 | 
				
			||||||
 | 
					        case CONST.DICE_ROLL_MODES.BLIND:
 | 
				
			||||||
 | 
					        case CONST.DICE_ROLL_MODES.SELF: return true;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return false
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static getActiveUser(id) {
 | 
					  static getActiveUser(id) {
 | 
				
			||||||
    return game.users.find(u => u.id == id && u.active);
 | 
					    return game.users.find(u => u.id == id && u.active);
 | 
				
			||||||
  }  
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static firstConnectedGM() {
 | 
					  static firstConnectedGM() {
 | 
				
			||||||
    return game.users.filter(u => u.isGM && u.active).sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active);
 | 
					    return game.users.filter(u => u.isGM && u.active).sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active);
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static isOwnerPlayer(actor, user=undefined) {
 | 
					  static isOwnerPlayer(actor, user=undefined) {
 | 
				
			||||||
@@ -133,7 +162,11 @@ export class Misc {
 | 
				
			|||||||
   * @returns true pour un seul utilisateur: le premier GM connecté par ordre d'id
 | 
					   * @returns true pour un seul utilisateur: le premier GM connecté par ordre d'id
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  static isUniqueConnectedGM() {
 | 
					  static isUniqueConnectedGM() {
 | 
				
			||||||
    return game.user.id == Misc.firstConnectedGM()?.id;
 | 
					    return game.user.id == Misc.firstConnectedGMId();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static firstConnectedGMId() {
 | 
				
			||||||
 | 
					    return Misc.firstConnectedGM()?.id;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -191,4 +224,4 @@ export class Misc {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return subset;
 | 
					    return subset;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,72 +1,13 @@
 | 
				
			|||||||
import { Misc } from "./misc.js"
 | 
					 | 
				
			||||||
import { RdDDice } from "./rdd-dice.js";
 | 
					import { RdDDice } from "./rdd-dice.js";
 | 
				
			||||||
 | 
					import { SystemCompendiums } from "./settings/system-compendiums.js";
 | 
				
			||||||
const poesieHautReve = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    reference: 'Le Ratier Bretonien',
 | 
					 | 
				
			||||||
    extrait: `Le courant du Fleuve
 | 
					 | 
				
			||||||
          <br>Te domine et te Porte
 | 
					 | 
				
			||||||
          <br>Avant que tu te moeuves
 | 
					 | 
				
			||||||
          <br>Combat le, ou il t'emporte`
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    reference: 'Incompatibilité, Charles Beaudelaire',
 | 
					 | 
				
			||||||
    extrait: `Et lorsque par hasard une nuée errante
 | 
					 | 
				
			||||||
          <br>Assombrit dans son vol le lac silencieux,
 | 
					 | 
				
			||||||
          <br>On croirait voir la robe ou l'ombre transparente
 | 
					 | 
				
			||||||
          <br>D'un esprit qui voyage et passe dans les cieux.`
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    reference: 'Au fleuve de Loire, Joachim du Bellay',
 | 
					 | 
				
			||||||
    extrait: `Ô de qui la vive course
 | 
					 | 
				
			||||||
          <br>Prend sa bienheureuse source,
 | 
					 | 
				
			||||||
          <br>D’une argentine fontaine,
 | 
					 | 
				
			||||||
          <br>Qui d’une fuite lointaine,
 | 
					 | 
				
			||||||
          <br>Te rends au sein fluctueux
 | 
					 | 
				
			||||||
          <br>De l’Océan monstrueux`
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    reference: 'Denis Gerfaud',
 | 
					 | 
				
			||||||
    extrait: `Et l'on peut savoir qui est le maître d'Oniros, c'est le Fleuve de l'Oubli.
 | 
					 | 
				
			||||||
            Et l'on sait qui est le créateur du Fleuve de l'Oubli, c'est Hypnos et Narcos.
 | 
					 | 
				
			||||||
            Mais l'on ne sait pas qui est le maître du Fleuve de l'Oubli,
 | 
					 | 
				
			||||||
            sinon peut-être lui-même, ou peut-être Thanatos` },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    reference: 'Denis Gerfaud',
 | 
					 | 
				
			||||||
    extrait: `Narcos est la source du Fleuve de l'Oubli et Hypnos l'embouchure
 | 
					 | 
				
			||||||
            Remonter le Fleuve est la Voie de la Nuit, la Voie du Souvenir.
 | 
					 | 
				
			||||||
            Descendre le Fleuve est la Voie du Jour, la Voie de l'Oubli`
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    reference: 'Denis Gerfaud',
 | 
					 | 
				
			||||||
    extrait: `Narcos engendre le fils dont il est la mère à l'heure du Vaisseau,
 | 
					 | 
				
			||||||
              car Oniros s'embarque pour redescendre le Fleuve
 | 
					 | 
				
			||||||
              vers son père Hypnos sur la Voie de l'Oubli`
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    reference: 'Denis Gerfaud',
 | 
					 | 
				
			||||||
    extrait: `Hypnos engendre le fils dont il est la mère à l'heure du Serpent, car
 | 
					 | 
				
			||||||
              tel les serpents, Oniros commence à remonter le Fleuve
 | 
					 | 
				
			||||||
              sur le Voie du Souvenir vers son père Narcos`
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    reference: 'Denis Gerfaud',
 | 
					 | 
				
			||||||
    extrait: `Ainsi se succèdent les Jours et les Ages.
 | 
					 | 
				
			||||||
          <br>Les jours des Dragons sont les Ages des Hommes.`
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    reference: 'Denis Gerfaud',
 | 
					 | 
				
			||||||
    extrait: `Ainsi parlent les sages:
 | 
					 | 
				
			||||||
              «Les Dragons sont créateurs de leurs rêves, mais ils ne sont pas créateurs d'Oniros
 | 
					 | 
				
			||||||
              Les Dragons ne sont pas les maîtres de leurs rêvezs, car ils ne sont pas maîtres d'Oniros.
 | 
					 | 
				
			||||||
              Nul ne sait qui est le créateur des Dragons, ni qui est leur maître.
 | 
					 | 
				
			||||||
              Mais l'on peut supposer qui est le maître du Rêve des Dragons, c'est Oniros»`
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class Poetique {
 | 
					export class Poetique {
 | 
				
			||||||
  static async getExtrait(){
 | 
					  static async getExtrait() {
 | 
				
			||||||
    return await RdDDice.rollOneOf(poesieHautReve);
 | 
					    const items = await SystemCompendiums.getItems('extrait-poetique', 'extraitpoetique')
 | 
				
			||||||
 | 
					    const selected = await RdDDice.rollOneOf(items);
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      reference: selected?.name,
 | 
				
			||||||
 | 
					      extrait: selected?.system.extrait
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,44 +0,0 @@
 | 
				
			|||||||
Le courant du Fleuve
 | 
					 | 
				
			||||||
Te domine et te Porte
 | 
					 | 
				
			||||||
Avant que tu te moeuves
 | 
					 | 
				
			||||||
Combat le, ou il t'emporte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
A vous qui faites ripaille
 | 
					 | 
				
			||||||
sourds aux damnés de la faim
 | 
					 | 
				
			||||||
à vous qui livrez
 | 
					 | 
				
			||||||
une inégale bataille
 | 
					 | 
				
			||||||
à ceux qui vous tendent la main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Ils sont tout près ! - Tenons fermée
 | 
					 | 
				
			||||||
<br>Cette salle, où nous les narguons.
 | 
					 | 
				
			||||||
<br>Quel bruit dehors ! Hideuse armée
 | 
					 | 
				
			||||||
<br>De vampires et de dragons !
 | 
					 | 
				
			||||||
<br>La poutre du toit descellée
 | 
					 | 
				
			||||||
<br>Ploie ainsi qu'une herbe mouillée,
 | 
					 | 
				
			||||||
<br>Et la vieille porte rouillée
 | 
					 | 
				
			||||||
<br>Tremble, à déraciner ses gonds !`),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
https://www.poetica.fr/poeme-1423/guy-de-maupassant-le-sommeil-du-mandarin/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Le monde est un rêve de Dragons. Nous
 | 
					 | 
				
			||||||
ne savons pas qui sont les Dragons ni à quoi
 | 
					 | 
				
			||||||
ils ressemblent, en dépit de l’antique iconographie qui les dépeint comme de gigantesques créatures ailées capables de cracher
 | 
					 | 
				
			||||||
feu et flammes. 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Car parmi les humains, autre nom lui est donné,
 | 
					 | 
				
			||||||
Nom sinistre parmi tous, nom funèbre, c'est la mort!
 | 
					 | 
				
			||||||
Un ami disparu... Thanatos est passé...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Messieurs, ne crachez pas de jurons ni d'ordure
 | 
					 | 
				
			||||||
Au visage fardé de cette pauvre impure
 | 
					 | 
				
			||||||
Que déesse Famine a par un soir d'hiver,
 | 
					 | 
				
			||||||
Contrainte à relever ses jupons en plein air.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -15,13 +15,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Common conf
 | 
					    // Common conf
 | 
				
			||||||
    let dialogConf = { content: html, title: "Editeur d'Astrologie", buttons: myButtons, default: "saveButton" };
 | 
					    let dialogConf = { content: html, title: "Editeur d'Astrologie", buttons: myButtons, default: "saveButton" };
 | 
				
			||||||
    let dialogOptions = { classes: ["rdddialog"], width: 600, height: 300, 'z-index': 99999 }  
 | 
					    let dialogOptions = { classes: ["rdd-roll-dialog"], width: 600, height: 300, 'z-index': 99999 }  
 | 
				
			||||||
    super(dialogConf, dialogOptions)
 | 
					    super(dialogConf, dialogOptions)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    this.calendrier = calendrier;
 | 
					    this.calendrier = calendrier;
 | 
				
			||||||
    this.updateData( calendrierData );
 | 
					    this.updateData( calendrierData );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */  
 | 
					  /* -------------------------------------------- */  
 | 
				
			||||||
  async resetNombreAstraux() {
 | 
					  async resetNombreAstraux() {
 | 
				
			||||||
    game.system.rdd.calendrier.resetNombreAstral();
 | 
					    game.system.rdd.calendrier.resetNombreAstral();
 | 
				
			||||||
@@ -39,15 +45,4 @@
 | 
				
			|||||||
    this.calendrierData = duplicate(calendrierData);
 | 
					    this.calendrierData = duplicate(calendrierData);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    let astrologieData = this.astrologieData;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $(function () {
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ export class RdDAstrologieJoueur extends Dialog {
 | 
				
			|||||||
      astrologie: RdDItemCompetence.findCompetence(actor.items, 'Astrologie')
 | 
					      astrologie: RdDItemCompetence.findCompetence(actor.items, 'Astrologie')
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html', dialogData);
 | 
					    const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html', dialogData);
 | 
				
			||||||
    let options = { classes: ["rdddialog"], width: 600, height: 500, 'z-index': 99999 };
 | 
					    let options = { classes: ["rdd-roll-dialog"], width: 600, height: 500, 'z-index': 99999 };
 | 
				
			||||||
    if (dialogConfig.options) {
 | 
					    if (dialogConfig.options) {
 | 
				
			||||||
      mergeObject(options, dialogConfig.options, { overwrite: true });
 | 
					      mergeObject(options, dialogConfig.options, { overwrite: true });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -29,21 +29,35 @@ export class RdDAstrologieJoueur extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  constructor(html, actor, dialogData) {
 | 
					  constructor(html, actor, dialogData) {
 | 
				
			||||||
 | 
					    const dialogConf = {
 | 
				
			||||||
    let myButtons = {
 | 
					      title: "Nombres Astraux",
 | 
				
			||||||
      saveButton: { label: "Fermer", callback: html => this.quitDialog() }
 | 
					      content: html,
 | 
				
			||||||
 | 
					      default: "saveButton",
 | 
				
			||||||
 | 
					      buttons: {
 | 
				
			||||||
 | 
					        saveButton: { label: "Fermer", callback: html => this.quitDialog() }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    const dialogOptions = { classes: ["rdd-roll-dialog"], width: 600, height: 300, 'z-index': 99999 };
 | 
				
			||||||
    // Get all n
 | 
					 | 
				
			||||||
    // Common conf
 | 
					 | 
				
			||||||
    let dialogConf = { content: html, title: "Nombres Astraux", buttons: myButtons, default: "saveButton" };
 | 
					 | 
				
			||||||
    let dialogOptions = { classes: ["rdddialog"], width: 600, height: 300, 'z-index': 99999 };
 | 
					 | 
				
			||||||
    super(dialogConf, dialogOptions);
 | 
					    super(dialogConf, dialogOptions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.actor = actor;
 | 
					    this.actor = actor;
 | 
				
			||||||
    this.dataNombreAstral = duplicate(dialogData);
 | 
					    this.dataNombreAstral = duplicate(dialogData);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find(function () {
 | 
				
			||||||
 | 
					      this.html.find("[name='diffConditions']").val(0);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('[name="jet-astrologie"]').click((event) => {
 | 
				
			||||||
 | 
					      this.requestJetAstrologie();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static organizeNombres(actor) {
 | 
					  static organizeNombres(actor) {
 | 
				
			||||||
    let itemNombres = actor.listItemsData('nombreastral');
 | 
					    let itemNombres = actor.listItemsData('nombreastral');
 | 
				
			||||||
@@ -68,8 +82,8 @@ export class RdDAstrologieJoueur extends Dialog {
 | 
				
			|||||||
      carac_vue: this.actor.system.carac['vue'].value,
 | 
					      carac_vue: this.actor.system.carac['vue'].value,
 | 
				
			||||||
      etat: this.dataNombreAstral.etat,
 | 
					      etat: this.dataNombreAstral.etat,
 | 
				
			||||||
      astrologie: this.dataNombreAstral.astrologie,
 | 
					      astrologie: this.dataNombreAstral.astrologie,
 | 
				
			||||||
      conditions: $("#diffConditions").val(),
 | 
					      conditions: this.html.find('[name="diffConditions"]').val(),
 | 
				
			||||||
      date: $("#joursAstrologie").val(),
 | 
					      date: this.html.find('[name="joursAstrologie"]').val(),
 | 
				
			||||||
      userId: game.user.id
 | 
					      userId: game.user.id
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (Misc.isUniqueConnectedGM()) {
 | 
					    if (Misc.isUniqueConnectedGM()) {
 | 
				
			||||||
@@ -87,17 +101,4 @@ export class RdDAstrologieJoueur extends Dialog {
 | 
				
			|||||||
  quitDialog() {
 | 
					  quitDialog() {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $(function () {
 | 
					 | 
				
			||||||
      $("#diffConditions").val(0);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    html.find('#jet-astrologie').click((event) => {
 | 
					 | 
				
			||||||
      this.requestJetAstrologie();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,50 +8,45 @@ export class RdDCalendrierEditeur extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  constructor(html, calendrier, calendrierData) {
 | 
					  constructor(html, calendrier, calendrierData) {
 | 
				
			||||||
 | 
					    let dialogConf = {
 | 
				
			||||||
    let myButtons = {
 | 
					      content: html,
 | 
				
			||||||
        saveButton: { label: "Enregistrer", callback: html => this.fillData() }
 | 
					      title: "Editeur de date/heure",
 | 
				
			||||||
      };
 | 
					      buttons: {
 | 
				
			||||||
 | 
					        save: { label: "Enregistrer", callback: html => this.fillData() }
 | 
				
			||||||
    // Common conf
 | 
					      },
 | 
				
			||||||
    let dialogConf = { content: html, title: "Editeur de date/heure", buttons: myButtons, default: "saveButton" };
 | 
					      default: "save"
 | 
				
			||||||
    let dialogOptions = { classes: ["rdddialog"], width: 400, height: 300, 'z-index': 99999 }  
 | 
					    };
 | 
				
			||||||
 | 
					    let dialogOptions = { classes: ["rdd-dialog-calendar-editor"], width: 400, height: 'fit-content', 'z-index': 99999 }
 | 
				
			||||||
    super(dialogConf, dialogOptions)
 | 
					    super(dialogConf, dialogOptions)
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    this.calendrier = calendrier;
 | 
					    this.calendrier = calendrier;
 | 
				
			||||||
    this.calendrierData = calendrierData; //duplicate(calendrierData);
 | 
					    this.calendrierData = calendrierData;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					    this.html.find("input[name='nomMois']").val(this.calendrierData.moisKey);
 | 
				
			||||||
 | 
					    this.html.find("select[name='nomHeure']").val(this.calendrierData.heureKey);
 | 
				
			||||||
 | 
					    this.html.find("select[name='jourMois']").val(this.calendrierData.jourMois);
 | 
				
			||||||
 | 
					    this.html.find("select[name='minutesRelative']").val(calendrierData.minutesRelative);
 | 
				
			||||||
 | 
					    this.html.find("select[name='annee']").val(this.calendrierData.annee);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  fillData( ) {
 | 
					  fillData() {
 | 
				
			||||||
    this.calendrierData.moisKey  = $("#nomMois").val();
 | 
					    this.calendrierData.annee = this.html.find("input[name='annee']").val();
 | 
				
			||||||
    this.calendrierData.heureKey = $("#nomHeure").val();
 | 
					    this.calendrierData.moisKey = this.html.find("select[name='nomMois']").val();
 | 
				
			||||||
    this.calendrierData.jourMois = $("#jourMois").val();
 | 
					    this.calendrierData.heureKey = this.html.find("select[name='nomHeure']").val();
 | 
				
			||||||
    this.calendrierData.minutesRelative = $("#minutesRelative").val();
 | 
					    this.calendrierData.jourMois = this.html.find("select[name='jourMois']").val();
 | 
				
			||||||
    
 | 
					    this.calendrierData.minutesRelative = this.html.find("select[name='minutesRelative']").val();
 | 
				
			||||||
    console.log("UPDATE  ", this.calendrierData);
 | 
					
 | 
				
			||||||
    this.calendrier.saveEditeur( this.calendrierData )
 | 
					    this.calendrier.saveEditeur(this.calendrierData)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  updateData( calendrierData ) {
 | 
					  updateData(calendrierData) {
 | 
				
			||||||
    this.calendrierData = duplicate(calendrierData);
 | 
					    this.calendrierData = duplicate(calendrierData);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    let calendrierData = this.calendrierData;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $(function () {
 | 
					 | 
				
			||||||
      console.log(calendrierData);
 | 
					 | 
				
			||||||
      $("#nomMois").val(calendrierData.moisKey);
 | 
					 | 
				
			||||||
      $("#nomHeure").val(calendrierData.heureKey);
 | 
					 | 
				
			||||||
      $("#jourMois").val(calendrierData.jourMois);
 | 
					 | 
				
			||||||
      $("#minutesRelative").val(calendrierData.minutesRelative);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,23 +8,24 @@ import { Grammar } from "./grammar.js";
 | 
				
			|||||||
import { RdDDice } from "./rdd-dice.js";
 | 
					import { RdDDice } from "./rdd-dice.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
 | 
					import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
 | 
				
			||||||
 | 
					import { DialogChronologie } from "./dialog-chronologie.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/'
 | 
					const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/'
 | 
				
			||||||
const heuresList = ["vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant"];
 | 
					const heuresList = ["vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant"];
 | 
				
			||||||
const heuresDef = {
 | 
					const heuresDef = {
 | 
				
			||||||
  "vaisseau": { label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' },
 | 
					  "vaisseau": {key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' },
 | 
				
			||||||
  "sirene": { label: "Sirène", lettreFont: 'i', saison: "printemps", heure: 1, icon: 'hd02.svg' },
 | 
					  "sirene": { key: "sirene", label: "Sirène", lettreFont: 'i', saison: "printemps", heure: 1, icon: 'hd02.svg' },
 | 
				
			||||||
  "faucon": { label: "Faucon", lettreFont: 'f', saison: "printemps", heure: 2, icon: 'hd03.svg' },
 | 
					  "faucon": { key: "faucon", label: "Faucon", lettreFont: 'f', saison: "printemps", heure: 2, icon: 'hd03.svg' },
 | 
				
			||||||
  "couronne": { label: "Couronne", lettreFont: '', saison: "ete", heure: 3, icon: 'hd04.svg' },
 | 
					  "couronne": { key: "couronne", label: "Couronne", lettreFont: '', saison: "ete", heure: 3, icon: 'hd04.svg' },
 | 
				
			||||||
  "dragon": { label: "Dragon", lettreFont: 'd', saison: "ete", heure: 4, icon: 'hd05.svg' },
 | 
					  "dragon": { key: "dragon", label: "Dragon", lettreFont: 'd', saison: "ete", heure: 4, icon: 'hd05.svg' },
 | 
				
			||||||
  "epees": { label: "Epées", lettreFont: 'e', saison: "ete", heure: 5, icon: 'hd06.svg' },
 | 
					  "epees": { key: "epees", label: "Epées", lettreFont: 'e', saison: "ete", heure: 5, icon: 'hd06.svg' },
 | 
				
			||||||
  "lyre": { label: "Lyre", lettreFont: 'l', saison: "automne", heure: 6, icon: 'hd07.svg' },
 | 
					  "lyre": { key: "lyre", label: "Lyre", lettreFont: 'l', saison: "automne", heure: 6, icon: 'hd07.svg' },
 | 
				
			||||||
  "serpent": { label: "Serpent", lettreFont: 's', saison: "automne", heure: 7, icon: 'hd08.svg' },
 | 
					  "serpent": { key: "serpent", label: "Serpent", lettreFont: 's', saison: "automne", heure: 7, icon: 'hd08.svg' },
 | 
				
			||||||
  "poissonacrobate": { label: "Poisson Acrobate", lettreFont: 'p', saison: "automne", heure: 8, icon: 'hd09.svg' },
 | 
					  "poissonacrobate": { key: "poissonacrobate", label: "Poisson Acrobate", lettreFont: 'p', saison: "automne", heure: 8, icon: 'hd09.svg' },
 | 
				
			||||||
  "araignee": { label: "Araignée", lettreFont: 'a', saison: "hiver", heure: 9, icon: 'hd10.svg' },
 | 
					  "araignee": { key: "araignee", label: "Araignée", lettreFont: 'a', saison: "hiver", heure: 9, icon: 'hd10.svg' },
 | 
				
			||||||
  "roseau": { label: "Roseau", lettreFont: 'r', saison: "hiver", heure: 10, icon: 'hd11.svg' },
 | 
					  "roseau": { key: "roseau", label: "Roseau", lettreFont: 'r', saison: "hiver", heure: 10, icon: 'hd11.svg' },
 | 
				
			||||||
  "chateaudormant": { label: "Château Dormant", lettreFont: 'c', saison: "hiver", heure: 11, icon: 'hd12.svg' }
 | 
					  "chateaudormant": { key: "chateaudormant", label: "Château Dormant", lettreFont: 'c', saison: "hiver", heure: 11, icon: 'hd12.svg' }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const saisonsDef = {
 | 
					const saisonsDef = {
 | 
				
			||||||
  "printemps": { label: "Printemps" },
 | 
					  "printemps": { label: "Printemps" },
 | 
				
			||||||
@@ -42,6 +43,14 @@ const MAX_NOMBRE_ASTRAL = 12;
 | 
				
			|||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
export class RdDCalendrier extends Application {
 | 
					export class RdDCalendrier extends Application {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get defaultOptions() {
 | 
				
			||||||
 | 
					    return mergeObject(super.defaultOptions, {
 | 
				
			||||||
 | 
					      template: "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html",
 | 
				
			||||||
 | 
					      popOut: false,
 | 
				
			||||||
 | 
					      resizable: false
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static createCalendrierPos() {
 | 
					  static createCalendrierPos() {
 | 
				
			||||||
    return { top: 200, left: 200 };
 | 
					    return { top: 200, left: 200 };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -51,21 +60,50 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
    return Object.values(heuresDef).find(h => h.heure == chiffre);
 | 
					    return Object.values(heuresDef).find(h => h.heure == chiffre);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getSigneAs(key, value) {
 | 
				
			||||||
 | 
					    const heure = (typeof value == 'string' || typeof value == 'number') && Number.isInteger(Number(value))
 | 
				
			||||||
 | 
					      ? Number(value)
 | 
				
			||||||
 | 
					      : (typeof value == 'string') ? RdDCalendrier.getChiffreFromSigne(value)
 | 
				
			||||||
 | 
					      : undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (heure != undefined && ['key', 'label', 'lettreFont', 'saison', 'heure', 'icon'].includes(key)) {
 | 
				
			||||||
 | 
					      return RdDCalendrier.getDefSigne(heure)[key]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (heure != undefined && ['webp'].includes(key)) {
 | 
				
			||||||
 | 
					      return RdDCalendrier.getDefSigne(heure)['icon'].replace('svg', 'webp');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    console.error(`Appel à getSigneAs('${key}', ${value}) avec une clé/heure incorrects`);
 | 
				
			||||||
 | 
					    return value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  static getChiffreFromSigne(signe) {
 | 
					  static getChiffreFromSigne(signe) {
 | 
				
			||||||
    return heuresList.indexOf(signe);
 | 
					    return heuresList.indexOf(signe);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static getCalendrier(index) {
 | 
					  static createCalendrierInitial() {
 | 
				
			||||||
    let calendrier = {
 | 
					    return {
 | 
				
			||||||
 | 
					      heureRdD: 0,
 | 
				
			||||||
 | 
					      minutesRelative: 0,
 | 
				
			||||||
 | 
					      indexJour: 0,
 | 
				
			||||||
 | 
					      annee: 0,
 | 
				
			||||||
 | 
					      moisRdD: 0,
 | 
				
			||||||
 | 
					      moisLabel: heuresDef["vaisseau"].label,
 | 
				
			||||||
 | 
					      jour: 0
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getCalendrier(index) {
 | 
				
			||||||
 | 
					    index = index ?? this.getCurrentDayIndex();
 | 
				
			||||||
 | 
					    const mois = Math.floor(index / RDD_JOUR_PAR_MOIS) % RDD_MOIS_PAR_AN;
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
      heureRdD: 0, // Index dans heuresList / heuresDef[x].heure
 | 
					      heureRdD: 0, // Index dans heuresList / heuresDef[x].heure
 | 
				
			||||||
      minutesRelative: 0,
 | 
					      minutesRelative: 0,
 | 
				
			||||||
      indexJour: index,
 | 
					      indexJour: index,
 | 
				
			||||||
      annee: Math.floor(index / (RDD_JOUR_PAR_MOIS * RDD_MOIS_PAR_AN)),
 | 
					      annee: Math.floor(index / (RDD_JOUR_PAR_MOIS * RDD_MOIS_PAR_AN)),
 | 
				
			||||||
      moisRdD: Math.floor(index / RDD_JOUR_PAR_MOIS) % RDD_MOIS_PAR_AN,
 | 
					      moisRdD: RdDCalendrier.getDefSigne(mois).heure,
 | 
				
			||||||
 | 
					      moisLabel: RdDCalendrier.getDefSigne(mois).label,
 | 
				
			||||||
      jour: (index % RDD_JOUR_PAR_MOIS) // Le calendrier stocke le jour en 0-27, mais en 1-28 à l'affichage
 | 
					      jour: (index % RDD_JOUR_PAR_MOIS) // Le calendrier stocke le jour en 0-27, mais en 1-28 à l'affichage
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    calendrier.moisLabel = RdDCalendrier.getDefSigne(calendrier.moisRdD).label;
 | 
					 | 
				
			||||||
    return calendrier;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
@@ -78,7 +116,7 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Calendrier
 | 
					    // Calendrier
 | 
				
			||||||
    this.calendrier = duplicate(game.settings.get(SYSTEM_RDD, "calendrier") ?? RdDCalendrier.getCalendrier(0));
 | 
					    this.calendrier = duplicate(game.settings.get(SYSTEM_RDD, "calendrier") ?? RdDCalendrier.createCalendrierInitial());
 | 
				
			||||||
    this.calendrier.annee = this.calendrier.annee ?? Math.floor((this.calendrier.moisRdD ?? 0) / RDD_MOIS_PAR_AN);
 | 
					    this.calendrier.annee = this.calendrier.annee ?? Math.floor((this.calendrier.moisRdD ?? 0) / RDD_MOIS_PAR_AN);
 | 
				
			||||||
    this.calendrier.moisRdD = (this.calendrier.moisRdD ?? 0) % RDD_MOIS_PAR_AN;
 | 
					    this.calendrier.moisRdD = (this.calendrier.moisRdD ?? 0) % RDD_MOIS_PAR_AN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -86,34 +124,117 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
      game.settings.set(SYSTEM_RDD, "calendrier", this.calendrier);
 | 
					      game.settings.set(SYSTEM_RDD, "calendrier", this.calendrier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.listeNombreAstral = this.getListeNombreAstral();
 | 
					      this.listeNombreAstral = this.getListeNombreAstral();
 | 
				
			||||||
      this.rebuildListeNombreAstral(false); // Ensure always up-to-date
 | 
					      this.rebuildListeNombreAstral(HIDE_DICE); // Ensure always up-to-date
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    console.log(this.calendrier, this.calendrierPos, this.listeNombreAstral);
 | 
					    console.log('RdDCalendrier.constructor()', this.calendrier, this.calendrierPos, this.listeNombreAstral);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  /** @override */
 | 
				
			||||||
 | 
					  async activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.updateDisplay();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('.ajout-chronologie').click(ev => DialogChronologie.create());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('.calendar-btn-edit').click(ev => {
 | 
				
			||||||
 | 
					      ev.preventDefault();
 | 
				
			||||||
 | 
					      this.showCalendarEditor();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('.astrologie-btn-edit').click(ev => {
 | 
				
			||||||
 | 
					      ev.preventDefault();
 | 
				
			||||||
 | 
					      this.showAstrologieEditor();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('#calendar-move-handle').mousedown(ev => {
 | 
				
			||||||
 | 
					      ev.preventDefault();
 | 
				
			||||||
 | 
					      ev = ev || window.event;
 | 
				
			||||||
 | 
					      let isRightMB = false;
 | 
				
			||||||
 | 
					      if ("which" in ev) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
 | 
				
			||||||
 | 
					        isRightMB = ev.which == 3;
 | 
				
			||||||
 | 
					      } else if ("button" in ev) { // IE, Opera 
 | 
				
			||||||
 | 
					        isRightMB = ev.button == 2;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (!isRightMB) {
 | 
				
			||||||
 | 
					        dragElement(document.getElementById("calendar-time-container"));
 | 
				
			||||||
 | 
					        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function dragElement(elmnt) {
 | 
				
			||||||
 | 
					          elmnt.onmousedown = dragMouseDown;
 | 
				
			||||||
 | 
					          function dragMouseDown(e) {
 | 
				
			||||||
 | 
					            e = e || window.event;
 | 
				
			||||||
 | 
					            e.preventDefault();
 | 
				
			||||||
 | 
					            pos3 = e.clientX;
 | 
				
			||||||
 | 
					            pos4 = e.clientY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            document.onmouseup = closeDragElement;
 | 
				
			||||||
 | 
					            document.onmousemove = elementDrag;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          function elementDrag(e) {
 | 
				
			||||||
 | 
					            e = e || window.event;
 | 
				
			||||||
 | 
					            e.preventDefault();
 | 
				
			||||||
 | 
					            // calculate the new cursor position:
 | 
				
			||||||
 | 
					            pos1 = pos3 - e.clientX;
 | 
				
			||||||
 | 
					            pos2 = pos4 - e.clientY;
 | 
				
			||||||
 | 
					            pos3 = e.clientX;
 | 
				
			||||||
 | 
					            pos4 = e.clientY;
 | 
				
			||||||
 | 
					            // set the element's new position:
 | 
				
			||||||
 | 
					            elmnt.style.bottom = undefined
 | 
				
			||||||
 | 
					            elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
 | 
				
			||||||
 | 
					            elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          function closeDragElement() {
 | 
				
			||||||
 | 
					            // stop moving when mouse button is released:
 | 
				
			||||||
 | 
					            elmnt.onmousedown = undefined;
 | 
				
			||||||
 | 
					            document.onmouseup = undefined;
 | 
				
			||||||
 | 
					            document.onmousemove = undefined;
 | 
				
			||||||
 | 
					            let xPos = (elmnt.offsetLeft - pos1) > window.innerWidth ? window.innerWidth - 200 : (elmnt.offsetLeft - pos1);
 | 
				
			||||||
 | 
					            let yPos = (elmnt.offsetTop - pos2) > window.innerHeight - 20 ? window.innerHeight - 100 : (elmnt.offsetTop - pos2)
 | 
				
			||||||
 | 
					            xPos = xPos < 0 ? 0 : xPos;
 | 
				
			||||||
 | 
					            yPos = yPos < 0 ? 0 : yPos;
 | 
				
			||||||
 | 
					            if (xPos != (elmnt.offsetLeft - pos1) || yPos != (elmnt.offsetTop - pos2)) {
 | 
				
			||||||
 | 
					              elmnt.style.top = (yPos) + "px";
 | 
				
			||||||
 | 
					              elmnt.style.left = (xPos) + "px";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            game.system.rdd.calendrier.calendrierPos.top = yPos;
 | 
				
			||||||
 | 
					            game.system.rdd.calendrier.calendrierPos.left = xPos;
 | 
				
			||||||
 | 
					            if (game.user.isGM) {
 | 
				
			||||||
 | 
					              game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else if (isRightMB) {
 | 
				
			||||||
 | 
					        game.system.rdd.calendrier.calendrierPos.top = 200;
 | 
				
			||||||
 | 
					        game.system.rdd.calendrier.calendrierPos.left = 200;
 | 
				
			||||||
 | 
					        if (game.user.isGM) {
 | 
				
			||||||
 | 
					          game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.setPos(game.system.rdd.calendrier.calendrierPos);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  getListeNombreAstral() {
 | 
					  getListeNombreAstral() {
 | 
				
			||||||
    return game.settings.get(SYSTEM_RDD, "liste-nombre-astral") ?? [];
 | 
					    return game.settings.get(SYSTEM_RDD, "liste-nombre-astral") ?? [];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static get defaultOptions() {
 | 
					 | 
				
			||||||
    return mergeObject(super.defaultOptions, {
 | 
					 | 
				
			||||||
      template: "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html",
 | 
					 | 
				
			||||||
      popOut: false,
 | 
					 | 
				
			||||||
      resizable: false
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  getDateFromIndex(index) {
 | 
					  getDateFromIndex(index) {
 | 
				
			||||||
    const date = RdDCalendrier.getCalendrier(index ?? this.getCurrentDayIndex());
 | 
					    const dateRdD = this.getCalendrier(index);
 | 
				
			||||||
    return (date.jour + 1) + ' ' + RdDCalendrier.getDefSigne(date.moisRdD).label;
 | 
					    return (dateRdD.jour + 1) + ' ' + dateRdD.moisLabel;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  getNumericDateFromIndex(index = undefined) {
 | 
					  getDayMonthFromIndex(index = undefined) {
 | 
				
			||||||
    const dateRdD = RdDCalendrier.getCalendrier(index ?? this.getCurrentDayIndex());
 | 
					    const dateRdD = this.getCalendrier(index);
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      day: dateRdD.jour + 1,
 | 
					      day: dateRdD.jour + 1,
 | 
				
			||||||
      month: heuresList[dateRdD.moisRdD]
 | 
					      month: heuresList[dateRdD.moisRdD]
 | 
				
			||||||
@@ -180,14 +301,14 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  getNombreAstral(indexDate) {
 | 
					  getNombreAstral(indexDate) {
 | 
				
			||||||
    let astralData = this.getListeNombreAstral().find((nombreAstral, i) => nombreAstral.index == indexDate);
 | 
					    const listNombreAstral = this.getListeNombreAstral();
 | 
				
			||||||
 | 
					    let astralData = listNombreAstral.find((nombreAstral, i) => nombreAstral.index == indexDate);
 | 
				
			||||||
    return astralData?.nombreAstral;
 | 
					    return astralData?.nombreAstral;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async rebuildListeNombreAstral(showDice = SHOW_DICE) {
 | 
					  async rebuildListeNombreAstral(showDice = HIDE_DICE) {
 | 
				
			||||||
    if (Misc.isUniqueConnectedGM()) {
 | 
					    if (Misc.isUniqueConnectedGM()) {
 | 
				
			||||||
      console.log("rebuildListeNombreAstral", showDice);
 | 
					 | 
				
			||||||
      let jourCourant = this.getCurrentDayIndex();
 | 
					      let jourCourant = this.getCurrentDayIndex();
 | 
				
			||||||
      let newList = [];
 | 
					      let newList = [];
 | 
				
			||||||
      for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) {
 | 
					      for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) {
 | 
				
			||||||
@@ -199,9 +320,8 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
          newList[i] = await this.ajouterNombreAstral(dayIndex, showDice);
 | 
					          newList[i] = await this.ajouterNombreAstral(dayIndex, showDice);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      //console.log("SAVE list", newList, jourCourant);
 | 
					      game.settings.set(SYSTEM_RDD, "liste-nombre-astral", newList);
 | 
				
			||||||
      this.listeNombreAstral = newList;
 | 
					      this.listeNombreAstral = newList;
 | 
				
			||||||
      game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.listeNombreAstral);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -264,7 +384,7 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async incrementerJour() {
 | 
					  async incrementerJour() {
 | 
				
			||||||
    const index = this.getCurrentDayIndex() + 1;
 | 
					    const index = this.getCurrentDayIndex() + 1;
 | 
				
			||||||
    this.calendrier = RdDCalendrier.getCalendrier(index);
 | 
					    this.calendrier = this.getCalendrier(index);
 | 
				
			||||||
    await this.rebuildListeNombreAstral();
 | 
					    await this.rebuildListeNombreAstral();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -286,18 +406,15 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  fillCalendrierData(formData = {}) {
 | 
					  fillCalendrierData(formData = {}) {
 | 
				
			||||||
    console.log(this.calendrier);
 | 
					    const mois = RdDCalendrier.getDefSigne(this.calendrier.moisRdD);
 | 
				
			||||||
    let moisKey = heuresList[this.calendrier.moisRdD];
 | 
					    const heure = RdDCalendrier.getDefSigne(this.calendrier.heureRdD);
 | 
				
			||||||
    let heureKey = heuresList[this.calendrier.heureRdD];
 | 
					    console.log('fillCalendrierData', this.calendrier, mois, heure);
 | 
				
			||||||
    console.log(moisKey, heureKey);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const mois = heuresDef[moisKey];
 | 
					    formData.heureKey = heure.key;
 | 
				
			||||||
    const heure = heuresDef[heureKey];
 | 
					    formData.moisKey = mois.key;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    formData.heureKey = heureKey;
 | 
					 | 
				
			||||||
    formData.moisKey = moisKey;
 | 
					 | 
				
			||||||
    formData.jourMois = this.calendrier.jour + 1;
 | 
					    formData.jourMois = this.calendrier.jour + 1;
 | 
				
			||||||
    formData.nomMois = mois.label; // heures et mois nommés identiques
 | 
					    formData.nomMois = mois.label; // heures et mois nommés identiques
 | 
				
			||||||
 | 
					    formData.annee = this.calendrier.annee;
 | 
				
			||||||
    formData.iconMois = dossierIconesHeures + mois.icon;
 | 
					    formData.iconMois = dossierIconesHeures + mois.icon;
 | 
				
			||||||
    formData.nomHeure = heure.label;
 | 
					    formData.nomHeure = heure.label;
 | 
				
			||||||
    formData.iconHeure = dossierIconesHeures + heure.icon;
 | 
					    formData.iconHeure = dossierIconesHeures + heure.icon;
 | 
				
			||||||
@@ -428,7 +545,7 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
      function check() {
 | 
					      function check() {
 | 
				
			||||||
        let elmnt = document.getElementById("calendar-time-container");
 | 
					        let elmnt = document.getElementById("calendar-time-container");
 | 
				
			||||||
        if (elmnt) {
 | 
					        if (elmnt) {
 | 
				
			||||||
          elmnt.style.bottom = null;
 | 
					          elmnt.style.bottom = undefined;
 | 
				
			||||||
          let xPos = (pos.left) > window.innerWidth ? window.innerWidth - 200 : pos.left;
 | 
					          let xPos = (pos.left) > window.innerWidth ? window.innerWidth - 200 : pos.left;
 | 
				
			||||||
          let yPos = (pos.top) > window.innerHeight - 20 ? window.innerHeight - 100 : pos.top;
 | 
					          let yPos = (pos.top) > window.innerHeight - 20 ? window.innerHeight - 100 : pos.top;
 | 
				
			||||||
          elmnt.style.top = (yPos) + "px";
 | 
					          elmnt.style.top = (yPos) + "px";
 | 
				
			||||||
@@ -446,7 +563,7 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
  updateDisplay() {
 | 
					  updateDisplay() {
 | 
				
			||||||
    let calendrier = this.fillCalendrierData();
 | 
					    let calendrier = this.fillCalendrierData();
 | 
				
			||||||
    // Rebuild text du calendrier
 | 
					    // Rebuild text du calendrier
 | 
				
			||||||
    let dateHTML = `Jour ${calendrier.jourMois} de ${calendrier.nomMois} (${calendrier.nomSaison})`
 | 
					    let dateHTML = `${calendrier.jourMois} ${calendrier.nomMois} ${calendrier.annee} (${calendrier.nomSaison})`
 | 
				
			||||||
    if (game.user.isGM) {
 | 
					    if (game.user.isGM) {
 | 
				
			||||||
      dateHTML = dateHTML + " - NA: " + (this.getCurrentNombreAstral() ?? "indéterminé");
 | 
					      dateHTML = dateHTML + " - NA: " + (this.getCurrentNombreAstral() ?? "indéterminé");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -469,6 +586,7 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
    this.calendrier.minutesRelative = Number(calendrierData.minutesRelative);
 | 
					    this.calendrier.minutesRelative = Number(calendrierData.minutesRelative);
 | 
				
			||||||
    this.calendrier.jour = Number(calendrierData.jourMois) - 1;
 | 
					    this.calendrier.jour = Number(calendrierData.jourMois) - 1;
 | 
				
			||||||
    this.calendrier.moisRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.moisKey);
 | 
					    this.calendrier.moisRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.moisKey);
 | 
				
			||||||
 | 
					    this.calendrier.annee = Number(calendrierData.annee);
 | 
				
			||||||
    this.calendrier.heureRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.heureKey);
 | 
					    this.calendrier.heureRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.heureKey);
 | 
				
			||||||
    game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier));
 | 
					    game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -528,95 +646,4 @@ export class RdDCalendrier extends Application {
 | 
				
			|||||||
    astrologieEditeur.updateData(calendrierData);
 | 
					    astrologieEditeur.updateData(calendrierData);
 | 
				
			||||||
    astrologieEditeur.render(true);
 | 
					    astrologieEditeur.render(true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  /** @override */
 | 
					 | 
				
			||||||
  async activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.updateDisplay();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    html.find('.calendar-btn-edit').click(ev => {
 | 
					 | 
				
			||||||
      ev.preventDefault();
 | 
					 | 
				
			||||||
      this.showCalendarEditor();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    html.find('.astrologie-btn-edit').click(ev => {
 | 
					 | 
				
			||||||
      ev.preventDefault();
 | 
					 | 
				
			||||||
      this.showAstrologieEditor();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    html.find('#calendar-move-handle').mousedown(ev => {
 | 
					 | 
				
			||||||
      ev.preventDefault();
 | 
					 | 
				
			||||||
      ev = ev || window.event;
 | 
					 | 
				
			||||||
      let isRightMB = false;
 | 
					 | 
				
			||||||
      if ("which" in ev) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
 | 
					 | 
				
			||||||
        isRightMB = ev.which == 3;
 | 
					 | 
				
			||||||
      } else if ("button" in ev) { // IE, Opera 
 | 
					 | 
				
			||||||
        isRightMB = ev.button == 2;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (!isRightMB) {
 | 
					 | 
				
			||||||
        dragElement(document.getElementById("calendar-time-container"));
 | 
					 | 
				
			||||||
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        function dragElement(elmnt) {
 | 
					 | 
				
			||||||
          elmnt.onmousedown = dragMouseDown;
 | 
					 | 
				
			||||||
          function dragMouseDown(e) {
 | 
					 | 
				
			||||||
            e = e || window.event;
 | 
					 | 
				
			||||||
            e.preventDefault();
 | 
					 | 
				
			||||||
            pos3 = e.clientX;
 | 
					 | 
				
			||||||
            pos4 = e.clientY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            document.onmouseup = closeDragElement;
 | 
					 | 
				
			||||||
            document.onmousemove = elementDrag;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          function elementDrag(e) {
 | 
					 | 
				
			||||||
            e = e || window.event;
 | 
					 | 
				
			||||||
            e.preventDefault();
 | 
					 | 
				
			||||||
            // calculate the new cursor position:
 | 
					 | 
				
			||||||
            pos1 = pos3 - e.clientX;
 | 
					 | 
				
			||||||
            pos2 = pos4 - e.clientY;
 | 
					 | 
				
			||||||
            pos3 = e.clientX;
 | 
					 | 
				
			||||||
            pos4 = e.clientY;
 | 
					 | 
				
			||||||
            // set the element's new position:
 | 
					 | 
				
			||||||
            elmnt.style.bottom = null
 | 
					 | 
				
			||||||
            elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
 | 
					 | 
				
			||||||
            elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          function closeDragElement() {
 | 
					 | 
				
			||||||
            // stop moving when mouse button is released:
 | 
					 | 
				
			||||||
            elmnt.onmousedown = null;
 | 
					 | 
				
			||||||
            document.onmouseup = null;
 | 
					 | 
				
			||||||
            document.onmousemove = null;
 | 
					 | 
				
			||||||
            let xPos = (elmnt.offsetLeft - pos1) > window.innerWidth ? window.innerWidth - 200 : (elmnt.offsetLeft - pos1);
 | 
					 | 
				
			||||||
            let yPos = (elmnt.offsetTop - pos2) > window.innerHeight - 20 ? window.innerHeight - 100 : (elmnt.offsetTop - pos2)
 | 
					 | 
				
			||||||
            xPos = xPos < 0 ? 0 : xPos;
 | 
					 | 
				
			||||||
            yPos = yPos < 0 ? 0 : yPos;
 | 
					 | 
				
			||||||
            if (xPos != (elmnt.offsetLeft - pos1) || yPos != (elmnt.offsetTop - pos2)) {
 | 
					 | 
				
			||||||
              elmnt.style.top = (yPos) + "px";
 | 
					 | 
				
			||||||
              elmnt.style.left = (xPos) + "px";
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            game.system.rdd.calendrier.calendrierPos.top = yPos;
 | 
					 | 
				
			||||||
            game.system.rdd.calendrier.calendrierPos.left = xPos;
 | 
					 | 
				
			||||||
            if (game.user.isGM) {
 | 
					 | 
				
			||||||
              game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else if (isRightMB) {
 | 
					 | 
				
			||||||
        game.system.rdd.calendrier.calendrierPos.top = 200;
 | 
					 | 
				
			||||||
        game.system.rdd.calendrier.calendrierPos.left = 200;
 | 
					 | 
				
			||||||
        if (game.user.isGM) {
 | 
					 | 
				
			||||||
          game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        this.setPos(game.system.rdd.calendrier.calendrierPos);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -52,6 +52,11 @@ export class RdDCarac {
 | 
				
			|||||||
    return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/);
 | 
					    return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static isActionPhysique(selectedCarac) {
 | 
				
			||||||
 | 
					    return !selectedCarac ||
 | 
				
			||||||
 | 
					      selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static isIgnoreEtatGeneral(rollData) {
 | 
					  static isIgnoreEtatGeneral(rollData) {
 | 
				
			||||||
    const selectedCarac = rollData.selectedCarac;
 | 
					    const selectedCarac = rollData.selectedCarac;
 | 
				
			||||||
    return !selectedCarac ||
 | 
					    return !selectedCarac ||
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
import { ChatUtility } from "./chat-utility.js";
 | 
					import { ChatUtility } from "./chat-utility.js";
 | 
				
			||||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
 | 
					import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
 | 
				
			||||||
 | 
					import { DialogSelectTarget } from "./dialog-select-target.js";
 | 
				
			||||||
import { Grammar } from "./grammar.js";
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
import { RdDItemArme } from "./item-arme.js";
 | 
					import { RdDItemArme } from "./item-arme.js";
 | 
				
			||||||
import { RdDItemCompetence } from "./item-competence.js";
 | 
					import { RdDItemCompetence } from "./item-competence.js";
 | 
				
			||||||
@@ -9,8 +10,9 @@ import { RdDBonus } from "./rdd-bonus.js";
 | 
				
			|||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
					import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
				
			||||||
import { RdDRoll } from "./rdd-roll.js";
 | 
					import { RdDRoll } from "./rdd-roll.js";
 | 
				
			||||||
import { RdDRollTables } from "./rdd-rolltables.js";
 | 
					import { RdDRollTables } from "./rdd-rolltables.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
import { STATUSES } from "./status-effects.js";
 | 
					import { STATUSES } from "./settings/status-effects.js";
 | 
				
			||||||
 | 
					import { Targets } from "./targets.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
const premierRoundInit = [
 | 
					const premierRoundInit = [
 | 
				
			||||||
@@ -82,7 +84,6 @@ export class RdDCombatManager extends Combat {
 | 
				
			|||||||
    console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
 | 
					    console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ids = typeof ids === "string" ? [ids] : ids;
 | 
					    ids = typeof ids === "string" ? [ids] : ids;
 | 
				
			||||||
    const currentId = this.combatant._id;
 | 
					 | 
				
			||||||
    // calculate initiative
 | 
					    // calculate initiative
 | 
				
			||||||
    for (let cId = 0; cId < ids.length; cId++) {
 | 
					    for (let cId = 0; cId < ids.length; cId++) {
 | 
				
			||||||
      const combatant = this.combatants.get(ids[cId]);
 | 
					      const combatant = this.combatants.get(ids[cId]);
 | 
				
			||||||
@@ -101,14 +102,14 @@ export class RdDCombatManager extends Combat {
 | 
				
			|||||||
            const carac = combatant.actor.system.carac[competence.system.defaut_carac].value;
 | 
					            const carac = combatant.actor.system.carac[competence.system.defaut_carac].value;
 | 
				
			||||||
            const niveau = competence.system.niveau;
 | 
					            const niveau = competence.system.niveau;
 | 
				
			||||||
            const bonusEcaille = (armeCombat?.system.magique) ? armeCombat.system.ecaille_efficacite : 0;
 | 
					            const bonusEcaille = (armeCombat?.system.magique) ? armeCombat.system.ecaille_efficacite : 0;
 | 
				
			||||||
            rollFormula = RdDCombatManager.formuleInitiative(2,  carac, niveau, bonusEcaille);
 | 
					            rollFormula = RdDCombatManager.formuleInitiative(2, carac, niveau, bonusEcaille);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      //console.log("Combatat", c);
 | 
					      //console.log("Combatat", c);
 | 
				
			||||||
      const roll = combatant.getInitiativeRoll(rollFormula);
 | 
					      const roll = combatant.getInitiativeRoll(rollFormula);
 | 
				
			||||||
      if ( !roll.total) {
 | 
					      if (!roll.total) {
 | 
				
			||||||
        roll.evaluate( {async: false});
 | 
					        roll.evaluate({ async: false });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (roll.total <= 0) roll.total = 0.00;
 | 
					      if (roll.total <= 0) roll.total = 0.00;
 | 
				
			||||||
      console.log("Compute init for", rollFormula, roll.total, combatant);
 | 
					      console.log("Compute init for", rollFormula, roll.total, combatant);
 | 
				
			||||||
@@ -121,7 +122,7 @@ export class RdDCombatManager extends Combat {
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
          speaker: {
 | 
					          speaker: {
 | 
				
			||||||
            scene: canvas.scene._id,
 | 
					            scene: canvas.scene._id,
 | 
				
			||||||
            actor: combatant.actor ? combatant.actor._id : null,
 | 
					            actor: combatant.actor?._id,
 | 
				
			||||||
            token: combatant.token._id,
 | 
					            token: combatant.token._id,
 | 
				
			||||||
            alias: combatant.token.name,
 | 
					            alias: combatant.token.name,
 | 
				
			||||||
            sound: CONFIG.sounds.dice,
 | 
					            sound: CONFIG.sounds.dice,
 | 
				
			||||||
@@ -151,79 +152,101 @@ export class RdDCombatManager extends Combat {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  /** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main */
 | 
					  /** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main / lancer */
 | 
				
			||||||
  static listActionsArmes(armes, competences, carac) {
 | 
					  static listActionsArmes(armes, competences, carac) {
 | 
				
			||||||
    // Gestion des armes 1/2 mains
 | 
					    let actions = [];
 | 
				
			||||||
    let actionsArme = [];
 | 
					 | 
				
			||||||
    for (const arme of armes) {
 | 
					    for (const arme of armes) {
 | 
				
			||||||
      let action = duplicate(arme)
 | 
					      if (arme.system.equipe) {
 | 
				
			||||||
      if (action.system.equipe) {
 | 
					        const dommages = arme.system.dommages.toString();
 | 
				
			||||||
        let compData = competences.find(c => c.name == action.system.competence)
 | 
					        const tableauDommages = dommages.includes("/") ? dommages.split("/") : [dommages, dommages];
 | 
				
			||||||
 | 
					        if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) {
 | 
				
			||||||
        actionsArme.push(action);
 | 
					          ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
 | 
				
			||||||
        action.action = 'attaque';
 | 
					        }
 | 
				
			||||||
        action.system.dommagesReels = Number(action.system.dommages);
 | 
					        console.log(">>>>", arme)
 | 
				
			||||||
        action.system.niveau = compData.system.niveau;
 | 
					        if ((arme.system.unemain && arme.system.competence) ||
 | 
				
			||||||
        action.system.initiative = RdDCombatManager.calculInitiative(compData.system.niveau, carac[compData.system.defaut_carac].value);
 | 
					          (arme.system.competence.toLowerCase().includes("corps à corps"))) {
 | 
				
			||||||
        // Dupliquer les armes pouvant être à 1 main et 2 mains en patchant la compétence
 | 
					          actions.push(RdDCombatManager.$prepareAttaqueArme({
 | 
				
			||||||
        if (action.system.unemain && !action.system.deuxmains) {
 | 
					            arme: arme,
 | 
				
			||||||
          action.system.mainInfo = "(1m)";
 | 
					            infoMain: "(1 main)",
 | 
				
			||||||
        } else if (!action.system.unemain && action.system.deuxmains) {
 | 
					            dommagesReel: Number(tableauDommages[0]),
 | 
				
			||||||
          action.system.mainInfo = "(2m)";
 | 
					            competence: arme.system.competence,
 | 
				
			||||||
        } else if (action.system.unemain && action.system.deuxmains) {
 | 
					            carac: carac,
 | 
				
			||||||
          action.system.mainInfo = "(1m)";
 | 
					            competences: competences
 | 
				
			||||||
 | 
					          }));
 | 
				
			||||||
          const comp2m = action.system.competence.replace(" 1 main", " 2 mains"); // Replace !
 | 
					        }
 | 
				
			||||||
          const comp = competences.find(c => c.name == comp2m)
 | 
					        if (arme.system.deuxmains && arme.system.competence) {
 | 
				
			||||||
 | 
					          actions.push(RdDCombatManager.$prepareAttaqueArme({
 | 
				
			||||||
          const arme2main = duplicate(action);
 | 
					            arme: arme,
 | 
				
			||||||
          arme2main.system.mainInfo = "(2m)";
 | 
					            infoMain: "(2 mains)",
 | 
				
			||||||
          arme2main.system.niveau = comp.system.niveau;
 | 
					            dommagesReel: Number(tableauDommages[1]),
 | 
				
			||||||
          arme2main.system.competence = comp2m;
 | 
					            competence: arme.system.competence.replace(" 1 main", " 2 mains"),
 | 
				
			||||||
          arme2main.system.initiative = RdDCombatManager.calculInitiative(arme2main.system.niveau, carac[comp.system.defaut_carac].value);
 | 
					            carac: carac,
 | 
				
			||||||
          actionsArme.push(arme2main);
 | 
					            competences: competences
 | 
				
			||||||
          const containsSlash = action.system.dommages.includes("/");
 | 
					          }));
 | 
				
			||||||
          if (containsSlash) {
 | 
					        }
 | 
				
			||||||
            const tableauDegats = action.system.dommages.split("/");
 | 
					        if (arme.system.lancer) {
 | 
				
			||||||
            action.system.dommagesReels = Number(tableauDegats[0]);
 | 
					          actions.push(RdDCombatManager.$prepareAttaqueArme({
 | 
				
			||||||
            arme2main.system.dommagesReels = Number(tableauDegats[1]);
 | 
					            arme: arme,
 | 
				
			||||||
          }
 | 
					            infoMain: "(lancer)",
 | 
				
			||||||
          else{
 | 
					            dommagesReel: Number(tableauDommages[0]),
 | 
				
			||||||
            ui.notifications.info("Les dommages de l'arme à 1/2 mains " + action.name + " ne sont pas corrects (ie sous la forme X/Y)");
 | 
					            competence: arme.system.lancer,
 | 
				
			||||||
          }
 | 
					            carac: carac,
 | 
				
			||||||
 | 
					            competences: competences
 | 
				
			||||||
 | 
					          }));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (arme.system.tir) {
 | 
				
			||||||
 | 
					          actions.push(RdDCombatManager.$prepareAttaqueArme({
 | 
				
			||||||
 | 
					            arme: arme,
 | 
				
			||||||
 | 
					            infoMain: "(tir)",
 | 
				
			||||||
 | 
					            dommagesReel: Number(tableauDommages[0]),
 | 
				
			||||||
 | 
					            competence: arme.system.tir,
 | 
				
			||||||
 | 
					            carac: carac,
 | 
				
			||||||
 | 
					            competences: competences
 | 
				
			||||||
 | 
					          }));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return actionsArme.sort(Misc.ascending(armeData => armeData.name + (armeData.system.mainInfo ?? '')));
 | 
					    return actions.sort(Misc.ascending(action => action.name + (action.system.infoMain ?? '')));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static $prepareAttaqueArme(infoAttaque) {
 | 
				
			||||||
 | 
					    const comp = infoAttaque.competences.find(c => c.name == infoAttaque.competence);
 | 
				
			||||||
 | 
					    const attaque = duplicate(infoAttaque.arme);
 | 
				
			||||||
 | 
					    attaque.action = 'attaque';
 | 
				
			||||||
 | 
					    attaque.system.competence = infoAttaque.competence;
 | 
				
			||||||
 | 
					    attaque.system.dommagesReels = infoAttaque.dommagesReel;
 | 
				
			||||||
 | 
					    attaque.system.infoMain = infoAttaque.infoMain;
 | 
				
			||||||
 | 
					    attaque.system.niveau = comp.system.niveau;
 | 
				
			||||||
 | 
					    attaque.system.initiative = RdDCombatManager.calculInitiative(comp.system.niveau, infoAttaque.carac[comp.system.defaut_carac].value);
 | 
				
			||||||
 | 
					    return attaque;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static listActionsCreature(competences) {
 | 
					  static listActionsCreature(competences) {
 | 
				
			||||||
    return competences.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
 | 
					    return competences.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
 | 
				
			||||||
      .map(it => RdDItemCompetenceCreature.toActionArme(it));
 | 
					      .map(it => RdDItemCompetenceCreature.armeNaturelle(it));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static listActionsPossessions(actor) {
 | 
					  static listActionsPossessions(actor) {
 | 
				
			||||||
    return RdDCombatManager._indexActions(actor.getPossessions().map(p =>
 | 
					    return RdDCombatManager._indexActions(actor.getPossessions().map(p => {
 | 
				
			||||||
      {
 | 
					      return {
 | 
				
			||||||
        return {
 | 
					        name: p.name,
 | 
				
			||||||
          name: p.name,
 | 
					        action: 'conjurer',
 | 
				
			||||||
          action: 'conjurer',
 | 
					        system: {
 | 
				
			||||||
          system: {
 | 
					          competence: p.name,
 | 
				
			||||||
            competence: p.name,
 | 
					          possessionid: p.system.possessionid,
 | 
				
			||||||
            possessionid: p.system.possessionid,
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }));
 | 
					      }
 | 
				
			||||||
 | 
					    }));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static listActionsCombat(combatant) {
 | 
					  static listActionsCombat(combatant) {
 | 
				
			||||||
    const actor = combatant.actor;
 | 
					    const actor = combatant.actor;
 | 
				
			||||||
    let actions = RdDCombatManager.listActionsPossessions(actor);
 | 
					    let actions = RdDCombatManager.listActionsPossessions(actor);
 | 
				
			||||||
    if (actions.length>0) {
 | 
					    if (actions.length > 0) {
 | 
				
			||||||
      return actions;
 | 
					      return actions;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (actor.isCreature()) {
 | 
					    if (actor.isCreatureEntite()) {
 | 
				
			||||||
      actions = actions.concat(RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']));
 | 
					      actions = actions.concat(RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']));
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      // Recupération des items 'arme'
 | 
					      // Recupération des items 'arme'
 | 
				
			||||||
@@ -334,7 +357,7 @@ export class RdDCombatManager extends Combat {
 | 
				
			|||||||
      compData = RdDItemCompetence.findCompetence(combatant.actor.items, action.system.competence);
 | 
					      compData = RdDItemCompetence.findCompetence(combatant.actor.items, action.system.competence);
 | 
				
			||||||
      compNiveau = compData.system.niveau;
 | 
					      compNiveau = compData.system.niveau;
 | 
				
			||||||
      initInfo = action.name + " / " + action.system.competence;
 | 
					      initInfo = action.name + " / " + action.system.competence;
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
      if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
 | 
					      if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
 | 
				
			||||||
        caracForInit = compData.system.carac_value;
 | 
					        caracForInit = compData.system.carac_value;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
@@ -362,7 +385,7 @@ export class RdDCombatManager extends Combat {
 | 
				
			|||||||
    switch (arme.system.cac) {
 | 
					    switch (arme.system.cac) {
 | 
				
			||||||
      case "empoignade":
 | 
					      case "empoignade":
 | 
				
			||||||
        return 3;
 | 
					        return 3;
 | 
				
			||||||
      case "pugilat": 
 | 
					      case "pugilat":
 | 
				
			||||||
      case "naturelle":
 | 
					      case "naturelle":
 | 
				
			||||||
        return 4;
 | 
					        return 4;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -373,7 +396,7 @@ export class RdDCombatManager extends Combat {
 | 
				
			|||||||
  static displayInitiativeMenu(html, combatantId) {
 | 
					  static displayInitiativeMenu(html, combatantId) {
 | 
				
			||||||
    console.log("Combatant ; ", combatantId);
 | 
					    console.log("Combatant ; ", combatantId);
 | 
				
			||||||
    const combatant = game.combat.combatants.get(combatantId);
 | 
					    const combatant = game.combat.combatants.get(combatantId);
 | 
				
			||||||
    if (! (combatant?.actor) ) {
 | 
					    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!`)
 | 
					      ui.notifications.warn(`Le combatant ${combatant.name ?? combatantId} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -448,49 +471,30 @@ export class RdDCombat {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static createUsingTarget(attacker) {
 | 
					  static rddCombatTarget(target, attacker) {
 | 
				
			||||||
    const target = RdDCombat.getTarget()
 | 
					    const defender = target?.actor;
 | 
				
			||||||
    if (target == undefined) {
 | 
					    const defenderTokenId = target?.id;
 | 
				
			||||||
      ui.notifications.warn((game.user.targets?.size ?? 0) > 1
 | 
					 | 
				
			||||||
        ? "Vous devez choisir <strong>une seule</strong> cible à attaquer!"
 | 
					 | 
				
			||||||
        : "Vous devez choisir une cible à attaquer!");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      const defender = target?.actor;
 | 
					 | 
				
			||||||
      const defenderTokenId = target?.id;
 | 
					 | 
				
			||||||
      if ( defender.type == 'entite' && defender.system.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)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static getTarget() {
 | 
					 | 
				
			||||||
    if (game.user.targets && game.user.targets.size == 1) {
 | 
					 | 
				
			||||||
      for (let target of game.user.targets) {
 | 
					 | 
				
			||||||
        return target;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return undefined;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static create(attacker, defender, defenderTokenId, target = undefined) {
 | 
					 | 
				
			||||||
    return new RdDCombat(attacker, defender, defenderTokenId, target)
 | 
					    return new RdDCombat(attacker, defender, defenderTokenId, target)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static createForAttackerAndDefender(attackerId, defenderTokenId) {
 | 
					  static rddCombatForAttackerAndDefender(attackerId, defenderTokenId) {
 | 
				
			||||||
    const attacker = game.actors.get(attackerId);
 | 
					    const attacker = game.actors.get(attackerId);
 | 
				
			||||||
    if (defenderTokenId) {
 | 
					    let defender = defenderTokenId ? canvas.tokens.get(defenderTokenId)?.actor : undefined;
 | 
				
			||||||
      const defenderToken = canvas.tokens.get(defenderTokenId);
 | 
					    let target = undefined
 | 
				
			||||||
      const defender = defenderToken.actor;
 | 
					    if (!defenderTokenId || !defender) {
 | 
				
			||||||
 | 
					      console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`);
 | 
				
			||||||
      return RdDCombat.create(attacker, defender, defenderTokenId);
 | 
					      target = Targets.getTarget()
 | 
				
			||||||
 | 
					      if (!target) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      defenderTokenId = target.id;
 | 
				
			||||||
 | 
					      defender = target.actor;
 | 
				
			||||||
 | 
					      if (!defenderTokenId || !defender) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return RdDCombat.createUsingTarget(attacker)
 | 
					    return new RdDCombat(attacker, defender, defenderTokenId, target)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -498,10 +502,10 @@ export class RdDCombat {
 | 
				
			|||||||
    let defender = canvas.tokens.get(msg.defenderTokenId).actor;
 | 
					    let defender = canvas.tokens.get(msg.defenderTokenId).actor;
 | 
				
			||||||
    if (Misc.isOwnerPlayerOrUniqueConnectedGM()) {
 | 
					    if (Misc.isOwnerPlayerOrUniqueConnectedGM()) {
 | 
				
			||||||
      let attackerRoll = msg.attackerRoll;
 | 
					      let attackerRoll = msg.attackerRoll;
 | 
				
			||||||
      let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : null;
 | 
					      let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      defender.encaisserDommages(attackerRoll, attacker);
 | 
					      defender.encaisserDommages(attackerRoll, attacker);
 | 
				
			||||||
      const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
 | 
					      const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
 | 
				
			||||||
      rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
 | 
					      rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -510,7 +514,7 @@ export class RdDCombat {
 | 
				
			|||||||
  static onMsgDefense(msg) {
 | 
					  static onMsgDefense(msg) {
 | 
				
			||||||
    let defenderToken = canvas.tokens.get(msg.defenderTokenId);
 | 
					    let defenderToken = canvas.tokens.get(msg.defenderTokenId);
 | 
				
			||||||
    if (defenderToken && Misc.isUniqueConnectedGM()) {
 | 
					    if (defenderToken && Misc.isUniqueConnectedGM()) {
 | 
				
			||||||
      const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
 | 
					      const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
 | 
				
			||||||
      rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme);
 | 
					      rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme);
 | 
				
			||||||
      rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll);
 | 
					      rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -537,11 +541,10 @@ export class RdDCombat {
 | 
				
			|||||||
      '#echec-total-attaque',
 | 
					      '#echec-total-attaque',
 | 
				
			||||||
    ]) {
 | 
					    ]) {
 | 
				
			||||||
      html.on("click", button, event => {
 | 
					      html.on("click", button, event => {
 | 
				
			||||||
        const rddCombat = RdDCombat.createForAttackerAndDefender(
 | 
					        const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(
 | 
				
			||||||
          event.currentTarget.attributes['data-attackerId']?.value,
 | 
					          event.currentTarget.attributes['data-attackerId']?.value,
 | 
				
			||||||
          event.currentTarget.attributes['data-defenderTokenId']?.value);
 | 
					          event.currentTarget.attributes['data-defenderTokenId']?.value);
 | 
				
			||||||
        if (rddCombat) {
 | 
					        if (rddCombat) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
          rddCombat.onEvent(button, event);
 | 
					          rddCombat.onEvent(button, event);
 | 
				
			||||||
          event.preventDefault();
 | 
					          event.preventDefault();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -568,7 +571,7 @@ export class RdDCombat {
 | 
				
			|||||||
  async onEvent(button, event) {
 | 
					  async onEvent(button, event) {
 | 
				
			||||||
    const chatMessage = ChatUtility.getChatMessage(event);
 | 
					    const chatMessage = ChatUtility.getChatMessage(event);
 | 
				
			||||||
    const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll');
 | 
					    const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll');
 | 
				
			||||||
    const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll') ;
 | 
					    const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll');
 | 
				
			||||||
    console.log('RdDCombat', attackerRoll, defenderRoll);
 | 
					    console.log('RdDCombat', attackerRoll, defenderRoll);
 | 
				
			||||||
    const defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value;
 | 
					    const defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -688,12 +691,13 @@ export class RdDCombat {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async proposerAjustementTirLancer( rollData ) {
 | 
					  async proposerAjustementTirLancer(rollData) {
 | 
				
			||||||
    if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) {
 | 
					    if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) {
 | 
				
			||||||
      if (this.defender.isEntite([ENTITE_BLURETTE])){
 | 
					      if (this.defender.isEntite([ENTITE_BLURETTE])) {
 | 
				
			||||||
        ChatMessage.create( {
 | 
					        ChatMessage.create({
 | 
				
			||||||
          content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`,
 | 
					          content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`,
 | 
				
			||||||
          whisper: ChatMessage.getWhisperRecipients("GM")})
 | 
					          whisper: ChatMessage.getWhisperRecipients("GM")
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else {
 | 
					      else {
 | 
				
			||||||
        const defenderToken = canvas.tokens.get(this.defenderTokenId);
 | 
					        const defenderToken = canvas.tokens.get(this.defenderTokenId);
 | 
				
			||||||
@@ -702,7 +706,7 @@ export class RdDCombat {
 | 
				
			|||||||
        const portee = this._ajustementPortee(dist, rollData.arme)
 | 
					        const portee = this._ajustementPortee(dist, rollData.arme)
 | 
				
			||||||
        const taille = this._ajustementTaille(this.defender)
 | 
					        const taille = this._ajustementTaille(this.defender)
 | 
				
			||||||
        const activite = this._ajustementMouvement(this.defender)
 | 
					        const activite = this._ajustementMouvement(this.defender)
 | 
				
			||||||
        const total = [portee, taille, activite].map(it=>it.diff).filter(d => !Number.isNaN(d)).reduce(Misc.sum(), 0)
 | 
					        const total = [portee, taille, activite].map(it => it.diff).filter(d => !Number.isNaN(d)).reduce(Misc.sum(), 0)
 | 
				
			||||||
        ChatMessage.create({
 | 
					        ChatMessage.create({
 | 
				
			||||||
          content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html', {
 | 
					          content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html', {
 | 
				
			||||||
            rollData: rollData,
 | 
					            rollData: rollData,
 | 
				
			||||||
@@ -724,32 +728,32 @@ export class RdDCombat {
 | 
				
			|||||||
  isVisible(token, defenderToken) {
 | 
					  isVisible(token, defenderToken) {
 | 
				
			||||||
    return canvas.effects.visibility.testVisibility(defenderToken.center, { object: token })
 | 
					    return canvas.effects.visibility.testVisibility(defenderToken.center, { object: token })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
  distance(token, defenderToken) {
 | 
					  distance(token, defenderToken) {
 | 
				
			||||||
    return Number(canvas.grid.measureDistances([{ ray: new Ray(token.center, defenderToken.center) }], { gridSpaces: false })).toFixed(1);
 | 
					    return Number(canvas.grid.measureDistances([{ ray: new Ray(token.center, defenderToken.center) }], { gridSpaces: false })).toFixed(1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _ajustementPortee(dist, arme) {
 | 
					  _ajustementPortee(dist, arme) {
 | 
				
			||||||
    if (dist <= arme.system.portee_courte) return {msg:"courte", diff:0};
 | 
					    if (dist <= arme.system.portee_courte) return { msg: "courte", diff: 0 };
 | 
				
			||||||
    if (dist <= arme.system.portee_moyenne) return {msg: "moyenne" , diff: -3};
 | 
					    if (dist <= arme.system.portee_moyenne) return { msg: "moyenne", diff: -3 };
 | 
				
			||||||
    if (dist <= arme.system.portee_extreme) return {msg: "extrême", diff:-5};
 | 
					    if (dist <= arme.system.portee_extreme) return { msg: "extrême", diff: -5 };
 | 
				
			||||||
    return {msg: "inatteignable", diff: -10};
 | 
					    return { msg: "inatteignable", diff: -10 };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _ajustementTaille(actor) {
 | 
					  _ajustementTaille(actor) {
 | 
				
			||||||
    if (actor.isVehicule()) return {msg: "véhicule", diff: 0}
 | 
					    if (actor.isVehicule()) return { msg: "véhicule", diff: 0 }
 | 
				
			||||||
    const taille = actor.getCaracByName('TAILLE')?.value ?? 1;
 | 
					    const taille = actor.getCaracByName('TAILLE')?.value ?? 1;
 | 
				
			||||||
    if (taille <= 1) return {msg: "souris", diff: -8};
 | 
					    if (taille <= 1) return { msg: "souris", diff: -8 };
 | 
				
			||||||
    if (taille <= 3) return {msg: "chat", diff: -4};
 | 
					    if (taille <= 3) return { msg: "chat", diff: -4 };
 | 
				
			||||||
    if (taille <= 5) return {msg: "chien", diff: -2};
 | 
					    if (taille <= 5) return { msg: "chien", diff: -2 };
 | 
				
			||||||
    if (taille <= 15) return {msg: "humanoïde", diff: 0};
 | 
					    if (taille <= 15) return { msg: "humanoïde", diff: 0 };
 | 
				
			||||||
    if (taille <= 20) return {msg: "ogre", diff: 2};
 | 
					    if (taille <= 20) return { msg: "ogre", diff: 2 };
 | 
				
			||||||
    return {msg: "gigantesque", diff: 4};
 | 
					    return { msg: "gigantesque", diff: 4 };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  _ajustementMouvement(defender) {
 | 
					  _ajustementMouvement(defender) {
 | 
				
			||||||
    if (defender.getSurprise(true)) return {msg: "immobile (surprise)", diff: 0};
 | 
					    if (defender.getSurprise(true)) return { msg: "immobile (surprise)", diff: 0 };
 | 
				
			||||||
    if (game.combat?.combatants.find(it => it.actorId == defender.id)) return {msg: "en mouvement (combat)", diff: -4};
 | 
					    if (game.combat?.combatants.find(it => it.actorId == defender.id)) return { msg: "en mouvement (combat)", diff: -4 };
 | 
				
			||||||
    return {msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3};
 | 
					    return { msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3 };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -763,7 +767,7 @@ export class RdDCombat {
 | 
				
			|||||||
    //     whisper: ChatMessage.getWhisperRecipients("GM")})
 | 
					    //     whisper: ChatMessage.getWhisperRecipients("GM")})
 | 
				
			||||||
    // }
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!await this.accorderEntite('avant-attaque')) {
 | 
					    if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (arme.system.cac == 'empoignade' && this.attacker.isCombatTouche()) {
 | 
					    if (arme.system.cac == 'empoignade' && this.attacker.isCombatTouche()) {
 | 
				
			||||||
@@ -786,23 +790,21 @@ export class RdDCombat {
 | 
				
			|||||||
    await this.proposerAjustementTirLancer(rollData)
 | 
					    await this.proposerAjustementTirLancer(rollData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const dialog = await RdDRoll.create(this.attacker, rollData,
 | 
					    const dialog = await RdDRoll.create(this.attacker, rollData,
 | 
				
			||||||
 | 
					      { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
 | 
					        name: 'jet-attaque',
 | 
				
			||||||
        options: { height: 540 }
 | 
					        label: 'Attaque: ' + (arme?.name ?? competence.name),
 | 
				
			||||||
      }, {
 | 
					        callbacks: [
 | 
				
			||||||
      name: 'jet-attaque',
 | 
					          this.attacker.createCallbackExperience(),
 | 
				
			||||||
      label: 'Attaque: ' + (arme?.name ?? competence.name),
 | 
					          this.attacker.createCallbackAppelAuMoral(),
 | 
				
			||||||
      callbacks: [
 | 
					          { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
 | 
				
			||||||
        this.attacker.createCallbackExperience(),
 | 
					          { condition: r => arme && !RdDCombat.isParticuliere(r), action: r => this.attacker.incDecItemUse(arme._id) },
 | 
				
			||||||
        this.attacker.createCallbackAppelAuMoral(),
 | 
					          { condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) },
 | 
				
			||||||
        { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
 | 
					          { condition: RdDCombat.isParticuliere, action: r => this._onAttaqueParticuliere(r) },
 | 
				
			||||||
        { condition: r => arme && !RdDCombat.isParticuliere(r), action: r => this.attacker.incDecItemUse(arme._id) },
 | 
					          { condition: RdDCombat.isEchec, action: r => this._onAttaqueEchec(r) },
 | 
				
			||||||
        { condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) },
 | 
					          { condition: RdDCombat.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) },
 | 
				
			||||||
        { condition: RdDCombat.isParticuliere, action: r => this._onAttaqueParticuliere(r) },
 | 
					        ]
 | 
				
			||||||
        { condition: RdDCombat.isEchec, action: r => this._onAttaqueEchec(r) },
 | 
					      });
 | 
				
			||||||
        { condition: RdDCombat.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) },
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    dialog.render(true);
 | 
					    dialog.render(true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -815,10 +817,11 @@ export class RdDCombat {
 | 
				
			|||||||
      competence: competence,
 | 
					      competence: competence,
 | 
				
			||||||
      surprise: this.attacker.getSurprise(true),
 | 
					      surprise: this.attacker.getSurprise(true),
 | 
				
			||||||
      surpriseDefenseur: this.defender.getSurprise(true),
 | 
					      surpriseDefenseur: this.defender.getSurprise(true),
 | 
				
			||||||
 | 
					      targetToken: Targets.extractTokenData(this.target),
 | 
				
			||||||
      essais: {}
 | 
					      essais: {}
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.attacker.isCreature()) {
 | 
					    if (this.attacker.isCreatureEntite()) {
 | 
				
			||||||
      RdDItemCompetenceCreature.setRollDataCreature(rollData);
 | 
					      RdDItemCompetenceCreature.setRollDataCreature(rollData);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (arme) {
 | 
					    else if (arme) {
 | 
				
			||||||
@@ -836,7 +839,7 @@ export class RdDCombat {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async _onAttaqueParticuliere(rollData) {
 | 
					  async _onAttaqueParticuliere(rollData) {
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    const isMeleeDiffNegative = (rollData.competence.type == 'competencecreature' || rollData.selectedCarac.label == "Mêlée") && rollData.diffLibre < 0;
 | 
					    const isMeleeDiffNegative = (rollData.competence.type == 'competencecreature' || rollData.selectedCarac.label == "Mêlée") && rollData.diffLibre < 0;
 | 
				
			||||||
    // force toujours, sauf empoignade
 | 
					    // force toujours, sauf empoignade
 | 
				
			||||||
    // finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
 | 
					    // finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
 | 
				
			||||||
@@ -854,7 +857,7 @@ export class RdDCombat {
 | 
				
			|||||||
    else if (!isForce && !isFinesse && isRapide) {
 | 
					    else if (!isForce && !isFinesse && isRapide) {
 | 
				
			||||||
      return await this.choixParticuliere(rollData, "rapidite");
 | 
					      return await this.choixParticuliere(rollData, "rapidite");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    const choixParticuliere = await ChatMessage.create({
 | 
					    const choixParticuliere = await ChatMessage.create({
 | 
				
			||||||
      alias: this.attacker.name,
 | 
					      alias: this.attacker.name,
 | 
				
			||||||
      whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name),
 | 
					      whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name),
 | 
				
			||||||
@@ -883,7 +886,7 @@ export class RdDCombat {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html');
 | 
					    await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!await this.accorderEntite('avant-defense')) {
 | 
					    if (!await this.attacker.accorder(this.defender, 'avant-defense')) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -893,7 +896,7 @@ export class RdDCombat {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  isPossession( attackerRoll) {
 | 
					  isPossession(attackerRoll) {
 | 
				
			||||||
    return attackerRoll.selectedCarac.label.toLowerCase() == 'possession';
 | 
					    return attackerRoll.selectedCarac.label.toLowerCase() == 'possession';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1036,31 +1039,28 @@ export class RdDCombat {
 | 
				
			|||||||
    const arme = this.defender.getArmeParade(armeParadeId);
 | 
					    const arme = this.defender.getArmeParade(armeParadeId);
 | 
				
			||||||
    console.log("RdDCombat.parade >>>", attackerRoll, armeParadeId, arme);
 | 
					    console.log("RdDCombat.parade >>>", attackerRoll, armeParadeId, arme);
 | 
				
			||||||
    const competence = arme?.system?.competence;
 | 
					    const competence = arme?.system?.competence;
 | 
				
			||||||
    if (competence == undefined)
 | 
					    if (competence == undefined) {
 | 
				
			||||||
    {
 | 
					      console.error("Pas de compétence de parade associée à ", arme?.name, armeParadeId);
 | 
				
			||||||
      console.error("Pas de compétence de parade associée à ", arme?.name, armeParadeId) ;
 | 
					 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let rollData = this._prepareParade(attackerRoll, arme, competence);
 | 
					    let rollData = this._prepareParade(attackerRoll, arme, competence);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const dialog = await RdDRoll.create(this.defender, rollData,
 | 
					    const dialog = await RdDRoll.create(this.defender, rollData,
 | 
				
			||||||
 | 
					      { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
 | 
					        name: 'jet-parade',
 | 
				
			||||||
        options: { height: 540 }
 | 
					        label: 'Parade: ' + (arme ? arme.name : rollData.competence.name),
 | 
				
			||||||
      }, {
 | 
					        callbacks: [
 | 
				
			||||||
      name: 'jet-parade',
 | 
					          this.defender.createCallbackExperience(),
 | 
				
			||||||
      label: 'Parade: ' + (arme ? arme.name : rollData.competence.name),
 | 
					          this.defender.createCallbackAppelAuMoral(),
 | 
				
			||||||
      callbacks: [
 | 
					          { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
 | 
				
			||||||
        this.defender.createCallbackExperience(),
 | 
					          { condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(armeParadeId) },
 | 
				
			||||||
        this.defender.createCallbackAppelAuMoral(),
 | 
					          { condition: RdDCombat.isReussite, action: r => this._onParadeNormale(r) },
 | 
				
			||||||
        { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
 | 
					          { condition: RdDCombat.isParticuliere, action: r => this._onParadeParticuliere(r) },
 | 
				
			||||||
        { condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(armeParadeId) },
 | 
					          { condition: RdDCombat.isEchec, action: r => this._onParadeEchec(r) },
 | 
				
			||||||
        { condition: RdDCombat.isReussite, action: r => this._onParadeNormale(r) },
 | 
					        ]
 | 
				
			||||||
        { condition: RdDCombat.isParticuliere, action: r => this._onParadeParticuliere(r) },
 | 
					      });
 | 
				
			||||||
        { condition: RdDCombat.isEchec, action: r => this._onParadeEchec(r) },
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    dialog.render(true);
 | 
					    dialog.render(true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1079,7 +1079,7 @@ export class RdDCombat {
 | 
				
			|||||||
      show: {}
 | 
					      show: {}
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.defender.isCreature()) {
 | 
					    if (this.defender.isCreatureEntite()) {
 | 
				
			||||||
      RdDItemCompetenceCreature.setRollDataCreature(defenderRoll);
 | 
					      RdDItemCompetenceCreature.setRollDataCreature(defenderRoll);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1128,19 +1128,20 @@ export class RdDCombat {
 | 
				
			|||||||
    let rollData = this._prepareEsquive(attackerRoll, esquive);
 | 
					    let rollData = this._prepareEsquive(attackerRoll, esquive);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const dialog = await RdDRoll.create(this.defender, rollData,
 | 
					    const dialog = await RdDRoll.create(this.defender, rollData,
 | 
				
			||||||
      { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' }, {
 | 
					      { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
 | 
				
			||||||
      name: 'jet-esquive',
 | 
					      {
 | 
				
			||||||
      label: 'Esquiver',
 | 
					        name: 'jet-esquive',
 | 
				
			||||||
      callbacks: [
 | 
					        label: 'Esquiver',
 | 
				
			||||||
        this.defender.createCallbackExperience(),
 | 
					        callbacks: [
 | 
				
			||||||
        this.defender.createCallbackAppelAuMoral(),
 | 
					          this.defender.createCallbackExperience(),
 | 
				
			||||||
        { condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(esquive._id) },
 | 
					          this.defender.createCallbackAppelAuMoral(),
 | 
				
			||||||
        { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
 | 
					          { condition: r => !RdDCombat.isParticuliere(r), action: r => this.defender.incDecItemUse(esquive._id) },
 | 
				
			||||||
        { condition: RdDCombat.isReussite, action: r => this._onEsquiveNormale(r) },
 | 
					          { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) },
 | 
				
			||||||
        { condition: RdDCombat.isParticuliere, action: r => this._onEsquiveParticuliere(r) },
 | 
					          { condition: RdDCombat.isReussite, action: r => this._onEsquiveNormale(r) },
 | 
				
			||||||
        { condition: RdDCombat.isEchec, action: r => this._onEsquiveEchec(r) },
 | 
					          { condition: RdDCombat.isParticuliere, action: r => this._onEsquiveParticuliere(r) },
 | 
				
			||||||
      ]
 | 
					          { condition: RdDCombat.isEchec, action: r => this._onEsquiveEchec(r) },
 | 
				
			||||||
    });
 | 
					        ]
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
    dialog.render(true);
 | 
					    dialog.render(true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1157,7 +1158,7 @@ export class RdDCombat {
 | 
				
			|||||||
      show: {}
 | 
					      show: {}
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.defender.isCreature()) {
 | 
					    if (this.defender.isCreatureEntite()) {
 | 
				
			||||||
      RdDItemCompetenceCreature.setRollDataCreature(rollData);
 | 
					      RdDItemCompetenceCreature.setRollDataCreature(rollData);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return rollData;
 | 
					    return rollData;
 | 
				
			||||||
@@ -1318,35 +1319,6 @@ export class RdDCombat {
 | 
				
			|||||||
    this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
 | 
					    this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  /* retourne true si on peut continuer, false si on ne peut pas continuer */
 | 
					 | 
				
			||||||
  async accorderEntite(when = 'avant-encaissement') {
 | 
					 | 
				
			||||||
    if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
 | 
					 | 
				
			||||||
      || this.defender == undefined
 | 
					 | 
				
			||||||
      || !this.defender.isEntite([ENTITE_INCARNE])
 | 
					 | 
				
			||||||
      || this.defender.isEntiteAccordee(this.attacker)) {
 | 
					 | 
				
			||||||
      return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let rolled = await RdDResolutionTable.roll(this.attacker.getReveActuel(), - Number(this.defender.system.carac.niveau.value));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let message = {
 | 
					 | 
				
			||||||
      content: "Jet de points actuels de rêve à " + rolled.finalLevel + RdDResolutionTable.explain(rolled) + "<br>",
 | 
					 | 
				
			||||||
      whisper: ChatMessage.getWhisperRecipients(this.attacker.name)
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (rolled.isSuccess) {
 | 
					 | 
				
			||||||
      await this.defender.setEntiteReveAccordee(this.attacker);
 | 
					 | 
				
			||||||
      message.content += this.attacker.name + " s'est accordé avec " + this.defender.name;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      message.content += this.attacker.name + " n'est pas accordé avec " + this.defender.name;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ChatMessage.create(message);
 | 
					 | 
				
			||||||
    return rolled.isSuccess;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async displayActorCombatStatus(combat, actor) {
 | 
					  static async displayActorCombatStatus(combat, actor) {
 | 
				
			||||||
    let formData = {
 | 
					    let formData = {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { DialogChronologie } from "./dialog-chronologie.js";
 | 
				
			||||||
import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js";
 | 
					import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js";
 | 
				
			||||||
import { DialogStress } from "./dialog-stress.js";
 | 
					import { DialogStress } from "./dialog-stress.js";
 | 
				
			||||||
import { Grammar } from "./grammar.js";
 | 
					 | 
				
			||||||
import { RdDItemCompetence } from "./item-competence.js";
 | 
					import { RdDItemCompetence } from "./item-competence.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
import { RdDCarac } from "./rdd-carac.js";
 | 
					import { RdDCarac } from "./rdd-carac.js";
 | 
				
			||||||
@@ -13,7 +13,7 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
				
			|||||||
import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
 | 
					import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
 | 
				
			||||||
import { RdDRollTables } from "./rdd-rolltables.js";
 | 
					import { RdDRollTables } from "./rdd-rolltables.js";
 | 
				
			||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
import { TMRRencontres } from "./tmr-rencontres.js";
 | 
					import { CompendiumTableHelpers } from "./settings/system-compendiums.js";
 | 
				
			||||||
import { TMRUtility } from "./tmr-utility.js";
 | 
					import { TMRUtility } from "./tmr-utility.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
 | 
					const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
 | 
				
			||||||
@@ -22,55 +22,100 @@ const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
 | 
				
			|||||||
export class RdDCommands {
 | 
					export class RdDCommands {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static init() {
 | 
					  static init() {
 | 
				
			||||||
    if (!game.system.rdd.commands) {
 | 
					    const rddCommands = new RdDCommands();
 | 
				
			||||||
      const rddCommands = new RdDCommands();
 | 
					 | 
				
			||||||
      rddCommands.registerCommand({ path: ["/aide"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
 | 
					 | 
				
			||||||
      rddCommands.registerCommand({ path: ["/help"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
 | 
					 | 
				
			||||||
      rddCommands.registerCommand({ path: ["/table", "queues"], func: (content, msg, params) => RdDRollTables.getQueue(true), descr: "Tire une Queue de Dragon" });
 | 
					 | 
				
			||||||
      rddCommands.registerCommand({ path: ["/table", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe(true), descr: "Tire une Idée fixe" });
 | 
					 | 
				
			||||||
      rddCommands.registerCommand({ path: ["/table", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant(true), descr: "Tire un Désir Lancinant" });
 | 
					 | 
				
			||||||
      rddCommands.registerCommand({ path: ["/table", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre(true), descr: "Tire une Ombre de Dragon" });
 | 
					 | 
				
			||||||
      rddCommands.registerCommand({ path: ["/table", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR(true), descr: "Tire une Tête de Dragon pour Hauts Revants" });
 | 
					 | 
				
			||||||
      rddCommands.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete(true), descr: "Tire une Tête de Dragon" });
 | 
					 | 
				
			||||||
      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({
 | 
					    Hooks.on("chatMessage", (html, content, msg) => {
 | 
				
			||||||
        path: ["/tmra"], func: (content, msg, params) => rddCommands.getTMRAleatoire(msg, params),
 | 
					      if (content[0] == '/') {
 | 
				
			||||||
        descr: `Tire une case aléatoire des Terres médianes
 | 
					        let regExp = /(\S+)/g;
 | 
				
			||||||
 | 
					        let commands = content.match(regExp);
 | 
				
			||||||
 | 
					        if (rddCommands.processChatCommand(commands, content, msg)) {
 | 
				
			||||||
 | 
					          return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    game.system.rdd.commands = rddCommands;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    this.commandsTable = undefined;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _registerCommands() {
 | 
				
			||||||
 | 
					    this.commandsTable = {}
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/aide"], func: (content, msg, params) => this.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/help"], func: (content, msg, params) => this.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/liste", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence('liste'), descr: "Affiche la liste des compétences" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/table", "queue"], func: (content, msg, params) => RdDRollTables.getQueue('liste'), descr: "Affiche la table des Queues de Dragon" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/table", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre('liste'), descr: "Affiche la table des Ombres de Thanatos" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/table", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR('liste'), descr: "Affiche la table des Têtes de Dragon pour Hauts Revants" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete('liste'), descr: "Affiche la table des Tête de Dragon pour tous" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/table", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle('liste'), descr: "Affiche la table des Souffles de Dragon" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/table", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot('liste'), descr: "Affiche la table les cartes du Tarot Draconique" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/table", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe('liste'), descr: "Affiche la table des Idées fixes" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/table", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant('liste'), descr: "Affiche la table des Désirs Lancinants" });
 | 
				
			||||||
 | 
					    this.registerCommand({
 | 
				
			||||||
 | 
					      path: ["/table", "rencontre"], func: (content, msg, params) => this.tableRencontres(msg, params),
 | 
				
			||||||
 | 
					      descr: `Affiche la table des Rencontres
 | 
				
			||||||
 | 
					          <br><strong>/table rencontre deso</strong> affiche la table des rencontres en Désolation
 | 
				
			||||||
 | 
					          <br><strong>/table rencontre mauvaise</strong> affiche la table des mauvaises rencontres`
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/table", "milieu"], func: (content, msg, params) => this.tableMilieu(msg, params, 'liste'), descr: "Affiche la table des ressource naturelles pour un milieu donné" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence('chat'), descr: "Tire une compétence au hasard" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "queue"], func: (content, msg, params) => RdDRollTables.getQueue('chat'), descr: "Tire une Queue de Dragon" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre('chat'), descr: "Tire une Ombre de Thanatos" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR('chat'), descr: "Tire une Tête de Dragon pour Hauts Revants" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "tete"], func: (content, msg, params) => RdDRollTables.getTete('chat'), descr: "Tire une Tête de Dragon" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle('chat'), descr: "Tire un Souffle de Dragon" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot('chat'), descr: "Tire une carte du Tarot Draconique" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe('chat'), descr: "Tire une Idée fixe" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant('chat'), descr: "Tire un Désir Lancinant" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "rencontre"], func: (content, msg, params) => this.getRencontreTMR(params), descr: `Détermine une rencontre dans les TMR (synonyme de "/tmrr")` });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/tirer", "milieu"], func: (content, msg, params) => this.tableMilieu(msg, params, 'chat'), descr: "Effectue un tirage dans la table desressource naturelles pour un milieu donné" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/meteo"], func: (content, msg, params) => this.getMeteo(msg, params), descr: "Propose une météo marine" });
 | 
				
			||||||
 | 
					    this.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.getName(msg, params), descr: "Génère un nom aléatoire" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.registerCommand({
 | 
				
			||||||
 | 
					      path: ["/tmr"], func: (content, msg, params) => this.findTMR(msg, params),
 | 
				
			||||||
 | 
					      descr: `Cherche où se trouve une case des Terres médianes
 | 
				
			||||||
 | 
					          <br><strong>/tmr sord</strong> indique que la cité Sordide est en D13
 | 
				
			||||||
 | 
					          <br><strong>/tmr foret</strong> donne la liste des TMR dont le nom contient "foret" (donc, toutes les forêts)`
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.registerCommand({
 | 
				
			||||||
 | 
					      path: ["/tmra"], func: (content, msg, params) => this.getTMRAleatoire(msg, params),
 | 
				
			||||||
 | 
					      descr: `Tire une case aléatoire des Terres médianes
 | 
				
			||||||
          <br><strong>/tmra forêt</strong> détermine une 'forêt' aléatoire
 | 
					          <br><strong>/tmra forêt</strong> détermine une 'forêt' aléatoire
 | 
				
			||||||
          <br><strong>/tmra</strong> détermine une case aléatoire dans toutes les TMR` });
 | 
					          <br><strong>/tmra</strong> détermine une case aléatoire dans toutes les TMR`
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					    });
 | 
				
			||||||
        path: ["/tmr"], func: (content, msg, params) => rddCommands.findTMR(msg, params),
 | 
					    this.registerCommand({
 | 
				
			||||||
        descr: `Cherche où se trouve une case des Terres médianes
 | 
					      path: ["/tmrr"], func: (content, msg, params) => this.getRencontreTMR(params),
 | 
				
			||||||
          <br><strong>/tmr? sordide</strong> indique que la cité Sordide est en D13
 | 
					      descr: `Détermine une rencontre dans les TMR
 | 
				
			||||||
          <br><strong>/tmr? foret</strong> donne la liste des TMR dont le nom contient "foret" (donc, toutes les forêts)` });
 | 
					          <br><strong>/tmrr forêt</strong> détermine une rencontre aléatoire en 'forêt'
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					          <br><strong>/tmrr mauvaise</strong> détermine une mauvaise rencontre aléatoire
 | 
				
			||||||
        path: ["/tmrr"], func: (content, msg, params) => rddCommands.getRencontreTMR(params),
 | 
					          <br><strong>/tmrr for 47</strong> détermine la rencontre en 'forêt' pour un jet de dé de 47`
 | 
				
			||||||
        descr: `Détermine une rencontre dans un type de case
 | 
					    });
 | 
				
			||||||
          <br><strong>/tmrr foret</strong> lance un d100 et détermine la rencontre correspondante en 'forêt'
 | 
					 | 
				
			||||||
          <br><strong>/tmrr forêt 47</strong> détermine la rencontre en 'forêt' pour un jet de dé de 47`
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					    this.registerCommand({
 | 
				
			||||||
        path: ["/xp", "comp"], func: (content, msg, params) => rddCommands.getCoutXpComp(msg, params),
 | 
					      path: ["/xp", "comp"], func: (content, msg, params) => this.getCoutXpComp(msg, params),
 | 
				
			||||||
        descr: `Détermine le coût d'expérience pour augmenter une compétence. Exemples:
 | 
					      descr: `Détermine le coût d'expérience pour augmenter une compétence. Exemples:
 | 
				
			||||||
        <br>/xp comp -6 1: pour passer de -6 à +1
 | 
					        <br>/xp comp -6 1: pour passer de -6 à +1
 | 
				
			||||||
        <br>/xp comp +4: pour atteindre le niveau 4 (depuis +3)`
 | 
					        <br>/xp comp +4: pour atteindre le niveau 4 (depuis +3)`
 | 
				
			||||||
      });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					    this.registerCommand({
 | 
				
			||||||
        path: ["/xp", "carac"], func: (content, msg, params) => rddCommands.getCoutXpCarac(msg, params),
 | 
					      path: ["/xp", "carac"], func: (content, msg, params) => this.getCoutXpCarac(msg, params),
 | 
				
			||||||
        descr: `Détermine le coût d'expérience pour augmenter une caractéristique. Exemples:
 | 
					      descr: `Détermine le coût d'expérience pour augmenter une caractéristique. Exemples:
 | 
				
			||||||
        <br>/xp carac 15: coût pour atteindre 15 (depuis 14)`
 | 
					        <br>/xp carac 15: coût pour atteindre 15 (depuis 14)`
 | 
				
			||||||
      });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					    this.registerCommand({
 | 
				
			||||||
        path: ["/rdd"], func: (content, msg, params) => rddCommands.rollRdd(msg, params),
 | 
					      path: ["/rdd"], func: (content, msg, params) => this.rollRdd(msg, params),
 | 
				
			||||||
        descr: `Effectue un jet de dés dans la table de résolution. Exemples:
 | 
					      descr: `Effectue un jet de dés dans la table de résolution. Exemples:
 | 
				
			||||||
          <br><strong>/rdd</strong> ouvre la table de résolution
 | 
					          <br><strong>/rdd</strong> ouvre la table de résolution
 | 
				
			||||||
          <br><strong>/rdd 10 3</strong> effectue un jet 10 à +3
 | 
					          <br><strong>/rdd 10 3</strong> effectue un jet 10 à +3
 | 
				
			||||||
          <br><strong>/rdd 15 -2</strong> effectue un jet 15 à -2
 | 
					          <br><strong>/rdd 15 -2</strong> effectue un jet 15 à -2
 | 
				
			||||||
@@ -78,47 +123,46 @@ export class RdDCommands {
 | 
				
			|||||||
          <br><strong>/rdd Vue Vigilance -2</strong> effectue un jet de Vue/Vigilance à -2 pour les tokens sélectionnés
 | 
					          <br><strong>/rdd Vue Vigilance -2</strong> effectue un jet de Vue/Vigilance à -2 pour les tokens sélectionnés
 | 
				
			||||||
          <br><strong>/rdd vol déser +2</strong> effectue un jet de Volonté/Survie en désert à +2 pour les tokens sélectionnés
 | 
					          <br><strong>/rdd vol déser +2</strong> effectue un jet de Volonté/Survie en désert à +2 pour les tokens sélectionnés
 | 
				
			||||||
          `
 | 
					          `
 | 
				
			||||||
      });
 | 
					    });
 | 
				
			||||||
      rddCommands.registerCommand({ path: ["/ddr"], func: (content, msg, params) => rddCommands.rollDeDraconique(msg), descr: "Lance un Dé Draconique" });
 | 
					    this.registerCommand({ path: ["/ddr"], func: (content, msg, params) => this.rollDeDraconique(msg), descr: "Lance un Dé Draconique" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					    this.registerCommand({
 | 
				
			||||||
        path: ["/payer"], func: (content, msg, params) => RdDUtility.afficherDemandePayer(params[0], params[1]),
 | 
					      path: ["/payer"], func: (content, msg, params) => RdDUtility.afficherDemandePayer(params[0], params[1]),
 | 
				
			||||||
        descr: `Permet de payer un montant. Exemples:
 | 
					      descr: `Demande aux joueurs de payer un montant. Exemples:
 | 
				
			||||||
          <br><strong>/payer 5s 10d</strong> permet d'envoyer un message pour payer 5 sols et 10 deniers
 | 
					          <br><strong>/payer 5s 10d</strong> permet d'envoyer un message pour payer 5 sols et 10 deniers
 | 
				
			||||||
          <br><strong>/payer 10d</strong> permet d'envoyer un message pour payer 10 deniers`
 | 
					          <br><strong>/payer 10d</strong> permet d'envoyer un message pour payer 10 deniers`
 | 
				
			||||||
      });
 | 
					    });
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					    this.registerCommand({
 | 
				
			||||||
        path: ["/astro"], func: (content, msg, params) => RdDUtility.afficherHeuresChanceMalchance(Misc.join(params, ' ')),
 | 
					      path: ["/astro"], func: (content, msg, params) => RdDUtility.afficherHeuresChanceMalchance(Misc.join(params, ' ')),
 | 
				
			||||||
        descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples pour l'heure de la Lyre:
 | 
					      descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples pour l'heure de la Lyre:
 | 
				
			||||||
          <br><strong>/astro 7</strong>
 | 
					          <br><strong>/astro 7</strong>
 | 
				
			||||||
          <br><strong>/astro Lyre</strong>
 | 
					          <br><strong>/astro Lyre</strong>
 | 
				
			||||||
          <br><strong>/astro Lyr</strong>`
 | 
					          <br><strong>/astro Lyr</strong>`
 | 
				
			||||||
      });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					    this.registerCommand({
 | 
				
			||||||
        path: ["/signe", "+"], func: (content, msg, params) => rddCommands.creerSignesDraconiques(),
 | 
					      path: ["/signe", "+"], func: (content, msg, params) => this.creerSignesDraconiques(),
 | 
				
			||||||
        descr: "Crée un signe draconique et l'ajoute aux haut-rêvants choisis."
 | 
					      descr: "Crée un signe draconique et l'ajoute aux haut-rêvants choisis."
 | 
				
			||||||
      });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					    this.registerCommand({
 | 
				
			||||||
        path: ["/signe", "-"], func: (content, msg, params) => rddCommands.supprimerSignesDraconiquesEphemeres(),
 | 
					      path: ["/signe", "-"], func: (content, msg, params) => this.supprimerSignesDraconiquesEphemeres(),
 | 
				
			||||||
        descr: "Supprime les signes draconiques éphémères"
 | 
					      descr: "Supprime les signes draconiques éphémères"
 | 
				
			||||||
      });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      rddCommands.registerCommand({
 | 
					    this.registerCommand({
 | 
				
			||||||
        path: ["/stress"], func: (content, msg, params) => rddCommands.distribuerStress(params),
 | 
					      path: ["/stress"], func: (content, msg, params) => this.distribuerStress(params),
 | 
				
			||||||
        descr: `Distribue du stress aux personnages. Exemples:
 | 
					      descr: `Distribue du stress aux personnages. Exemples:
 | 
				
			||||||
          <br><strong>/stress</strong> : Ouvre une fenêtre pour donner du stress ou de l'expérience à un ensemble de personnages
 | 
					          <br><strong>/stress</strong> : Ouvre une fenêtre pour donner du stress ou de l'expérience à un ensemble de personnages
 | 
				
			||||||
          <br><strong>/stress 6</strong> : Distribue 6 points des Stress à tout les personnages joueurs, sans raison renseignée
 | 
					          <br><strong>/stress 6</strong> : Distribue 6 points des Stress à tout les personnages joueurs, sans raison renseignée
 | 
				
			||||||
          <br><strong>/stress 6 Tigre</strong> : Distribue 6 points des Stress à tout les personnages joueurs, à cause d'un Tigre (Vert)
 | 
					          <br><strong>/stress 6 Tigre</strong> : Distribue 6 points des Stress à tout les personnages joueurs, à cause d'un Tigre (Vert)
 | 
				
			||||||
          <br><strong>/stress 6 Glou Paulo</strong> : Distribue 6 points de Stress au personnage Paulon ou au personnage joueur Paulo, à cause d'un Glou`
 | 
					          <br><strong>/stress 6 Glou Paulo</strong> : Distribue 6 points de Stress au personnage Paulon ou au personnage joueur Paulo, à cause d'un Glou`
 | 
				
			||||||
      });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      game.system.rdd.commands = rddCommands;
 | 
					    this.registerCommand({
 | 
				
			||||||
    }
 | 
					      path: ["/chrono"], func: (content, msg, params) => DialogChronologie.create(),
 | 
				
			||||||
  }
 | 
					      descr: `Enregistre une entrée de chronologie dans un article de journal`
 | 
				
			||||||
  constructor() {
 | 
					    });
 | 
				
			||||||
    this.commandsTable = {};
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -160,37 +204,50 @@ export class RdDCommands {
 | 
				
			|||||||
  processChatCommand(commandLine, content = '', msg = {}) {
 | 
					  processChatCommand(commandLine, content = '', msg = {}) {
 | 
				
			||||||
    // Setup new message's visibility
 | 
					    // Setup new message's visibility
 | 
				
			||||||
    let rollMode = game.settings.get("core", "rollMode");
 | 
					    let rollMode = game.settings.get("core", "rollMode");
 | 
				
			||||||
    if (["gmroll", "blindroll"].includes(rollMode)) msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
 | 
					    if (["gmroll", "blindroll"].includes(rollMode)) {
 | 
				
			||||||
    if (rollMode === "blindroll") msg["blind"] = true;
 | 
					      msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					    if (rollMode === "blindroll"){
 | 
				
			||||||
 | 
					      msg["blind"] = true;
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
    msg["type"] = 0;
 | 
					    msg["type"] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!this.commandsTable) {
 | 
				
			||||||
 | 
					      this._registerCommands();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
    let command = commandLine[0].toLowerCase();
 | 
					    let command = commandLine[0].toLowerCase();
 | 
				
			||||||
    let params = commandLine.slice(1);
 | 
					    if (this._isCommandHandled(command)) {
 | 
				
			||||||
 | 
					      let params = commandLine.slice(1);
 | 
				
			||||||
    return this.process(command, params, content, msg);
 | 
					      this._processCommand(this.commandsTable, command, params, content, msg);
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  process(command, params, content, msg) {
 | 
					  _isCommandHandled(command){
 | 
				
			||||||
    return this._processCommand(this.commandsTable, command, params, content, msg);
 | 
					    return this.commandsTable[command] != undefined;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
 | 
					  async _processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
 | 
				
			||||||
    let command = commandsTable[name];
 | 
					    let command = commandsTable[name];
 | 
				
			||||||
    path = path + name + " ";
 | 
					    path = path + name + " ";
 | 
				
			||||||
    if (command && command.subTable) {
 | 
					    if (command && command.subTable) {
 | 
				
			||||||
      if (params[0]) {
 | 
					      if (params[0]) {
 | 
				
			||||||
        return this._processCommand(command.subTable, params[0], params.slice(1), content, msg, path)
 | 
					        this._processCommand(command.subTable, params[0], params.slice(1), content, msg, path)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else {
 | 
					      else {
 | 
				
			||||||
        this.help(msg, command.subTable);
 | 
					        this.help(msg, command.subTable);
 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (command && command.func) {
 | 
					    if (command && command.func) {
 | 
				
			||||||
      const result = command.func(content, msg, params);
 | 
					      new Promise(async () => {
 | 
				
			||||||
      if (result == false) {
 | 
					        const result = await command.func(content, msg, params);
 | 
				
			||||||
        RdDCommands._chatAnswer(msg, command.descr);
 | 
					        if (result == false) {
 | 
				
			||||||
      }
 | 
					          RdDCommands._chatAnswer(msg, command.descr);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
@@ -201,10 +258,10 @@ export class RdDCommands {
 | 
				
			|||||||
    this.help(msg, undefined);
 | 
					    this.help(msg, undefined);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  async help(msg, table) {
 | 
					  async help(msg, table) {
 | 
				
			||||||
    let list = []
 | 
					    let commands = []
 | 
				
			||||||
    this._buildSubTableHelp(list, table || this.commandsTable);
 | 
					    this._buildSubTableHelp(commands, table ?? this.commandsTable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/settings/dialog-aide-commands.html", { commands: list });
 | 
					    let html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/settings/dialog-aide-commands.html", { commands: commands });
 | 
				
			||||||
    let d = new Dialog(
 | 
					    let d = new Dialog(
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        title: "Commandes disponibles dans le tchat",
 | 
					        title: "Commandes disponibles dans le tchat",
 | 
				
			||||||
@@ -212,7 +269,7 @@ export class RdDCommands {
 | 
				
			|||||||
        buttons: {},
 | 
					        buttons: {},
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        width: 600, height: 500,
 | 
					        width: 600, height: 600,
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    d.render(true);
 | 
					    d.render(true);
 | 
				
			||||||
@@ -242,11 +299,9 @@ export class RdDCommands {
 | 
				
			|||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async getRencontreTMR(params) {
 | 
					  async getRencontreTMR(params) {
 | 
				
			||||||
    if (params.length == 1 || params.length == 2) {
 | 
					    if (params.length == 1 || params.length == 2) {
 | 
				
			||||||
      return TMRRencontres.rollRencontre(params[0], params[1])
 | 
					      return game.system.rdd.rencontresTMR.rollRencontre(params[0], params[1])
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -299,20 +354,20 @@ export class RdDCommands {
 | 
				
			|||||||
      show: { title: "Table de résolution" }
 | 
					      show: { title: "Table de résolution" }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    await RdDResolutionTable.rollData(rollData);
 | 
					    await RdDResolutionTable.rollData(rollData);
 | 
				
			||||||
    RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData));
 | 
					    return RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async rollDeDraconique(msg) {
 | 
					  async rollDeDraconique(msg) {
 | 
				
			||||||
    let ddr = await RdDDice.rollTotal("1dr + 7");
 | 
					    let ddr = await RdDDice.rollTotal("1dr + 7");
 | 
				
			||||||
    RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr}`);
 | 
					    return RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr}`);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async getTMRAleatoire(msg, params) {
 | 
					  async getTMRAleatoire(msg, params) {
 | 
				
			||||||
    if (params.length < 2) {
 | 
					    if (params.length < 2) {
 | 
				
			||||||
      let type = params[0];
 | 
					      let type = params[0];
 | 
				
			||||||
      const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true));
 | 
					      const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true));
 | 
				
			||||||
      RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`);
 | 
					      return RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
@@ -320,20 +375,61 @@ export class RdDCommands {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async findTMR(msg, params) {
 | 
					  async findTMR(msg, params) {
 | 
				
			||||||
    const search = Misc.join(params, ' ');
 | 
					    if (params && params.length > 0) {
 | 
				
			||||||
    const found = TMRUtility.findTMR(search);
 | 
					      const search = Misc.join(params, ' ');
 | 
				
			||||||
    if (found?.length > 0) {
 | 
					      const found = TMRUtility.findTMR(search);
 | 
				
			||||||
      return RdDCommands._chatAnswer(msg, `Les TMRs correspondant à '${search}' sont:` + Misc.join(found.map(it => `<br>${it.coord}: ${it.label}`)));
 | 
					      if (found?.length > 0) {
 | 
				
			||||||
 | 
					        return RdDCommands._chatAnswer(msg, `Les TMRs correspondant à '${search}' sont:` + Misc.join(found.map(it => `<br>${it.coord}: ${it.label}`)));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return RdDCommands._chatAnswer(msg, 'Aucune TMR correspondant à ' + search);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return RdDCommands._chatAnswer(msg, 'Aucune TMR correspondant à ' + search);
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async tableRencontres(msg, params) {
 | 
				
			||||||
 | 
					    if (params && params.length > 0) {
 | 
				
			||||||
 | 
					      const search = Misc.join(params, ' ');
 | 
				
			||||||
 | 
					      const solvedTerrain = TMRUtility.findTMRLike(search);
 | 
				
			||||||
 | 
					      if (solvedTerrain == undefined) {
 | 
				
			||||||
 | 
					        return RdDCommands._chatAnswer(msg, 'Aucune TMR correspondant à ' + search);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return await game.system.rdd.rencontresTMR.chatTable(solvedTerrain);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async tableMilieu(msg, params, toChat) {
 | 
				
			||||||
 | 
					    if (params && params.length > 0) {
 | 
				
			||||||
 | 
					      const search = Misc.join(params, ' ');
 | 
				
			||||||
 | 
					      const milieux = await game.system.rdd.environnement.findEnvironnementsLike(search);
 | 
				
			||||||
 | 
					      if (milieux.length == 0) {
 | 
				
			||||||
 | 
					        const tous = Object.values(await game.system.rdd.environnement.milieux());
 | 
				
			||||||
 | 
					        return RdDCommands._chatAnswer(msg, `<strong>Aucun milieu correspondant à '${search}'.</strong>
 | 
				
			||||||
 | 
					          <br>Milieux disponibles:
 | 
				
			||||||
 | 
					          <br><ul class="chat-list"><li>${tous.reduce(Misc.joining('</li><li>'))}</li></ul>`);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (milieux.length > 1) {
 | 
				
			||||||
 | 
					        ui.notifications.warn(`<strong>Plusieurs milieux correspondent à '${search}'</strong>:
 | 
				
			||||||
 | 
					          <br><ul class="chat-list"><li>${milieux.reduce(Misc.joining('</li><li>'))}</li></ul>`);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      const tableName = `ressources en ${milieux.reduce(Misc.joining(', '))}`;
 | 
				
			||||||
 | 
					      if (toChat == 'liste') {
 | 
				
			||||||
 | 
					        return await game.system.rdd.environnement.searchToChatMessage(milieux, tableName);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else {
 | 
				
			||||||
 | 
					        const row = await game.system.rdd.environnement.getRandom(milieux, tableName);
 | 
				
			||||||
 | 
					        await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item');
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  getCoutXpComp(msg, params) {
 | 
					  getCoutXpComp(msg, params) {
 | 
				
			||||||
    if (params && (params.length == 1 || params.length == 2)) {
 | 
					    if (params && (params.length == 1 || params.length == 2)) {
 | 
				
			||||||
      let to = params.length == 1 ? Number(params[0]) : Number(params[1]);
 | 
					      let to = params.length == 1 ? Number(params[0]) : Number(params[1]);
 | 
				
			||||||
      let from = params.length == 1 ? to - 1 : Number(params[0]);
 | 
					      let from = params.length == 1 ? to - 1 : Number(params[0]);
 | 
				
			||||||
      RdDCommands._chatAnswer(msg, `Coût pour passer une compétence de ${from} à ${to}: ${RdDItemCompetence.getDeltaXp(from, to)}`);
 | 
					      return RdDCommands._chatAnswer(msg, `Coût pour passer une compétence de ${from} à ${to}: ${RdDItemCompetence.getDeltaXp(from, to)}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
@@ -344,7 +440,7 @@ export class RdDCommands {
 | 
				
			|||||||
  getCoutXpCarac(msg, params) {
 | 
					  getCoutXpCarac(msg, params) {
 | 
				
			||||||
    if (params && params.length == 1) {
 | 
					    if (params && params.length == 1) {
 | 
				
			||||||
      let to = Number(params[0]);
 | 
					      let to = Number(params[0]);
 | 
				
			||||||
      RdDCommands._chatAnswer(msg, `Coût pour passer une caractéristique de ${to - 1} à ${to}: ${RdDCarac.getCaracXp(to)}`);
 | 
					      return RdDCommands._chatAnswer(msg, `Coût pour passer une caractéristique de ${to - 1} à ${to}: ${RdDCarac.getCaracXp(to)}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
@@ -404,5 +500,6 @@ export class RdDCommands {
 | 
				
			|||||||
  async getMeteo(msg, params) {
 | 
					  async getMeteo(msg, params) {
 | 
				
			||||||
    return await RdDMeteo.getMeteo();
 | 
					    return await RdDMeteo.getMeteo();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,13 +29,14 @@ export class RddCompendiumOrganiser {
 | 
				
			|||||||
  
 | 
					  
 | 
				
			||||||
  static getEntityTypeLabel(entity) {
 | 
					  static getEntityTypeLabel(entity) {
 | 
				
			||||||
    const documentName = entity?.documentName
 | 
					    const documentName = entity?.documentName
 | 
				
			||||||
    const type = entity?.type 
 | 
					    const type = entity?.type
 | 
				
			||||||
    if (documentName === 'Actor' || documentName === 'Item') {
 | 
					    if (documentName === 'Actor' || documentName === 'Item') {
 | 
				
			||||||
      const label = CONFIG[documentName]?.typeLabels?.[type] ?? type;
 | 
					      const label = CONFIG[documentName]?.typeLabels?.[type] ?? type;
 | 
				
			||||||
      return game.i18n.has(label) ? game.i18n.localize(label) : t;
 | 
					      if (game.i18n.has(label)) {
 | 
				
			||||||
 | 
					        return game.i18n.localize(label);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return type;
 | 
					    return type;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
import { Grammar } from "./grammar.js";
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class RdDConfirm {
 | 
					export class RdDConfirm {
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -45,7 +45,7 @@ export class RdDConfirm {
 | 
				
			|||||||
    return {
 | 
					    return {
 | 
				
			||||||
      "actionSave": {
 | 
					      "actionSave": {
 | 
				
			||||||
        icon: '<i class="fas fa-user-check"></i>',
 | 
					        icon: '<i class="fas fa-user-check"></i>',
 | 
				
			||||||
        label: "Toujours "+ options.buttonLabel.toLowerCase(),
 | 
					        label: options.buttonLabel + "<br>et ne plus demander",
 | 
				
			||||||
        callback: () => {
 | 
					        callback: () => {
 | 
				
			||||||
          ReglesOptionelles.set(options.settingConfirmer, false);
 | 
					          ReglesOptionelles.set(options.settingConfirmer, false);
 | 
				
			||||||
          options.onAction();
 | 
					          options.onAction();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -144,6 +144,9 @@ export class RdDDice {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async rollOneOf(array) {
 | 
					  static async rollOneOf(array) {
 | 
				
			||||||
 | 
					    if (array == undefined || array.length == 0) {
 | 
				
			||||||
 | 
					      return undefined;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    const roll = await RdDDice.rollTotal(`1d${array.length}`);
 | 
					    const roll = await RdDDice.rollTotal(`1d${array.length}`);
 | 
				
			||||||
    return array[roll - 1];
 | 
					    return array[roll - 1];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -241,7 +244,7 @@ export class RdDDice {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static _getWhisperBlind(options) {
 | 
					  static _getWhisperBlind(options) {
 | 
				
			||||||
    let whisper = null;
 | 
					    let whisper = undefined;
 | 
				
			||||||
    let blind = false;
 | 
					    let blind = false;
 | 
				
			||||||
    let rollMode = options.rollMode ?? game.settings.get("core", "rollMode");
 | 
					    let rollMode = options.rollMode ?? game.settings.get("core", "rollMode");
 | 
				
			||||||
    switch (rollMode) {
 | 
					    switch (rollMode) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
import { RdDCalendrier } from "./rdd-calendrier.js";
 | 
					import { RdDCalendrier } from "./rdd-calendrier.js";
 | 
				
			||||||
import { Grammar } from "./grammar.js";
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
 | 
					import { SystemCompendiums } from "./settings/system-compendiums.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
export class RdDHerbes extends Item {
 | 
					export class RdDHerbes extends Item {
 | 
				
			||||||
@@ -12,9 +13,8 @@ export class RdDHerbes extends Item {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async listCategorieHerbes(categorie) {
 | 
					  static async listCategorieHerbes(categorie) {
 | 
				
			||||||
    return await RdDUtility.loadItems(
 | 
					    const herbes = await SystemCompendiums.getWorldOrCompendiumItems('herbe', 'faune-flore-mineraux');
 | 
				
			||||||
      it => it.type == 'herbe' && it.system.categorie.toLowerCase() == categorie.toLowerCase(),
 | 
					    return herbes.filter(it => Grammar.equalsInsensitive(it.system.categorie, categorie));
 | 
				
			||||||
      'foundryvtt-reve-de-dragon.botanique');
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -42,7 +42,7 @@ export class RdDHerbes extends Item {
 | 
				
			|||||||
    formData.herbesRepos = RdDHerbes.buildHerbesList(this.herbesRepos, 7);
 | 
					    formData.herbesRepos = RdDHerbes.buildHerbesList(this.herbesRepos, 7);
 | 
				
			||||||
    formData.jourMoisOptions = RdDCalendrier.buildJoursMois();
 | 
					    formData.jourMoisOptions = RdDCalendrier.buildJoursMois();
 | 
				
			||||||
    formData.dateActuelle = game.system.rdd.calendrier.getDateFromIndex();
 | 
					    formData.dateActuelle = game.system.rdd.calendrier.getDateFromIndex();
 | 
				
			||||||
    formData.splitDate = game.system.rdd.calendrier.getNumericDateFromIndex(formData.system.prdate);
 | 
					    formData.splitDate = game.system.rdd.calendrier.getDayMonthFromIndex(formData.system.prdate);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,10 +23,9 @@ import { RdDTokenHud } from "./rdd-token-hud.js";
 | 
				
			|||||||
import { RdDCommands } from "./rdd-commands.js";
 | 
					import { RdDCommands } from "./rdd-commands.js";
 | 
				
			||||||
import { RdDCombatManager, RdDCombat } from "./rdd-combat.js";
 | 
					import { RdDCombatManager, RdDCombat } from "./rdd-combat.js";
 | 
				
			||||||
import { ChatUtility } from "./chat-utility.js";
 | 
					import { ChatUtility } from "./chat-utility.js";
 | 
				
			||||||
import { StatusEffects } from "./status-effects.js";
 | 
					import { StatusEffects } from "./settings/status-effects.js";
 | 
				
			||||||
import { RddCompendiumOrganiser } from "./rdd-compendium-organiser.js";
 | 
					import { RddCompendiumOrganiser } from "./rdd-compendium-organiser.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
import { TMRRencontres } from "./tmr-rencontres.js";
 | 
					 | 
				
			||||||
import { RdDHotbar } from "./rdd-hotbar-drop.js"
 | 
					import { RdDHotbar } from "./rdd-hotbar-drop.js"
 | 
				
			||||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
 | 
					import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
 | 
				
			||||||
import { RdDHerbes } from "./rdd-herbes.js";
 | 
					import { RdDHerbes } from "./rdd-herbes.js";
 | 
				
			||||||
@@ -36,6 +35,15 @@ import { RdDPossession } from "./rdd-possession.js";
 | 
				
			|||||||
import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js";
 | 
					import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
import { Migrations } from './migrations.js';
 | 
					import { Migrations } from './migrations.js';
 | 
				
			||||||
 | 
					import { DialogChronologie } from "./dialog-chronologie.js";
 | 
				
			||||||
 | 
					import { SystemCompendiums } from "./settings/system-compendiums.js";
 | 
				
			||||||
 | 
					import { RdDRencontreItemSheet } from "./item-rencontre-sheet.js";
 | 
				
			||||||
 | 
					import { TMRRencontres } from "./tmr-rencontres.js";
 | 
				
			||||||
 | 
					import { RdDHerbeItemSheet } from "./item-herbe-sheet.js";
 | 
				
			||||||
 | 
					import { Environnement } from "./environnement.js";
 | 
				
			||||||
 | 
					import { RdDIngredientItemSheet } from "./item-ingredient-sheet.js";
 | 
				
			||||||
 | 
					import { RdDFauneItemSheet } from "./item-faune-sheet.js";
 | 
				
			||||||
 | 
					import { RdDConteneurItemSheet } from "./item-conteneur-sheet.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
/*  Foundry VTT Initialization                  */
 | 
					/*  Foundry VTT Initialization                  */
 | 
				
			||||||
@@ -77,7 +85,7 @@ Hooks.once("init", async function () {
 | 
				
			|||||||
    name: "calendrier",
 | 
					    name: "calendrier",
 | 
				
			||||||
    scope: "world",
 | 
					    scope: "world",
 | 
				
			||||||
    config: false,
 | 
					    config: false,
 | 
				
			||||||
    default: RdDCalendrier.getCalendrier(0),
 | 
					    default: RdDCalendrier.createCalendrierInitial(),
 | 
				
			||||||
    type: Object
 | 
					    type: Object
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -107,6 +115,8 @@ Hooks.once("init", async function () {
 | 
				
			|||||||
    default: RdDCalendrier.createCalendrierPos(),
 | 
					    default: RdDCalendrier.createCalendrierPos(),
 | 
				
			||||||
    type: Object
 | 
					    type: Object
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
 | 
					  game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
 | 
				
			||||||
    name: "Supprimer les dialogues de combat",
 | 
					    name: "Supprimer les dialogues de combat",
 | 
				
			||||||
@@ -155,8 +165,8 @@ Hooks.once("init", async function () {
 | 
				
			|||||||
      RdDCombat.onSocketMessage(sockmsg);
 | 
					      RdDCombat.onSocketMessage(sockmsg);
 | 
				
			||||||
      ChatUtility.onSocketMessage(sockmsg);
 | 
					      ChatUtility.onSocketMessage(sockmsg);
 | 
				
			||||||
      RdDActor.onSocketMessage(sockmsg);
 | 
					      RdDActor.onSocketMessage(sockmsg);
 | 
				
			||||||
    } catch(e) {
 | 
					    } catch (e) {
 | 
				
			||||||
      console.error('game.socket.on(SYSTEM_SOCKET_ID) Exception: ', sockmsg,' => ', e)
 | 
					      console.error('game.socket.on(SYSTEM_SOCKET_ID) Exception: ', sockmsg, ' => ', e)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -179,19 +189,30 @@ Hooks.once("init", async function () {
 | 
				
			|||||||
  Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
 | 
					  Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
 | 
				
			||||||
  Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
 | 
					  Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
 | 
				
			||||||
  Items.unregisterSheet("core", ItemSheet);
 | 
					  Items.unregisterSheet("core", ItemSheet);
 | 
				
			||||||
  Items.registerSheet(SYSTEM_RDD, RdDSigneDraconiqueItemSheet, {
 | 
					
 | 
				
			||||||
    label: "Signe draconique",
 | 
					  RdDItemSheet.register(RdDSigneDraconiqueItemSheet);
 | 
				
			||||||
    types: ["signedraconique"],
 | 
					  RdDItemSheet.register(RdDRencontreItemSheet);
 | 
				
			||||||
    makeDefault: true
 | 
					  RdDItemSheet.register(RdDConteneurItemSheet);
 | 
				
			||||||
  });
 | 
					  RdDItemSheet.register(RdDHerbeItemSheet);
 | 
				
			||||||
 | 
					  RdDItemSheet.register(RdDFauneItemSheet);
 | 
				
			||||||
 | 
					  RdDItemSheet.register(RdDIngredientItemSheet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
 | 
					  Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
 | 
				
			||||||
    types: ["arme", "armure", "objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle",
 | 
					    types: [
 | 
				
			||||||
      "tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique", "gemme",
 | 
					      "competence", "competencecreature",
 | 
				
			||||||
      "musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "possession", "sortreserve"], makeDefault: true
 | 
					      "recettealchimique", "musique", "chant", "danse", "jeu", "recettecuisine", "oeuvre",
 | 
				
			||||||
 | 
					      "objet", "arme", "armure", "livre", "potion", "munition",
 | 
				
			||||||
 | 
					      "monnaie", "nourritureboisson", "gemme",
 | 
				
			||||||
 | 
					      "meditation", "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve",
 | 
				
			||||||
 | 
					      "nombreastral", "tache", "maladie", "poison", "possession",
 | 
				
			||||||
 | 
					      "tarot", "extraitpoetique"
 | 
				
			||||||
 | 
					    ], makeDefault: true
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  CONFIG.Combat.documentClass = RdDCombatManager;
 | 
					  CONFIG.Combat.documentClass = RdDCombatManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // préparation des différents modules
 | 
					  // préparation des différents modules
 | 
				
			||||||
 | 
					  SystemCompendiums.init();
 | 
				
			||||||
 | 
					  DialogChronologie.init();
 | 
				
			||||||
  ReglesOptionelles.init();
 | 
					  ReglesOptionelles.init();
 | 
				
			||||||
  RdDUtility.init();
 | 
					  RdDUtility.init();
 | 
				
			||||||
  RdDDice.init();
 | 
					  RdDDice.init();
 | 
				
			||||||
@@ -203,9 +224,10 @@ Hooks.once("init", async function () {
 | 
				
			|||||||
  RddCompendiumOrganiser.init();
 | 
					  RddCompendiumOrganiser.init();
 | 
				
			||||||
  EffetsDraconiques.init()
 | 
					  EffetsDraconiques.init()
 | 
				
			||||||
  TMRUtility.init();
 | 
					  TMRUtility.init();
 | 
				
			||||||
  TMRRencontres.init();
 | 
					 | 
				
			||||||
  RdDHotbar.initDropbar();
 | 
					  RdDHotbar.initDropbar();
 | 
				
			||||||
  RdDPossession.init();
 | 
					  RdDPossession.init();
 | 
				
			||||||
 | 
					  TMRRencontres.init();
 | 
				
			||||||
 | 
					  Environnement.init();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
@@ -223,8 +245,8 @@ function messageDeBienvenue() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
// Register world usage statistics
 | 
					// Register world usage statistics
 | 
				
			||||||
function registerUsageCount( registerKey ) {
 | 
					function registerUsageCount(registerKey) {
 | 
				
			||||||
  if ( game.user.isGM ) {
 | 
					  if (game.user.isGM) {
 | 
				
			||||||
    game.settings.register("world", "world-key", {
 | 
					    game.settings.register("world", "world-key", {
 | 
				
			||||||
      name: "Unique world key",
 | 
					      name: "Unique world key",
 | 
				
			||||||
      scope: "world",
 | 
					      scope: "world",
 | 
				
			||||||
@@ -234,9 +256,9 @@ function registerUsageCount( registerKey ) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let worldKey = game.settings.get("world", "world-key")
 | 
					    let worldKey = game.settings.get("world", "world-key")
 | 
				
			||||||
    if ( worldKey == undefined || worldKey == "" ) {
 | 
					    if (worldKey == undefined || worldKey == "") {
 | 
				
			||||||
      worldKey = randomID(32)
 | 
					      worldKey = randomID(32)
 | 
				
			||||||
      game.settings.set("world", "world-key", worldKey )
 | 
					      game.settings.set("world", "world-key", worldKey)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
 | 
					    let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
 | 
				
			||||||
    $.ajax(regURL)
 | 
					    $.ajax(regURL)
 | 
				
			||||||
@@ -276,7 +298,7 @@ Hooks.once("ready", async function () {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  if (Misc.isUniqueConnectedGM()) {
 | 
					  if (Misc.isUniqueConnectedGM()) {
 | 
				
			||||||
    messageDeBienvenue();
 | 
					    messageDeBienvenue();
 | 
				
			||||||
    registerUsageCount( SYSTEM_RDD );
 | 
					    registerUsageCount(SYSTEM_RDD);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -321,17 +343,3 @@ async function migrationPngWebp_1_5_34() {
 | 
				
			|||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d));
 | 
					Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					 | 
				
			||||||
/*  Foundry VTT chat message                    */
 | 
					 | 
				
			||||||
/* -------------------------------------------- */
 | 
					 | 
				
			||||||
Hooks.on("chatMessage", (html, content, msg) => {
 | 
					 | 
				
			||||||
  if (content[0] == '/') {
 | 
					 | 
				
			||||||
    let regExp = /(\S+)/g;
 | 
					 | 
				
			||||||
    let commands = content.match(regExp);
 | 
					 | 
				
			||||||
    if (game.system.rdd.commands.processChatCommand(commands, content, msg)) {
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ import { RdDCombat } from "./rdd-combat.js";
 | 
				
			|||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
					import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
				
			||||||
import { RdDRoll } from "./rdd-roll.js";
 | 
					import { RdDRoll } from "./rdd-roll.js";
 | 
				
			||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
 | 
					import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
 | 
				
			||||||
 | 
					import { Targets } from "./targets.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
/* On part du principe qu'une entité démarre tjs 
 | 
					/* On part du principe qu'une entité démarre tjs 
 | 
				
			||||||
@@ -27,7 +28,139 @@ export class RdDPossession {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static updateEtatPossession(possession) {
 | 
					  static async onAttaquePossession(target, attacker, competence, suitePossession = undefined) {
 | 
				
			||||||
 | 
					    const defender = target.actor;
 | 
				
			||||||
 | 
					    const fromEntite = RdDPossession.searchPossessionFromEntite(attacker, defender);
 | 
				
			||||||
 | 
					    const isNouvelle = !suitePossession && ! fromEntite;
 | 
				
			||||||
 | 
					    const possession = (suitePossession ?? fromEntite ?? (await RdDPossession.createPossession(attacker, defender)));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    RdDPossession.$updateEtatPossession(possession)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let rollData = {
 | 
				
			||||||
 | 
					      mode: "possession",
 | 
				
			||||||
 | 
					      isECNIDefender: false,
 | 
				
			||||||
 | 
					      competence: competence,
 | 
				
			||||||
 | 
					      possession: possession,
 | 
				
			||||||
 | 
					      attacker: attacker,
 | 
				
			||||||
 | 
					      defender: defender,
 | 
				
			||||||
 | 
					      targetToken: Targets.extractTokenData(target)
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    if (attacker.isCreatureEntite()) {
 | 
				
			||||||
 | 
					      RdDItemCompetenceCreature.setRollDataCreature(rollData)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    await RdDPossession.$rollAttaquePossession(attacker, rollData, isNouvelle);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async onConjurerPossession(attacker, competence, possession) {
 | 
				
			||||||
 | 
					    possession = duplicate(possession);
 | 
				
			||||||
 | 
					    RdDPossession.$updateEtatPossession(possession)
 | 
				
			||||||
 | 
					    let rollData = {
 | 
				
			||||||
 | 
					      mode: "possession",
 | 
				
			||||||
 | 
					      isECNIDefender: true,
 | 
				
			||||||
 | 
					      competence: competence,
 | 
				
			||||||
 | 
					      possession: possession,
 | 
				
			||||||
 | 
					      attacker: attacker,
 | 
				
			||||||
 | 
					      defender: game.actors.get(possession.system.possesseurid)
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    await RdDPossession.$rollAttaquePossession(attacker, rollData);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async onDefensePossession(attackerId, defenderId, possessionId) {
 | 
				
			||||||
 | 
					    let attacker = game.actors.get(attackerId)
 | 
				
			||||||
 | 
					    let possession = attacker?.getPossession(possessionId)
 | 
				
			||||||
 | 
					    defenderId = defenderId ?? possession?.system.possesseurid ?? undefined
 | 
				
			||||||
 | 
					    let defender = game.actors.get(defenderId)
 | 
				
			||||||
 | 
					    possession = possession ?? defender?.getPossession(possessionId) ?? undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!possession) {
 | 
				
			||||||
 | 
					      ui.notifications.warn("Une erreur s'est produite : Aucune possession trouvée !!")
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    possession = duplicate(possession)
 | 
				
			||||||
 | 
					    // Update for draconic roll
 | 
				
			||||||
 | 
					    let rollData = {
 | 
				
			||||||
 | 
					      mode: "conjuration",
 | 
				
			||||||
 | 
					      isECNIDefender: defender.type == "entite",
 | 
				
			||||||
 | 
					      possession: possession,
 | 
				
			||||||
 | 
					      attacker: attacker,
 | 
				
			||||||
 | 
					      defender: defender,
 | 
				
			||||||
 | 
					      competence: defender.getDraconicOuPossession(),
 | 
				
			||||||
 | 
					      selectedCarac: defender.system.carac.reve,
 | 
				
			||||||
 | 
					      forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: defender.getReveActuel() } }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    rollData.competence.system.defaut_carac = 'reve-actuel'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await RdDPossession.$rollDefensePossession(defender, rollData);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async $rollAttaquePossession(attacker, rollData, isNouvelle = false) {
 | 
				
			||||||
 | 
					    const dialog = await RdDRoll.create(attacker, rollData,
 | 
				
			||||||
 | 
					      { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'jet-possession',
 | 
				
			||||||
 | 
					        label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession',
 | 
				
			||||||
 | 
					        callbacks: [
 | 
				
			||||||
 | 
					          { condition: r => (r.rolled.isSuccess), action: async (r) => await RdDPossession.$onRollPossession(r, true, isNouvelle) },
 | 
				
			||||||
 | 
					          { condition: r => (r.rolled.isEchec), action: async (r) => await RdDPossession.$onRollPossession(r, false, isNouvelle) },
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      dialog.render(true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async $onRollPossession(rollData, isSuccess, isNouvelle = false) {
 | 
				
			||||||
 | 
					    rollData.possession.isSuccess = isSuccess;
 | 
				
			||||||
 | 
					    RdDPossession.$updateEtatPossession(rollData.possession);
 | 
				
			||||||
 | 
					    if (isNouvelle) {
 | 
				
			||||||
 | 
					      // Creer la possession sur le defenseur
 | 
				
			||||||
 | 
					      rollData.defender.createEmbeddedDocuments('Item', [rollData.possession.toObject()])
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async $rollDefensePossession(defender, rollData) {
 | 
				
			||||||
 | 
					    const dialog = await RdDRoll.create(defender, rollData,
 | 
				
			||||||
 | 
					      { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.html' },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: 'conjurer',
 | 
				
			||||||
 | 
					        label: 'Conjurer une Possession',
 | 
				
			||||||
 | 
					        callbacks: [
 | 
				
			||||||
 | 
					          { action: async (r) => await RdDPossession.$onRollConjuration(r) }
 | 
				
			||||||
 | 
					        ]  
 | 
				
			||||||
 | 
					      }  
 | 
				
			||||||
 | 
					    );  
 | 
				
			||||||
 | 
					    dialog.render(true);
 | 
				
			||||||
 | 
					  }  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async $onRollConjuration(rollData) {
 | 
				
			||||||
 | 
					    let actor = game.actors.get(rollData.possession.system.possedeid)
 | 
				
			||||||
 | 
					    if (!rollData.rolled.isSuccess) {
 | 
				
			||||||
 | 
					      if (rollData.isECNIDefender) {
 | 
				
			||||||
 | 
					        rollData.possession.system.compteur--
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        rollData.possession.system.compteur++
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      let update = { _id: rollData.possession._id, "system.compteur": rollData.possession.system.compteur }
 | 
				
			||||||
 | 
					      await actor.updateEmbeddedDocuments('Item', [update])
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RdDPossession.$updateEtatPossession(rollData.possession)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await RdDResolutionTable.displayRollData(rollData,rollData.defender, 'chat-resultat-possession.html')
 | 
				
			||||||
 | 
					    if (rollData.possession.isPosseder || rollData.possession.isConjurer) {
 | 
				
			||||||
 | 
					      // conjuration
 | 
				
			||||||
 | 
					      actor.deleteEmbeddedDocuments("Item", [rollData.possession._id])
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static $updateEtatPossession(possession) {
 | 
				
			||||||
    possession.ptsConjuration = 0
 | 
					    possession.ptsConjuration = 0
 | 
				
			||||||
    possession.ptsPossession = 0
 | 
					    possession.ptsPossession = 0
 | 
				
			||||||
    console.log("Possession", possession)
 | 
					    console.log("Possession", possession)
 | 
				
			||||||
@@ -48,122 +181,15 @@ export class RdDPossession {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async resultConjuration(rollData) {
 | 
					  static async createPossession(attacker, defender) {
 | 
				
			||||||
    let actor = game.actors.get(rollData.possession.system.possedeid)
 | 
					    return await Item.create({
 | 
				
			||||||
    if (!rollData.rolled.isSuccess) {
 | 
					        name: "Possession en cours de " + attacker.name, type: 'possession',
 | 
				
			||||||
      if (rollData.isECNIDefender) {
 | 
					        img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
 | 
				
			||||||
        rollData.possession.system.compteur--
 | 
					        system: { description: "", typepossession: attacker.name, possede: false, possessionid: randomID(16), possesseurid: attacker.id, possedeid: defender.id, date: 0, compteur: 0 }
 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        rollData.possession.system.compteur++
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      let update = { _id: rollData.possession._id, "system.compteur": rollData.possession.system.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) {
 | 
					 | 
				
			||||||
      actor.deleteEmbeddedDocuments("Item", [rollData.possession._id])
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async onDefensePossession(attackerId, defenderId, possessionId) {
 | 
					 | 
				
			||||||
    let attacker = game.actors.get(attackerId)
 | 
					 | 
				
			||||||
    let defender = game.actors.get(defenderId)
 | 
					 | 
				
			||||||
    let possession = attacker.getPossession(possessionId) ?? defender.getPossession(possessionId) ;
 | 
					 | 
				
			||||||
    if (!possession) {
 | 
					 | 
				
			||||||
      ui.notifications.warn("Une erreur s'est produite : Aucune possession trouvée !!")
 | 
					 | 
				
			||||||
      return
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // Update for draconic roll
 | 
					 | 
				
			||||||
    let rollData = {
 | 
					 | 
				
			||||||
      mode: "conjuration",
 | 
					 | 
				
			||||||
      isECNIDefender: defender.type == "entite",
 | 
					 | 
				
			||||||
      possession: duplicate(possession),
 | 
					 | 
				
			||||||
      attacker: attacker,
 | 
					 | 
				
			||||||
      defender: defender,
 | 
					 | 
				
			||||||
      competence: defender.getDraconicOuPossession(),
 | 
					 | 
				
			||||||
      selectedCarac: defender.system.carac.reve,
 | 
					 | 
				
			||||||
      forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: defender.getReveActuel() } }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    rollData.competence.system.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: 450 }
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        name: 'conjurer',
 | 
					        temporary: true
 | 
				
			||||||
        label: 'Conjurer une Possession',
 | 
					      })
 | 
				
			||||||
        callbacks: [
 | 
					 | 
				
			||||||
          { action: async r => await this.resultConjuration(r) }
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    dialog.render(true)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  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;
 | 
					 | 
				
			||||||
    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,
 | 
					 | 
				
			||||||
      attacker: attacker,
 | 
					 | 
				
			||||||
      defender: defender
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    if (attacker.isCreature()) {
 | 
					 | 
				
			||||||
      RdDItemCompetenceCreature.setRollDataCreature(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: 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) },
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    dialog.render(true)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  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",
 | 
					 | 
				
			||||||
      system: { description: "", typepossession: attacker.name, possede: false, possessionid: randomID(16), possesseurid: attacker.id, possedeid: defender.id, date: 0, compteur: 0 }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // Creates only the possession on the personnage side
 | 
					 | 
				
			||||||
    let poss = await defender.createEmbeddedDocuments('Item', [possessionData])
 | 
					 | 
				
			||||||
    return duplicate(poss[0])
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import { ChatUtility } from "./chat-utility.js";
 | 
					import { ChatUtility } from "./chat-utility.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
import { RdDDice } from "./rdd-dice.js";
 | 
					import { RdDDice } from "./rdd-dice.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * difficultés au delà de -10
 | 
					 * difficultés au delà de -10
 | 
				
			||||||
@@ -14,7 +14,7 @@ const levelDown = [
 | 
				
			|||||||
  { level: -15, score: 1, norm: 1, sign: 0, part: 0, epart: 2, etotal: 10 },
 | 
					  { level: -15, score: 1, norm: 1, sign: 0, part: 0, epart: 2, etotal: 10 },
 | 
				
			||||||
  { level: -16, score: 1, norm: 1, sign: 0, part: 0, epart: 0, etotal: 2 }
 | 
					  { level: -16, score: 1, norm: 1, sign: 0, part: 0, epart: 0, etotal: 2 }
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
const levelImpossible = { score: 0, norm:0, sign: 0, part: 0, epart: 0, etotal: 1 };
 | 
					const levelImpossible = { score: 0, norm: 0, sign: 0, part: 0, epart: 0, etotal: 1 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const reussites = [
 | 
					const reussites = [
 | 
				
			||||||
  { code: "etotal", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: -4, ptQualite: -6, quality: "Echec total", condition: (target, roll) => roll >= target.etotal && roll <= 100 },
 | 
					  { code: "etotal", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: -4, ptQualite: -6, quality: "Echec total", condition: (target, roll) => roll >= target.etotal && roll <= 100 },
 | 
				
			||||||
@@ -42,6 +42,44 @@ export class RdDResolutionTable {
 | 
				
			|||||||
    return table;
 | 
					    return table;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static computeChances(carac, level) {
 | 
				
			||||||
 | 
					    if (level < -16) {
 | 
				
			||||||
 | 
					      return levelImpossible;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (level < -10) {
 | 
				
			||||||
 | 
					      return levelDown.find(it => it.level == level);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const percentage = RdDResolutionTable.computePercentage(carac, level);
 | 
				
			||||||
 | 
					    return this._computeCell(level, percentage);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static _computeRow(caracValue) {
 | 
				
			||||||
 | 
					    let dataRow = [
 | 
				
			||||||
 | 
					      this._computeCell(-10, Math.max(Math.floor(caracValue / 4), 1)),
 | 
				
			||||||
 | 
					      this._computeCell(-9, Math.max(Math.floor(caracValue / 2), 1))
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    for (var diff = -8; diff <= 22; diff++) {
 | 
				
			||||||
 | 
					      dataRow[diff + 10] = this._computeCell(diff, RdDResolutionTable.computePercentage(caracValue, diff));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return dataRow;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static _computeCell(niveau, percentage) {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      niveau: niveau,
 | 
				
			||||||
 | 
					      score: percentage,
 | 
				
			||||||
 | 
					      norm: Math.min(99, percentage),
 | 
				
			||||||
 | 
					      sign: this._reussiteSignificative(percentage),
 | 
				
			||||||
 | 
					      part: this._reussitePart(percentage),
 | 
				
			||||||
 | 
					      epart: this._echecParticulier(percentage),
 | 
				
			||||||
 | 
					      etotal: this._echecTotal(percentage)
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static getResultat(code) {
 | 
					  static getResultat(code) {
 | 
				
			||||||
    let resultat = reussites.find(r => code == r.code);
 | 
					    let resultat = reussites.find(r => code == r.code);
 | 
				
			||||||
@@ -51,17 +89,6 @@ export class RdDResolutionTable {
 | 
				
			|||||||
    return resultat;
 | 
					    return resultat;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static explain(rolled) {
 | 
					 | 
				
			||||||
    let message = "<br>Jet : <strong>" + rolled.roll + "</strong> sur " + rolled.score + "% ";
 | 
					 | 
				
			||||||
    if (rolled.caracValue != null && rolled.finalLevel != null) {
 | 
					 | 
				
			||||||
      message += (rolled.diviseurSignificative > 1 ? `(1/${rolled.diviseurSignificative} de ` : "(")
 | 
					 | 
				
			||||||
        + rolled.caracValue + " à " + Misc.toSignedString(rolled.finalLevel) + ") ";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    message += '<strong>' + rolled.quality + '</strong>'
 | 
					 | 
				
			||||||
    return message;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
 | 
					  static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
 | 
				
			||||||
    return await ChatUtility.createChatWithRollMode(actor?.userName ?? game.user.name, {
 | 
					    return await ChatUtility.createChatWithRollMode(actor?.userName ?? game.user.name, {
 | 
				
			||||||
@@ -82,8 +109,8 @@ export class RdDResolutionTable {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async roll(caracValue, finalLevel, rollData = {}){
 | 
					  static async roll(caracValue, finalLevel, rollData = {}) {
 | 
				
			||||||
    let chances = this.computeChances(caracValue, finalLevel);
 | 
					    let chances = duplicate(this.computeChances(caracValue, finalLevel));
 | 
				
			||||||
    this._updateChancesWithBonus(chances, rollData.bonus, finalLevel);
 | 
					    this._updateChancesWithBonus(chances, rollData.bonus, finalLevel);
 | 
				
			||||||
    this._updateChancesFactor(chances, rollData.diviseurSignificative);
 | 
					    this._updateChancesFactor(chances, rollData.diviseurSignificative);
 | 
				
			||||||
    chances.showDice = rollData.showDice;
 | 
					    chances.showDice = rollData.showDice;
 | 
				
			||||||
@@ -95,7 +122,7 @@ export class RdDResolutionTable {
 | 
				
			|||||||
    rolled.bonus = rollData.bonus;
 | 
					    rolled.bonus = rollData.bonus;
 | 
				
			||||||
    rolled.factorHtml = Misc.getFractionHtml(rollData.diviseurSignificative);
 | 
					    rolled.factorHtml = Misc.getFractionHtml(rollData.diviseurSignificative);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ReglesOptionelles.isUsing("afficher-colonnes-reussite")){
 | 
					    if (ReglesOptionelles.isUsing("afficher-colonnes-reussite")) {
 | 
				
			||||||
      rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll);
 | 
					      rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll);
 | 
				
			||||||
      rolled.ajustementNecessaire = rolled.niveauNecessaire - finalLevel;
 | 
					      rolled.ajustementNecessaire = rolled.niveauNecessaire - finalLevel;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -103,28 +130,39 @@ export class RdDResolutionTable {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static findNiveauNecessaire(caracValue, rollValue) {
 | 
					  static findNiveauNecessaire(carac, rolled) {
 | 
				
			||||||
    for (let cell of this.resolutionTable[caracValue]) {
 | 
					    if (carac == 0) {
 | 
				
			||||||
      if ( rollValue <= cell.norm) {
 | 
					      return NaN;
 | 
				
			||||||
        return cell.niveau;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 16; // Dummy default
 | 
					    if (rolled >= carac){
 | 
				
			||||||
 | 
					      const upper = Math.ceil(rolled/carac);
 | 
				
			||||||
 | 
					      return 2*upper -10
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (rolled > Math.floor(carac/2)) {
 | 
				
			||||||
 | 
					      return -8
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (rolled > Math.floor(carac/4)) {
 | 
				
			||||||
 | 
					      return -9
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (rolled > 1) {
 | 
				
			||||||
 | 
					      return -10
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return -11;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static _updateChancesFactor(chances, diviseur) {
 | 
					  static _updateChancesFactor(chances, diviseur) {
 | 
				
			||||||
    if (chances.level > -11 && diviseur && diviseur > 1) {
 | 
					    if (chances.level > -11 && diviseur && diviseur > 1) {
 | 
				
			||||||
      let newScore = Math.floor(chances.score / diviseur);
 | 
					      let newScore = Math.floor(chances.score / diviseur);
 | 
				
			||||||
      mergeObject(chances, this._computeCell(null, newScore), { overwrite: true });
 | 
					      mergeObject(chances, this._computeCell(undefined, newScore), { overwrite: true });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static _updateChancesWithBonus(chances, bonus, finalLevel) {
 | 
					  static _updateChancesWithBonus(chances, bonus, finalLevel) {
 | 
				
			||||||
    if (bonus && finalLevel>-11) {
 | 
					    if (bonus && finalLevel > -11) {
 | 
				
			||||||
      let newScore = Number(chances.score) + bonus;
 | 
					      let newScore = Number(chances.score) + bonus;
 | 
				
			||||||
      mergeObject(chances, this._computeCell(null, newScore), { overwrite: true });
 | 
					      mergeObject(chances, this._computeCell(undefined, newScore), { overwrite: true });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -142,21 +180,19 @@ export class RdDResolutionTable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async rollChances(chances, diviseur, forceDiceResult = -1) {
 | 
					  static async rollChances(chances, diviseur, forceDiceResult = -1) {
 | 
				
			||||||
    chances.forceDiceResult = forceDiceResult <= 0 || forceDiceResult > 100 ? undefined : {total: forceDiceResult};
 | 
					    chances.forceDiceResult = forceDiceResult <= 0 || forceDiceResult > 100 ? undefined : { total: forceDiceResult };
 | 
				
			||||||
    chances.roll = await RdDDice.rollTotal( "1d100", chances);
 | 
					    chances.roll = await RdDDice.rollTotal("1d100", chances);
 | 
				
			||||||
    mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
 | 
					    mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
 | 
				
			||||||
    return chances;
 | 
					    return chances;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static computeChances(caracValue, difficulte) {
 | 
					  static computePercentage(carac, diff) {
 | 
				
			||||||
    if (difficulte < -16) {
 | 
					    if (diff < -16) return 0
 | 
				
			||||||
      return duplicate(levelImpossible);
 | 
					    if (diff < -10) return 1
 | 
				
			||||||
    }
 | 
					    if (diff == -10) return Math.max(Math.floor(carac / 4), 1)
 | 
				
			||||||
    if (difficulte < -10) {
 | 
					    if (diff == -9) return Math.max(Math.floor(carac / 2), 1)
 | 
				
			||||||
      return duplicate(levelDown.find(levelData => levelData.level == difficulte));
 | 
					    return Math.max(Math.floor(carac * (diff + 10) / 2), 1);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return duplicate(RdDResolutionTable.resolutionTable[caracValue][difficulte + 10]);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -213,31 +249,6 @@ export class RdDResolutionTable {
 | 
				
			|||||||
    return reussite;
 | 
					    return reussite;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static _computeRow(caracValue) {
 | 
					 | 
				
			||||||
    let dataRow = [
 | 
					 | 
				
			||||||
      this._computeCell(-10, Math.max(Math.floor(caracValue / 4), 1)),
 | 
					 | 
				
			||||||
      this._computeCell(-9, Math.max(Math.floor(caracValue / 2), 1))
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
    for (var diff = -8; diff <= 22; diff++) {
 | 
					 | 
				
			||||||
      dataRow[diff + 10] = this._computeCell(diff, Math.max(Math.floor(caracValue * (diff + 10) / 2), 1));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return dataRow;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static _computeCell(niveau, percentage) {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      niveau: niveau,
 | 
					 | 
				
			||||||
      score: percentage,
 | 
					 | 
				
			||||||
      norm: Math.min(99, percentage),
 | 
					 | 
				
			||||||
      sign: this._reussiteSignificative(percentage),
 | 
					 | 
				
			||||||
      part: this._reussitePart(percentage),
 | 
					 | 
				
			||||||
      epart: this._echecParticulier(percentage),
 | 
					 | 
				
			||||||
      etotal: this._echecTotal(percentage)
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static _reussiteSignificative(percentage) {
 | 
					  static _reussiteSignificative(percentage) {
 | 
				
			||||||
    return Math.floor(percentage / 2);
 | 
					    return Math.floor(percentage / 2);
 | 
				
			||||||
@@ -261,92 +272,34 @@ export class RdDResolutionTable {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static buildHTMLResults(caracValue, levelValue) {
 | 
					  static subTable(carac, level, delta = { carac: 2, level: 5}) {
 | 
				
			||||||
    if (caracValue == undefined || isNaN(caracValue)) caracValue = 10;
 | 
					    return {
 | 
				
			||||||
    if (levelValue == undefined || isNaN(levelValue)) levelValue = 0;
 | 
					      carac,
 | 
				
			||||||
 | 
					      level,
 | 
				
			||||||
    let cell = this.computeChances(caracValue, levelValue);
 | 
					      minCarac: carac - (delta?.carac ?? 2),
 | 
				
			||||||
    cell.epart = cell.epart > 99 ? 'N/A' : cell.epart;
 | 
					      maxCarac: carac + (delta?.carac ?? 2),
 | 
				
			||||||
    cell.etotal = cell.etotal > 100 ? 'N/A' : cell.etotal;
 | 
					      minLevel: level - (delta?.level ?? 5),
 | 
				
			||||||
    cell.score = Math.min(cell.score, 99);
 | 
					      maxLevel: level + (delta?.level ?? 5)
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    return `
 | 
					 | 
				
			||||||
    <span class="table-proba-reussite competence-label">
 | 
					 | 
				
			||||||
    Particulière: <span class="rdd-roll-part">${cell.part}</span>
 | 
					 | 
				
			||||||
    - Significative: <span class="rdd-roll-sign">${cell.sign}</span>
 | 
					 | 
				
			||||||
    - Réussite: <span class="rdd-roll-norm">${cell.score}</span>
 | 
					 | 
				
			||||||
    - Echec Particulier: <span class="rdd-roll-epart">${cell.epart}</span>
 | 
					 | 
				
			||||||
    - Echec Total: <span class="rdd-roll-etotal">${cell.etotal}</span>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
    `
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static buildHTMLTableExtract(caracValue, levelValue) {
 | 
					  static async buildHTMLTable({ carac: carac, level: level, minCarac = 1, maxCarac = 21, minLevel = -10, maxLevel = 11 }) {
 | 
				
			||||||
    return this.buildHTMLTable(caracValue, levelValue, caracValue - 2, caracValue + 2, levelValue - 5, levelValue + 5)
 | 
					    let colonnes = maxLevel - minLevel;
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static buildHTMLTable(caracValue, levelValue, minCarac = 1, maxCarac = 21, minLevel = -10, maxLevel = 11) {
 | 
					 | 
				
			||||||
    return this._buildHTMLTable(caracValue, levelValue, minCarac, maxCarac, minLevel, maxLevel)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static _buildHTMLTable(caracValue, levelValue, minCarac, maxCarac, minLevel, maxLevel) {
 | 
					 | 
				
			||||||
    let countColonnes = maxLevel - minLevel;
 | 
					 | 
				
			||||||
    minCarac = Math.max(minCarac, 1);
 | 
					    minCarac = Math.max(minCarac, 1);
 | 
				
			||||||
    maxCarac = Math.min(maxCarac, caracMaximumResolution);
 | 
					    maxCarac = Math.min(maxCarac, minCarac + 20);
 | 
				
			||||||
    minLevel = Math.max(minLevel, -10);
 | 
					    minLevel = Math.max(minLevel, -10);
 | 
				
			||||||
    maxLevel = Math.max(Math.min(maxLevel, 22), minLevel + countColonnes);
 | 
					    maxLevel = Math.max(Math.min(maxLevel, 30), minLevel + colonnes);
 | 
				
			||||||
 | 
					    return await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.html', {
 | 
				
			||||||
    let table = $("<table class='table-resolution'/>")
 | 
					      carac: carac,
 | 
				
			||||||
      .append(this._buildHTMLHeader(RdDResolutionTable.resolutionTable[0], minLevel, maxLevel));
 | 
					      difficulte: level,
 | 
				
			||||||
 | 
					      min: minLevel,
 | 
				
			||||||
    for (var rowIndex = minCarac; rowIndex <= maxCarac; rowIndex++) {
 | 
					      rows: RdDResolutionTable.incrementalArray(minCarac, maxCarac),
 | 
				
			||||||
      table.append(this._buildHTMLRow(RdDResolutionTable.resolutionTable[rowIndex], rowIndex, caracValue, levelValue, minLevel, maxLevel));
 | 
					      cols: RdDResolutionTable.incrementalArray(minLevel, maxLevel)
 | 
				
			||||||
    }
 | 
					    });
 | 
				
			||||||
    table.append("</table>");
 | 
					 | 
				
			||||||
    return table;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  static incrementalArray(min, max) {
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					    return Array.from(Array(max-min+1).keys()).map(i=>i+min)
 | 
				
			||||||
  static _buildHTMLHeader(dataRow, minLevel, maxLevel) {
 | 
					 | 
				
			||||||
    let tr = $("<tr/>");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (minLevel > -8) {
 | 
					 | 
				
			||||||
      tr.append($("<th class='table-resolution-level'/>").text("-8"))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (minLevel > -7) {
 | 
					 | 
				
			||||||
      tr.append($("<th class='table-resolution-level'/>").text("..."));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    for (let difficulte = minLevel; difficulte <= maxLevel; difficulte++) {
 | 
					 | 
				
			||||||
      tr.append($("<th class='table-resolution-level'/>").text(Misc.toSignedString(difficulte)));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return tr;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static _buildHTMLRow(dataRow, rowIndex, caracValue, levelValue, minLevel, maxLevel) {
 | 
					 | 
				
			||||||
    let tr = $("<tr/>");
 | 
					 | 
				
			||||||
    let max = maxLevel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (minLevel > -8) {
 | 
					 | 
				
			||||||
      let score = dataRow[-8 + 10].score;
 | 
					 | 
				
			||||||
      tr.append($("<td class='table-resolution-carac'/>").text(score))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (minLevel > -7) {
 | 
					 | 
				
			||||||
      tr.append($("<td/>"))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    for (let difficulte = minLevel; difficulte <= max; difficulte++) {
 | 
					 | 
				
			||||||
      let td = $("<td/>");
 | 
					 | 
				
			||||||
      let score = dataRow[difficulte + 10].score;
 | 
					 | 
				
			||||||
      if (rowIndex == caracValue && levelValue == difficulte) {
 | 
					 | 
				
			||||||
        td.addClass('table-resolution-target');
 | 
					 | 
				
			||||||
      } else if (difficulte == -8) {
 | 
					 | 
				
			||||||
        td.addClass('table-resolution-carac');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      tr.append(td.text(score));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return tr;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import { ENTITE_BLURETTE, ENTITE_INCARNE} from "./constants.js";
 | 
					import { ENTITE_BLURETTE, ENTITE_INCARNE } from "./constants.js";
 | 
				
			||||||
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Extend the base Dialog entity by defining a custom window to perform roll.
 | 
					 * Extend the base Dialog entity by defining a custom window to perform roll.
 | 
				
			||||||
@@ -6,34 +7,39 @@ import { ENTITE_BLURETTE, ENTITE_INCARNE} from "./constants.js";
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export class RdDEncaisser extends Dialog {
 | 
					export class RdDEncaisser extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async encaisser(actor) {
 | 
				
			||||||
 | 
					    let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html',
 | 
				
			||||||
 | 
					      { ajustementsEncaissement: RdDUtility.getAjustementsEncaissement() }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    new RdDEncaisser(html, actor).render(true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  constructor(html, actor) {
 | 
					  constructor(html, actor) {
 | 
				
			||||||
    // Common conf
 | 
					    let dialogConf = {
 | 
				
			||||||
    let buttons = {};
 | 
					      title: "Jet d'Encaissement",
 | 
				
			||||||
    if (!actor.isEntite()){
 | 
					      content: html,
 | 
				
			||||||
      buttons = {
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!actor.isEntite()) {
 | 
				
			||||||
 | 
					      dialogConf.default = "mortel";
 | 
				
			||||||
 | 
					      dialogConf.buttons = {
 | 
				
			||||||
        "mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") },
 | 
					        "mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") },
 | 
				
			||||||
        "non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") },
 | 
					        "non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") },
 | 
				
			||||||
        "sonne": { label: "Sonné", callback: html => this.actor.setSonne() },
 | 
					        "sonne": { label: "Sonné", callback: html => this.actor.setSonne() },
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])){
 | 
					    else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])) {
 | 
				
			||||||
      buttons = {
 | 
					      dialogConf.default = "cauchemar"
 | 
				
			||||||
        "cauchemar": { label: "cauchemar", callback: html => this.performEncaisser("cauchemar") }
 | 
					      dialogConf.buttons = {
 | 
				
			||||||
 | 
					        "cauchemar": { label: "Cauchemar", callback: html => this.performEncaisser("cauchemar") }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let dialogConf = {
 | 
					 | 
				
			||||||
      title: "Jet d'Encaissement",
 | 
					 | 
				
			||||||
      content: html,
 | 
					 | 
				
			||||||
      buttons: buttons,
 | 
					 | 
				
			||||||
      default: "mortel"
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let dialogOptions = {
 | 
					    let dialogOptions = {
 | 
				
			||||||
      classes: ["rdddialog"],
 | 
					      classes: ["rdd-roll-dialog"],
 | 
				
			||||||
      width: 320,
 | 
					      width: 320,
 | 
				
			||||||
      height: 260
 | 
					      height: 'fit-content'
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Select proper roll dialog template and stuff
 | 
					    // Select proper roll dialog template and stuff
 | 
				
			||||||
@@ -44,7 +50,18 @@ export class RdDEncaisser extends Dialog {
 | 
				
			|||||||
    this.encaisserSpecial = "aucun";
 | 
					    this.encaisserSpecial = "aucun";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('[name="modificateurDegats"]').val("0");
 | 
				
			||||||
 | 
					    this.html.find('[name="modificateurDegats"]').change((event) => {
 | 
				
			||||||
 | 
					      this.modifier = event.currentTarget.value; // Update the selected bonus/malus
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.html.find('[name="encaisserSpecial"]').change((event) => {
 | 
				
			||||||
 | 
					      this.encaisserSpecial = event.currentTarget.value; // Update the selected bonus/malus
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  performEncaisser(mortalite) {
 | 
					  performEncaisser(mortalite) {
 | 
				
			||||||
@@ -58,22 +75,4 @@ export class RdDEncaisser extends Dialog {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Setup everything onload
 | 
					 | 
				
			||||||
    $(function () {
 | 
					 | 
				
			||||||
      $("#modificateurDegats").val("0");
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    html.find('#modificateurDegats').change((event) => {
 | 
					 | 
				
			||||||
      this.modifier = event.currentTarget.value; // Update the selected bonus/malus
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('#encaisserSpecial').change((event) => {
 | 
					 | 
				
			||||||
      this.encaisserSpecial = event.currentTarget.value; // Update the selected bonus/malus
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,47 +13,33 @@ export class RdDRollDialogEthylisme extends Dialog {
 | 
				
			|||||||
      title: "Test d'éthylisme",
 | 
					      title: "Test d'éthylisme",
 | 
				
			||||||
      content: html,
 | 
					      content: html,
 | 
				
			||||||
      default: "rollButton",
 | 
					      default: "rollButton",
 | 
				
			||||||
      buttons: { "rollButton": { label: "Test d'éthylisme", callback: html => this.onButton(html) } }
 | 
					      buttons: { "rollButton": { label: "Test d'éthylisme", callback: html => onRoll(this.rollData) } }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    let dialogOptions = { classes: ["rdddialog"], width: 400, height: 270, 'z-index': 99999 }
 | 
					    let dialogOptions = { classes: ["rdd-roll-dialog"], width: 400, height: 'fit-content', 'z-index': 99999 }
 | 
				
			||||||
    super(dialogConf, dialogOptions)
 | 
					    super(dialogConf, dialogOptions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //console.log("ETH", rollData);
 | 
					 | 
				
			||||||
    this.onRoll = onRoll;
 | 
					 | 
				
			||||||
    this.rollData = rollData;
 | 
					    this.rollData = rollData;
 | 
				
			||||||
    this.actor = actor;
 | 
					    this.actor = actor;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async onButton(html) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    this.onRoll(this.rollData);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					    this.bringToTop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find(".force-alcool").change((event) => {
 | 
				
			||||||
 | 
					      this.rollData.forceAlcool = Misc.toInt(event.currentTarget.value);
 | 
				
			||||||
 | 
					      this.updateRollResult();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find(".force-alcool").val(Misc.toInt(this.rollData.forceAlcool));
 | 
				
			||||||
 | 
					    this.updateRollResult();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.bringToTop(); // Ensure top level
 | 
					 | 
				
			||||||
    // Get the rollData stuff
 | 
					 | 
				
			||||||
    var rollData = this.rollData;
 | 
					 | 
				
			||||||
    var dialog = this;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Setup everything onload
 | 
					 | 
				
			||||||
    $(function () {
 | 
					 | 
				
			||||||
      $("#forceAlcool").val(Misc.toInt(rollData.forceAlcool));
 | 
					 | 
				
			||||||
      dialog.updateRollResult();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Update !
 | 
					 | 
				
			||||||
    html.find('#forceAlcool').change((event) => {
 | 
					 | 
				
			||||||
      rollData.forceAlcool = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
 | 
					 | 
				
			||||||
      dialog.updateRollResult();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  async updateRollResult() {
 | 
					  async updateRollResult() {
 | 
				
			||||||
    
 | 
					    this.html.find(".roll-ethylisme").text(this.rollData.vie + " / " + Misc.toSignedString(Number(this.rollData.etat) + Number(this.rollData.forceAlcool) + this.rollData.diffNbDoses));
 | 
				
			||||||
    // Mise à jour valeurs
 | 
					    this.html.find(".table-resolution").remove();
 | 
				
			||||||
    $("#roll-param").text(this.rollData.vie + " / " + Misc.toSignedString(Number(this.rollData.etat) + Number(this.rollData.forceAlcool) + this.rollData.diffNbDoses));
 | 
					 | 
				
			||||||
    $(".table-resolution").remove();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,12 +9,19 @@ const titleTableDeResolution = 'Table de résolution';
 | 
				
			|||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
export class RdDRollResolutionTable extends Dialog {
 | 
					export class RdDRollResolutionTable extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static resolutionTable = undefined;
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async open(rollData = {}) {
 | 
					  static async open() {
 | 
				
			||||||
    RdDRollResolutionTable._setDefaultOptions(rollData);
 | 
					    if (RdDRollResolutionTable.resolutionTable == undefined) {
 | 
				
			||||||
    let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html', rollData);
 | 
					      const rollData = {}
 | 
				
			||||||
    const dialog = new RdDRollResolutionTable(rollData, html);
 | 
					      RdDRollResolutionTable._setDefaultOptions(rollData);
 | 
				
			||||||
    dialog.render(true);
 | 
					      let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html', rollData);
 | 
				
			||||||
 | 
					      RdDRollResolutionTable.resolutionTable = new RdDRollResolutionTable(rollData, html);
 | 
				
			||||||
 | 
					      RdDRollResolutionTable.resolutionTable.render(true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else{
 | 
				
			||||||
 | 
					      RdDRollResolutionTable.resolutionTable.bringToTop();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -53,11 +60,40 @@ export class RdDRollResolutionTable extends Dialog {
 | 
				
			|||||||
        'lancer-fermer': { label: 'Lancer les dés et fermer', callback: html => this.onLancerFermer() }
 | 
					        'lancer-fermer': { label: 'Lancer les dés et fermer', callback: html => this.onLancerFermer() }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    super(conf, { classes: ["rdddialog"], width: 800, height: 800, 'z-index': 99999 });
 | 
					    super(conf, { classes: ["rdd-roll-dialog"], top: 50, width: 'fit-content', height: 'fit-content', 'z-index': 99999 });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.rollData = rollData;
 | 
					    this.rollData = rollData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					    this.bringToTop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find("[name='diffLibre']").val(Misc.toInt(this.rollData.diffLibre));
 | 
				
			||||||
 | 
					    this.html.find("[name='diffConditions']").val(Misc.toInt(this.rollData.diffConditions));
 | 
				
			||||||
 | 
					    this.updateRollResult();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.html.find('.lancer-table-resolution').click((event) => {
 | 
				
			||||||
 | 
					      this.onLancer();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    // Update !
 | 
				
			||||||
 | 
					    this.html.find("[name='diffLibre']").change((event) => {
 | 
				
			||||||
 | 
					      this.rollData.diffLibre = Misc.toInt(event.currentTarget.value);
 | 
				
			||||||
 | 
					      this.updateRollResult();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.html.find("[name='diffConditions']").change((event) => {
 | 
				
			||||||
 | 
					      this.rollData.diffConditions = Misc.toInt(event.currentTarget.value);
 | 
				
			||||||
 | 
					      this.updateRollResult();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.html.find("[name='carac']").change((event) => {
 | 
				
			||||||
 | 
					      let caracKey = event.currentTarget.value;
 | 
				
			||||||
 | 
					      this.rollData.selectedCarac = this.rollData.carac[caracKey];
 | 
				
			||||||
 | 
					      this.updateRollResult();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async onLancer() {
 | 
					  async onLancer() {
 | 
				
			||||||
    await RdDResolutionTable.rollData(this.rollData);
 | 
					    await RdDResolutionTable.rollData(this.rollData);
 | 
				
			||||||
@@ -72,65 +108,36 @@ export class RdDRollResolutionTable extends Dialog {
 | 
				
			|||||||
    await RdDResolutionTable.displayRollData(this.rollData);
 | 
					    await RdDResolutionTable.displayRollData(this.rollData);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					 | 
				
			||||||
    super.activateListeners(html);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.bringToTop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var dialog = this;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Setup everything onload
 | 
					 | 
				
			||||||
    function onLoad(){
 | 
					 | 
				
			||||||
      $("#diffLibre").val(Misc.toInt(dialog.rollData.diffLibre));
 | 
					 | 
				
			||||||
      $("#diffConditions").val(Misc.toInt(dialog.rollData.diffConditions));
 | 
					 | 
				
			||||||
      dialog.updateRollResult();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $(function () { onLoad();});
 | 
					 | 
				
			||||||
    html.find('#lancer').click((event) => {
 | 
					 | 
				
			||||||
      this.onLancer();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    // Update !
 | 
					 | 
				
			||||||
    html.find('#diffLibre').change((event) => {
 | 
					 | 
				
			||||||
      this.rollData.diffLibre = Misc.toInt(event.currentTarget.value);
 | 
					 | 
				
			||||||
      this.updateRollResult();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('#diffConditions').change((event) => {
 | 
					 | 
				
			||||||
      this.rollData.diffConditions = Misc.toInt(event.currentTarget.value);
 | 
					 | 
				
			||||||
      this.updateRollResult();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    html.find('#carac').change((event) => {
 | 
					 | 
				
			||||||
      let caracKey = event.currentTarget.value;
 | 
					 | 
				
			||||||
      this.rollData.selectedCarac = this.rollData.carac[caracKey];
 | 
					 | 
				
			||||||
      this.updateRollResult();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async updateRollResult() {
 | 
					  async updateRollResult() {
 | 
				
			||||||
    let rollData = this.rollData;
 | 
					    let rollData = this.rollData;
 | 
				
			||||||
    rollData.caracValue = parseInt(rollData.selectedCarac.value)
 | 
					    rollData.caracValue = parseInt(rollData.selectedCarac.value)
 | 
				
			||||||
    rollData.finalLevel = this._computeFinalLevel(rollData);
 | 
					    rollData.finalLevel = this._computeFinalLevel(rollData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const htmlTable = await RdDResolutionTable.buildHTMLTable({
 | 
				
			||||||
 | 
					      carac: rollData.caracValue,
 | 
				
			||||||
 | 
					      level: rollData.finalLevel,
 | 
				
			||||||
 | 
					      maxCarac: 20,
 | 
				
			||||||
 | 
					      maxLevel: 10
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Mise à jour valeurs
 | 
					    // Mise à jour valeurs
 | 
				
			||||||
    $("#carac").val(rollData.caracValue);
 | 
					    this.html.find("[name='carac']").val(rollData.caracValue);
 | 
				
			||||||
    $("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
 | 
					    this.html.find(".roll-param-resolution").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
 | 
				
			||||||
    $(".table-resolution").remove();
 | 
					    this.html.find("div.placeholder-resolution").empty().append(htmlTable)
 | 
				
			||||||
    $(".table-proba-reussite").remove();
 | 
					
 | 
				
			||||||
    $("#tableResolution").append(RdDResolutionTable.buildHTMLTable(rollData.caracValue, rollData.finalLevel));
 | 
					 | 
				
			||||||
    $("#tableProbaReussite").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _computeFinalLevel(rollData) {
 | 
					  _computeFinalLevel(rollData) {
 | 
				
			||||||
    const diffConditions = Misc.toInt(rollData.diffConditions);
 | 
					    const diffConditions = Misc.toInt(rollData.diffConditions);
 | 
				
			||||||
    const diffLibre = this._computeDiffLibre(rollData);
 | 
					    const diffLibre = Misc.toInt(rollData.diffLibre);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return diffLibre + diffConditions;
 | 
					    return diffLibre + diffConditions;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  async close() {
 | 
				
			||||||
  _computeDiffLibre(rollData) {
 | 
					    await super.close();
 | 
				
			||||||
    return Misc.toInt(rollData.diffLibre);
 | 
					    RdDRollResolutionTable.resolutionTable = undefined;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ import { Misc } from "./misc.js";
 | 
				
			|||||||
import { RdDBonus } from "./rdd-bonus.js";
 | 
					import { RdDBonus } from "./rdd-bonus.js";
 | 
				
			||||||
import { RdDCarac } from "./rdd-carac.js";
 | 
					import { RdDCarac } from "./rdd-carac.js";
 | 
				
			||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
					import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Extend the base Dialog entity to select roll parameters
 | 
					 * Extend the base Dialog entity to select roll parameters
 | 
				
			||||||
@@ -16,48 +16,42 @@ import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
				
			|||||||
export class RdDRoll extends Dialog {
 | 
					export class RdDRoll extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async create(actor, rollData, dialogConfig, ...actions) {
 | 
					  static async create(actor, rollData, dialogConfig, action) {
 | 
				
			||||||
 | 
					    RdDRoll._ensureCorrectAction(action);
 | 
				
			||||||
    if (actor.isRollWindowsOpened()) {
 | 
					 | 
				
			||||||
      ui.notifications.warn("Vous avez déja une fenêtre de Test ouverte, il faut la fermer avant d'en ouvrir une autre.")
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    actor.setRollWindowsOpened(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    RdDRoll._ensureCorrectActions(actions);
 | 
					 | 
				
			||||||
    RdDRoll._setDefaultOptions(actor, rollData);
 | 
					    RdDRoll._setDefaultOptions(actor, rollData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const html = await renderTemplate(dialogConfig.html, rollData);
 | 
					    const html = await renderTemplate(dialogConfig.html, rollData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let options = { classes: ["rdddialog"], width: 600, height: 500, 'z-index': 99999 };
 | 
					    let options = { classes: ["rdd-roll-dialog"], width: 600, height: 'fit-content', 'z-index': 99999, close: html => {} };
 | 
				
			||||||
    if (dialogConfig.options) {
 | 
					    if (dialogConfig.close) {
 | 
				
			||||||
      mergeObject(options, dialogConfig.options, { overwrite: true })
 | 
					      options.close = dialogConfig.close;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return new RdDRoll(actor, rollData, html, options, actions, dialogConfig.close);
 | 
					    return new RdDRoll(actor, rollData, html, options, action);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static _setDefaultOptions(actor, rollData) {
 | 
					  static _setDefaultOptions(actor, rollData) {
 | 
				
			||||||
    const actorData = actor.system
 | 
					 | 
				
			||||||
    let defaultRollData = {
 | 
					    let defaultRollData = {
 | 
				
			||||||
      alias: actor.name,
 | 
					      alias: actor.name,
 | 
				
			||||||
      ajustementsConditions: CONFIG.RDD.ajustementsConditions,
 | 
					      ajustementsConditions: CONFIG.RDD.ajustementsConditions,
 | 
				
			||||||
      difficultesLibres: CONFIG.RDD.difficultesLibres,
 | 
					      difficultesLibres: CONFIG.RDD.difficultesLibres,
 | 
				
			||||||
      etat: actor.getEtatGeneral(),
 | 
					      etat: actor.getEtatGeneral(),
 | 
				
			||||||
      moral: actor.getMoralTotal(), /* La valeur du moral pour les jets de volonté */
 | 
					      moral: actor.getMoralTotal(), /* La valeur du moral pour les jets de volonté */
 | 
				
			||||||
      carac: actorData.carac,
 | 
					      carac: actor.system.carac,
 | 
				
			||||||
      finalLevel: 0,
 | 
					      finalLevel: 0,
 | 
				
			||||||
      diffConditions: 0,
 | 
					      diffConditions: 0,
 | 
				
			||||||
      diffLibre: rollData.competence?.system.default_diffLibre ?? 0,
 | 
					      diffLibre: rollData.competence?.system.default_diffLibre ?? 0,
 | 
				
			||||||
      malusArmureValue: actor.getMalusArmure(),
 | 
					 | 
				
			||||||
      surencMalusFlag: actor.isPersonnage() ? (actorData.compteurs.surenc.value < 0) : false,
 | 
					 | 
				
			||||||
      surencMalusValue: actor.computeMalusSurEncombrement(),
 | 
					 | 
				
			||||||
      useMalusSurenc: false,
 | 
					 | 
				
			||||||
      useMoral: false,     /* Est-ce que le joueur demande d'utiliser le moral ? Utile si le joueur change plusieurs fois de carac associée. */
 | 
					 | 
				
			||||||
      perteMoralEchec: false, /* Pour l'affichage dans le chat */
 | 
					      perteMoralEchec: false, /* Pour l'affichage dans le chat */
 | 
				
			||||||
      use: { libre: true, conditions: true, surenc: false, encTotal: false },
 | 
					      use: {
 | 
				
			||||||
      isMalusEncombrementTotal: rollData.competence ? RdDItemCompetence.isMalusEncombrementTotal(rollData.competence) : 0,
 | 
					        moral: false, /* Est-ce que le joueur demande d'utiliser le moral ? Utile si le joueur change plusieurs fois de carac associée. */
 | 
				
			||||||
      useMalusEncTotal: false,
 | 
					        libre: true,
 | 
				
			||||||
 | 
					        conditions: true,
 | 
				
			||||||
 | 
					        surenc: actor.isSurenc(),
 | 
				
			||||||
 | 
					        encTotal: true
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
 | 
				
			||||||
 | 
					      malusArmureValue: actor.getMalusArmure(),
 | 
				
			||||||
 | 
					      surencMalusValue: actor.computeMalusSurEncombrement(),
 | 
				
			||||||
      encTotal: actor.getEncTotal(),
 | 
					      encTotal: actor.getEncTotal(),
 | 
				
			||||||
      ajustementAstrologique: actor.ajustementAstrologique(),
 | 
					      ajustementAstrologique: actor.ajustementAstrologique(),
 | 
				
			||||||
      surprise: actor.getSurprise(false),
 | 
					      surprise: actor.getSurprise(false),
 | 
				
			||||||
@@ -66,8 +60,8 @@ export class RdDRoll extends Dialog {
 | 
				
			|||||||
      forceDiceResult: -1
 | 
					      forceDiceResult: -1
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // Mini patch :Ajout du rêve actuel
 | 
					    // Mini patch :Ajout du rêve actuel
 | 
				
			||||||
    if ( actorData.type == "personnage") {
 | 
					    if (actor.system.type == "personnage") {
 | 
				
			||||||
      defaultRollData.carac["reve-actuel"] = actorData.reve.reve
 | 
					      defaultRollData.carac["reve-actuel"] = actor.system.reve.reve
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false });
 | 
					    mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false });
 | 
				
			||||||
@@ -78,6 +72,7 @@ export class RdDRoll extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    RollDataAjustements.calcul(rollData, actor);
 | 
					    RollDataAjustements.calcul(rollData, actor);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static getDiviseurSignificative(rollData) {
 | 
					  static getDiviseurSignificative(rollData) {
 | 
				
			||||||
    let facteurSign = 1;
 | 
					    let facteurSign = 1;
 | 
				
			||||||
@@ -96,159 +91,133 @@ export class RdDRoll extends Dialog {
 | 
				
			|||||||
    return facteurSign;
 | 
					    return facteurSign;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static _ensureCorrectActions(actions) {
 | 
					  static _ensureCorrectAction(action) {
 | 
				
			||||||
    if (actions.length == 0) {
 | 
					    if (action.callbacks == undefined) {
 | 
				
			||||||
      throw 'No action defined';
 | 
					      console.warn('No callback defined for ', action.name);
 | 
				
			||||||
 | 
					      action.callbacks = [{ action: r => console.warn(action.name, r) }];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    actions.forEach(action => {
 | 
					 | 
				
			||||||
      if (action.callbacks == undefined) {
 | 
					 | 
				
			||||||
        action.callbacks = [{ action: r => console.log(action.name, r) }];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  constructor(actor, rollData, html, options, actions, close = undefined) {
 | 
					  constructor(actor, rollData, html, options, action) {
 | 
				
			||||||
    let conf = {
 | 
					    let conf = {
 | 
				
			||||||
      title: actions[0].label,
 | 
					      title: action.label,
 | 
				
			||||||
      content: html,
 | 
					      content: html,
 | 
				
			||||||
      buttons: {},
 | 
					      buttons: {
 | 
				
			||||||
      default: actions[0].name,
 | 
					        "onAction": {
 | 
				
			||||||
      close: close
 | 
					          label: action.label, callback: html => {
 | 
				
			||||||
    };
 | 
					            this.rollData.canClose = true;
 | 
				
			||||||
    for (let action of actions) {
 | 
					            this.onAction(action)
 | 
				
			||||||
      conf.buttons[action.name] = {
 | 
					          }
 | 
				
			||||||
        label: action.label, callback: html => {
 | 
					 | 
				
			||||||
          this.rollData.canClose = true;
 | 
					 | 
				
			||||||
          this.onAction(action, html)
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      };
 | 
					      },
 | 
				
			||||||
    }
 | 
					      default: "onAction",
 | 
				
			||||||
 | 
					      close: options.close
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    super(conf, options);
 | 
					    super(conf, options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.actor = actor;
 | 
					    this.actor = actor;
 | 
				
			||||||
    this.rollData = rollData;
 | 
					    this.rollData = rollData;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  close() {
 | 
					 | 
				
			||||||
    if (this.rollData.canClose) {
 | 
					 | 
				
			||||||
      this.actor.setRollWindowsOpened(false);
 | 
					 | 
				
			||||||
      return super.close();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    ui.notifications.info("Vous devez faire ce jet de dés!");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  async onAction(action, html) {
 | 
					 | 
				
			||||||
    this.rollData.forceDiceResult = Number.parseInt($('#force-dice-result').val()) ?? -1;
 | 
					 | 
				
			||||||
    await RdDResolutionTable.rollData(this.rollData);
 | 
					 | 
				
			||||||
    console.log("RdDRoll -=>", this.rollData, this.rollData.rolled);
 | 
					 | 
				
			||||||
    this.actor.setRollWindowsOpened(false);
 | 
					 | 
				
			||||||
    if (action.callbacks)
 | 
					 | 
				
			||||||
      for (let callback of action.callbacks) {
 | 
					 | 
				
			||||||
        if (callback.condition == undefined || callback.condition(this.rollData)) {
 | 
					 | 
				
			||||||
          await callback.action(this.rollData);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  activateListeners(html) {
 | 
					  activateListeners(html) {
 | 
				
			||||||
    super.activateListeners(html);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
    this.bringToTop();
 | 
					    this.bringToTop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var dialog = this;
 | 
					    console.log('RdDRoll.activateListeners', this.rollData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function onLoad() {
 | 
					    // Update html, according to rollData
 | 
				
			||||||
      let rollData = dialog.rollData;
 | 
					    if (this.rollData.competence) {
 | 
				
			||||||
      console.log('Ouverture RdDRoll', rollData);
 | 
					      const defaut_carac = this.rollData.competence.system.defaut_carac
 | 
				
			||||||
      // Update html, according to rollData
 | 
					      // Set the default carac from the competence item
 | 
				
			||||||
      if (rollData.competence) {
 | 
					      this.rollData.selectedCarac = this.rollData.carac[defaut_carac];
 | 
				
			||||||
        const defaut_carac = rollData.competence.system.defaut_carac
 | 
					      this.html.find("[name='carac']").val(defaut_carac);
 | 
				
			||||||
        // Set the default carac from the competence item
 | 
					 | 
				
			||||||
        rollData.selectedCarac = rollData.carac[defaut_carac];
 | 
					 | 
				
			||||||
        $("#carac").val(defaut_carac);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (rollData.selectedSort) {
 | 
					 | 
				
			||||||
        dialog.setSelectedSort(rollData.selectedSort);
 | 
					 | 
				
			||||||
        $(".draconic").val(rollData.selectedSort.system.listIndex); // Uniquement a la selection du sort, pour permettre de changer 
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      RdDItemSort.setCoutReveReel(rollData.selectedSort);
 | 
					 | 
				
			||||||
      $("#diffLibre").val(Misc.toInt(rollData.diffLibre));
 | 
					 | 
				
			||||||
      $("#diffConditions").val(Misc.toInt(rollData.diffConditions));
 | 
					 | 
				
			||||||
      dialog.updateRollResult();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (this.rollData.selectedSort) {
 | 
				
			||||||
 | 
					      this.setSelectedSort(this.rollData.selectedSort);
 | 
				
			||||||
 | 
					      this.html.find(".draconic").val(this.rollData.selectedSort.system.listIndex); // Uniquement a la selection du sort, pour permettre de changer 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    RdDItemSort.setCoutReveReel(this.rollData.selectedSort);
 | 
				
			||||||
 | 
					    this.html.find("[name='diffLibre']").val(Misc.toInt(this.rollData.diffLibre));
 | 
				
			||||||
 | 
					    this.html.find("[name='diffConditions']").val(Misc.toInt(this.rollData.diffConditions));
 | 
				
			||||||
 | 
					    this.updateRollResult(html);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Setup everything onload
 | 
					    this.html.find("[name='diffLibre']").change((event) => {
 | 
				
			||||||
    $(function () { onLoad(); });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Update !
 | 
					 | 
				
			||||||
    html.find('#diffLibre').change((event) => {
 | 
					 | 
				
			||||||
      this.rollData.diffLibre = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
 | 
					      this.rollData.diffLibre = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('#diffConditions').change((event) => {
 | 
					    this.html.find("[name='diffConditions']").change((event) => {
 | 
				
			||||||
      this.rollData.diffConditions = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
 | 
					      this.rollData.diffConditions = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('#force-dice-result').change((event) => {
 | 
					    this.html.find("[name='force-dice-result']").change((event) => {
 | 
				
			||||||
      this.rollData.forceDiceResult = Misc.toInt(event.currentTarget.value);
 | 
					      this.rollData.forceDiceResult = Misc.toInt(event.currentTarget.value);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('#carac').change((event) => {
 | 
					    this.html.find("[name='carac']").change((event) => {
 | 
				
			||||||
      let caracKey = event.currentTarget.value;
 | 
					      let caracKey = event.currentTarget.value;
 | 
				
			||||||
      this.rollData.selectedCarac = this.rollData.carac[caracKey]; // Update the selectedCarac
 | 
					      this.rollData.selectedCarac = this.rollData.carac[caracKey]; // Update the selectedCarac
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.roll-draconic').change((event) => {
 | 
					    this.html.find('.roll-draconic').change((event) => {
 | 
				
			||||||
      let draconicKey = Misc.toInt(event.currentTarget.value);
 | 
					      let draconicKey = Misc.toInt(event.currentTarget.value);
 | 
				
			||||||
      this.rollData.competence = this.rollData.draconicList[draconicKey]; // Update the selectedCarac
 | 
					      this.rollData.competence = this.rollData.draconicList[draconicKey]; // Update the selectedCarac
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.roll-sort').change((event) => {
 | 
					    this.html.find('.roll-sort').change((event) => {
 | 
				
			||||||
      let sortKey = Misc.toInt(event.currentTarget.value);
 | 
					      let sortKey = Misc.toInt(event.currentTarget.value);
 | 
				
			||||||
      this.setSelectedSort(this.rollData.sortList[sortKey]);
 | 
					      this.setSelectedSort(this.rollData.sortList[sortKey]);
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
      $("#diffLibre").val(this.rollData.diffLibre);
 | 
					      this.html.find("[name='diffLibre']").val(this.rollData.diffLibre);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.roll-signedraconique').change((event) => {
 | 
					    this.html.find('.roll-carac-competence').change((event) => {
 | 
				
			||||||
 | 
					      const competence = event.currentTarget.value;
 | 
				
			||||||
 | 
					      this.rollData.competence = this.rollData.competences.find(it => it.name == competence);
 | 
				
			||||||
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.html.find('.roll-signedraconique').change((event) => {
 | 
				
			||||||
      let sortKey = Misc.toInt(event.currentTarget.value);
 | 
					      let sortKey = Misc.toInt(event.currentTarget.value);
 | 
				
			||||||
      this.setSelectedSigneDraconique(this.rollData.signes[sortKey]);
 | 
					      this.setSelectedSigneDraconique(this.rollData.signes[sortKey]);
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('#ptreve-variable').change((event) => {
 | 
					    this.html.find("[name='ptreve-variable']").change((event) => {
 | 
				
			||||||
      let ptreve = Misc.toInt(event.currentTarget.value);
 | 
					      let ptreve = Misc.toInt(event.currentTarget.value);
 | 
				
			||||||
      this.rollData.selectedSort.system.ptreve_reel = ptreve;
 | 
					      this.rollData.selectedSort.system.ptreve_reel = ptreve;
 | 
				
			||||||
      console.log("RdDRollSelectDialog - Cout reve", ptreve);
 | 
					      console.log("RdDRollSelectDialog - Cout reve", ptreve);
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find("[name='coupsNonMortels']").change((event) => {
 | 
					    this.html.find("[name='coupsNonMortels']").change((event) => {
 | 
				
			||||||
      this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel";
 | 
					      this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel";
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.cuisine-proportions').change((event) => {
 | 
					    this.html.find('.cuisine-proportions').change((event) => {
 | 
				
			||||||
      this.rollData.proportions = Number(event.currentTarget.value);
 | 
					      this.rollData.proportions = Number(event.currentTarget.value);
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.select-by-name').change((event) => {
 | 
					    this.html.find('.select-by-name').change((event) => {
 | 
				
			||||||
      const attribute = event.currentTarget.attributes['name'].value;
 | 
					      const attribute = event.currentTarget.attributes['name'].value;
 | 
				
			||||||
      this.rollData[attribute] = event.currentTarget.value;
 | 
					      this.rollData[attribute] = event.currentTarget.value;
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.checkbox-by-name').change((event) => {
 | 
					    this.html.find('.checkbox-by-name').change((event) => {
 | 
				
			||||||
      const attribute = event.currentTarget.attributes['name'].value;
 | 
					      const attribute = event.currentTarget.attributes['name'].value;
 | 
				
			||||||
      this.rollData[attribute] = event.currentTarget.checked;
 | 
					      this.rollData[attribute] = event.currentTarget.checked;
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.appel-moral').click((event) => { /* l'appel au moral, qui donne un bonus de +1 */
 | 
					    this.html.find('input.use-encTotal').change((event) => {
 | 
				
			||||||
      this.rollData.useMoral = !this.rollData.useMoral;
 | 
					      this.rollData.use.encTotal = event.currentTarget.checked;
 | 
				
			||||||
      const appelMoral = html.find('.icon-appel-moral')[0];
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
      const tooltip = html.find('.tooltipAppelAuMoralText')[0];
 | 
					    });
 | 
				
			||||||
      if (this.rollData.useMoral) {
 | 
					    this.html.find('input.use-surenc').change((event) => {
 | 
				
			||||||
 | 
					      this.rollData.use.surenc = event.currentTarget.checked;
 | 
				
			||||||
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.html.find('.appel-moral').click((event) => { /* l'appel au moral, qui donne un bonus de +1 */
 | 
				
			||||||
 | 
					      this.rollData.use.moral = !this.rollData.use.moral;
 | 
				
			||||||
 | 
					      const appelMoral = this.html.find('.icon-appel-moral')[0];
 | 
				
			||||||
 | 
					      const tooltip = this.html.find('.tooltipAppelAuMoralText')[0];
 | 
				
			||||||
 | 
					      if (this.rollData.use.moral) {
 | 
				
			||||||
        if (this.rollData.moral > 0) {
 | 
					        if (this.rollData.moral > 0) {
 | 
				
			||||||
          tooltip.innerHTML = "Appel au moral";
 | 
					          tooltip.innerHTML = "Appel au moral";
 | 
				
			||||||
          appelMoral.src = "/systems/foundryvtt-reve-de-dragon/icons/moral-heureux.svg";
 | 
					          appelMoral.src = "/systems/foundryvtt-reve-de-dragon/icons/moral-heureux.svg";
 | 
				
			||||||
@@ -260,16 +229,36 @@ export class RdDRoll extends Dialog {
 | 
				
			|||||||
        tooltip.innerHTML = "Sans appel au moral";
 | 
					        tooltip.innerHTML = "Sans appel au moral";
 | 
				
			||||||
        appelMoral.src = "/systems/foundryvtt-reve-de-dragon/icons/moral-neutre.svg";
 | 
					        appelMoral.src = "/systems/foundryvtt-reve-de-dragon/icons/moral-neutre.svg";
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    // Section Méditation
 | 
					    // Section Méditation
 | 
				
			||||||
    html.find('.conditionMeditation').change((event) => {
 | 
					    this.html.find('.conditionMeditation').change((event) => {
 | 
				
			||||||
      let condition = event.currentTarget.attributes['id'].value;
 | 
					      let condition = event.currentTarget.attributes['name'].value;
 | 
				
			||||||
      this.rollData.conditionMeditation[condition] = event.currentTarget.checked;
 | 
					      this.rollData.conditionMeditation[condition] = event.currentTarget.checked;
 | 
				
			||||||
      this.updateRollResult();
 | 
					      this.updateRollResult(html);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  close() {
 | 
				
			||||||
 | 
					    if (this.rollData.canClose) {
 | 
				
			||||||
 | 
					      return super.close();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ui.notifications.info("Vous devez faire ce jet de dés!");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async onAction(action) {
 | 
				
			||||||
 | 
					    this.rollData.forceDiceResult = Number.parseInt(this.html.find("[name='force-dice-result']").val()) ?? -1;
 | 
				
			||||||
 | 
					    await RdDResolutionTable.rollData(this.rollData);
 | 
				
			||||||
 | 
					    console.log("RdDRoll -=>", this.rollData, this.rollData.rolled);
 | 
				
			||||||
 | 
					    if (action.callbacks)
 | 
				
			||||||
 | 
					      for (let callback of action.callbacks) {
 | 
				
			||||||
 | 
					        if (callback.condition == undefined || callback.condition(this.rollData)) {
 | 
				
			||||||
 | 
					          await callback.action(this.rollData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async setSelectedSort(sort) {
 | 
					  async setSelectedSort(sort) {
 | 
				
			||||||
    this.rollData.selectedSort = sort; // Update the selectedCarac
 | 
					    this.rollData.selectedSort = sort; // Update the selectedCarac
 | 
				
			||||||
    this.rollData.competence = RdDItemCompetence.getVoieDraconic(this.rollData.draconicList, sort.system.draconic);
 | 
					    this.rollData.competence = RdDItemCompetence.getVoieDraconic(this.rollData.draconicList, sort.system.draconic);
 | 
				
			||||||
@@ -277,30 +266,31 @@ export class RdDRoll extends Dialog {
 | 
				
			|||||||
    this.rollData.diffLibre = RdDItemSort.getDifficulte(sort, -7);
 | 
					    this.rollData.diffLibre = RdDItemSort.getDifficulte(sort, -7);
 | 
				
			||||||
    RdDItemSort.setCoutReveReel(sort);
 | 
					    RdDItemSort.setCoutReveReel(sort);
 | 
				
			||||||
    const htmlSortDescription = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html", { sort: sort });
 | 
					    const htmlSortDescription = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html", { sort: sort });
 | 
				
			||||||
    $(".sort-ou-rituel").text(sort.system.isrituel ? "rituel" : "sort");
 | 
					    this.html.find(".sort-ou-rituel").text(sort.system.isrituel ? "rituel" : "sort");
 | 
				
			||||||
    $(".bonus-case").text(`${this.rollData.bonus}%`);
 | 
					    this.html.find(".bonus-case").text(`${this.rollData.bonus}%`);
 | 
				
			||||||
    $(".details-sort").remove();
 | 
					    this.html.find(".placeholder-description-sort").children().remove();
 | 
				
			||||||
    $(".description-sort").append(htmlSortDescription);
 | 
					    this.html.find(".placeholder-description-sort").append(htmlSortDescription);
 | 
				
			||||||
    $(".roll-draconic").val(sort.system.listIndex);
 | 
					    this.html.find(".roll-draconic").val(sort.system.listIndex);
 | 
				
			||||||
    $(".div-sort-difficulte-fixe").text(Misc.toSignedString(sort.system.difficulte));
 | 
					    this.html.find(".div-sort-difficulte-fixe").text(Misc.toSignedString(sort.system.difficulte));
 | 
				
			||||||
    $(".div-sort-ptreve-fixe").text(sort.system.ptreve);
 | 
					    this.html.find(".div-sort-ptreve-fixe").text(sort.system.ptreve);
 | 
				
			||||||
    const diffVariable = RdDItemSort.isDifficulteVariable(sort);
 | 
					    const diffVariable = RdDItemSort.isDifficulteVariable(sort);
 | 
				
			||||||
    const coutVariable = RdDItemSort.isCoutVariable(sort);
 | 
					    const coutVariable = RdDItemSort.isCoutVariable(sort);
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".div-sort-non-rituel"), !sort.system.isrituel);
 | 
					
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".div-sort-difficulte-var"), diffVariable);
 | 
					    HtmlUtility._showControlWhen(this.html.find(".div-sort-non-rituel"), !sort.system.isrituel);
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".div-sort-difficulte-fixe"), !diffVariable);
 | 
					    HtmlUtility._showControlWhen(this.html.find(".div-sort-difficulte-var"), diffVariable);
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".div-sort-ptreve-var"), coutVariable);
 | 
					    HtmlUtility._showControlWhen(this.html.find(".div-sort-difficulte-fixe"), !diffVariable);
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".div-sort-ptreve-fixe"), !coutVariable);
 | 
					    HtmlUtility._showControlWhen(this.html.find(".div-sort-ptreve-var"), coutVariable);
 | 
				
			||||||
 | 
					    HtmlUtility._showControlWhen(this.html.find(".div-sort-ptreve-fixe"), !coutVariable);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async setSelectedSigneDraconique(signe){
 | 
					  async setSelectedSigneDraconique(signe) {
 | 
				
			||||||
    this.rollData.signe = signe;
 | 
					    this.rollData.signe = signe;
 | 
				
			||||||
    this.rollData.diffLibre = signe.system.difficulte,
 | 
					    this.rollData.diffLibre = signe.system.difficulte,
 | 
				
			||||||
    $(".signe-difficulte").text(Misc.toSignedString(this.rollData.diffLibre));
 | 
					      $(".signe-difficulte").text(Misc.toSignedString(this.rollData.diffLibre));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async updateRollResult() {
 | 
					  async updateRollResult(html) {
 | 
				
			||||||
    let rollData = this.rollData;
 | 
					    let rollData = this.rollData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat())
 | 
					    rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat())
 | 
				
			||||||
@@ -310,36 +300,35 @@ export class RdDRoll extends Dialog {
 | 
				
			|||||||
    rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac);
 | 
					    rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac);
 | 
				
			||||||
    let dmgText = Misc.toSignedString(rollData.dmg.total);
 | 
					    let dmgText = Misc.toSignedString(rollData.dmg.total);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (rollData.mortalite){
 | 
					    switch (rollData.mortalite) {
 | 
				
			||||||
      case 'non-mortel':  dmgText = `(${dmgText}) non-mortel`; break;
 | 
					      case 'non-mortel': dmgText = `(${dmgText}) non-mortel`; break;
 | 
				
			||||||
      case 'empoignade':  dmgText = `empoignade`; break;
 | 
					      case 'empoignade': dmgText = `empoignade`; break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RollDataAjustements.calcul(rollData, this.actor);
 | 
					    RollDataAjustements.calcul(rollData, this.actor);
 | 
				
			||||||
    rollData.finalLevel = this._computeFinalLevel(rollData);
 | 
					    rollData.finalLevel = this._computeFinalLevel(rollData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".diffMoral"), rollData.ajustements.moralTotal.used);
 | 
					    const resolutionTable = await RdDResolutionTable.buildHTMLTable(RdDResolutionTable.subTable(rollData.caracValue, rollData.finalLevel))
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".divAppelAuMoral"), rollData.use.appelAuMoral);
 | 
					    const adjustements = await this.buildAjustements(rollData);
 | 
				
			||||||
    HtmlUtility._showControlWhen($("#etat-general"), !RdDCarac.isIgnoreEtatGeneral(rollData));
 | 
					
 | 
				
			||||||
    HtmlUtility._showControlWhen($("#ajust-astrologique"), RdDResolutionTable.isAjustementAstrologique(rollData));
 | 
					    HtmlUtility._showControlWhen(this.html.find(".use-encTotal"), rollData.ajustements.encTotal.visible && RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac));
 | 
				
			||||||
 | 
					    HtmlUtility._showControlWhen(this.html.find(".use-surenc"), rollData.ajustements.surenc.visible && RdDCarac.isActionPhysique(rollData.selectedCarac));
 | 
				
			||||||
 | 
					    HtmlUtility._showControlWhen(this.html.find(".utilisation-moral"), rollData.use.appelAuMoral);
 | 
				
			||||||
 | 
					    HtmlUtility._showControlWhen(this.html.find(".diffMoral"), rollData.ajustements.moralTotal.used);
 | 
				
			||||||
 | 
					    HtmlUtility._showControlWhen(this.html.find(".divAppelAuMoral"), rollData.use.appelAuMoral);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Mise à jour valeurs
 | 
					    // Mise à jour valeurs
 | 
				
			||||||
    $(".dialog-roll-title").text(this._getTitle(rollData));
 | 
					    this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
 | 
				
			||||||
    $("[name='coupsNonMortels']").prop('checked', rollData.mortalite == 'non-mortel');
 | 
					    this.html.find("[name='coupsNonMortels']").prop('checked', rollData.mortalite == 'non-mortel');
 | 
				
			||||||
    $(".dmg-arme-actor").text(dmgText);
 | 
					    this.html.find(".dmg-arme-actor").text(dmgText);
 | 
				
			||||||
    $('.table-ajustement').remove();
 | 
					    this.html.find("div.placeholder-ajustements").empty().append(adjustements);
 | 
				
			||||||
    $(".table-resolution").remove();
 | 
					    this.html.find("div.placeholder-resolution").empty().append(resolutionTable)
 | 
				
			||||||
    $(".table-proba-reussite").remove();
 | 
					 | 
				
			||||||
    $("#tableAjustements").append(await this.buildAjustements(rollData));
 | 
					 | 
				
			||||||
    $("#tableResolution").append(RdDResolutionTable.buildHTMLTableExtract(rollData.caracValue, rollData.finalLevel));
 | 
					 | 
				
			||||||
    $("#tableProbaReussite").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async buildAjustements(rollData) {
 | 
					  async buildAjustements(rollData) {
 | 
				
			||||||
    const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html`, rollData);
 | 
					    return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html`, rollData);
 | 
				
			||||||
    return html;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -357,23 +346,11 @@ export class RdDRoll extends Dialog {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  _computeDiffLibre(rollData) {
 | 
					 | 
				
			||||||
    let diffLibre = Misc.toInt(rollData.diffLibre);
 | 
					 | 
				
			||||||
    if (rollData.draconicList && rollData.selectedSort) {
 | 
					 | 
				
			||||||
      return RdDItemSort.getDifficulte(rollData.selectedSort, diffLibre);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return diffLibre;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _computeMalusArmure(rollData) {
 | 
					  _computeMalusArmure(rollData) {
 | 
				
			||||||
    let malusArmureValue = 0;
 | 
					    let malusArmureValue = 0;
 | 
				
			||||||
    if (rollData.malusArmureValue && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) {
 | 
					    if (rollData.malusArmureValue && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) {
 | 
				
			||||||
      $("#addon-message").text("Malus armure appliqué : " + rollData.malusArmureValue);
 | 
					 | 
				
			||||||
      malusArmureValue = rollData.malusArmureValue;
 | 
					      malusArmureValue = rollData.malusArmureValue;
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      $("#addon-message").text("");
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return malusArmureValue;
 | 
					    return malusArmureValue;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,13 @@
 | 
				
			|||||||
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
 | 
					import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class RdDRollTables {
 | 
					export class RdDRollTables {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async genericGetTableResult(tableName, toChat) {
 | 
					  static async genericGetTableResult(tableName, toChat) {
 | 
				
			||||||
    let table = RdDRollTables.getWorldTable(tableName) ?? (await RdDRollTables.getSystemTable(tableName));
 | 
					    let table = RdDRollTables.getWorldTable(tableName) ?? (await RdDRollTables.getSystemTable(tableName));
 | 
				
			||||||
    const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"});
 | 
					    const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll" });
 | 
				
			||||||
    //console.log("RdDRollTables", tableName, toChat, ":", draw);
 | 
					 | 
				
			||||||
    return draw.results.length > 0 ? draw.results[0] : undefined;
 | 
					    return draw.results.length > 0 ? draw.results[0] : undefined;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static getWorldTable(tableName) {
 | 
					  static getWorldTable(tableName) {
 | 
				
			||||||
@@ -14,7 +15,7 @@ export class RdDRollTables {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async getSystemTable(tableName) {
 | 
					  static async getSystemTable(tableName) {
 | 
				
			||||||
    const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
 | 
					    const pack = SystemCompendiums.getPack("tables-diverses");
 | 
				
			||||||
    const index = await pack.getIndex();
 | 
					    const index = await pack.getIndex();
 | 
				
			||||||
    const entry = index.find(e => e.name === tableName);
 | 
					    const entry = index.find(e => e.name === tableName);
 | 
				
			||||||
    return await pack.getDocument(entry._id);
 | 
					    return await pack.getDocument(entry._id);
 | 
				
			||||||
@@ -24,10 +25,9 @@ export class RdDRollTables {
 | 
				
			|||||||
  static async drawItemFromRollTable(tableName, toChat = false) {
 | 
					  static async drawItemFromRollTable(tableName, toChat = false) {
 | 
				
			||||||
    const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
 | 
					    const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
 | 
				
			||||||
    const pack = game.packs.get(drawResult.documentCollection)
 | 
					    const pack = game.packs.get(drawResult.documentCollection)
 | 
				
			||||||
    let doc = await pack.getDocument(drawResult.documentId)
 | 
					    return await pack.getDocument(drawResult.documentId)
 | 
				
			||||||
    return doc
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async drawTextFromRollTable(tableName, toChat) {
 | 
					  static async drawTextFromRollTable(tableName, toChat) {
 | 
				
			||||||
    const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
 | 
					    const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
 | 
				
			||||||
@@ -36,58 +36,74 @@ export class RdDRollTables {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getCompetence(toChat = false) {
 | 
					  static async getCompetence(toChat = false) {
 | 
				
			||||||
    return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat);
 | 
					    if (toChat == 'liste') {
 | 
				
			||||||
 | 
					      return await RdDRollTables.listOrRoll('competences', 'Item', ['competence'], toChat, it => 1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getSouffle(toChat = false) {
 | 
					  static async getSouffle(toChat = false) {
 | 
				
			||||||
    return await RdDRollTables.drawItemFromRollTable("Souffles de Dragon", toChat);
 | 
					    return await RdDRollTables.listOrRoll('souffles-de-dragon', 'Item', ['souffle'], toChat);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getQueue(toChat = false) {
 | 
					  static async getQueue(toChat = false) {
 | 
				
			||||||
    let queue = await RdDRollTables.drawItemFromRollTable("Queues de dragon", toChat);
 | 
					    return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat);
 | 
				
			||||||
    if (queue.name.toLowerCase().includes('lancinant') ) {
 | 
					 | 
				
			||||||
      return await RdDRollTables.getDesirLancinant(toChat);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (queue.name.toLowerCase().includes('fixe') ) {
 | 
					 | 
				
			||||||
      return await RdDRollTables.getIdeeFixe(toChat);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return queue;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async getDesirLancinant(toChat = false) {
 | 
					  static async getDesirLancinant(toChat = false) {
 | 
				
			||||||
    return await RdDRollTables.drawItemFromRollTable("Désirs lancinants", toChat);
 | 
					    return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat,
 | 
				
			||||||
 | 
					      it => it.system.frequence,
 | 
				
			||||||
 | 
					      it => it.system.categorie == 'lancinant');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  static async getIdeeFixe(toChat = false) {
 | 
					  static async getIdeeFixe(toChat = false) {
 | 
				
			||||||
    return await RdDRollTables.drawItemFromRollTable("Idées fixes", toChat);
 | 
					    return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat,
 | 
				
			||||||
 | 
					      it => it.system.frequence,
 | 
				
			||||||
 | 
					      it => it.system.categorie == 'ideefixe');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getTeteHR(toChat = false) {
 | 
					  static async getTeteHR(toChat = false) {
 | 
				
			||||||
    return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour haut-rêvants", toChat);
 | 
					    return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-haut-revants', 'Item', ['tete'], toChat);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getTete(toChat = false) {
 | 
					  static async getTete(toChat = false) {
 | 
				
			||||||
    return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour tous personnages", toChat);
 | 
					    return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-tous-personnages', 'Item', ['tete'], toChat);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getOmbre(toChat = false) {
 | 
					  static async getOmbre(toChat = false) {
 | 
				
			||||||
    return await RdDRollTables.drawItemFromRollTable("Ombre de Thanatos", toChat);
 | 
					    return await RdDRollTables.listOrRoll('ombres-de-thanatos', 'Item', ['ombre'], toChat);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getTarot(toChat = true) {
 | 
					  static async getTarot(toChat = true) {
 | 
				
			||||||
    return await RdDRollTables.drawItemFromRollTable("Tarot Draconique", toChat);
 | 
					    return await RdDRollTables.listOrRoll('tarot-draconique', 'Item', ['tarot'], toChat);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getMaladresse(options = {toChat: false, arme: false}) {
 | 
					  static async listOrRoll(compendium, type, subTypes, toChat, itemFrequence = it => it.system.frequence, filter = it => true) {
 | 
				
			||||||
 | 
					    const table = new CompendiumTable(compendium, type, subTypes);
 | 
				
			||||||
 | 
					    if (toChat == 'liste') {
 | 
				
			||||||
 | 
					      return await table.toChatMessage(itemFrequence, filter);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const row = await table.getRandom(itemFrequence, filter);
 | 
				
			||||||
 | 
					    if (row) {
 | 
				
			||||||
 | 
					      await CompendiumTableHelpers.tableRowToChatMessage(row, type);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return row;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async getMaladresse(options = { toChat: false, arme: false }) {
 | 
				
			||||||
    return await RdDRollTables.drawTextFromRollTable(
 | 
					    return await RdDRollTables.drawTextFromRollTable(
 | 
				
			||||||
      options.arme ? "Maladresse armé" : "Maladresses non armé",
 | 
					      options.arme ? "Maladresse armé" : "Maladresses non armé",
 | 
				
			||||||
      options.toChat);
 | 
					      options.toChat);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,17 +19,23 @@ export class RdDSheetUtility {
 | 
				
			|||||||
    return $(event.currentTarget)?.parents(".item");
 | 
					    return $(event.currentTarget)?.parents(".item");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static prepareItemDropParameters(destItemId, actorId, dragData, objetVersConteneur) {
 | 
					  static prepareItemDropParameters(destItemId, actor, dragData, objetVersConteneur) {
 | 
				
			||||||
    const item = fromUuidSync(dragData.uuid)
 | 
					    const item = fromUuidSync(dragData.uuid)
 | 
				
			||||||
    return {
 | 
					    if (actor.canReceive(item)) {
 | 
				
			||||||
      destId: destItemId,
 | 
					      return {
 | 
				
			||||||
      targetActorId: actorId,
 | 
					        destId: destItemId,
 | 
				
			||||||
      itemId: item.id,
 | 
					        targetActorId: actor.id,
 | 
				
			||||||
      sourceActorId: item.actor?.id,
 | 
					        itemId: item.id,
 | 
				
			||||||
      srcId: objetVersConteneur[item.id],
 | 
					        sourceActorId: item.actor?.id,
 | 
				
			||||||
      onEnleverConteneur: () => { delete objetVersConteneur[item.id]; },
 | 
					        srcId: objetVersConteneur[item.id],
 | 
				
			||||||
      onAjouterDansConteneur: (itemId, conteneurId) => { objetVersConteneur[itemId] = conteneurId; }
 | 
					        onEnleverConteneur: () => { delete objetVersConteneur[item.id]; },
 | 
				
			||||||
 | 
					        onAjouterDansConteneur: (itemId, conteneurId) => { objetVersConteneur[itemId] = conteneurId; }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      ui.notifications.warn(`Impossible de donner ${item.name} à ${actor.name}: ${item.type} / ${actor.type}`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return undefined;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async splitItem(item, actor, onSplit = () => { }) {
 | 
					  static async splitItem(item, actor, onSplit = () => { }) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,26 +1,29 @@
 | 
				
			|||||||
 | 
					import { SHOW_DICE } from "./constants.js";
 | 
				
			||||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
 | 
					import { RollDataAjustements } from "./rolldata-ajustements.js";
 | 
				
			||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
import { TMRUtility } from "./tmr-utility.js";
 | 
					import { TMRUtility } from "./tmr-utility.js";
 | 
				
			||||||
import { tmrConstants } from "./tmr-constants.js";
 | 
					import { tmrConstants } from "./tmr-constants.js";
 | 
				
			||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
					import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
				
			||||||
import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js";
 | 
					import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js";
 | 
				
			||||||
import { TMRRencontres } from "./tmr-rencontres.js";
 | 
					 | 
				
			||||||
import { ChatUtility } from "./chat-utility.js";
 | 
					import { ChatUtility } from "./chat-utility.js";
 | 
				
			||||||
import { RdDRoll } from "./rdd-roll.js";
 | 
					import { RdDRoll } from "./rdd-roll.js";
 | 
				
			||||||
import { Poetique } from "./poetique.js";
 | 
					import { Poetique } from "./poetique.js";
 | 
				
			||||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
 | 
					import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
 | 
				
			||||||
import { PixiTMR } from "./tmr/pixi-tmr.js";
 | 
					import { PixiTMR } from "./tmr/pixi-tmr.js";
 | 
				
			||||||
import { Draconique } from "./tmr/draconique.js";
 | 
					import { Draconique } from "./tmr/draconique.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					 | 
				
			||||||
import { HtmlUtility } from "./html-utility.js";
 | 
					import { HtmlUtility } from "./html-utility.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
import { RdDDice } from "./rdd-dice.js";
 | 
					import { RdDDice } from "./rdd-dice.js";
 | 
				
			||||||
import { STATUSES } from "./status-effects.js";
 | 
					import { STATUSES } from "./settings/status-effects.js";
 | 
				
			||||||
 | 
					import { RdDRencontre } from "./item-rencontre.js";
 | 
				
			||||||
 | 
					import { RdDCalendrier } from "./rdd-calendrier.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class RdDTMRDialog extends Dialog {
 | 
					export class RdDTMRDialog extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static async create(html, actor, tmrData) {
 | 
					  static async create(actor, tmrData) {
 | 
				
			||||||
 | 
					    let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html', tmrData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (tmrData.mode != 'visu') {
 | 
					    if (tmrData.mode != 'visu') {
 | 
				
			||||||
      // Notification au MJ
 | 
					      // Notification au MJ
 | 
				
			||||||
@@ -89,7 +92,7 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
      TMRUtility.getTMR(coord).type == 'fleuve'
 | 
					      TMRUtility.getTMR(coord).type == 'fleuve'
 | 
				
			||||||
        ? it => TMRUtility.getTMR(it.system.coord).type == 'fleuve'
 | 
					        ? it => TMRUtility.getTMR(it.system.coord).type == 'fleuve'
 | 
				
			||||||
        : it => it.system.coord == coord
 | 
					        : it => it.system.coord == coord
 | 
				
			||||||
      );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -146,7 +149,7 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _tokenRencontre(rencontre) {
 | 
					  _tokenRencontre(rencontre) {
 | 
				
			||||||
    return EffetsDraconiques.rencontre.token(this.pixiTMR, rencontre, () => rencontre.coord);
 | 
					    return EffetsDraconiques.rencontre.token(this.pixiTMR, rencontre, () => rencontre.system.coord);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  _tokenCaseSpeciale(casetmr) {
 | 
					  _tokenCaseSpeciale(casetmr) {
 | 
				
			||||||
    const caseData = casetmr;
 | 
					    const caseData = casetmr;
 | 
				
			||||||
@@ -194,32 +197,33 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async activateListeners(html) {
 | 
					  async activateListeners(html) {
 | 
				
			||||||
    super.activateListeners(html);
 | 
					    super.activateListeners(html);
 | 
				
			||||||
 | 
					    this.html = html;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    document.getElementById("tmrrow1").insertCell(0).append(this.pixiApp.view);
 | 
					    document.getElementById("tmrrow1").insertCell(0).append(this.pixiApp.view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.viewOnly) {
 | 
					    if (this.viewOnly) {
 | 
				
			||||||
      html.find('.lancer-sort').remove();
 | 
					      this.html.find('.lancer-sort').remove();
 | 
				
			||||||
      html.find('.lire-signe-draconique').remove();
 | 
					      this.html.find('.lire-signe-draconique').remove();
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
 | 
					    HtmlUtility._showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord()));
 | 
					    HtmlUtility._showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Roll Sort
 | 
					    // Roll Sort
 | 
				
			||||||
    html.find('.lancer-sort').click((event) => {
 | 
					    this.html.find('.lancer-sort').click((event) => {
 | 
				
			||||||
      this.actor.rollUnSort(this._getActorCoord());
 | 
					      this.actor.rollUnSort(this._getActorCoord());
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    html.find('.lire-signe-draconique').click((event) => {
 | 
					    this.html.find('.lire-signe-draconique').click((event) => {
 | 
				
			||||||
      this.actor.rollLireSigneDraconique(this._getActorCoord());
 | 
					      this.actor.rollLireSigneDraconique(this._getActorCoord());
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html.find('#dir-top').click((event) => this.moveFromKey("top"));
 | 
					    this.html.find('#dir-top').click((event) => this.moveFromKey("top"));
 | 
				
			||||||
    html.find('#dir-top-left').click((event) => this.moveFromKey("top-left"));
 | 
					    this.html.find('#dir-top-left').click((event) => this.moveFromKey("top-left"));
 | 
				
			||||||
    html.find('#dir-top-right').click((event) => this.moveFromKey("top-right"));
 | 
					    this.html.find('#dir-top-right').click((event) => this.moveFromKey("top-right"));
 | 
				
			||||||
    html.find('#dir-bottom-left').click((event) => this.moveFromKey("bottom-left"));
 | 
					    this.html.find('#dir-bottom-left').click((event) => this.moveFromKey("bottom-left"));
 | 
				
			||||||
    html.find('#dir-bottom-right').click((event) => this.moveFromKey("bottom-right"));
 | 
					    this.html.find('#dir-bottom-right').click((event) => this.moveFromKey("bottom-right"));
 | 
				
			||||||
    html.find('#dir-bottom').click((event) => this.moveFromKey("bottom"));
 | 
					    this.html.find('#dir-bottom').click((event) => this.moveFromKey("bottom"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Gestion du cout de montée en points de rêve
 | 
					    // Gestion du cout de montée en points de rêve
 | 
				
			||||||
    let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse();
 | 
					    let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse();
 | 
				
			||||||
@@ -241,14 +245,14 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    const coord = this._getActorCoord();
 | 
					    const coord = this._getActorCoord();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(coord));
 | 
					    HtmlUtility._showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(coord));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let ptsreve = document.getElementById("tmr-pointsreve-value");
 | 
					    let ptsreve = document.getElementById("tmr-pointsreve-value");
 | 
				
			||||||
    ptsreve.innerHTML = this.actor.system.reve.reve.value;
 | 
					    ptsreve.innerHTML = this.actor.system.reve.reve.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let tmrpos = document.getElementById("tmr-pos");
 | 
					    let tmrpos = document.getElementById("tmr-pos");
 | 
				
			||||||
    if (this.isDemiReveCache()) {
 | 
					    if (this.isDemiReveCache()) {
 | 
				
			||||||
      tmrpos.innerHTML = `?? ( ${ TMRUtility.getTMRType(coord)})`;
 | 
					      tmrpos.innerHTML = `?? ( ${TMRUtility.getTMRType(coord)})`;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      tmrpos.innerHTML = `${coord} ( ${TMRUtility.getTMRLabel(coord)})`;
 | 
					      tmrpos.innerHTML = `${coord} ( ${TMRUtility.getTMRLabel(coord)})`;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -276,29 +280,48 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      await this.actor.santeIncDec("fatigue", this.cumulFatigue)
 | 
					      await this.actor.santeIncDec("fatigue", this.cumulFatigue)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    await super.close(); // moving 1 cell costs 1 fatigue
 | 
					    await super.close();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async onActionRencontre(action, tmr) {
 | 
				
			||||||
 | 
					    switch (action) {
 | 
				
			||||||
 | 
					      case 'derober':
 | 
				
			||||||
 | 
					        await this.derober();
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      case 'refouler':
 | 
				
			||||||
 | 
					        await this.refouler();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'maitriser':
 | 
				
			||||||
 | 
					        await this.maitriserRencontre();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'ignorer':
 | 
				
			||||||
 | 
					        await this.ignorerRencontre();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    await this.postRencontre(tmr);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async derober() {
 | 
					  async derober() {
 | 
				
			||||||
    await this.actor.addTMRRencontre(this.currentRencontre);
 | 
					 | 
				
			||||||
    console.log("-> derober", this.currentRencontre);
 | 
					    console.log("-> derober", this.currentRencontre);
 | 
				
			||||||
 | 
					    await this.actor.addTMRRencontre(this.currentRencontre);
 | 
				
			||||||
    this._tellToGM(this.actor.name + " s'est dérobé et quitte les TMR.");
 | 
					    this._tellToGM(this.actor.name + " s'est dérobé et quitte les TMR.");
 | 
				
			||||||
    this.close();
 | 
					    this.close();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async refouler() {
 | 
					  async refouler() {
 | 
				
			||||||
    await this.actor.ajouterRefoulement(this.currentRencontre.refoulement ?? 1, `une rencontre ${this.currentRencontre.name}`);
 | 
					    console.log("-> refouler", this.currentRencontre);
 | 
				
			||||||
 | 
					    await this.actor.ajouterRefoulement(this.currentRencontre.system.refoulement, `${this.currentRencontre.system.genre == 'f' ? 'une' : 'un'} ${this.currentRencontre.name}`);
 | 
				
			||||||
    await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
 | 
					    await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
 | 
				
			||||||
    this.updateTokens();
 | 
					    this.updateTokens();
 | 
				
			||||||
    console.log("-> refouler", this.currentRencontre)
 | 
					 | 
				
			||||||
    this.updateValuesDisplay();
 | 
					    this.updateValuesDisplay();
 | 
				
			||||||
    this.nettoyerRencontre();
 | 
					    this.nettoyerRencontre();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async ignorerRencontre() {
 | 
					  async ignorerRencontre() {
 | 
				
			||||||
 | 
					    console.log("-> ignorer", this.currentRencontre);
 | 
				
			||||||
    this._tellToGM(this.actor.name + " a ignoré: " + this.currentRencontre.name);
 | 
					    this._tellToGM(this.actor.name + " a ignoré: " + this.currentRencontre.name);
 | 
				
			||||||
    await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
 | 
					    await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
 | 
				
			||||||
    this.updateTokens();
 | 
					    this.updateTokens();
 | 
				
			||||||
@@ -307,7 +330,14 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  colorierZoneRencontre(listCoordTMR) {
 | 
					  // garder la trace de l'état en cours
 | 
				
			||||||
 | 
					  setRencontreState(state, listCoordTMR) {
 | 
				
			||||||
 | 
					    this.rencontreState = state;
 | 
				
			||||||
 | 
					    this.$marquerCasesTMR(listCoordTMR ?? []);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  $marquerCasesTMR(listCoordTMR) {
 | 
				
			||||||
    this.currentRencontre.graphics = []; // Keep track of rectangles to delete it
 | 
					    this.currentRencontre.graphics = []; // Keep track of rectangles to delete it
 | 
				
			||||||
    this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location
 | 
					    this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location
 | 
				
			||||||
    for (let coordTMR of listCoordTMR) {
 | 
					    for (let coordTMR of listCoordTMR) {
 | 
				
			||||||
@@ -323,23 +353,6 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  // garder la trace de l'état en cours
 | 
					 | 
				
			||||||
  setStateRencontre(state) {
 | 
					 | 
				
			||||||
    this.rencontreState = state;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  async choisirCasePortee(coord, portee) {
 | 
					 | 
				
			||||||
    // Récupère la liste des cases à portées
 | 
					 | 
				
			||||||
    this.colorierZoneRencontre(TMRUtility.getTMRPortee(coord, portee));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  async choisirCaseType(type) {
 | 
					 | 
				
			||||||
    this.colorierZoneRencontre(TMRUtility.filterTMR(it => it.type == type).map(it => it.coord));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  checkQuitterTMR() {
 | 
					  checkQuitterTMR() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -364,15 +377,15 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async quitterLesTMRInconscient() {
 | 
					  async quitterLesTMRInconscient() {
 | 
				
			||||||
    if (this.currentRencontre?.isPersistant) {
 | 
					    await this.refouler();
 | 
				
			||||||
      await this.refouler();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    this.close();
 | 
					    this.close();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async maitriserRencontre() {
 | 
					  async maitriserRencontre() {
 | 
				
			||||||
    this.actor.deleteTMRRencontreAtPosition();
 | 
					    console.log("-> maitriser", this.currentRencontre);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await this.actor.deleteTMRRencontreAtPosition();
 | 
				
			||||||
    this.updateTokens();
 | 
					    this.updateTokens();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let rencontreData = {
 | 
					    let rencontreData = {
 | 
				
			||||||
@@ -383,7 +396,7 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
      rencontre: this.currentRencontre,
 | 
					      rencontre: this.currentRencontre,
 | 
				
			||||||
      nbRounds: 1,
 | 
					      nbRounds: 1,
 | 
				
			||||||
      canClose: false,
 | 
					      canClose: false,
 | 
				
			||||||
      selectedCarac: {label: "reve-actuel"},
 | 
					      selectedCarac: { label: "reve-actuel" },
 | 
				
			||||||
      tmr: TMRUtility.getTMR(this._getActorCoord())
 | 
					      tmr: TMRUtility.getTMR(this._getActorCoord())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -392,8 +405,6 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async _tentativeMaitrise(rencData) {
 | 
					  async _tentativeMaitrise(rencData) {
 | 
				
			||||||
    console.log("-> matriser", rencData);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    rencData.reve = this.actor.getReveActuel();
 | 
					    rencData.reve = this.actor.getReveActuel();
 | 
				
			||||||
    rencData.etat = this.actor.getEtatGeneral();
 | 
					    rencData.etat = this.actor.getEtatGeneral();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -403,41 +414,67 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
      ? this._rollPresentCite(rencData)
 | 
					      ? this._rollPresentCite(rencData)
 | 
				
			||||||
      : await RdDResolutionTable.roll(rencData.reve, RollDataAjustements.sum(rencData.ajustements));
 | 
					      : await RdDResolutionTable.roll(rencData.reve, RollDataAjustements.sum(rencData.ajustements));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let postProcess = await TMRRencontres.gererRencontre(this, rencData);
 | 
					    const result = rencData.rolled.isSuccess
 | 
				
			||||||
 | 
					      ? rencData.rencontre.system.succes
 | 
				
			||||||
 | 
					      : rencData.rencontre.system.echec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await RdDRencontre.appliquer(result.effets, this, rencData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rencData.poesie = { extrait: result.poesie, reference: result.reference };
 | 
				
			||||||
 | 
					    rencData.message = this.formatMessageRencontre(rencData, result.message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ChatMessage.create({
 | 
					    ChatMessage.create({
 | 
				
			||||||
      whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
 | 
					      whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
 | 
				
			||||||
      content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencData)
 | 
					      content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencData)
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (postProcess) {
 | 
					 | 
				
			||||||
      /** Gère les rencontres avec du post-processing (passeur, messagers, tourbillons, ...) */
 | 
					 | 
				
			||||||
      await postProcess(this, rencData);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      this.currentRencontre = undefined;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.updateValuesDisplay();
 | 
					    this.updateValuesDisplay();
 | 
				
			||||||
    if (this.checkQuitterTMR()) {
 | 
					    if (this.checkQuitterTMR()) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (rencData.rolled.isEchec && rencData.rencontre.isPersistant) {
 | 
					    if (this.rencontreState == 'persistant') {
 | 
				
			||||||
      setTimeout(() => {
 | 
					      this._nouvelleTentativeMaitrise(rencData);
 | 
				
			||||||
        rencData.nbRounds++;
 | 
					    }
 | 
				
			||||||
        if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
 | 
					    else if (!this.isRencontreDeplacement()) {
 | 
				
			||||||
          this.cumulFatigue += this.fatigueParCase;
 | 
					      this.nettoyerRencontre();
 | 
				
			||||||
        }
 | 
					    }
 | 
				
			||||||
        this._tentativeMaitrise(rencData);
 | 
					  }
 | 
				
			||||||
        this._deleteTmrMessages(rencData.actor, rencData.nbRounds);
 | 
					
 | 
				
			||||||
      }, 2000);
 | 
					  _nouvelleTentativeMaitrise(rencData) {
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					      // TODO: remplacer par une boucle while(this.currentRencontre) ?
 | 
				
			||||||
 | 
					      rencData.nbRounds++;
 | 
				
			||||||
 | 
					      if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
 | 
				
			||||||
 | 
					        this.cumulFatigue += this.fatigueParCase;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      this._tentativeMaitrise(rencData);
 | 
				
			||||||
 | 
					      this._deleteTmrMessages(rencData.actor, rencData.nbRounds);
 | 
				
			||||||
 | 
					    }, 2000);
 | 
				
			||||||
 | 
					    this.rencontreState == 'normal';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  formatMessageRencontre(rencData, template) {
 | 
				
			||||||
 | 
					    let messageDuree = ''
 | 
				
			||||||
 | 
					    if (rencData.nbRounds > 1) {
 | 
				
			||||||
 | 
					      if (rencData.rolled.isSuccess) {
 | 
				
			||||||
 | 
					        messageDuree = ` Au total, vous avez passé ${rencData.nbRounds} rounds à vous battre!`;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else {
 | 
				
			||||||
 | 
					        messageDuree  = ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const compiled = Handlebars.compile(template);
 | 
				
			||||||
 | 
					      return compiled(rencData) + messageDuree ;
 | 
				
			||||||
 | 
					    } catch (error) {
 | 
				
			||||||
 | 
					      return template + messageDuree ;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _rollPresentCite(rencontreData) {
 | 
					  _rollPresentCite(rencData) {
 | 
				
			||||||
    let rolled = RdDResolutionTable.computeChances(rencontreData.reve, 0);
 | 
					    let rolled = RdDResolutionTable.computeChances(rencData.reve, 0);
 | 
				
			||||||
    mergeObject(rolled, { caracValue: rencontreData.reve, finalLevel: 0, roll: rolled.score });
 | 
					    mergeObject(rolled, { caracValue: rencData.reve, finalLevel: 0, roll: rolled.score });
 | 
				
			||||||
    RdDResolutionTable.succesRequis(rolled);
 | 
					    RdDResolutionTable.succesRequis(rolled);
 | 
				
			||||||
    return rolled;
 | 
					    return rolled;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -481,15 +518,16 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
    if (this._presentCite(tmr)) {
 | 
					    if (this._presentCite(tmr)) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let rencontre = await this._jetDeRencontre(tmr);
 | 
					    this.currentRencontre = await this._jetDeRencontre(tmr);
 | 
				
			||||||
 | 
					    if (this.currentRencontre) {
 | 
				
			||||||
    if (rencontre) { // Manages it
 | 
					      if (this.rencontresExistantes.find(it => it.id == this.currentRencontre.id)){
 | 
				
			||||||
      if (rencontre.rencontre) rencontre = rencontre.rencontre; // Manage stored rencontres
 | 
					        // rencontre en attente suite à dérobade
 | 
				
			||||||
      console.log("manageRencontre", rencontre);
 | 
					        await this.maitriserRencontre();
 | 
				
			||||||
      this.currentRencontre = duplicate(rencontre);
 | 
					      }
 | 
				
			||||||
 | 
					      else {
 | 
				
			||||||
      let dialog = new RdDTMRRencontreDialog(this, this.currentRencontre, () => this.postRencontre(tmr));
 | 
					        let dialog = new RdDTMRRencontreDialog(this, this.currentRencontre, tmr);
 | 
				
			||||||
      dialog.render(true);
 | 
					        dialog.render(true);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      this.postRencontre(tmr);
 | 
					      this.postRencontre(tmr);
 | 
				
			||||||
@@ -502,15 +540,18 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
    if (presentCite) {
 | 
					    if (presentCite) {
 | 
				
			||||||
      this.minimize();
 | 
					      this.minimize();
 | 
				
			||||||
      const caseData = presentCite;
 | 
					      const caseData = presentCite;
 | 
				
			||||||
      EffetsDraconiques.presentCites.choisirUnPresent(caseData, (type => this._utiliserPresentCite(presentCite, type, tmr)));
 | 
					      EffetsDraconiques.presentCites.choisirUnPresent(caseData, (present => this._utiliserPresentCite(presentCite, present, tmr)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return presentCite;
 | 
					    return presentCite;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async _utiliserPresentCite(presentCite, typeRencontre, tmr) {
 | 
					  async _utiliserPresentCite(presentCite, present, tmr) {
 | 
				
			||||||
    this.currentRencontre = TMRRencontres.getRencontre(typeRencontre);
 | 
					    this.currentRencontre = present.clone({
 | 
				
			||||||
    await TMRRencontres.evaluerForceRencontre(this.currentRencontre);
 | 
					      'system.force': await RdDDice.rollTotal(present.system.formule),
 | 
				
			||||||
 | 
					      'system.coord': tmr.coord
 | 
				
			||||||
 | 
					    }, {save: false});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await EffetsDraconiques.presentCites.ouvrirLePresent(this.actor, presentCite);
 | 
					    await EffetsDraconiques.presentCites.ouvrirLePresent(this.actor, presentCite);
 | 
				
			||||||
    this.removeToken(tmr, presentCite);
 | 
					    this.removeToken(tmr, presentCite);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -532,33 +573,26 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async _jetDeRencontre(tmr) {
 | 
					  async _jetDeRencontre(tmr) {
 | 
				
			||||||
    let rencontre = this.rencontresExistantes.find(prev => prev.coord == tmr.coord);
 | 
					    let rencontre = this.lookupRencontreExistente(tmr);
 | 
				
			||||||
    if (rencontre) {
 | 
					    if (rencontre) {
 | 
				
			||||||
      return rencontre;
 | 
					      return game.system.rdd.rencontresTMR.calculRencontre(rencontre, tmr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let locTMR = (this.isDemiReveCache()
 | 
					    let locTMR = (this.isDemiReveCache()
 | 
				
			||||||
      ? Misc.upperFirst(tmr.type) + " ??"
 | 
					      ? TMRUtility.getTMRType(tmr.coord) + " ??"
 | 
				
			||||||
      : tmr.label + " (" + tmr.coord + ")");
 | 
					      : tmr.label + " (" + tmr.coord + ")");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let myRoll = await RdDDice.rollTotal("1dt");
 | 
					    let myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE });
 | 
				
			||||||
    if (TMRUtility.isForceRencontre() || myRoll == 7) {
 | 
					    if (myRoll == 7) {
 | 
				
			||||||
      this._tellToUser(myRoll + ": Rencontre en " + locTMR);
 | 
					      this._tellToUser(myRoll + ": Rencontre en " + locTMR);
 | 
				
			||||||
      return await this.rencontreTMRRoll(tmr, this.actor.isRencontreSpeciale());
 | 
					      return await game.system.rdd.rencontresTMR.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre())
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this._tellToUser(myRoll + ": Pas de rencontre en " + locTMR);
 | 
					      this._tellToUser(myRoll + ": Pas de rencontre en " + locTMR);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  lookupRencontreExistente(tmr) {
 | 
				
			||||||
  async rencontreTMRRoll(tmr, isMauvaise = false) {
 | 
					    return this.rencontresExistantes.find(it => it.system.coord == tmr.coord)
 | 
				
			||||||
    let rencontre = TMRUtility.utiliseForceRencontre() ??
 | 
					      ?? this.rencontresExistantes.find(it => it.system.coord == "");
 | 
				
			||||||
      (isMauvaise
 | 
					 | 
				
			||||||
        ? await TMRRencontres.getMauvaiseRencontre()
 | 
					 | 
				
			||||||
        : await TMRRencontres.getRencontreAleatoire(tmr.type));
 | 
					 | 
				
			||||||
    rencontre.coord = tmr.coord;
 | 
					 | 
				
			||||||
    rencontre.date = game.system.rdd.calendrier.getDateFromIndex();
 | 
					 | 
				
			||||||
    rencontre.heure = game.system.rdd.calendrier.getCurrentHeure();
 | 
					 | 
				
			||||||
    return rencontre;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -586,7 +620,7 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
        maitrise: { verbe: 'maîtriser', action: 'Maîtriser le fleuve' }
 | 
					        maitrise: { verbe: 'maîtriser', action: 'Maîtriser le fleuve' }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      rollData.double = EffetsDraconiques.isDoubleResistanceFleuve(this.actor) ? true : undefined,
 | 
					      rollData.double = EffetsDraconiques.isDoubleResistanceFleuve(this.actor) ? true : undefined,
 | 
				
			||||||
      rollData.competence.system.defaut_carac = 'reve-actuel';
 | 
					        rollData.competence.system.defaut_carac = 'reve-actuel';
 | 
				
			||||||
      await this._rollMaitriseCaseHumide(rollData);
 | 
					      await this._rollMaitriseCaseHumide(rollData);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -741,7 +775,6 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
    const dialog = await RdDRoll.create(this.actor, rollData,
 | 
					    const dialog = await RdDRoll.create(this.actor, rollData,
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html',
 | 
					        html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html',
 | 
				
			||||||
        options: { height: 420 },
 | 
					 | 
				
			||||||
        close: html => { this.maximize(); } // Re-display TMR
 | 
					        close: html => { this.maximize(); } // Re-display TMR
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
@@ -806,12 +839,13 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
  async processSortReserve(sortReserve) {
 | 
					  async processSortReserve(sortReserve) {
 | 
				
			||||||
    await this.actor.deleteEmbeddedDocuments('Item', [sortReserve.id]);
 | 
					    await this.actor.deleteEmbeddedDocuments('Item', [sortReserve.id]);
 | 
				
			||||||
    console.log("declencheSortEnReserve", sortReserve);
 | 
					    console.log("declencheSortEnReserve", sortReserve);
 | 
				
			||||||
 | 
					    const heureCible = RdDCalendrier.getSigneAs('label', sortReserve.system.heurecible);
 | 
				
			||||||
    this._tellToUserAndGM(`Vous avez déclenché 
 | 
					    this._tellToUserAndGM(`Vous avez déclenché 
 | 
				
			||||||
        ${sortReserve.system.echectotal ? "<strong>l'échec total!</strong>" : "le sort"}
 | 
					        ${sortReserve.system.echectotal ? "<strong>l'échec total!</strong>" : "le sort"}
 | 
				
			||||||
        en réserve <strong>${sortReserve.name}</strong>
 | 
					        en réserve <strong>${sortReserve.name}</strong>
 | 
				
			||||||
        avec ${sortReserve.system.ptreve} points de Rêve
 | 
					        avec ${sortReserve.system.ptreve} points de Rêve
 | 
				
			||||||
        en ${sortReserve.system.coord} (${TMRUtility.getTMRLabel(sortReserve.system.coord)}).
 | 
					        en ${sortReserve.system.coord} (${TMRUtility.getTMRLabel(sortReserve.system.coord)}).
 | 
				
			||||||
        L'heure ciblée est ${sortReserve.system.heurecible}`);
 | 
					        L'heure ciblée est ${heureCible}`);
 | 
				
			||||||
    this.close();
 | 
					    this.close();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -877,16 +911,14 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (this.isDemiReveCache()) {
 | 
					    if (this.isDemiReveCache()) {
 | 
				
			||||||
      if (this.isTerreAttache(targetCoord)
 | 
					      if (this.isTerreAttache(targetCoord)
 | 
				
			||||||
      || this.isConnaissanceFleuve(currentCoord, targetCoord)
 | 
					        || this.isConnaissanceFleuve(currentCoord, targetCoord)
 | 
				
			||||||
      || deplacementType == 'changeur')
 | 
					        || deplacementType == 'changeur') {
 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        // déplacement possible
 | 
					        // déplacement possible
 | 
				
			||||||
        await this.actor.setTMRVisible(true);
 | 
					        await this.actor.setTMRVisible(true);
 | 
				
			||||||
        this.demiReve = this._tokenDemiReve();
 | 
					        this.demiReve = this._tokenDemiReve();
 | 
				
			||||||
        this._trackToken(this.demiReve);
 | 
					        this._trackToken(this.demiReve);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else
 | 
					      else {
 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        ui.notifications.error(`Vous ne connaissez plus votre position dans les TMR.
 | 
					        ui.notifications.error(`Vous ne connaissez plus votre position dans les TMR.
 | 
				
			||||||
        Vous devez utiliser les boutons de direction pour vous déplacer.
 | 
					        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.
 | 
					        Une fois que vous aurez retrouvé votre demi-rêve, demandez au gardien de vérifier et rendre les TMR visibles.
 | 
				
			||||||
@@ -895,20 +927,18 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (deplacementType){
 | 
					    switch (deplacementType) {
 | 
				
			||||||
      case 'normal':
 | 
					      case 'normal':
 | 
				
			||||||
 | 
					      case 'changeur':
 | 
				
			||||||
 | 
					      case 'passeur':
 | 
				
			||||||
        await this._deplacerDemiReve(targetCoord, deplacementType);
 | 
					        await this._deplacerDemiReve(targetCoord, deplacementType);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case 'messager':
 | 
					      case 'messager':
 | 
				
			||||||
        await this._messagerDemiReve(targetCoord);
 | 
					        await this._messagerDemiReve(targetCoord);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case 'changeur':
 | 
					 | 
				
			||||||
      case 'passeur':
 | 
					 | 
				
			||||||
        await this._deplacerDemiReve(targetCoord, deplacementType);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      default:
 | 
					      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");
 | 
					        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);
 | 
					        console.log("STATUS :", this.rencontreState, this.currentRencontre);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.checkQuitterTMR();
 | 
					    this.checkQuitterTMR();
 | 
				
			||||||
@@ -916,19 +946,23 @@ export class RdDTMRDialog extends Dialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  _calculDeplacement(targetCoord, currentCoord, fromOddq, toOddq) {
 | 
					  _calculDeplacement(targetCoord, currentCoord, fromOddq, toOddq) {
 | 
				
			||||||
 | 
					    if (this.isRencontreDeplacement()) {
 | 
				
			||||||
    const isInArea = this.rencontreState == 'aucune'
 | 
					      if (this.currentRencontre?.locList?.find(coord => coord == targetCoord)) {
 | 
				
			||||||
      ? (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1)
 | 
					        return this.rencontreState;
 | 
				
			||||||
      : this.currentRencontre?.locList?.find(coord => coord == targetCoord) ?? false
 | 
					      }
 | 
				
			||||||
    if (isInArea) {
 | 
					    }
 | 
				
			||||||
      switch (this.rencontreState) {
 | 
					    else {
 | 
				
			||||||
        case 'aucune': return 'normal';
 | 
					      if (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1) {
 | 
				
			||||||
        case 'passeur': case 'changeur': case 'messager': return this.rencontreState;
 | 
					        return 'normal'
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 'erreur';
 | 
					    return 'erreur';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  isRencontreDeplacement() {
 | 
				
			||||||
 | 
					    return ['passeur', 'changeur', 'messager'].includes(this.rencontreState);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  async _messagerDemiReve(targetCoord) {
 | 
					  async _messagerDemiReve(targetCoord) {
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,46 +2,41 @@
 | 
				
			|||||||
export class RdDTMRRencontreDialog extends Dialog {
 | 
					export class RdDTMRRencontreDialog extends Dialog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  constructor(tmrApp, rencontre, postRencontre) {
 | 
					  constructor(tmrApp, rencontre, tmr) {
 | 
				
			||||||
    const dialogConf = {
 | 
					    const dialogConf = {
 | 
				
			||||||
      title: "Rencontre en TMR!",
 | 
					      title: "Rencontre en TMR!",
 | 
				
			||||||
      content: "Vous rencontrez un " + rencontre.name + " de force " + rencontre.force + "<br>",
 | 
					      content: "Vous rencontrez un " + rencontre.name + " de force " + rencontre.system.force + "<br>",
 | 
				
			||||||
      buttons: {
 | 
					      buttons: {
 | 
				
			||||||
        derober: { icon: '<i class="fas fa-check"></i>', label: "Se dérober", callback: () => { this.onButtonFuir(() => tmrApp.derober()); } },
 | 
					        derober: { icon: '<i class="fas fa-check"></i>', label: "Se dérober", callback: () => this.onButtonAction('derober') },
 | 
				
			||||||
        refouler: { icon: '<i class="fas fa-check"></i>', label: "Refouler", callback: () => this.onButtonAction(() => tmrApp.refouler()) },
 | 
					        maitiser: { icon: '<i class="fas fa-check"></i>', label: "Maîtriser", callback: () => this.onButtonAction('maitriser') }
 | 
				
			||||||
        maitiser: { icon: '<i class="fas fa-check"></i>', label: "Maîtriser", callback: () => this.onButtonAction(() => tmrApp.maitriserRencontre()) }
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      default: "derober"
 | 
					      default: "derober"
 | 
				
			||||||
    };
 | 
					    }
 | 
				
			||||||
    if (rencontre.ignorer) {
 | 
					    if ((rencontre.system.refoulement ?? 0) == 0) {
 | 
				
			||||||
      dialogConf.buttons.ignorer = { icon: '<i class="fas fa-check"></i>', label: "Ignorer", callback: () => this.onButtonAction(() => tmrApp.ignorerRencontre()) }
 | 
					      dialogConf.buttons.ignorer = { icon: '<i class="fas fa-check"></i>', label: "Ignorer", callback: () => this.onButtonAction('ignorer') }
 | 
				
			||||||
    };
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      dialogConf.buttons.refouler =  { icon: '<i class="fas fa-check"></i>', label: "Refouler", callback: () => this.onButtonAction('refouler') }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const dialogOptions = {
 | 
					    const dialogOptions = {
 | 
				
			||||||
      classes: ["tmrrencdialog"],
 | 
					      classes: ["tmrrencdialog"],
 | 
				
			||||||
      width: 320, height: 240,
 | 
					      width: 320, height: 'fit-content',
 | 
				
			||||||
      'z-index': 50
 | 
					      'z-index': 50
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    super(dialogConf, dialogOptions);
 | 
					    super(dialogConf, dialogOptions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.toClose = false;
 | 
					    this.toClose = false;
 | 
				
			||||||
    this.rencontreData = duplicate(rencontre);
 | 
					    this.tmr = tmr;
 | 
				
			||||||
    this.postRencontre = postRencontre;
 | 
					 | 
				
			||||||
    this.tmrApp = tmrApp;
 | 
					    this.tmrApp = tmrApp;
 | 
				
			||||||
    this.tmrApp.minimize();
 | 
					    this.tmrApp.minimize();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async onButtonAction(action) {
 | 
					  async onButtonAction(action) {
 | 
				
			||||||
    this.toClose = true;
 | 
					    this.toClose = true;
 | 
				
			||||||
    await action();
 | 
					    this.tmrApp.onActionRencontre(action, this.tmr)
 | 
				
			||||||
    this.postRencontre();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  async onButtonFuir(action) {
 | 
					 | 
				
			||||||
    this.toClose = true;
 | 
					 | 
				
			||||||
    await action();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  close() {
 | 
					  close() {
 | 
				
			||||||
    if (this.toClose) {
 | 
					    if (this.toClose) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,19 +1,21 @@
 | 
				
			|||||||
/* Common useful functions shared between objects */
 | 
					/* Common useful functions shared between objects */
 | 
				
			||||||
 | 
					 | 
				
			||||||
import { ChatUtility } from "./chat-utility.js";
 | 
					import { ChatUtility } from "./chat-utility.js";
 | 
				
			||||||
import { RdDCombat } from "./rdd-combat.js";
 | 
					import { RdDCombat } from "./rdd-combat.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
import { Grammar } from "./grammar.js";
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
import { TMRUtility } from "./tmr-utility.js";
 | 
					import { TMRUtility } from "./tmr-utility.js";
 | 
				
			||||||
import { DialogItemAchat } from "./dialog-item-achat.js";
 | 
					import { DialogItemAchat } from "./dialog-item-achat.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
import { RdDDice } from "./rdd-dice.js";
 | 
					import { RdDDice } from "./rdd-dice.js";
 | 
				
			||||||
import { RdDItem } from "./item.js";
 | 
					import { RdDItem } from "./item.js";
 | 
				
			||||||
import { Monnaie } from "./item-monnaie.js";
 | 
					import { Monnaie } from "./item-monnaie.js";
 | 
				
			||||||
import { RdDPossession } from "./rdd-possession.js";
 | 
					import { RdDPossession } from "./rdd-possession.js";
 | 
				
			||||||
import { RdDNameGen } from "./rdd-namegen.js";
 | 
					import { RdDNameGen } from "./rdd-namegen.js";
 | 
				
			||||||
import { RdDConfirm } from "./rdd-confirm.js";
 | 
					import { RdDConfirm } from "./rdd-confirm.js";
 | 
				
			||||||
import { RdDActor } from "./actor.js";
 | 
					import { RdDCalendrier } from "./rdd-calendrier.js";
 | 
				
			||||||
 | 
					import { Environnement } from "./environnement.js";
 | 
				
			||||||
 | 
					import { RdDItemCompetence } from "./item-competence.js";
 | 
				
			||||||
 | 
					import { RdDResolutionTable } from "./rdd-resolution-table.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
// This table starts at 0 -> niveau -10
 | 
					// This table starts at 0 -> niveau -10
 | 
				
			||||||
@@ -168,6 +170,12 @@ export class RdDUtility {
 | 
				
			|||||||
      'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.html',
 | 
				
			||||||
      //Items
 | 
					      //Items
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-competence-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-competence-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-competencecreature-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-competencecreature-sheet.html',
 | 
				
			||||||
@@ -178,10 +186,11 @@ export class RdDUtility {
 | 
				
			|||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-sort-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-sort-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-herbe-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-herbe-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-ingredient-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-ingredient-sheet.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-faune-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-livre-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-livre-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-tache-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-tache-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-potion-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-potion-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-rencontresTMR-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-rencontre-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-souffle-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-souffle-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-tarot-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-tarot-sheet.html',
 | 
				
			||||||
@@ -192,22 +201,45 @@ export class RdDUtility {
 | 
				
			|||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-nourritureboisson-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-nourritureboisson-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/item-possession-sheet.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-possession-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/competence-carac-defaut.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/item-extraitpoetique-sheet.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/competence-base.html',
 | 
					      // partial enums
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-competence.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-competence.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-herbesoin-ingredient.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-herbesoin-ingredient.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-heures.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-initpremierround.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-initpremierround.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-niveau-ethylisme.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/sort-draconic.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-queue.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/sort-tmr.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-draconic.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/niveau-ethylisme.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-type.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/casetmr-specific-list.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.html',
 | 
				
			||||||
 | 
					      // Partials
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffLibre.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffFixe.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-surenc.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-competences.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-item-hautrevant.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-item-frequence.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/roll/explain.hbs',
 | 
				
			||||||
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/resolution-table.html',
 | 
				
			||||||
      // Dialogs
 | 
					      // Dialogs
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
 | 
				
			||||||
@@ -219,23 +251,9 @@ export class RdDUtility {
 | 
				
			|||||||
      'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html',
 | 
				
			||||||
      // Partials
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffLibre.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffFixe.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-surenc.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.html',
 | 
					 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html',
 | 
					 | 
				
			||||||
      // Calendrier
 | 
					      // Calendrier
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/calendar-template.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/calendar-template.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/heures-select-option.html',
 | 
					 | 
				
			||||||
      // HUD
 | 
					      // HUD
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html',
 | 
				
			||||||
      'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html',
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html',
 | 
				
			||||||
@@ -266,6 +284,9 @@ export class RdDUtility {
 | 
				
			|||||||
      'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html'
 | 
					      'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html'
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Handlebars.registerHelper('either', (a, b) => a ?? b);
 | 
				
			||||||
 | 
					    Handlebars.registerHelper('computeResolutionScore', (row, col) => RdDResolutionTable.computePercentage(row, col));
 | 
				
			||||||
 | 
					    Handlebars.registerHelper('computeResolutionChances', (row, col) => RdDResolutionTable.computeChances(row, col));
 | 
				
			||||||
    Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
 | 
					    Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
 | 
				
			||||||
    Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null'));
 | 
					    Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null'));
 | 
				
			||||||
    Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? 'NULL');
 | 
					    Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? 'NULL');
 | 
				
			||||||
@@ -277,46 +298,28 @@ export class RdDUtility {
 | 
				
			|||||||
    Handlebars.registerHelper('buildContenu', (objet) => { return new Handlebars.SafeString(RdDUtility.buildContenu(objet, 1, true)); });
 | 
					    Handlebars.registerHelper('buildContenu', (objet) => { return new Handlebars.SafeString(RdDUtility.buildContenu(objet, 1, true)); });
 | 
				
			||||||
    Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
 | 
					    Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
 | 
				
			||||||
    Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord));
 | 
					    Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord));
 | 
				
			||||||
    Handlebars.registerHelper('typeTmr-name', coord => TMRUtility.typeTmrName(coord));
 | 
					    Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type));
 | 
				
			||||||
 | 
					    Handlebars.registerHelper('effetRencontre-name', coord => TMRUtility.typeTmrName(coord));
 | 
				
			||||||
 | 
					    Handlebars.registerHelper('signeHeure', (key, heure)  => RdDCalendrier.getSigneAs(key, heure));
 | 
				
			||||||
    Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
 | 
					    Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
 | 
				
			||||||
    Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option));
 | 
					    Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option));
 | 
				
			||||||
    Handlebars.registerHelper('trier', competences => competences.sort((a, b) => a.name.localeCompare(b.name)));
 | 
					    Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name)));
 | 
				
			||||||
    Handlebars.registerHelper('filtreTriCompetences', competences => competences.filter(it => it.system.isVisible)
 | 
					    Handlebars.registerHelper('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences));
 | 
				
			||||||
      .sort((a, b) => {
 | 
					    Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
 | 
				
			||||||
        if (a.name.startsWith("Survie") && b.name.startsWith("Survie")) {
 | 
					    Handlebars.registerHelper('uniteQuantite', (itemId, actorId) => RdDUtility.getItem(itemId, actorId)?.getUniteQuantite());
 | 
				
			||||||
          if (a.name.includes("Cité")) return -1;
 | 
					    Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field));
 | 
				
			||||||
          if (b.name.includes("Cité")) return 1;
 | 
					    Handlebars.registerHelper('getFrequenceRarete', (rarete, field) => Environnement.getFrequenceRarete(rarete, field));
 | 
				
			||||||
          if (a.name.includes("Extérieur")) return -1;
 | 
					 | 
				
			||||||
          if (b.name.includes("Extérieur")) return 1;
 | 
					 | 
				
			||||||
          return a.name.localeCompare(b.name);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (a.system.categorie.startsWith("melee") && b.system.categorie.startsWith("melee")) {
 | 
					 | 
				
			||||||
          if (a.name.includes("Corps")) return -1;
 | 
					 | 
				
			||||||
          if (b.name.includes("Corps")) return 1;
 | 
					 | 
				
			||||||
          if (a.name.includes("Dague")) return -1;
 | 
					 | 
				
			||||||
          if (b.name.includes("Dague")) return 1;
 | 
					 | 
				
			||||||
          if (a.name.includes("Esquive")) return -1;
 | 
					 | 
				
			||||||
          if (b.name.includes("Esquive")) return 1;
 | 
					 | 
				
			||||||
          return a.name.localeCompare(b.name);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (a.name.startsWith("Voie") && b.name.startsWith("Voie")) {
 | 
					 | 
				
			||||||
          if (a.name.includes("Oniros")) return -1;
 | 
					 | 
				
			||||||
          if (b.name.includes("Oniros")) return 1;
 | 
					 | 
				
			||||||
          if (a.name.includes("Hypnos")) return -1;
 | 
					 | 
				
			||||||
          if (b.name.includes("Hypnos")) return 1;
 | 
					 | 
				
			||||||
          if (a.name.includes("Narcos")) return -1;
 | 
					 | 
				
			||||||
          if (b.name.includes("Narcos")) return 1;
 | 
					 | 
				
			||||||
          if (a.name.includes("Thanatos")) return -1;
 | 
					 | 
				
			||||||
          if (b.name.includes("Thanatos")) return 1;
 | 
					 | 
				
			||||||
          return a.name.localeCompare(b.name);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return a.name.localeCompare(b.name);
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return loadTemplates(templatePaths);
 | 
					    return loadTemplates(templatePaths);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getItem(itemId, actorId = undefined) {
 | 
				
			||||||
 | 
					    return actorId ? game.actors.get(actorId)?.getObjet(itemId) : game.items.get(itemId);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static linkCompendium(pack, id, name) {
 | 
				
			||||||
 | 
					    return `@Compendium[${pack}.${id}]{${name}}`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async creerObjet(actorSheet) {
 | 
					  static async creerObjet(actorSheet) {
 | 
				
			||||||
    let itemType = $(".item-type").val();
 | 
					    let itemType = $(".item-type").val();
 | 
				
			||||||
@@ -325,7 +328,7 @@ export class RdDUtility {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async selectObjetType(actorSheet) {
 | 
					  static async selectObjetType(actorSheet) {
 | 
				
			||||||
    let typeObjets = RdDItem.getTypesObjetsEquipement();
 | 
					    let typeObjets = RdDItem.getItemTypesInventaire();
 | 
				
			||||||
    let options = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
 | 
					    let options = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
 | 
				
			||||||
    for (let typeName of typeObjets) {
 | 
					    for (let typeName of typeObjets) {
 | 
				
			||||||
      options += `<option value="${typeName}">${typeName}</option>`
 | 
					      options += `<option value="${typeName}">${typeName}</option>`
 | 
				
			||||||
@@ -412,6 +415,7 @@ export class RdDUtility {
 | 
				
			|||||||
    RdDUtility.filterEquipementParType(formData, itemTypes);
 | 
					    RdDUtility.filterEquipementParType(formData, itemTypes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    formData.sorts = this.arrayOrEmpty(itemTypes['sort']);
 | 
					    formData.sorts = this.arrayOrEmpty(itemTypes['sort']);
 | 
				
			||||||
 | 
					    formData.rencontres = this.arrayOrEmpty(itemTypes['rencontre']);
 | 
				
			||||||
    formData.casestmr = this.arrayOrEmpty(itemTypes['casetmr']);
 | 
					    formData.casestmr = this.arrayOrEmpty(itemTypes['casetmr']);
 | 
				
			||||||
    formData.signesdraconiques = this.arrayOrEmpty(itemTypes['signedraconique']);
 | 
					    formData.signesdraconiques = this.arrayOrEmpty(itemTypes['signedraconique']);
 | 
				
			||||||
    formData.queues = this.arrayOrEmpty(itemTypes['queue']);
 | 
					    formData.queues = this.arrayOrEmpty(itemTypes['queue']);
 | 
				
			||||||
@@ -446,9 +450,9 @@ export class RdDUtility {
 | 
				
			|||||||
    formData.livres = this.arrayOrEmpty(itemTypes['livre']);
 | 
					    formData.livres = this.arrayOrEmpty(itemTypes['livre']);
 | 
				
			||||||
    formData.potions = this.arrayOrEmpty(itemTypes['potion']);
 | 
					    formData.potions = this.arrayOrEmpty(itemTypes['potion']);
 | 
				
			||||||
    formData.ingredients = this.arrayOrEmpty(itemTypes['ingredient']);
 | 
					    formData.ingredients = this.arrayOrEmpty(itemTypes['ingredient']);
 | 
				
			||||||
 | 
					    formData.faunes = this.arrayOrEmpty(itemTypes['faune']);
 | 
				
			||||||
    formData.herbes = this.arrayOrEmpty(itemTypes['herbe']);
 | 
					    formData.herbes = this.arrayOrEmpty(itemTypes['herbe']);
 | 
				
			||||||
    formData.monnaie = this.arrayOrEmpty(itemTypes['monnaie']);
 | 
					    formData.monnaie = this.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere());
 | 
				
			||||||
    formData.monnaie.sort(Monnaie.triValeurDenier());
 | 
					 | 
				
			||||||
    formData.nourritureboissons = this.arrayOrEmpty(itemTypes['nourritureboisson']);
 | 
					    formData.nourritureboissons = this.arrayOrEmpty(itemTypes['nourritureboisson']);
 | 
				
			||||||
    formData.gemmes = this.arrayOrEmpty(itemTypes['gemme']);
 | 
					    formData.gemmes = this.arrayOrEmpty(itemTypes['gemme']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -461,6 +465,7 @@ export class RdDUtility {
 | 
				
			|||||||
      .concat(formData.potions)
 | 
					      .concat(formData.potions)
 | 
				
			||||||
      .concat(formData.ingredients)
 | 
					      .concat(formData.ingredients)
 | 
				
			||||||
      .concat(formData.herbes)
 | 
					      .concat(formData.herbes)
 | 
				
			||||||
 | 
					      .concat(formData.faunes)
 | 
				
			||||||
      .concat(formData.monnaie)
 | 
					      .concat(formData.monnaie)
 | 
				
			||||||
      .concat(formData.nourritureboissons)
 | 
					      .concat(formData.nourritureboissons)
 | 
				
			||||||
      .concat(formData.gemmes);
 | 
					      .concat(formData.gemmes);
 | 
				
			||||||
@@ -534,8 +539,7 @@ export class RdDUtility {
 | 
				
			|||||||
    if (!profondeur) profondeur = 1;
 | 
					    if (!profondeur) profondeur = 1;
 | 
				
			||||||
    objet.niveau = profondeur;
 | 
					    objet.niveau = profondeur;
 | 
				
			||||||
    const display = afficherContenu ? 'item-display-show' : 'item-display-hide';
 | 
					    const display = afficherContenu ? 'item-display-show' : 'item-display-hide';
 | 
				
			||||||
    //console.log("ITEM DISPLAYED", objet );
 | 
					    let strContenu = `<ul class='item-list alterne-list ${display} list-item-margin${Math.min(profondeur,6)}'>`;
 | 
				
			||||||
    let strContenu = `<ul class='item-list alterne-list ${display} list-item-margin${profondeur}'>`;
 | 
					 | 
				
			||||||
    for (let subItem of objet.subItems) {
 | 
					    for (let subItem of objet.subItems) {
 | 
				
			||||||
      strContenu += this.buildConteneur(subItem, profondeur + 1);
 | 
					      strContenu += this.buildConteneur(subItem, profondeur + 1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -752,29 +756,6 @@ export class RdDUtility {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async loadItems(filter, compendium) {
 | 
					 | 
				
			||||||
    let items = game.items.filter(filter);
 | 
					 | 
				
			||||||
    if (compendium) {
 | 
					 | 
				
			||||||
      const ids = items.map(it => it.id);
 | 
					 | 
				
			||||||
      const names = items.map(it => it.name.toLowerCase());
 | 
					 | 
				
			||||||
      items = items.concat(await RdDUtility.loadCompendium(compendium, it => !ids.includes(it.id) && !names.includes(it.name.toLowerCase()) && filter(it)));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return items;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async loadCompendium(compendium, filter = it => true) {
 | 
					 | 
				
			||||||
    let compendiumData = await RdDUtility.loadCompendiumData(compendium);
 | 
					 | 
				
			||||||
    return compendiumData.filter(filter);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async loadCompendiumData(compendium) {
 | 
					 | 
				
			||||||
    const pack = game.packs.get(compendium);
 | 
					 | 
				
			||||||
    return await pack?.getDocuments() ?? [];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async responseNombreAstral(callData) {
 | 
					  static async responseNombreAstral(callData) {
 | 
				
			||||||
    let actor = game.actors.get(callData.id);
 | 
					    let actor = game.actors.get(callData.id);
 | 
				
			||||||
@@ -841,17 +822,10 @@ export class RdDUtility {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Gestion du bouton payer
 | 
					    // Gestion du bouton payer
 | 
				
			||||||
    html.on("click", '.payer-button', event => {
 | 
					    html.on("click", '.payer-button', event => {
 | 
				
			||||||
      let sumdenier = event.currentTarget.attributes['data-somme-denier']?.value ?? 0;
 | 
					      let sommeAPayer = Number(event.currentTarget.attributes['data-somme-a-payer']?.value ?? 0);
 | 
				
			||||||
      let quantite = event.currentTarget.attributes['data-quantite']?.value ?? 1;
 | 
					 | 
				
			||||||
      let fromActorId = event.currentTarget.attributes['data-actor-id']?.value;
 | 
					 | 
				
			||||||
      let jsondata = event.currentTarget.attributes['data-jsondata']
 | 
					 | 
				
			||||||
      let objData
 | 
					 | 
				
			||||||
      if (jsondata) {
 | 
					 | 
				
			||||||
        objData = JSON.parse(jsondata.value)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      let actor = RdDUtility.getSelectedActor("Pour effectuer le paiement:");
 | 
					      let actor = RdDUtility.getSelectedActor("Pour effectuer le paiement:");
 | 
				
			||||||
      if (actor) {
 | 
					      if (actor) {
 | 
				
			||||||
        actor.depenserDeniers(sumdenier, objData, quantite, fromActorId);
 | 
					        actor.payerSols(sommeAPayer);
 | 
				
			||||||
        ChatUtility.removeChatMessageId(RdDUtility.findChatMessageId(event.currentTarget));
 | 
					        ChatUtility.removeChatMessageId(RdDUtility.findChatMessageId(event.currentTarget));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@@ -902,12 +876,12 @@ export class RdDUtility {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static createMonnaie(name, valeur_deniers, img = "", enc = 0.01) {
 | 
					  static createMonnaie(name, cout, img = "", enc = 0.01) {
 | 
				
			||||||
    let piece = {
 | 
					    let piece = {
 | 
				
			||||||
      name: name, type: 'monnaie', img: img, _id: randomID(16),
 | 
					      name: name, type: 'monnaie', img: img, _id: randomID(16),
 | 
				
			||||||
      dasystemta: {
 | 
					      dasystemta: {
 | 
				
			||||||
        quantite: 0,
 | 
					        quantite: 0,
 | 
				
			||||||
        valeur_deniers: valeur_deniers,
 | 
					        cout: cout,
 | 
				
			||||||
        encombrement: enc,
 | 
					        encombrement: enc,
 | 
				
			||||||
        description: ""
 | 
					        description: ""
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -919,20 +893,20 @@ export class RdDUtility {
 | 
				
			|||||||
  static afficherDemandePayer(som1, som2) {
 | 
					  static afficherDemandePayer(som1, som2) {
 | 
				
			||||||
    som1 = (som1) ? som1.toLowerCase() : "0d";
 | 
					    som1 = (som1) ? som1.toLowerCase() : "0d";
 | 
				
			||||||
    som2 = (som2) ? som2.toLowerCase() : "0d";
 | 
					    som2 = (som2) ? som2.toLowerCase() : "0d";
 | 
				
			||||||
    let regExp = /(\d+)(\w+)/g;
 | 
					    let regExp1 = /(\d+)(\w+)/g;
 | 
				
			||||||
    let p1 = regExp.exec(som1);
 | 
					    let p1 = regExp1.exec(som1);
 | 
				
			||||||
    regExp = /(\d+)(\w+)/g;
 | 
					    let regExp2 = /(\d+)(\w+)/g;
 | 
				
			||||||
    let p2 = regExp.exec(som2);
 | 
					    let p2 = regExp2.exec(som2);
 | 
				
			||||||
    let sumd = 0;
 | 
					    let deniers = 0;
 | 
				
			||||||
    let sums = 0;
 | 
					    let sols = 0;
 | 
				
			||||||
    if (p1[2] == 'd') sumd += Number(p1[1]);
 | 
					    if (p1[2] == 'd') deniers += Number(p1[1]);
 | 
				
			||||||
    if (p1[2] == 's') sums += Number(p1[1]);
 | 
					    if (p1[2] == 's') sols += Number(p1[1]);
 | 
				
			||||||
    if (p2[2] == 'd') sumd += Number(p2[1]);
 | 
					    if (p2[2] == 'd') deniers += Number(p2[1]);
 | 
				
			||||||
    if (p2[2] == 's') sums += Number(p2[1]);
 | 
					    if (p2[2] == 's') sols += Number(p2[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let sumtotald = sumd + (sums * 100);
 | 
					    let sommeAPayer = sols + deniers/100;
 | 
				
			||||||
    let msgPayer = "La somme de " + sums + " Sols et " + sumd + " Deniers est à payer, cliquer sur le lien ci-dessous si besoin.<br>";
 | 
					    let msgPayer = `La somme de ${sols} Sols et ${deniers} Deniers est à payer<br>
 | 
				
			||||||
    msgPayer += "<a class='payer-button chat-card-button' data-somme-denier='" + sumtotald + "'>Payer</a>"
 | 
					      <a class='payer-button chat-card-button' data-somme-a-payer='${sommeAPayer}'>Payer</a>`
 | 
				
			||||||
    ChatMessage.create({ content: msgPayer });
 | 
					    ChatMessage.create({ content: msgPayer });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1007,7 +981,7 @@ export class RdDUtility {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static slideOnDelete(sheet, htmlToDelete) {
 | 
					  static slideOnDelete(sheet, htmlToDelete) {
 | 
				
			||||||
    return htmlToDelete.slideUp(200, () => sheet.render(false));
 | 
					    return htmlToDelete?.slideUp(200, () => sheet.render(false));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ import { Misc } from "./misc.js";
 | 
				
			|||||||
import { RdDBonus } from "./rdd-bonus.js";
 | 
					import { RdDBonus } from "./rdd-bonus.js";
 | 
				
			||||||
import { RdDCarac } from "./rdd-carac.js";
 | 
					import { RdDCarac } from "./rdd-carac.js";
 | 
				
			||||||
import { RdDUtility } from "./rdd-utility.js";
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
import { ReglesOptionelles } from "./regles-optionelles.js";
 | 
					import { ReglesOptionelles } from "./settings/regles-optionelles.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * tous les ajustements pouvant s'appliquer.
 | 
					 * tous les ajustements pouvant s'appliquer.
 | 
				
			||||||
@@ -62,20 +62,20 @@ export const referenceAjustements = {
 | 
				
			|||||||
    getValue: (rollData, actor) => actor.getMalusArmure()
 | 
					    getValue: (rollData, actor) => actor.getMalusArmure()
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  encTotal: {
 | 
					  encTotal: {
 | 
				
			||||||
    isVisible: (rollData, actor) => RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
 | 
					    isVisible: (rollData, actor) => RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac) && RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
 | 
				
			||||||
    isUsed: (rollData, actor) => rollData.useMalusEncTotal,
 | 
					    isUsed: (rollData, actor) => !rollData.oeuvre && RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac) && RdDItemCompetence.isMalusEncombrementTotal(rollData.competence) && rollData.use.encTotal,
 | 
				
			||||||
    getLabel: (rollData, actor) => 'Encombrement total',
 | 
					    getLabel: (rollData, actor) => 'Encombrement total',
 | 
				
			||||||
    getValue: (rollData, actor) => -actor.getEncTotal()
 | 
					    getValue: (rollData, actor) => -actor.getEncTotal()
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  surenc: {
 | 
					  surenc: {
 | 
				
			||||||
    isVisible: (rollData, actor) => rollData.useMalusSurenc,
 | 
					    isVisible: (rollData, actor) => actor.isSurenc(),
 | 
				
			||||||
    isUsed: (rollData, actor) => rollData.useMalusSurenc,
 | 
					    isUsed: (rollData, actor) => rollData.use?.surenc,
 | 
				
			||||||
    getLabel: (rollData, actor) => 'Sur-encombrement',
 | 
					    getLabel: (rollData, actor) => 'Sur-encombrement',
 | 
				
			||||||
    getValue: (rollData, actor) => actor.computeMalusSurEncombrement()
 | 
					    getValue: (rollData, actor) => actor.computeMalusSurEncombrement()
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  moral: {
 | 
					  moral: {
 | 
				
			||||||
    isVisible: (rollData, actor) => actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac) && rollData.useMoral,
 | 
					    isVisible: (rollData, actor) => actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac) && rollData.use?.moral,
 | 
				
			||||||
    isUsed: (rollData, actor) => rollData.useMoral,
 | 
					    isUsed: (rollData, actor) => rollData.use?.moral,
 | 
				
			||||||
    getLabel: (rollData, actor) => 'Appel au moral',
 | 
					    getLabel: (rollData, actor) => 'Appel au moral',
 | 
				
			||||||
    getValue: (rollData, actor) => 1
 | 
					    getValue: (rollData, actor) => 1
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
@@ -120,7 +120,7 @@ export const referenceAjustements = {
 | 
				
			|||||||
    isVisible: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
 | 
					    isVisible: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
 | 
				
			||||||
    isUsed: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
 | 
					    isUsed: (rollData, actor) => rollData.tmr && rollData.rencontre?.name,
 | 
				
			||||||
    getLabel: (rollData, actor) => rollData.rencontre?.name,
 | 
					    getLabel: (rollData, actor) => rollData.rencontre?.name,
 | 
				
			||||||
    getValue: (rollData, actor) => - (rollData.rencontre?.force ?? 0)
 | 
					    getValue: (rollData, actor) => - (rollData.rencontre?.system.force ?? 0)
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  ethylismeAlcool: {
 | 
					  ethylismeAlcool: {
 | 
				
			||||||
    isVisible: (rollData, actor) => rollData.nbDoses != undefined,
 | 
					    isVisible: (rollData, actor) => rollData.nbDoses != undefined,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
import { SYSTEM_RDD } from "./constants.js";
 | 
					import { SYSTEM_RDD } from "../constants.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					import { Misc } from "../misc.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const listeReglesOptionelles = [
 | 
					const listeReglesOptionelles = [
 | 
				
			||||||
  { group: 'Règles de combat', name: 'recul', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
 | 
					  { group: 'Règles de combat', name: 'recul', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
 | 
				
			||||||
@@ -18,6 +18,7 @@ const listeReglesOptionelles = [
 | 
				
			|||||||
  { group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"},
 | 
					  { group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"},
 | 
				
			||||||
  { group: 'Règles générales', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
 | 
					  { group: 'Règles générales', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  { group: 'Confirmations', name: 'confirmer-combat-sans-cible',         descr: "Confirmer avant une attaque sans cible", scope: "client"},
 | 
				
			||||||
  { group: 'Confirmations', name: 'confirmation-tmr',                    descr: "Confirmer pour monter dans les TMR", scope: "client"},
 | 
					  { group: 'Confirmations', name: 'confirmation-tmr',                    descr: "Confirmer pour monter dans les TMR", scope: "client"},
 | 
				
			||||||
  { group: 'Confirmations', name: 'confirmation-refouler',               descr: "Confirmer avant de refouler", scope: "client"},
 | 
					  { group: 'Confirmations', name: 'confirmation-refouler',               descr: "Confirmer avant de refouler", scope: "client"},
 | 
				
			||||||
  { group: 'Confirmations', name: 'confirmation-vider',                  descr: "Confirmer pour vider l'équipement", scope: "client"},
 | 
					  { group: 'Confirmations', name: 'confirmation-vider',                  descr: "Confirmer pour vider l'équipement", scope: "client"},
 | 
				
			||||||
@@ -43,7 +44,7 @@ export class ReglesOptionelles extends FormApplication {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    game.settings.registerMenu(SYSTEM_RDD, "rdd-options-regles", {
 | 
					    game.settings.registerMenu(SYSTEM_RDD, "rdd-options-regles", {
 | 
				
			||||||
      name: "Choisir les règles optionelles",
 | 
					      name: "Choisir les règles optionelles",
 | 
				
			||||||
      label: "Choix des règles optionelles",
 | 
					      label: "Règles optionelles",
 | 
				
			||||||
      hint: "Ouvre la fenêtre de sélection des règles optionelles",
 | 
					      hint: "Ouvre la fenêtre de sélection des règles optionelles",
 | 
				
			||||||
      icon: "fas fa-bars",
 | 
					      icon: "fas fa-bars",
 | 
				
			||||||
      type: ReglesOptionelles
 | 
					      type: ReglesOptionelles
 | 
				
			||||||
@@ -61,8 +62,8 @@ export class ReglesOptionelles extends FormApplication {
 | 
				
			|||||||
  static get defaultOptions() {
 | 
					  static get defaultOptions() {
 | 
				
			||||||
    const options = super.defaultOptions;
 | 
					    const options = super.defaultOptions;
 | 
				
			||||||
    mergeObject(options, {
 | 
					    mergeObject(options, {
 | 
				
			||||||
      id: "optional-settings",
 | 
					      id: "regles-optionelles",
 | 
				
			||||||
      template: "systems/foundryvtt-reve-de-dragon/templates/regles-optionelles.html",
 | 
					      template: "systems/foundryvtt-reve-de-dragon/templates/settings/regles-optionelles.html",
 | 
				
			||||||
      height: 600,
 | 
					      height: 600,
 | 
				
			||||||
      width: 450,
 | 
					      width: 450,
 | 
				
			||||||
      minimizable: false,
 | 
					      minimizable: false,
 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { SYSTEM_RDD } from "./constants.js";
 | 
					import { SYSTEM_RDD } from "../constants.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const STATUSES = {
 | 
					export const STATUSES = {
 | 
				
			||||||
  StatusStunned : 'stun',
 | 
					  StatusStunned : 'stun',
 | 
				
			||||||
@@ -32,7 +32,7 @@ const demiReveStatusEffect = rddStatusEffects.find(it => it.id == STATUSES.Statu
 | 
				
			|||||||
const statusDemiSurprise = [STATUSES.StatusStunned, STATUSES.StatusProne, STATUSES.StatusRestrained];
 | 
					const statusDemiSurprise = [STATUSES.StatusStunned, STATUSES.StatusProne, STATUSES.StatusRestrained];
 | 
				
			||||||
const statusSurpriseTotale = [STATUSES.StatusUnconscious, STATUSES.StatusBlind, STATUSES.StatusComma];
 | 
					const statusSurpriseTotale = [STATUSES.StatusUnconscious, STATUSES.StatusBlind, STATUSES.StatusComma];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class StatusEffects {
 | 
					export class StatusEffects extends FormApplication {
 | 
				
			||||||
  static onReady() {
 | 
					  static onReady() {
 | 
				
			||||||
    const rddStatusIds = rddStatusEffects.map(it => it.id);
 | 
					    const rddStatusIds = rddStatusEffects.map(it => it.id);
 | 
				
			||||||
    rddStatusEffects.forEach(it => it.flags = { core: { statusId: it.id } });
 | 
					    rddStatusEffects.forEach(it => it.flags = { core: { statusId: it.id } });
 | 
				
			||||||
@@ -50,7 +50,7 @@ export class StatusEffects {
 | 
				
			|||||||
      label: "Choix des effets",
 | 
					      label: "Choix des effets",
 | 
				
			||||||
      hint: "Ouvre la fenêtre de sélection des effets/status appliqués aux acteurs",
 | 
					      hint: "Ouvre la fenêtre de sélection des effets/status appliqués aux acteurs",
 | 
				
			||||||
      icon: "fas fa-bars",
 | 
					      icon: "fas fa-bars",
 | 
				
			||||||
      type: StatusEffectsSettings,
 | 
					      type: StatusEffects,
 | 
				
			||||||
      restricted: true
 | 
					      restricted: true
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -69,13 +69,12 @@ export class StatusEffects {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static _getUseStatusEffects() {
 | 
					  static _getUseStatusEffects() {
 | 
				
			||||||
    const setting = game.settings.get(SYSTEM_RDD, "use-status-effects");
 | 
					     return game.settings.get(SYSTEM_RDD, "use-status-effects")?.split(',') ?? [];
 | 
				
			||||||
    return setting ? setting.split(',') : [];
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static _setUseStatusEffects(statusIds) {
 | 
					  static _setUseStatusEffects(statusIds) {
 | 
				
			||||||
    if (game.user.isGM) {
 | 
					    if (game.user.isGM) {
 | 
				
			||||||
      game.settings.set(SYSTEM_RDD, "use-status-effects", StatusEffects._toSetting(statusIds));
 | 
					      game.settings.set(SYSTEM_RDD, "use-status-effects", statusIds.join());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (let effect of CONFIG.RDD.allEffects) {
 | 
					    for (let effect of CONFIG.RDD.allEffects) {
 | 
				
			||||||
@@ -84,10 +83,6 @@ export class StatusEffects {
 | 
				
			|||||||
    CONFIG.statusEffects = CONFIG.RDD.allEffects.filter(it => it.active);
 | 
					    CONFIG.statusEffects = CONFIG.RDD.allEffects.filter(it => it.active);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static _toSetting(statusIds) {
 | 
					 | 
				
			||||||
    return statusIds.join();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static status(statusId) {
 | 
					  static status(statusId) {
 | 
				
			||||||
    return rddStatusEffects.find(it => it.flags?.core?.statusId == statusId);
 | 
					    return rddStatusEffects.find(it => it.flags?.core?.statusId == statusId);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -95,9 +90,7 @@ export class StatusEffects {
 | 
				
			|||||||
  static demiReve() {
 | 
					  static demiReve() {
 | 
				
			||||||
    return demiReveStatusEffect;
 | 
					    return demiReveStatusEffect;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StatusEffectsSettings extends FormApplication {
 | 
					 | 
				
			||||||
  constructor(...args) {
 | 
					  constructor(...args) {
 | 
				
			||||||
    super(...args);
 | 
					    super(...args);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -105,9 +98,9 @@ class StatusEffectsSettings extends FormApplication {
 | 
				
			|||||||
  static get defaultOptions() {
 | 
					  static get defaultOptions() {
 | 
				
			||||||
    const options = super.defaultOptions;
 | 
					    const options = super.defaultOptions;
 | 
				
			||||||
    mergeObject(options, {
 | 
					    mergeObject(options, {
 | 
				
			||||||
      id: "status-effects-settings",
 | 
					      id: "status-effects",
 | 
				
			||||||
      template: "systems/foundryvtt-reve-de-dragon/templates/status-effects-settings.html",
 | 
					      template: "systems/foundryvtt-reve-de-dragon/templates/settings/status-effects.html",
 | 
				
			||||||
      height: "800",
 | 
					      height: 800,
 | 
				
			||||||
      width: 350,
 | 
					      width: 350,
 | 
				
			||||||
      minimizable: false,
 | 
					      minimizable: false,
 | 
				
			||||||
      closeOnSubmit: true,
 | 
					      closeOnSubmit: true,
 | 
				
			||||||
							
								
								
									
										287
									
								
								module/settings/system-compendiums.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,287 @@
 | 
				
			|||||||
 | 
					import { HIDE_DICE, SYSTEM_RDD } from "../constants.js";
 | 
				
			||||||
 | 
					import { RdDItem } from "../item.js";
 | 
				
			||||||
 | 
					import { Misc } from "../misc.js";
 | 
				
			||||||
 | 
					import { RdDDice } from "../rdd-dice.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const COMPENDIUM_SETTING_PREFIX = 'compendium-';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CONFIGURABLE_COMPENDIUMS = {
 | 
				
			||||||
 | 
					  'tables-diverses': { label: "Tables aléatoires", type: "RollTable" },
 | 
				
			||||||
 | 
					  'competences': { label: "Compétences", type: "Item" },
 | 
				
			||||||
 | 
					  'extrait-poetique': { label: "Extraits poetiques", type: "Item" },
 | 
				
			||||||
 | 
					  'queues-de-dragon': { label: "Queues de dragon", type: "Item" },
 | 
				
			||||||
 | 
					  'ombres-de-thanatos': { label: "Ombres de Thanatos", type: "Item" },
 | 
				
			||||||
 | 
					  'souffles-de-dragon': { label: "Souffles de Dragon", type: "Item" },
 | 
				
			||||||
 | 
					  'tarot-draconique': { label: "Tarots draconiques", type: "Item" },
 | 
				
			||||||
 | 
					  'rencontres': { label: "Rencontres dans les TMR", type: "Item" },
 | 
				
			||||||
 | 
					  'tetes-de-dragon-pour-haut-revants': { label: "Têtes de dragons (haut-rêvant)", type: "Item" },
 | 
				
			||||||
 | 
					  'tetes-de-dragon-pour-tous-personnages': { label: "Têtes de dragons (tous)", type: "Item" },
 | 
				
			||||||
 | 
					  'faune-flore-mineraux': { label: "Herbes & plantes", type: "Item" },
 | 
				
			||||||
 | 
					  'equipement': { label: "Equipements", type: "Item" },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ======= Gestion des accès aux compendiums systèmes (ou surchargés) =======
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export class SystemCompendiums extends FormApplication {
 | 
				
			||||||
 | 
					  static init() {
 | 
				
			||||||
 | 
					    Object.keys(CONFIGURABLE_COMPENDIUMS).forEach(compendium => {
 | 
				
			||||||
 | 
					      const definition = CONFIGURABLE_COMPENDIUMS[compendium];
 | 
				
			||||||
 | 
					      mergeObject(definition, {
 | 
				
			||||||
 | 
					        compendium: compendium,
 | 
				
			||||||
 | 
					        default: SystemCompendiums._getDefaultCompendium(compendium),
 | 
				
			||||||
 | 
					        setting: SystemCompendiums._getSettingCompendium(compendium)
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      game.settings.register(SYSTEM_RDD, definition.setting, {
 | 
				
			||||||
 | 
					        name: definition.label,
 | 
				
			||||||
 | 
					        default: definition.default,
 | 
				
			||||||
 | 
					        scope: "world",
 | 
				
			||||||
 | 
					        config: false,
 | 
				
			||||||
 | 
					        type: String
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    game.settings.registerMenu(SYSTEM_RDD, "compendium-settings", {
 | 
				
			||||||
 | 
					      name: "Choisir les compendiums système",
 | 
				
			||||||
 | 
					      label: "Compendiums système",
 | 
				
			||||||
 | 
					      hint: "Ouvre la fenêtre de sélection des compendiums système",
 | 
				
			||||||
 | 
					      icon: "fas fa-bars",
 | 
				
			||||||
 | 
					      type: SystemCompendiums
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getPack(compendium) {
 | 
				
			||||||
 | 
					    return game.packs.get(SystemCompendiums.getCompendium(compendium)) ?? game.packs.get(SystemCompendiums._getDefaultCompendium(compendium));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async getPackContent(compendium, docType) {
 | 
				
			||||||
 | 
					    const pack = SystemCompendiums.getPack(compendium);
 | 
				
			||||||
 | 
					    if (pack.metadata.type == docType) {
 | 
				
			||||||
 | 
					      return await pack.getDocuments();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return [];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async getCompetences(actorType) {
 | 
				
			||||||
 | 
					    switch (actorType ?? 'personnage') {
 | 
				
			||||||
 | 
					      case 'personnage': return await SystemCompendiums.getWorldOrCompendiumItems('competence', 'competences');
 | 
				
			||||||
 | 
					      case 'creature': return await SystemCompendiums.getWorldOrCompendiumItems('competencecreature', 'competences-creatures');
 | 
				
			||||||
 | 
					      case 'entite': return await SystemCompendiums.getWorldOrCompendiumItems('competencecreature', 'competences-entites');
 | 
				
			||||||
 | 
					      case 'vehicule': return [];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async getWorldOrCompendiumItems(itemType, compendium) {
 | 
				
			||||||
 | 
					    let items = game.items.filter(it => it.type == itemType);
 | 
				
			||||||
 | 
					    if (compendium) {
 | 
				
			||||||
 | 
					      const ids = items.map(it => it.id);
 | 
				
			||||||
 | 
					      const names = items.map(it => it.name.toLowerCase());
 | 
				
			||||||
 | 
					      const compendiumItems = await SystemCompendiums.getItems(compendium);
 | 
				
			||||||
 | 
					      items = items.concat(compendiumItems
 | 
				
			||||||
 | 
					        .filter(it => it.type == itemType)
 | 
				
			||||||
 | 
					        .filter(it => !ids.includes(it.id))
 | 
				
			||||||
 | 
					        .filter(it => !names.includes(it.name.toLowerCase())));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return items;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async getItems(compendium, itemType = undefined) {
 | 
				
			||||||
 | 
					    const items = await SystemCompendiums.getPackContent(compendium, 'Item');
 | 
				
			||||||
 | 
					    return (itemType ? items.filter(it => it.type == itemType) : items);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async getContent(compendium, type, filter, itemFrequence, sorting) {
 | 
				
			||||||
 | 
					    let elements = await SystemCompendiums.getPackContent(compendium, type);
 | 
				
			||||||
 | 
					    elements = elements.filter(filter).filter(it => itemFrequence(it) > 0);
 | 
				
			||||||
 | 
					    if (sorting) {
 | 
				
			||||||
 | 
					      elements = elements.sort(sorting);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return elements;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async getDefaultItems(compendium) {
 | 
				
			||||||
 | 
					    const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium));
 | 
				
			||||||
 | 
					    if (pack.metadata.type == 'Item') {
 | 
				
			||||||
 | 
					      return await pack.getDocuments();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return [];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getCompendium(compendium) {
 | 
				
			||||||
 | 
					    const setting = CONFIGURABLE_COMPENDIUMS[compendium]?.setting;
 | 
				
			||||||
 | 
					    return setting ? game.settings.get(SYSTEM_RDD, setting) : SystemCompendiums._getDefaultCompendium(compendium);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static _getSettingCompendium(compendium) {
 | 
				
			||||||
 | 
					    return COMPENDIUM_SETTING_PREFIX + compendium;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static _getDefaultCompendium(compendium) {
 | 
				
			||||||
 | 
					    return `${SYSTEM_RDD}.${compendium}`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(...args) {
 | 
				
			||||||
 | 
					    super(...args);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get defaultOptions() {
 | 
				
			||||||
 | 
					    const options = super.defaultOptions;
 | 
				
			||||||
 | 
					    mergeObject(options, {
 | 
				
			||||||
 | 
					      id: "system-compendiums",
 | 
				
			||||||
 | 
					      template: "systems/foundryvtt-reve-de-dragon/templates/settings/system-compendiums.html",
 | 
				
			||||||
 | 
					      height: 'fit-content',
 | 
				
			||||||
 | 
					      width: 600,
 | 
				
			||||||
 | 
					      minimizable: false,
 | 
				
			||||||
 | 
					      closeOnSubmit: true,
 | 
				
			||||||
 | 
					      title: "Compendiums système"
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return options;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getData() {
 | 
				
			||||||
 | 
					    const systemCompendiums = Object.values(CONFIGURABLE_COMPENDIUMS)
 | 
				
			||||||
 | 
					      .map(it => mergeObject(it, { value: SystemCompendiums.getCompendium(it.compendium) }));
 | 
				
			||||||
 | 
					    const availableCompendiums = game.packs.map(pack => {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        name: pack.collection,
 | 
				
			||||||
 | 
					        path: pack.collection.replace('.', " / "),
 | 
				
			||||||
 | 
					        type: pack.metadata.type
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return mergeObject(super.getData(), {
 | 
				
			||||||
 | 
					      systemCompendiums: systemCompendiums,
 | 
				
			||||||
 | 
					      availableCompendiums: availableCompendiums
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  activateListeners(html) {
 | 
				
			||||||
 | 
					    html.find("select.system-compendium-setting").change((event) => {
 | 
				
			||||||
 | 
					      const compendium = $(event.currentTarget).data('compendium')
 | 
				
			||||||
 | 
					      const value = $(event.currentTarget).val();
 | 
				
			||||||
 | 
					      const systemCompendium = CONFIGURABLE_COMPENDIUMS[compendium];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      game.settings.set(SYSTEM_RDD, systemCompendium.setting, value);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ======= Gestion de jets dans une table correspondant à un compendium =======
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export class CompendiumTable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(compendium, type, subTypes, sorting = undefined) {
 | 
				
			||||||
 | 
					    this.compendium = compendium;
 | 
				
			||||||
 | 
					    this.type = type;
 | 
				
			||||||
 | 
					    this.subTypes = subTypes;
 | 
				
			||||||
 | 
					    this.sorting = sorting ?? Misc.ascending(it => it.name);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getContent(itemFrequence = it => it.system.frequence, filter = it => true) {
 | 
				
			||||||
 | 
					    return await SystemCompendiums.getContent(this.compendium,
 | 
				
			||||||
 | 
					      this.type,
 | 
				
			||||||
 | 
					      it => this.subTypes.includes(it.type) && filter(it),
 | 
				
			||||||
 | 
					      itemFrequence,
 | 
				
			||||||
 | 
					      this.sorting);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async buildTable(itemFrequence = it => it.system.frequence, filter = it => true) {
 | 
				
			||||||
 | 
					    const elements = await this.getContent(filter, itemFrequence);
 | 
				
			||||||
 | 
					    return CompendiumTableHelpers.buildTable(elements, itemFrequence);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getRandom(itemFrequence = it => it.system.frequence, filter = it => true, forcedRoll = undefined) {
 | 
				
			||||||
 | 
					    const table = await this.buildTable(itemFrequence, filter);
 | 
				
			||||||
 | 
					    return await CompendiumTableHelpers.getRandom(table, this.type, this.subTypes, forcedRoll, SystemCompendiums.getCompendium(compendium));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async toChatMessage(itemFrequence = it => it.system.frequence, filter = it => true, typeName = undefined) {
 | 
				
			||||||
 | 
					    const table = await this.buildTable(itemFrequence, filter);
 | 
				
			||||||
 | 
					    await CompendiumTableHelpers.tableToChatMessage(table, this.type, this.subTypes, typeName);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ======= Gestion de tables correspondant à un compendium =======
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export class CompendiumTableHelpers {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static buildTable(elements, itemFrequence) {
 | 
				
			||||||
 | 
					    let max = 0;
 | 
				
			||||||
 | 
					    const total = elements.map(it => itemFrequence(it)).reduce(Misc.sum(), 0);
 | 
				
			||||||
 | 
					    return elements.map(it => {
 | 
				
			||||||
 | 
					      const frequence = itemFrequence(it);
 | 
				
			||||||
 | 
					      let row = { document: it, frequence: frequence, min: max + 1, max: max + frequence, total: total };
 | 
				
			||||||
 | 
					      max += frequence;
 | 
				
			||||||
 | 
					      return row;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async getRandom(table, type, subTypes, forcedRoll = undefined, localisation = undefined) {
 | 
				
			||||||
 | 
					    if (table.length == 0) {
 | 
				
			||||||
 | 
					      ui.notifications.warn(`Aucun ${Misc.typeName(type, subTypes[0])} trouvé dans ${localisation ?? ' les compendiums'}`);
 | 
				
			||||||
 | 
					      return undefined;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return await CompendiumTableHelpers.selectRow(table, forcedRoll);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async selectRow(table, forcedRoll = undefined) {
 | 
				
			||||||
 | 
					    if (table.length == 0) {
 | 
				
			||||||
 | 
					      return undefined
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const total = table[0].total;
 | 
				
			||||||
 | 
					    const formula = `1d${total}`;
 | 
				
			||||||
 | 
					    if (forcedRoll == undefined && (forcedRoll > total || forcedRoll <= 0)) {
 | 
				
			||||||
 | 
					      ui.notifications.warn(`Jet de rencontre ${forcedRoll} en dehors de la table [1..${total}], le jet est relancé`);
 | 
				
			||||||
 | 
					      forcedRoll = undefined;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const roll = forcedRoll ? { total: forcedRoll, formula } : await RdDDice.roll(formula, { showDice: HIDE_DICE });
 | 
				
			||||||
 | 
					    const row = table.find(it => it.min <= roll.total && roll.total <= it.max);
 | 
				
			||||||
 | 
					    row.roll = roll;
 | 
				
			||||||
 | 
					    return row;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async tableRowToChatMessage(row, type = 'Item') {
 | 
				
			||||||
 | 
					    if (!row) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const percentages = (row.total == 100) ? '%' : ''
 | 
				
			||||||
 | 
					    const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.html', {
 | 
				
			||||||
 | 
					      roll: row.roll,
 | 
				
			||||||
 | 
					      document: row.document,
 | 
				
			||||||
 | 
					      percentages,
 | 
				
			||||||
 | 
					      typeName: Misc.typeName(type, row.document.type),
 | 
				
			||||||
 | 
					      isGM: game.user.isGM,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    const messageData = {
 | 
				
			||||||
 | 
					      // flavor: flavorContent,
 | 
				
			||||||
 | 
					      user: game.user.id,
 | 
				
			||||||
 | 
					      type: CONST.CHAT_MESSAGE_TYPES.ROLL,
 | 
				
			||||||
 | 
					      roll: row.roll,
 | 
				
			||||||
 | 
					      sound: CONFIG.sounds.dice,
 | 
				
			||||||
 | 
					      content: flavorContent
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    ChatMessage.create(messageData, { rollMode: "gmroll" });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  static async tableToChatMessage(table, type, subTypes, typeName = undefined) {
 | 
				
			||||||
 | 
					    const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table.html', {
 | 
				
			||||||
 | 
					      img: RdDItem.getDefaultImg(subTypes[0]),
 | 
				
			||||||
 | 
					      typeName: typeName ?? Misc.typeName(type, subTypes[0]),
 | 
				
			||||||
 | 
					      table,
 | 
				
			||||||
 | 
					      isGM: game.user.isGM,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    ChatMessage.create({
 | 
				
			||||||
 | 
					      user: game.user.id,
 | 
				
			||||||
 | 
					      whisper: game.user.id,
 | 
				
			||||||
 | 
					      content: flavorContent
 | 
				
			||||||
 | 
					    }, { rollMode: "gmroll" });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								module/targets.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					import { ENTITE_NONINCARNE } from "./constants.js";
 | 
				
			||||||
 | 
					import { DialogSelectTarget } from "./dialog-select-target.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Targets {
 | 
				
			||||||
 | 
					  static listTargets() {
 | 
				
			||||||
 | 
					    return Array.from(game.user.targets);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static hasTargets() {
 | 
				
			||||||
 | 
					    return Targets.listTargets().length > 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static extractTokenData(target) {
 | 
				
			||||||
 | 
					    if (!target) {
 | 
				
			||||||
 | 
					      return undefined
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return { id: target.id, name: target.document.name, img: target.document.texture.src ?? target.actor.img ?? 'icons/svg/mystery-man.svg' };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static isTargetEntite(target) {
 | 
				
			||||||
 | 
					    return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static async selectOneToken(onSelectTarget = target => { }) {
 | 
				
			||||||
 | 
					    const targets = Targets.listTargets();
 | 
				
			||||||
 | 
					    switch (targets.length) {
 | 
				
			||||||
 | 
					      case 0: return;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        onSelectTarget(targets[0]);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          const tokens = targets.map(it => Targets.extractTokenData(it))
 | 
				
			||||||
 | 
					          const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-select-target.html", {
 | 
				
			||||||
 | 
					            tokens: tokens
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          new DialogSelectTarget(html, onSelectTarget, targets).render(true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getTarget() {
 | 
				
			||||||
 | 
					    const targets = Targets.listTargets();
 | 
				
			||||||
 | 
					    switch (targets.length) {
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        return targets[0];
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        ui.notifications.warn("Vous devez choisir une cible à attaquer!");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        ui.notifications.warn("Vous devez choisir une cible (et <strong>une seule</strong>) à attaquer!");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,500 +1,132 @@
 | 
				
			|||||||
import { Grammar } from "./grammar.js";
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
import { RdDDice } from "./rdd-dice.js";
 | 
					import { RdDDice } from "./rdd-dice.js";
 | 
				
			||||||
 | 
					import { RdDUtility } from "./rdd-utility.js";
 | 
				
			||||||
 | 
					import { SystemCompendiums, CompendiumTable, CompendiumTableHelpers } from "./settings/system-compendiums.js";
 | 
				
			||||||
import { TMRUtility } from "./tmr-utility.js";
 | 
					import { TMRUtility } from "./tmr-utility.js";
 | 
				
			||||||
import { TMRType } from "./tmr-utility.js";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* -------------------------------------------- */
 | 
					 | 
				
			||||||
const typeRencontres = {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  messager: {
 | 
					 | 
				
			||||||
    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);
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    poesieSucces: {
 | 
					 | 
				
			||||||
      reference: "La chevelure, Charles Baudelaire",
 | 
					 | 
				
			||||||
      extrait: `J'irai là-bas où l'arbre et l'homme, pleins de sève,
 | 
					 | 
				
			||||||
                <br>Se pâment longuement sous l'ardeur des climats ;
 | 
					 | 
				
			||||||
                <br>Fortes tresses, soyez la houle qui m'enlève !`
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "Rêve de Dragon, Denis Gerfaud",
 | 
					 | 
				
			||||||
      extrait: `En réalité, tous les éléments du rêve des Dragons expriment
 | 
					 | 
				
			||||||
                le Draconic : chaque pierre, chaque fleur, chaque goutte d'eau,
 | 
					 | 
				
			||||||
                chaque nuage est porteur d'un message dans la langue des Dragons`}
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  passeur: {
 | 
					 | 
				
			||||||
    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);
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    poesieSucces: {
 | 
					 | 
				
			||||||
      reference: "Femmes damnées (2), Charles Baudelaire",
 | 
					 | 
				
			||||||
      extrait: `Comme je descendais des Fleuves impassibles,
 | 
					 | 
				
			||||||
                <br>Je ne me sentis plus guidé par les haleurs :
 | 
					 | 
				
			||||||
                <br>Des Peaux-Rouges criards les avaient pris pour cibles,
 | 
					 | 
				
			||||||
                <br>Les ayant cloués nus aux poteaux de couleurs.`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "Le bateau ivre, Arthur Rimbaud",
 | 
					 | 
				
			||||||
      extrait: `Loin des peuples vivants, errantes, condamnées,
 | 
					 | 
				
			||||||
                <br>A travers les déserts courez comme les loups ;
 | 
					 | 
				
			||||||
                <br>Faites votre destin, âmes désordonnées,
 | 
					 | 
				
			||||||
                <br>Et fuyez l'infini que vous portez en vous !`}
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fleur: {
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
                <br>Trouveront dans ce sol lavé comme une grève
 | 
					 | 
				
			||||||
                <br>Le mystique aliment qui ferait leur vigueur ?`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "Une charogne, Charles Baudelaire",
 | 
					 | 
				
			||||||
      extrait: `Et le ciel regardait la carcasse superbe
 | 
					 | 
				
			||||||
                <br>Comme une fleur s'épanouir.
 | 
					 | 
				
			||||||
                <br>La puanteur était si forte, que sur l'herbe
 | 
					 | 
				
			||||||
                <br>Vous crûtes vous évanouir.`},
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  mangeur: {
 | 
					 | 
				
			||||||
    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.
 | 
					 | 
				
			||||||
                <br>Le peuple a froid l'hiver, le peuple a faim toujours.
 | 
					 | 
				
			||||||
                <br>Rendez-lui son sort plus facile.
 | 
					 | 
				
			||||||
                <br>Le peuple souvent porte un bien rude collier.
 | 
					 | 
				
			||||||
                <br>Ouvrez l'école aux fils, aux pères l'atelier,
 | 
					 | 
				
			||||||
                <br>À tous vos bras, auguste asile !`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "El Desdichado, Gérard de Nerval",
 | 
					 | 
				
			||||||
      extrait: `Suis-je Amour ou Phébus ?... Lusignan ou Biron ?
 | 
					 | 
				
			||||||
                <br>Mon front est rouge encor du baiser de la Reine ;
 | 
					 | 
				
			||||||
                <br>J'ai rêvé dans la Grotte où nage la sirène...`}
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  changeur: {
 | 
					 | 
				
			||||||
    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: 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
 | 
					 | 
				
			||||||
                <br>Chaque âme selon son désir,
 | 
					 | 
				
			||||||
                <br>Et que, close après vous, la porte
 | 
					 | 
				
			||||||
                <br>Ne se rouvre plus qu'au plaisir.`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "Rêve de Dragon, Denis Gerfaud",
 | 
					 | 
				
			||||||
      extrait: `Les sages ont encore coutume de dire :
 | 
					 | 
				
			||||||
                <br>« Mais comment les Dragons peuvent-ils
 | 
					 | 
				
			||||||
                être influencés par une créature qui, tout
 | 
					 | 
				
			||||||
                bien considéré, n'existe pas vraiment pour eux,
 | 
					 | 
				
			||||||
                qui n'est que le fantasme de leur activité nocturne ? »`}
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  briseur: {
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
              les premiers haut-rêvants. En observant les pierres précieuses,
 | 
					 | 
				
			||||||
              les gemmes qui sont les larmes de joie des Dragons, ils parvinrent à
 | 
					 | 
				
			||||||
              en comprendre la langue. Et l'ayant comprise, ils purent s'en servir
 | 
					 | 
				
			||||||
              pour influencer le cours du rêve`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "Quand le rêve se brise, Cypora Sebagh",
 | 
					 | 
				
			||||||
      extrait: `Quand le rêve se brise,
 | 
					 | 
				
			||||||
              <br>Dans la plainte du jour,
 | 
					 | 
				
			||||||
              <br>Ma mémoire devient grise
 | 
					 | 
				
			||||||
              <br>Et sombre, tour à tour,
 | 
					 | 
				
			||||||
              <br>Dans le puits du silence
 | 
					 | 
				
			||||||
              <br>Et de la solitude ;
 | 
					 | 
				
			||||||
              <br>Elle reprend son errance
 | 
					 | 
				
			||||||
              <br>Parmi la multitude.`}
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  reflet: {
 | 
					 | 
				
			||||||
    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,
 | 
					 | 
				
			||||||
              <br>Une ébauche lente à venir
 | 
					 | 
				
			||||||
              <br>Sur la toile oubliée, et que l'artiste achève
 | 
					 | 
				
			||||||
              <br>Seulement par le souvenir.`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "La chevelure, Charles Baudelaire",
 | 
					 | 
				
			||||||
      extrait: `Longtemps ! toujours ! ma main dans ta crinière lourde
 | 
					 | 
				
			||||||
              <br>Sèmera le rubis, la perle et le saphir,
 | 
					 | 
				
			||||||
              <br>Afin qu'à mon désir tu ne sois jamais sourde !
 | 
					 | 
				
			||||||
              <br>N'es-tu pas l'oasis où je rêve, et la gourde
 | 
					 | 
				
			||||||
              <br>Où je hume à longs traits le vin du souvenir`}
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  passeurfou: {
 | 
					 | 
				
			||||||
    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.
 | 
					 | 
				
			||||||
              <br>Le Sage se retourne et lui dit : Mon ami,
 | 
					 | 
				
			||||||
              <br>C'est fort bien fait à toi ; reçois cet écu-ci :
 | 
					 | 
				
			||||||
              <br>Tu fatigues assez pour gagner davantage.`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "Guitare, Victor Hugo",
 | 
					 | 
				
			||||||
      extrait: `Je la voyais passer de ma demeure,
 | 
					 | 
				
			||||||
              <br>Et c'était tout.
 | 
					 | 
				
			||||||
              <br>Mais à présent je m'ennuie à toute heure,
 | 
					 | 
				
			||||||
              <br>Plein de dégoût,
 | 
					 | 
				
			||||||
              <br>Rêveur oisif, l'âme dans la campagne,
 | 
					 | 
				
			||||||
              <br>La dague au clou ... –
 | 
					 | 
				
			||||||
              <br>Le vent qui vient à travers la montagne
 | 
					 | 
				
			||||||
              <br>M'a rendu fou !`}
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  tbblanc: {
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
              des temps, le commencement des rêves. Durant cette période plus mythique
 | 
					 | 
				
			||||||
              que réellement historique, les Dragons aimaient à se rêver eux-mêmes.`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "Les Djinns, Victor Hugo",
 | 
					 | 
				
			||||||
      extrait: `C'est l'essaim des Djinns qui passe,
 | 
					 | 
				
			||||||
              <br>Et tourbillonne en sifflant !
 | 
					 | 
				
			||||||
              <br>Les ifs, que leur vol fracasse,
 | 
					 | 
				
			||||||
              <br>Craquent comme un pin brûlant.`},
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  tbnoir: {
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
              Gnomes s'enfoncèrent profondément sous les montagnes et la magie passa aux
 | 
					 | 
				
			||||||
              mains des Humains qui en usèrent et abusèrent, se croyant devenus les maîtres du monde`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "Lily, Pierre Perret",
 | 
					 | 
				
			||||||
      extrait: `Elle aurait pas cru sans le voir
 | 
					 | 
				
			||||||
              <br>Que la couleur du désespoir
 | 
					 | 
				
			||||||
              <br>Là-bas aussi ce fût le noir.`},
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  tbrouge: {
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
              <br>De fumière à flot gris, parmi l'air se jouant,
 | 
					 | 
				
			||||||
              <br>Qui passe plus soudain que foudre meurtrière.`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "Les Djinns, poème Victor Hugo",
 | 
					 | 
				
			||||||
      extrait: `Cris de l'enfer! voix qui hurle et qui pleure !
 | 
					 | 
				
			||||||
              <br>L'horrible essaim, poussé par l'aquilon,
 | 
					 | 
				
			||||||
              <br>Sans doute, ô ciel ! s'abat sur ma demeure.
 | 
					 | 
				
			||||||
              <br>Le mur fléchit sous le noir bataillon.
 | 
					 | 
				
			||||||
              <br>La maison crie et chancelle penchée,
 | 
					 | 
				
			||||||
              <br>Et l'on dirait que, du sol arrachée,
 | 
					 | 
				
			||||||
              <br>Ainsi qu'il chasse une feuille séchée,
 | 
					 | 
				
			||||||
              <br>Le vent la roule avec leur tourbillon !`},
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  rdd: {
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
              <br>ni leur apparence ni qui sont les dragons.
 | 
					 | 
				
			||||||
              <br>En dépit de l'iconographie qui les clame
 | 
					 | 
				
			||||||
              <br>immenses créatures ailées crachant des flammes`},
 | 
					 | 
				
			||||||
    poesieEchec: {
 | 
					 | 
				
			||||||
      reference: "El Desdichado, Gérard de Nerval",
 | 
					 | 
				
			||||||
      extrait: `Je suis le Ténébreux, – le Veuf, – l'Inconsolé,
 | 
					 | 
				
			||||||
              <br>Le Prince d'Aquitaine à la Tour abolie :
 | 
					 | 
				
			||||||
              <br>Ma seule Etoile est morte, – et mon luth constellé
 | 
					 | 
				
			||||||
              <br>Porte le Soleil noir de la Mélancolie.`}
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* -------------------------------------------- */
 | 
					 | 
				
			||||||
const mauvaisesRencontres = [
 | 
					 | 
				
			||||||
  { code: "mangeur", name: "Mangeur de Rêve", type: "mangeur", genre: "m", force: "1d6", refoulement: 2, isMauvaise: true },
 | 
					 | 
				
			||||||
  { code: "mangeur2d6", name: "Mangeur de Rêve", type: "mangeur", genre: "m", force: "2d6", refoulement: 2, isMauvaise: true },
 | 
					 | 
				
			||||||
  { code: "reflet+4", name: "Reflet d'ancien Rêve", type: "reflet", genre: "m", force: "2d6+4", refoulement: 2, isPersistant: true, isMauvaise: true },
 | 
					 | 
				
			||||||
  { code: "tbblanc+4", name: "Tourbillon blanc", type: "tbblanc", genre: "m", force: "2d6+4", refoulement: 2, isPersistant: true, isMauvaise: true },
 | 
					 | 
				
			||||||
  { code: "tbnoir+4", name: "Tourbillon noir", type: "tbnoir", genre: "m", force: "2d8+4", refoulement: 2, isPersistant: true, isMauvaise: true },
 | 
					 | 
				
			||||||
  { code: "passfou", name: "Passeur fou", type: "passeurfou", genre: "m", force: "2d8", refoulement: 2, isMauvaise: true },
 | 
					 | 
				
			||||||
  { code: "tbrouge", name: "Tourbillon rouge", type: "tbrouge", genre: "m", force: "2d8", refoulement: 3, isPersistant: true, isMauvaise: true }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* -------------------------------------------- */
 | 
					 | 
				
			||||||
const rencontresStandard = [
 | 
					 | 
				
			||||||
  { code: "messager", name: "Messager des Rêves", type: "messager", genre: "m", force: "2d4", ignorer: true },
 | 
					 | 
				
			||||||
  { code: "passeur", name: "Passeur des Rêves", type: "passeur", genre: "m", force: "2d4", ignorer: true },
 | 
					 | 
				
			||||||
  { code: "fleur", name: "Fleur des Rêves", type: "fleur", genre: "f", force: "1d6", ignorer: true },
 | 
					 | 
				
			||||||
  { code: "mangeur", name: "Mangeur de Rêve", type: "mangeur", genre: "m", force: "1d6" },
 | 
					 | 
				
			||||||
  { code: "changeur", name: "Changeur de Rêve", type: "changeur", genre: "m", force: "2d6" },
 | 
					 | 
				
			||||||
  { code: "briseur", name: "Briseur de Rêve", type: "briseur", genre: "m", force: "2d6", quitterTMR: true },
 | 
					 | 
				
			||||||
  { code: "reflet", name: "Reflet d'ancien Rêve", type: "reflet", genre: "m", force: "2d6", isPersistant: true },
 | 
					 | 
				
			||||||
  { code: "tbblanc", name: "Tourbillon blanc", type: "tbblanc", genre: "m", force: "2d6", isPersistant: true },
 | 
					 | 
				
			||||||
  { code: "tbnoir", name: "Tourbillon noir", type: "tbnoir", genre: "m", force: "2d8", isPersistant: true },
 | 
					 | 
				
			||||||
  { code: "rdd", name: "Rêve de Dragon", type: "rdd", genre: "m", force: "1dr + 7", refoulement: 2, quitterTMR: true }
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const rencontresPresentCite = [
 | 
					 | 
				
			||||||
  { code: "messager2d6", name: "Messager des Rêves", type: "messager", genre: "m", force: "2d6", ignorer: true },
 | 
					 | 
				
			||||||
  { code: "passeur2d6", name: "Passeur des Rêves", type: "passeur", genre: "m", force: "2d6", ignorer: true },
 | 
					 | 
				
			||||||
  { code: "fleur2d6", name: "Fleur des Rêves", type: "fleur", genre: "f", force: "2d6", ignorer: true }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
const rencontresAll = [].concat(rencontresStandard).concat(mauvaisesRencontres).concat(rencontresPresentCite);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const tableRencontres = {
 | 
					 | 
				
			||||||
  cite: [{ code: 'messager', range: [1, 25] }, { code: 'passeur', range: [26, 50] }, { code: 'fleur', range: [51, 65] }, { code: 'mangeur', range: [66, 70] }, { code: 'changeur', range: [71, 80] }, { code: 'briseur', range: [81, 85] }, { code: 'reflet', range: [86, 90] }, { code: 'tbblanc', range: [91, 94] }, { code: 'tbnoir', range: [95, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  sanctuaire: [{ code: 'messager', range: [1, 25] }, { code: 'passeur', range: [26, 50] }, { code: 'fleur', range: [51, 65] }, { code: 'mangeur', range: [66, 70] }, { code: 'changeur', range: [71, 80] }, { code: 'briseur', range: [81, 85] }, { code: 'reflet', range: [86, 90] }, { code: 'tbblanc', range: [91, 94] }, { code: 'tbnoir', range: [95, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  plaines: [{ code: 'messager', range: [1, 20] }, { code: 'passeur', range: [21, 40] }, { code: 'fleur', range: [41, 55] }, { code: 'mangeur', range: [56, 60] }, { code: 'changeur', range: [61, 75] }, { code: 'briseur', range: [76, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  pont: [{ code: 'messager', range: [1, 20] }, { code: 'passeur', range: [21, 40] }, { code: 'fleur', range: [41, 55] }, { code: 'mangeur', range: [56, 60] }, { code: 'changeur', range: [61, 75] }, { code: 'briseur', range: [76, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  collines: [{ code: 'messager', range: [1, 15] }, { code: 'passeur', range: [16, 30] }, { code: 'fleur', range: [31, 42] }, { code: 'mangeur', range: [43, 54] }, { code: 'changeur', range: [55, 69] }, { code: 'briseur', range: [70, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  foret: [{ code: 'messager', range: [1, 15] }, { code: 'passeur', range: [16, 30] }, { code: 'fleur', range: [31, 42] }, { code: 'mangeur', range: [43, 54] }, { code: 'changeur', range: [55, 69] }, { code: 'briseur', range: [70, 82] }, { code: 'reflet', range: [83, 88] }, { code: 'tbblanc', range: [89, 93] }, { code: 'tbnoir', range: [94, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  monts: [{ code: 'messager', range: [1, 10] }, { code: 'passeur', range: [11, 20] }, { code: 'fleur', range: [21, 26] }, { code: 'mangeur', range: [27, 44] }, { code: 'changeur', range: [45, 59] }, { code: 'briseur', range: [60, 75] }, { code: 'reflet', range: [76, 85] }, { code: 'tbblanc', range: [86, 92] }, { code: 'tbnoir', range: [93, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  desert: [{ code: 'messager', range: [1, 10] }, { code: 'passeur', range: [11, 20] }, { code: 'fleur', range: [21, 26] }, { code: 'mangeur', range: [27, 44] }, { code: 'changeur', range: [45, 59] }, { code: 'briseur', range: [60, 75] }, { code: 'reflet', range: [76, 85] }, { code: 'tbblanc', range: [86, 92] }, { code: 'tbnoir', range: [93, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  fleuve: [{ code: 'messager', range: [1, 5] }, { code: 'passeur', range: [6, 10] }, { code: 'fleur', range: [11, 13] }, { code: 'mangeur', range: [14, 37] }, { code: 'changeur', range: [38, 49] }, { code: 'briseur', range: [50, 65] }, { code: 'reflet', range: [66, 79] }, { code: 'tbblanc', range: [80, 89] }, { code: 'tbnoir', range: [90, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  lac: [{ code: 'messager', range: [1, 5] }, { code: 'passeur', range: [6, 10] }, { code: 'fleur', range: [11, 13] }, { code: 'mangeur', range: [14, 37] }, { code: 'changeur', range: [38, 49] }, { code: 'briseur', range: [50, 65] }, { code: 'reflet', range: [66, 79] }, { code: 'tbblanc', range: [80, 89] }, { code: 'tbnoir', range: [90, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  marais: [{ code: 'messager', range: [1, 2] }, { code: 'passeur', range: [3, 4] }, { code: 'fleur', range: [5, 5] }, { code: 'mangeur', range: [6, 29] }, { code: 'changeur', range: [30, 39] }, { code: 'briseur', range: [40, 60] }, { code: 'reflet', range: [61, 75] }, { code: 'tbblanc', range: [76, 86] }, { code: 'tbnoir', range: [87, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  gouffre: [{ code: 'messager', range: [1, 2] }, { code: 'passeur', range: [3, 4] }, { code: 'fleur', range: [5, 5] }, { code: 'mangeur', range: [6, 29] }, { code: 'changeur', range: [30, 39] }, { code: 'briseur', range: [40, 60] }, { code: 'reflet', range: [61, 75] }, { code: 'tbblanc', range: [76, 86] }, { code: 'tbnoir', range: [87, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  necropole: [{ code: 'mangeur', range: [1, 20] }, { code: 'changeur', range: [21, 30] }, { code: 'briseur', range: [31, 50] }, { code: 'reflet', range: [51, 65] }, { code: 'tbblanc', range: [66, 80] }, { code: 'tbnoir', range: [81, 97] }, { code: 'rdd', range: [98, 100] }],
 | 
					 | 
				
			||||||
  desolation: [{ code: 'mangeur', range: [1, 20] }, { code: 'changeur', range: [21, 30] }, { code: 'briseur', range: [31, 50] }, { code: 'reflet', range: [51, 65] }, { code: 'tbblanc', range: [66, 80] }, { code: 'tbnoir', range: [81, 97] }, { code: 'rdd', range: [98, 100] }]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* -------------------------------------------- */
 | 
					/* -------------------------------------------- */
 | 
				
			||||||
export class TMRRencontres {
 | 
					export class TMRRencontres {
 | 
				
			||||||
  static gestionRencontre = {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static init() {
 | 
					  static init() {
 | 
				
			||||||
    for (let type in typeRencontres) {
 | 
					    const tmrRencontre = new TMRRencontres();
 | 
				
			||||||
      TMRRencontres.register(type, typeRencontres[type]);
 | 
					    game.system.rdd.rencontresTMR = tmrRencontre;
 | 
				
			||||||
    }
 | 
					    
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  constructor(){
 | 
				
			||||||
  static register(type, rencontre) {
 | 
					    this.table = new CompendiumTable('rencontres', 'Item', 'rencontre', Misc.ascending(it => it.system.ordreTri));
 | 
				
			||||||
    TMRRencontres.gestionRencontre[type] = rencontre;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Retourne une recontre en fonction de la case et du tirage
 | 
					   * Retourne une recontre en fonction de la case et du tirage
 | 
				
			||||||
   * @param {*} terrain 
 | 
					   * @param {*} terrain 
 | 
				
			||||||
   * @param {*} roll 
 | 
					   * @param {*} forcedRoll 
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  static async rollRencontre(terrain, roll = undefined) {
 | 
					  async rollRencontre(terrain, forcedRoll) {
 | 
				
			||||||
    if (!terrain) {
 | 
					    terrain = TMRUtility.findTMRLike(terrain);
 | 
				
			||||||
      ChatMessage.create({ content: "Un type de case doit être indiqué (par exemple sanctuaire, desert ou cité)" });
 | 
					    if (terrain == undefined) {
 | 
				
			||||||
      return false;
 | 
					      return undefined;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!roll || roll <= 0 || roll > 100) {
 | 
					
 | 
				
			||||||
      roll = await RdDDice.rollTotal("1d100");
 | 
					    if (forcedRoll && (forcedRoll <= 0 || forcedRoll > 100)) {
 | 
				
			||||||
 | 
					      forcedRoll = undefined;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let rencontre = await TMRRencontres.getRencontreAleatoire(terrain, roll);
 | 
					    const codeTerrain = Grammar.toLowerCaseNoAccent(terrain)
 | 
				
			||||||
    ChatMessage.create({
 | 
					    const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
 | 
				
			||||||
      user: game.user.id,
 | 
					    const frequence = it => it.system.frequence[codeTerrain];
 | 
				
			||||||
      whisper: [game.user.id],
 | 
					    const row = await this.table.getRandom(frequence, filtreMauvaise, forcedRoll);
 | 
				
			||||||
      content: `Rencontre en ${terrain} (jet : ${roll}%)<br>Vous rencontrez un ${rencontre.name} de ${rencontre.force} Points de Rêve`
 | 
					    if (row) {
 | 
				
			||||||
    });
 | 
					      await CompendiumTableHelpers.tableRowToChatMessage(row);
 | 
				
			||||||
    return false;
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return row?.document;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async chatTable(terrain) {
 | 
				
			||||||
 | 
					    const codeTerrain = Grammar.toLowerCaseNoAccent(terrain)
 | 
				
			||||||
 | 
					    const isMauvaise = codeTerrain == 'mauvaise';
 | 
				
			||||||
 | 
					    const filtreMauvaise = isMauvaise ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
 | 
				
			||||||
 | 
					    const frequence = it => it.system.frequence[codeTerrain];
 | 
				
			||||||
 | 
					    const typeName = isMauvaise ? 'Mauvaises rencontres' : `Rencontres en ${Misc.upperFirst(terrain)}`;
 | 
				
			||||||
 | 
					    return await this.table.toChatMessage(frequence, filtreMauvaise, typeName);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static getRencontre(index) {
 | 
					  async createRencontre(rencontre, tmr = undefined) {
 | 
				
			||||||
    let rencontre;
 | 
					    return rencontre.clone({
 | 
				
			||||||
    if (isNaN(index)) {
 | 
					      'system.force': await RdDDice.rollTotal(rencontre.system.formule),
 | 
				
			||||||
      rencontre = rencontresAll.find(r => r.type == index) ?? rencontresAll.find(r => r.code == index)
 | 
					      'system.coord': tmr?.coord,
 | 
				
			||||||
 | 
					      'system.date': game.system.rdd.calendrier.getDateFromIndex(),
 | 
				
			||||||
 | 
					      'system.heure': game.system.rdd.calendrier.getCurrentHeure()
 | 
				
			||||||
 | 
					    }, { save: false });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async calculRencontre(rencontre, tmr = undefined) {
 | 
				
			||||||
 | 
					    if (rencontre.system.coord == "") {
 | 
				
			||||||
 | 
					      rencontre.system.coord = tmr?.coord;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (0 <= index && index < rencontresAll.length) {
 | 
					    if (rencontre.system.force == 0) {
 | 
				
			||||||
      rencontre = rencontresAll[index];
 | 
					      rencontre.system.force = await RdDDice.rollTotal(rencontre.system.formule);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (rencontre) {
 | 
					    if (rencontre.system.date == "") {
 | 
				
			||||||
      return duplicate(rencontre);
 | 
					      rencontre.system.date = game.system.rdd.calendrier.getDateFromIndex();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    if (rencontre.system.heure == "") {
 | 
				
			||||||
      ui.notifications.info(`Pas de rencontre pour ${index}, seulement ${rencontresAll.length} rencontres sont connues.<br>Vous pouvez aussi essayer par type (ie: mangeur, fleur, fleur2d6, ...)`)
 | 
					      rencontre.system.heure = game.system.rdd.calendrier.getCurrentHeure();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return rencontre;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getPresentsCite() {
 | 
				
			||||||
 | 
					    const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
 | 
				
			||||||
 | 
					    return rencontres.filter(it => !it.system.mauvaiseRencontre && it.system.presentCite).map(it =>
 | 
				
			||||||
 | 
					      it.clone({ 'system.formule': "2d6" }, { save: false }));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getReveDeDragon(force) {
 | 
				
			||||||
 | 
					    const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
 | 
				
			||||||
 | 
					    const reveDeDragon = rencontres.find(it => Grammar.equalsInsensitive(it.name, 'Rêve de Dragon'));
 | 
				
			||||||
 | 
					    return reveDeDragon?.clone({ 'system.force': force }, { save: false });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
 | 
					  async getRencontreAleatoire(tmr, mauvaise) {
 | 
				
			||||||
 | 
					    const codeTerrain = mauvaise ? 'mauvaise' : tmr.type;
 | 
				
			||||||
 | 
					    const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
 | 
				
			||||||
 | 
					    const frequence = it => it.system.frequence[codeTerrain];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const row = await this.table.getRandom(frequence, filtreMauvaise);
 | 
				
			||||||
 | 
					    if (row) {
 | 
				
			||||||
 | 
					      const rencontre = await this.createRencontre(row.document, tmr);
 | 
				
			||||||
 | 
					      await this.$chatRolledRencontre(row, rencontre, tmr);
 | 
				
			||||||
 | 
					      return rencontre;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return undefined;
 | 
					    return undefined;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async getRencontreAleatoire(terrain, roll = undefined) {
 | 
					 | 
				
			||||||
    if (!roll || roll <= 0 || roll > 100) {
 | 
					 | 
				
			||||||
      roll = await RdDDice.rollTotal("1d100");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    terrain = Grammar.toLowerCaseNoAccent(terrain);
 | 
					 | 
				
			||||||
    const code = tableRencontres[terrain].find(it => it.range[0] <= roll && roll <= it.range[1]).code;
 | 
					 | 
				
			||||||
    const rencontre = duplicate(rencontresStandard.find(it => it.code == code));
 | 
					 | 
				
			||||||
    rencontre.roll = roll;
 | 
					 | 
				
			||||||
    await TMRRencontres.evaluerForceRencontre(rencontre);
 | 
					 | 
				
			||||||
    return rencontre;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getMauvaiseRencontre(index = undefined) {
 | 
					  async $chatRolledRencontre(row, rencontre,tmr) {
 | 
				
			||||||
    const rencontre = duplicate(
 | 
					    const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll-rencontre.html',
 | 
				
			||||||
      (index && index >= 0 && index < mauvaisesRencontres.length)
 | 
					      {
 | 
				
			||||||
        ? mauvaisesRencontres[index]
 | 
					        roll: row.roll,
 | 
				
			||||||
        : await RdDDice.rollOneOf(mauvaisesRencontres));
 | 
					        rencontre,
 | 
				
			||||||
    await TMRRencontres.evaluerForceRencontre(rencontre);
 | 
					        row,
 | 
				
			||||||
    return rencontre;
 | 
					        percentages: (row.total == 100) ? '%' : '',
 | 
				
			||||||
  }
 | 
					        tmr,
 | 
				
			||||||
 | 
					        isGM: game.user.isGM,
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					      });
 | 
				
			||||||
  static async evaluerForceRencontre(rencontre) {
 | 
					    const messageData = {
 | 
				
			||||||
    const rollForce = new Roll(rencontre.force);
 | 
					      user: game.user.id,
 | 
				
			||||||
    await rollForce.evaluate();
 | 
					      type: CONST.CHAT_MESSAGE_TYPES.ROLL,
 | 
				
			||||||
    rencontre.force = rollForce.total;
 | 
					      roll: row.roll,
 | 
				
			||||||
    return rencontre.force;
 | 
					      sound: CONFIG.sounds.dice,
 | 
				
			||||||
  }
 | 
					      content: flavorContent
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					    ChatMessage.create(messageData, { rollMode: "gmroll" });
 | 
				
			||||||
  static isReveDeDragon(rencontre) {
 | 
					 | 
				
			||||||
    return rencontre.type == "rdd";
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static getGestionRencontre(name) {
 | 
					 | 
				
			||||||
    let gestion = TMRRencontres.gestionRencontre[name];
 | 
					 | 
				
			||||||
    if (!gestion) {
 | 
					 | 
				
			||||||
      ui.notifications.error(`La rencontre ${name} est inconnue, pas de méthode de gestion associée`)
 | 
					 | 
				
			||||||
      gestion = TMRRencontres.gestionRencontre['messager'];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return gestion;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async gererRencontre(tmrDialog, rencData) {
 | 
					 | 
				
			||||||
    let gestion = TMRRencontres.getGestionRencontre(rencData.rencontre.type);
 | 
					 | 
				
			||||||
    if (rencData.rolled.isSuccess) {
 | 
					 | 
				
			||||||
      rencData.message = await gestion.msgSucces(rencData);
 | 
					 | 
				
			||||||
      if (rencData.nbRounds > 1) {
 | 
					 | 
				
			||||||
        rencData.message += ` Au total, vous avez passé ${rencData.nbRounds} rounds à vous battre!`;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      rencData.poesie = gestion.poesieSucces;
 | 
					 | 
				
			||||||
      return gestion.postSucces;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    rencData.message = await gestion.msgEchec(rencData);
 | 
					 | 
				
			||||||
    if (rencData.nbRounds > 1) {
 | 
					 | 
				
			||||||
      rencData.message += ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    rencData.poesie = gestion.poesieEchec;
 | 
					 | 
				
			||||||
    return gestion.postEchec;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async msgEchecPasseurFou(tmrData) {
 | 
					 | 
				
			||||||
    tmrData.sortReserve = RdDDice.rollOneOf(tmrData.actor.itemTypes['sortreserve']);
 | 
					 | 
				
			||||||
    if (tmrData.sortReserve) {
 | 
					 | 
				
			||||||
      // Passeur fou positionne sur la case d'un sort en réserve
 | 
					 | 
				
			||||||
      tmrData.newTMR = TMRUtility.getTMR(tmrData.sortReserve.coord);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      // Déplacement aléatoire de la force du Passeur Fou
 | 
					 | 
				
			||||||
      const newCoord = await RdDDice.rollOneOf(TMRUtility.getTMRPortee(tmrData.tmr.coord, tmrData.rencontre.force));
 | 
					 | 
				
			||||||
      tmrData.newTMR = TMRUtility.getTMR(newCoord);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (tmrData.sortReserve) {
 | 
					 | 
				
			||||||
      return `Le ${tmrData.rencontre.name} vous dérobe la clé de vos sorts. Vous vous saisissez de lui, mais dans un nuage violet, il vous emporte en ${tmrData.newTMR.label} déclencher votre sort en réserve de ${tmrData.sortReserve.name}.`;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      return `Le ${tmrData.rencontre.name} tente de vous dérober la clé de vos sorts. Ne la trouvant pas, il déclenche un nuage violet et vous emporte en ${tmrData.newTMR.label}`;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async postEchecPasseurFou(tmrDialog, tmrData) {
 | 
					 | 
				
			||||||
    if (tmrData.sortReserve) {
 | 
					 | 
				
			||||||
      await tmrDialog.processSortReserve(tmrData.sortReserve);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    await tmrDialog.positionnerDemiReve(tmrData.newTMR.coord);
 | 
					 | 
				
			||||||
    if (tmrData.sortReserve) {
 | 
					 | 
				
			||||||
      tmrDialog.close();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async onPostEchecTourbillon(tmrDialog, tmrData, cases) {
 | 
					 | 
				
			||||||
    await tmrData.actor.reveActuelIncDec(-cases);
 | 
					 | 
				
			||||||
    await TMRRencontres._toubillonner(tmrDialog, tmrData.actor, cases);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async onPostEchecTourbillonRouge(tmrDialog, rencontre) {
 | 
					 | 
				
			||||||
    await rencontre.actor.reveActuelIncDec(-2); // -2 pts de Reve a chaque itération
 | 
					 | 
				
			||||||
    TMRRencontres._toubillonner(tmrDialog, rencontre.actor, 4);
 | 
					 | 
				
			||||||
    await rencontre.actor.santeIncDec("vie", -1); // Et -1 PV
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async _toubillonner(tmrDialog, actor, cases) {
 | 
					 | 
				
			||||||
    let coord = actor.system.reve.tmrpos.coord;
 | 
					 | 
				
			||||||
    for (let i = 0; i < cases; i++) {
 | 
					 | 
				
			||||||
      coord = await TMRUtility.deplaceTMRAleatoire(actor, coord).coord;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    await tmrDialog.positionnerDemiReve(coord)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async onPostSuccessReveDeDragon(tmrDialog, tmrData) {
 | 
					 | 
				
			||||||
    if (tmrData.rolled.isPart) {
 | 
					 | 
				
			||||||
      await tmrData.actor.appliquerAjoutExperience(tmrData);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    await tmrData.actor.resultCombatReveDeDragon(tmrData);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static async onPostEchecReveDeDragon(tmrDialog, tmrData) {
 | 
					 | 
				
			||||||
    await tmrData.actor.resultCombatReveDeDragon(tmrData);
 | 
					 | 
				
			||||||
    tmrDialog.close();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
import { TMRRencontres } from "./tmr-rencontres.js";
 | 
					 | 
				
			||||||
import { Misc } from "./misc.js";
 | 
					import { Misc } from "./misc.js";
 | 
				
			||||||
import { Grammar } from "./grammar.js";
 | 
					import { Grammar } from "./grammar.js";
 | 
				
			||||||
import { RdDDice } from "./rdd-dice.js";
 | 
					import { RdDDice } from "./rdd-dice.js";
 | 
				
			||||||
@@ -287,13 +286,30 @@ export class TMRUtility {
 | 
				
			|||||||
    const tmr = TMRMapping[coord];
 | 
					    const tmr = TMRMapping[coord];
 | 
				
			||||||
    return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
 | 
					    return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  static findTMRLike(type, options = {inclusMauvaise:true}) {
 | 
				
			||||||
 | 
					    const choix = [...Object.values(TMRType)]
 | 
				
			||||||
 | 
					    if (options.inclusMauvaise){
 | 
				
			||||||
 | 
					      choix.push({name: 'Mauvaise'});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const selection = Misc.findAllLike(type, choix).map(it => it.name);
 | 
				
			||||||
 | 
					    if (selection.length == 0) {
 | 
				
			||||||
 | 
					      ui.notifications.warn(`Un type de TMR doit être indiqué, '${type}' n'est pas trouvé dans ${choix}`);
 | 
				
			||||||
 | 
					      return undefined;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (selection.length > 1) {
 | 
				
			||||||
 | 
					      ui.notifications.warn(`Plusieurs types de TMR pourraient correspondre à '${type}': ${selection}`);
 | 
				
			||||||
 | 
					      return undefined;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return selection[0];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static typeTmrName(type) {
 | 
					  static typeTmrName(type) {
 | 
				
			||||||
    return Misc.upperFirst(TMRType[Grammar.toLowerCaseNoAccent(type)].name);
 | 
					    return Misc.upperFirst(TMRType[Grammar.toLowerCaseNoAccent(type)].name);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  static buildSelectionTypesTMR(typesTMR) {
 | 
					  static buildSelectionTypesTMR(typesTMR) {
 | 
				
			||||||
    typesTMR= typesTMR?? [];
 | 
					    typesTMR = typesTMR?? [];
 | 
				
			||||||
    return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
 | 
					    return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
 | 
				
			||||||
      .sort()
 | 
					      .sort()
 | 
				
			||||||
      .map(name => { return { name: name, selected: typesTMR.includes(name) } });
 | 
					      .map(name => { return { name: name, selected: typesTMR.includes(name) } });
 | 
				
			||||||
@@ -307,35 +323,6 @@ export class TMRUtility {
 | 
				
			|||||||
    return tmr.type == 'fleuve' || tmr.type == 'lac' || tmr.type == 'marais';
 | 
					    return tmr.type == 'fleuve' || tmr.type == 'lac' || tmr.type == 'marais';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  /** Some debug functions  */
 | 
					 | 
				
			||||||
  static async setForceRencontre(index, force = undefined) {
 | 
					 | 
				
			||||||
    this.prochaineRencontre = TMRRencontres.getRencontre(index);
 | 
					 | 
				
			||||||
    if (this.prochaineRencontre) {
 | 
					 | 
				
			||||||
      if (force) {
 | 
					 | 
				
			||||||
        this.prochaineRencontre.force = force;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      else {
 | 
					 | 
				
			||||||
        await TMRRencontres.evaluerForceRencontre(this.prochaineRencontre);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      console.log("La prochaine rencontre sera:", this.prochaineRencontre.name, " force:", this.prochaineRencontre.force);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      ui.notifications.warn("Pas de prochaine rencontre valide pour " + index);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static isForceRencontre() {
 | 
					 | 
				
			||||||
    return this.prochaineRencontre;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					 | 
				
			||||||
  static utiliseForceRencontre() {
 | 
					 | 
				
			||||||
    const rencontre = this.prochaineRencontre;
 | 
					 | 
				
			||||||
    this.prochaineRencontre = undefined;
 | 
					 | 
				
			||||||
    return rencontre;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async getDirectionPattern() {
 | 
					  static async getDirectionPattern() {
 | 
				
			||||||
    return await RdDDice.rollOneOf(tmrRandomMovePatten);
 | 
					    return await RdDDice.rollOneOf(tmrRandomMovePatten);
 | 
				
			||||||
@@ -343,24 +330,15 @@ export class TMRUtility {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
  static async deplaceTMRAleatoire(actor, coord) {
 | 
					  static async deplaceTMRAleatoire(actor, coord) {
 | 
				
			||||||
    return TMRUtility.deplaceTMRSelonPattern(actor, coord, await TMRUtility.getDirectionPattern(), 1);
 | 
					    const currentOddq = TMRUtility.coordTMRToOddq(coord);
 | 
				
			||||||
  }
 | 
					    const direction = await TMRUtility.getDirectionPattern();
 | 
				
			||||||
 | 
					    currentOddq.col = currentOddq.col + direction.col;
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					    currentOddq.row = currentOddq.row + direction.row;
 | 
				
			||||||
  static async deplaceTMRSelonPattern(actor, coordTMR, direction, nTime) {
 | 
					    if (this.isOddqInTMR(currentOddq)) { // Sortie de carte ! Ré-insertion aléatoire
 | 
				
			||||||
    let coord;
 | 
					      return TMRUtility.getTMR(TMRUtility.oddqToCoordTMR(currentOddq));
 | 
				
			||||||
    for (let i = 0; i < nTime; i++) {
 | 
					    } else {
 | 
				
			||||||
      let currentOddq = TMRUtility.coordTMRToOddq(coordTMR);
 | 
					      return await actor.reinsertionAleatoire('Sortie de carte');
 | 
				
			||||||
      currentOddq.col = currentOddq.col + direction.col;
 | 
					 | 
				
			||||||
      currentOddq.row = currentOddq.row + direction.row;
 | 
					 | 
				
			||||||
      if (this.isOddqInTMR(currentOddq)) { // Sortie de carte ! Ré-insertion aléatoire
 | 
					 | 
				
			||||||
        coord = TMRUtility.getTMR(TMRUtility.oddqToCoordTMR(currentOddq));
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        coord = await actor.reinsertionAleatoire('Sortie de carte');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      console.log("Nouvelle case iteration !!!", i, coord);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return coord;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -372,9 +350,12 @@ export class TMRUtility {
 | 
				
			|||||||
    return Object.values(TMRMapping).filter(filter);
 | 
					    return Object.values(TMRMapping).filter(filter);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getCasesType(type) {
 | 
				
			||||||
 | 
					    return TMRUtility.filterTMR(it => it.type == type).map(it => it.coord);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static findTMR(search) {
 | 
					  static findTMR(search) {
 | 
				
			||||||
    const labelSearch = Grammar.toLowerCaseNoAccent(search)
 | 
					    return TMRUtility.filterTMR(it => Grammar.includesLowerCaseNoAccent(it.label, search) || it.coord == search);
 | 
				
			||||||
    return TMRUtility.filterTMR(it => Grammar.toLowerCaseNoAccent(it.label).match(labelSearch) || it.coord == search);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static filterTMRCoord(filter) {
 | 
					  static filterTMRCoord(filter) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								module/tmr/augmentation-seuil.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					import { Grammar } from "../grammar.js";
 | 
				
			||||||
 | 
					import { Draconique } from "./draconique.js";
 | 
				
			||||||
 | 
					import { Misc } from "../misc.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class AugmentationSeuil extends Draconique {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    super();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  type() { return 'tete' }
 | 
				
			||||||
 | 
					  match(item) { return Draconique.isTeteDragon(item) && Grammar.toLowerCaseNoAccent(item.name).includes('augmentation du seuil de reve'); }
 | 
				
			||||||
 | 
					  manualMessage() { return false }
 | 
				
			||||||
 | 
					  async onActorCreateOwned(actor, tete) {
 | 
				
			||||||
 | 
					    const seuil = Misc.toInt(actor.system.reve.seuil.value) + 2;
 | 
				
			||||||
 | 
					    await actor.update({ "system.reve.seuil.value": seuil })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -17,6 +17,7 @@ import { Pelerinage } from "./pelerinage.js";
 | 
				
			|||||||
import { Periple } from "./periple.js";
 | 
					import { Periple } from "./periple.js";
 | 
				
			||||||
import { UrgenceDraconique } from "./urgence-draconique.js";
 | 
					import { UrgenceDraconique } from "./urgence-draconique.js";
 | 
				
			||||||
import { Grammar } from "../grammar.js";
 | 
					import { Grammar } from "../grammar.js";
 | 
				
			||||||
 | 
					import { AugmentationSeuil } from "./augmentation-seuil.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class EffetsDraconiques {
 | 
					export class EffetsDraconiques {
 | 
				
			||||||
@@ -37,6 +38,7 @@ export class EffetsDraconiques {
 | 
				
			|||||||
  static pelerinage = new Pelerinage();
 | 
					  static pelerinage = new Pelerinage();
 | 
				
			||||||
  static periple = new Periple();
 | 
					  static periple = new Periple();
 | 
				
			||||||
  static urgenceDraconique = new UrgenceDraconique();
 | 
					  static urgenceDraconique = new UrgenceDraconique();
 | 
				
			||||||
 | 
					  static augmentationSeuil = new AugmentationSeuil();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static init() {
 | 
					  static init() {
 | 
				
			||||||
    Draconique.register(EffetsDraconiques.carteTmr);
 | 
					    Draconique.register(EffetsDraconiques.carteTmr);
 | 
				
			||||||
@@ -56,6 +58,7 @@ export class EffetsDraconiques {
 | 
				
			|||||||
    Draconique.register(EffetsDraconiques.pelerinage);
 | 
					    Draconique.register(EffetsDraconiques.pelerinage);
 | 
				
			||||||
    Draconique.register(EffetsDraconiques.periple);
 | 
					    Draconique.register(EffetsDraconiques.periple);
 | 
				
			||||||
    Draconique.register(EffetsDraconiques.urgenceDraconique);
 | 
					    Draconique.register(EffetsDraconiques.urgenceDraconique);
 | 
				
			||||||
 | 
					    Draconique.register(EffetsDraconiques.augmentationSeuil)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* -------------------------------------------- */
 | 
					  /* -------------------------------------------- */
 | 
				
			||||||
@@ -116,6 +119,10 @@ export class EffetsDraconiques {
 | 
				
			|||||||
      .filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
 | 
					      .filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static countAugmentationSeuil(actor) {
 | 
				
			||||||
 | 
					    return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Augmentation du seuil de rêve').length;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static isDonDoubleReve(actor) {
 | 
					  static isDonDoubleReve(actor) {
 | 
				
			||||||
    return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Don de double-rêve').length>0;
 | 
					    return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Don de double-rêve').length>0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,15 +46,13 @@ export class PresentCites extends Draconique {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async choisirUnPresent(casetmr, onChoixPresent) {
 | 
					  async choisirUnPresent(casetmr, onChoixPresent) {
 | 
				
			||||||
 | 
					    const presents = await game.system.rdd.rencontresTMR.getPresentsCite()
 | 
				
			||||||
 | 
					    const buttons = {};
 | 
				
			||||||
 | 
					    presents.forEach(r =>  buttons['present'+r.id] = { icon: '<i class="fas fa-check"></i>', label: r.name, callback: async () => onChoixPresent(r) });
 | 
				
			||||||
    let d = new Dialog({
 | 
					    let d = new Dialog({
 | 
				
			||||||
      title: "Présent des cités",
 | 
					      title: "Présent des cités",
 | 
				
			||||||
      content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faite votre choix`,
 | 
					      content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faites votre choix`,
 | 
				
			||||||
      buttons: {
 | 
					      buttons: buttons
 | 
				
			||||||
        messager: { icon: '<i class="fas fa-check"></i>', label: "Un Messager des rêves", callback: () => onChoixPresent('messager2d6') },
 | 
					 | 
				
			||||||
        passeur: { icon: '<i class="fas fa-check"></i>', label: "Un Passeur des rêves", callback: () => onChoixPresent('passeur2d6') },
 | 
					 | 
				
			||||||
        fleur: { icon: '<i class="fas fa-check"></i>', label: "Une Fleur des rêves", callback: () => onChoixPresent('fleur2d6') },
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      default: "fleur"
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    d.render(true);
 | 
					    d.render(true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||