forked from public/foundryvtt-reve-de-dragon
		
	Compare commits
	
		
			70 Commits
		
	
	
		
			foundryvtt
			...
			12.0.23
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 56c99c5044 | |||
| a7862a25e5 | |||
| f4b5a4a4d2 | |||
| 6a17586a6c | |||
| 40f7ef48c9 | |||
| 62dfa8a580 | |||
| e71088fe2f | |||
| b7cb0f0752 | |||
| 9b31f25640 | |||
| 2291eaf135 | |||
| a91264cd82 | |||
| 864194e3b4 | |||
| 2c836f17e7 | |||
| 444e52cb49 | |||
| 82b0537d43 | |||
| 1eea07c8a8 | |||
| de70ba8a3c | |||
| f0e02e2205 | |||
| 7d9ccfaf28 | |||
| 830cd1c200 | |||
| b9458c717e | |||
| 22f25b45ce | |||
| dca9505925 | |||
| 45e9e94646 | |||
| a0c7b87996 | |||
| a214256d69 | |||
| d2de8aa972 | |||
| 00ec86632f | |||
| 010234e001 | |||
| 39604afa32 | |||
| aad256bfee | |||
| 6ebd2ee576 | |||
| ac6e8b4689 | |||
| 387713e6f8 | |||
| c69cb3c13a | |||
| bda2e39e35 | |||
| cb2d462cfe | |||
| 5f8b5b104d | |||
| 9fe265165b | |||
| b92003ac1f | |||
| a1e4bfb529 | |||
| b4f0be5d64 | |||
| 5ff31d462f | |||
| be1d109def | |||
| d91bee0f42 | |||
| ed222c7b6d | |||
| 70198a5727 | |||
| bfe70c6634 | |||
| 09365eb744 | |||
| 894d4f3941 | |||
| 6e234411ca | |||
| 85acb5a255 | |||
| 6106e2a19e | |||
| f896f1da6e | |||
| 9bb45c2349 | |||
| 5cab219e0e | |||
| 2de9ea49c8 | |||
| 1760d26014 | |||
| 92185d4a5b | |||
| 210b129934 | |||
| b892068b38 | |||
| 3906cb0a7b | |||
| 5c58932a0d | |||
| 3b06bd382b | |||
| b4a725ff12 | |||
| 05df6a68cc | |||
| 025c3483a9 | |||
| 97138b25c7 | |||
| c0066f79c1 | |||
| 4db8bf95f9 | 
							
								
								
									
										63
									
								
								.gitea/workflows/release.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								.gitea/workflows/release.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | name: Release Creation | ||||||
|  |  | ||||||
|  | on:  | ||||||
|  |   release: | ||||||
|  |     types: [published] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - run: echo "💡 The ${{ gitea.repository }} repository will cloned to the runner." | ||||||
|  |      | ||||||
|  |     #- uses: actions/checkout@v3 | ||||||
|  |     - uses: RouxAntoine/checkout@v3.5.4 | ||||||
|  |  | ||||||
|  |     # get part of the tag after the `v` | ||||||
|  |     - name: Extract tag version number | ||||||
|  |       id: get_version | ||||||
|  |       uses: battila7/get-version-action@v2 | ||||||
|  |  | ||||||
|  |     # Substitute the Manifest and Download URLs in the module.json | ||||||
|  |     - name: Substitute Manifest and Download Links For Versioned Ones | ||||||
|  |       id: sub_manifest_link_version | ||||||
|  |       uses: microsoft/variable-substitution@v1 | ||||||
|  |       with: | ||||||
|  |         files: 'system.json' | ||||||
|  |       env: | ||||||
|  |         version: ${{steps.get_version.outputs.version-without-v}} | ||||||
|  |         url: https://www.uberwald.me/gitea/${{gitea.repository}} | ||||||
|  |         manifest: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download//${{github.event.release.tag_name}}/system.json | ||||||
|  |         download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/rddsystem.zip | ||||||
|  |      | ||||||
|  |     - name: Set up Node.js | ||||||
|  |       uses: actions/setup-node@v2 | ||||||
|  |       with: | ||||||
|  |         node-version: '18'  # Use the node version your project requires | ||||||
|  |  | ||||||
|  |     - name: Install dependencies | ||||||
|  |       run: npm install | ||||||
|  |        | ||||||
|  |     - name: Build the compendiums | ||||||
|  |       run: node ./tools/packCompendiumsToDist.mjs | ||||||
|  |  | ||||||
|  |     # Create a zip file with all files required by the module to add to the release | ||||||
|  |     - run: | | ||||||
|  |          apt update -y | ||||||
|  |          apt install -y zip | ||||||
|  |  | ||||||
|  |     - run: zip -r ./rddsystem.zip system.json template.json README.md LICENSE.txt assets/ fonts/ icons lang/ module/ packs/ pic/ sounds/ styles/ templates/  | ||||||
|  |      | ||||||
|  |     - name: setup go | ||||||
|  |       uses: actions/setup-go@v3 | ||||||
|  |       with: | ||||||
|  |         go-version: '>=1.20.1' | ||||||
|  |      | ||||||
|  |     - name: Use Go Action   | ||||||
|  |       id: use-go-action | ||||||
|  |       uses: https://gitea.com/actions/release-action@main | ||||||
|  |       with: | ||||||
|  |         files: |- | ||||||
|  |           ./rddsystem.zip   | ||||||
|  |           system.json | ||||||
|  |         api_key: '${{secrets.ALLOW_PUSH_RELEASE}}' | ||||||
							
								
								
									
										
											BIN
										
									
								
								assets/scenes/YSpVuLeMCX9tAmgn-thumb.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/scenes/YSpVuLeMCX9tAmgn-thumb.webp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 7.3 KiB | 
							
								
								
									
										49
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,4 +1,53 @@ | |||||||
| # 12.0 | # 12.0 | ||||||
|  | ## 12.0.23 - La bibliothèque d'Astrobazzarh | ||||||
|  | - corrections mineures | ||||||
|  |   - meilleure gestion de la parade des armes naturelles | ||||||
|  |   - cas de "User lacks permission to update" pour les blessures et les StatusEffects | ||||||
|  |   - risque de message d'encaissement non affiché | ||||||
|  |   - support de sorts à voies multiples | ||||||
|  | - correction de compendiums | ||||||
|  |   - résistance des armes mise à jour | ||||||
|  |   - voies multiples pour las sorts de Lecture d'aura, Détection d'aura et Annulation de magie | ||||||
|  | - améliorations "Scriptarium" | ||||||
|  |   - recherche des compétences sans accents pour permettre les noms accentués (standard Scriptarium) | ||||||
|  |   - affichage r1+ des sorts à coût variable dans la feuille simplifiée | ||||||
|  |   - affichage de Corps à corps pour le combat à mains nues dans la feuille simplifiée | ||||||
|  |   - dans les compendiums, les compétences Écriture et Épée ont une majuscule accentuée. Les Épée dans le compendium d'équipements référence le nom de compétence accentué. | ||||||
|  |  | ||||||
|  | ## 12.0.21 - La nomination d'Astrobazzarh | ||||||
|  | - Les noms pour les messages dans le tchat sont maintenant ceux des tokens plutôt que ceux des acteurs | ||||||
|  | - Fix: le choix des effets dans les options s'affiche correctement | ||||||
|  |  | ||||||
|  | ## 12.0.20 - Le tableau d'Astrobazzarh | ||||||
|  | - Ecran d'accueil officiel Scriptarium | ||||||
|  |  | ||||||
|  | ## 12.0.19 - La témérité d'Astrobazzarh | ||||||
|  | - Fix | ||||||
|  |   - les défenses des créatures sont correctement filtrées | ||||||
|  |   - le lancer d'initiative pour tous les personnages/PNJs fonctionne correctement | ||||||
|  |   - les lieux et commerces n'ont pas d'initiative | ||||||
|  |  | ||||||
|  | ## 12.0.18 - A la barbe d'Astrobazzarh | ||||||
|  | - Améliorations sur la feuille de PNJ simplifiée | ||||||
|  |   - Ajout du portrait | ||||||
|  |   - Ajout du corps à corps | ||||||
|  |   - Affichage du niveau d'esquive | ||||||
|  |   - Un clic sur l'initiative permet de lancer l'initiative | ||||||
|  |   - les boutons +/- pour la vie, l'endurance et la fatigue changent si on est à la valeur normale | ||||||
|  |   - un clic sur l'endurance effectue un jet d'endurance | ||||||
|  | - Fix | ||||||
|  |   - les achats des commerces sont de nouveau possibles | ||||||
|  |   - la commande /astro fonctionne de nouveau | ||||||
|  |   - le nombre d'utilisations d'items est réinitialisé à chaque round et fin de combat | ||||||
|  |   - la difficulté de parade pour les armes à distances n'est plus indiquée | ||||||
|  |   - les propositions d'armes de parade sont corrigées | ||||||
|  | - Ajout d'un indicateur pour les armes de parade nécessitant une significative | ||||||
|  |  | ||||||
|  | ## 12.0.16 - Le secret d'Astrobazzarh | ||||||
|  | - Fix: les jets envoyés messages uniquement au MJ ne sont plus envoyés à tous les autres joueurs (et dupliqués) | ||||||
|  | - Les noms affichés dans les automatisations de combat sont maintenant ceux des tokens plutôt que ceux des acteurs | ||||||
|  | - Ajout d'une option pour la localisation des blessures | ||||||
|  |  | ||||||
| ## 12.0.15 - Le messager d'Astrobazzarh | ## 12.0.15 - Le messager d'Astrobazzarh | ||||||
| - Correction des faces de dés personalisés dice-so-nice | - Correction des faces de dés personalisés dice-so-nice | ||||||
| - Les messages de maladies ne sont plus publics | - Les messages de maladies ne sont plus publics | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								dev-notes.md
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								dev-notes.md
									
									
									
									
									
								
							| @@ -1,61 +0,0 @@ | |||||||
| # Actor notes |  | ||||||
|  |  | ||||||
| > The Actor#getData default implementation gives you the following for use in sheet rendering: |  | ||||||
|  |  | ||||||
| ``` |  | ||||||
|   actor -> the Actor instance |  | ||||||
|   data -> a cloned copy of Actor#data |  | ||||||
|   items -> a cloned copy of Actor#data#items |  | ||||||
|   effects -> a cloned copy of Actor#data#effects |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| > if all you need is a safe copy of `Actor#data`, you'll be much better off by simply defining your own function and avoiding all the wasted work that the parent class does which will slow down your sheet |  | ||||||
| ```js |  | ||||||
| getData(options) { |  | ||||||
|   return { |  | ||||||
|     data: foundry.utils.deepClone(this.object.data) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| who knows, maybe you don't even need to copy your actor data, skip the copy and it's even faster: |  | ||||||
| ```js |  | ||||||
| getData(options) { |  | ||||||
|   return { |  | ||||||
|     data: this.object.data |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Atropos19/02/2021 |  | ||||||
| There are two recommended ways to create owned items in 0.8.0: |  | ||||||
| ```js |  | ||||||
| await Item.create(itemData, {parent: actor}); |  | ||||||
| await actor.createEmbeddedDocuments("Item", itemDataArray); |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
|  |  | ||||||
| You can update an embedded item in one of two ways: |  | ||||||
| ```js |  | ||||||
| //Method 1: |  | ||||||
|  |  | ||||||
| const item = actor.items.get(itemId); |  | ||||||
| item.update(data); |  | ||||||
|  |  | ||||||
| //Method 2: |  | ||||||
| actor.updateEmbeddedDocuments("Item", [{_id: itemId, ...}]); |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
|  |  | ||||||
| I noticed adding an ActiveEffect to an actor in code using |  | ||||||
|  |  | ||||||
| ```js |  | ||||||
| this.createEmbeddedDocuments('ActiveEffect', [effet], options); |  | ||||||
| this.applyActiveEffects(); |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| Atropos — Aujourd’hui à 14:42 |  | ||||||
| Two notes on this: |  | ||||||
| 1. You don't actually need to call this.applyActiveEffects() because this will happen automatically whenever an effect is created/updated/deleted |  | ||||||
| 2. If you want to suppress the automatic display of the sheet for the newly created document, you can pass options.renderSheet = false as part of your options object |  | ||||||
| @@ -80,7 +80,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|       const actor = this.actor; |       const actor = this.actor; | ||||||
|       formData.combat = foundry.utils.duplicate(formData.armes); |       formData.combat = foundry.utils.duplicate(formData.armes); | ||||||
|       RdDItemArme.computeNiveauArmes(formData.combat, formData.competences); |       RdDItemArme.computeNiveauArmes(formData.combat, formData.competences); | ||||||
|       formData.combat.push(RdDItemArme.mainsNues(actor)); |       formData.combat.push(RdDItemArme.corpsACorps(actor)); | ||||||
|       formData.combat.push(RdDItemArme.empoignade(actor)); |       formData.combat.push(RdDItemArme.empoignade(actor)); | ||||||
|  |  | ||||||
|       formData.esquives = this.actor.getCompetences("Esquive"); |       formData.esquives = this.actor.getCompetences("Esquive"); | ||||||
| @@ -220,18 +220,18 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|     // Points de reve actuel |     // Points de reve actuel | ||||||
|     this.html.find('.roll-reve-actuel').click(async event => this.actor.rollCarac('reve-actuel', true)) |     this.html.find('.roll-reve-actuel').click(async event => this.actor.rollCarac('reve-actuel', true)) | ||||||
|     this.html.find('.empoignade-label a').click(async event => RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) |     this.html.find('.empoignade-label a').click(async event => RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) | ||||||
|     this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)))) |  | ||||||
|  |     this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence')) | ||||||
|  |  | ||||||
|     // Initiative pour l'arme |     // Initiative pour l'arme | ||||||
|     this.html.find('.arme-initiative a').click(async event => { |     this.html.find('.roll-init-arme').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); |         RdDCombatManager.rollInitiativeAction(combatant._id, this._getEventArmeCombat(event)); | ||||||
|         RdDCombatManager.rollInitiativeAction(combatant._id, action); |  | ||||||
|       } else { |       } else { | ||||||
|         ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat."); |         ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat."); | ||||||
|       } |       } | ||||||
|     }); |     }) | ||||||
|     // Display TMR |     // Display TMR | ||||||
|  |  | ||||||
|     this.html.find('.button-tmr').click(async event => this.actor.displayTMR("normal")) |     this.html.find('.button-tmr').click(async event => this.actor.displayTMR("normal")) | ||||||
|   | |||||||
| @@ -36,6 +36,8 @@ import { ITEM_TYPES } from "./item.js"; | |||||||
| import { RdDBaseActorSang } from "./actor/base-actor-sang.js"; | import { RdDBaseActorSang } from "./actor/base-actor-sang.js"; | ||||||
| import { RdDCoeur } from "./coeur/rdd-coeur.js"; | import { RdDCoeur } from "./coeur/rdd-coeur.js"; | ||||||
| import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js"; | import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js"; | ||||||
|  | import { RdDItemArme } from "./item-arme.js"; | ||||||
|  | import { RdDCombatManager } from "./rdd-combat.js"; | ||||||
|  |  | ||||||
| export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] | export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] | ||||||
|  |  | ||||||
| @@ -130,6 +132,23 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|       .reduce(Misc.sum(), 0); |       .reduce(Misc.sum(), 0); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   listActionsCombat() { | ||||||
|  |     // Recupération des armes | ||||||
|  |     const actions = RdDCombatManager.listActionsArmes( | ||||||
|  |       this.itemTypes[ITEM_TYPES.arme] | ||||||
|  |         .filter(it => RdDItemArme.isAttaque(it)) | ||||||
|  |         .concat(RdDItemArme.corpsACorps(this)) | ||||||
|  |         .concat(RdDItemArme.empoignade(this)) | ||||||
|  |       , | ||||||
|  |       this.itemTypes[ITEM_TYPES.competence], | ||||||
|  |       this.system.carac) | ||||||
|  |  | ||||||
|  |     if (this.system.attributs.hautrevant.value) { | ||||||
|  |       actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } }); | ||||||
|  |     } | ||||||
|  |     return actions | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   getTache(id) { return this.findItemLike(id, 'tache') } |   getTache(id) { return this.findItemLike(id, 'tache') } | ||||||
|   getMeditation(id) { return this.findItemLike(id, 'meditation') } |   getMeditation(id) { return this.findItemLike(id, 'meditation') } | ||||||
| @@ -162,7 +181,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|         whisper: ChatUtility.getOwners(this), |         whisper: ChatUtility.getOwners(this), | ||||||
|         content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, { |         content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, { | ||||||
|           pr: nouveauReve, |           pr: nouveauReve, | ||||||
|           alias: this.name, |           alias: this.getAlias(), | ||||||
|           potionName: it.name, |           potionName: it.name, | ||||||
|           potionImg: it.img |           potionImg: it.img | ||||||
|         }) |         }) | ||||||
| @@ -1322,7 +1341,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     const etat = this.getEtatGeneral({ ethylisme: true }); |     const etat = this.getEtatGeneral({ ethylisme: true }); | ||||||
|     const nbDoses = Number(this.system.compteurs.ethylisme.nb_doses || 0); |     const nbDoses = Number(this.system.compteurs.ethylisme.nb_doses || 0); | ||||||
|     const ethylismeData = { |     const ethylismeData = { | ||||||
|       alias: this.name, |       alias: this.getAlias(), | ||||||
|       actor: this, |       actor: this, | ||||||
|       vie: this.system.sante.vie.max, |       vie: this.system.sante.vie.max, | ||||||
|       alcool: alcool, |       alcool: alcool, | ||||||
| @@ -1407,7 +1426,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     const perteDissolution = Math.max(0, Math.min(dissolution, conversion)); |     const perteDissolution = Math.max(0, Math.min(dissolution, conversion)); | ||||||
|  |  | ||||||
|     let stressRollData = { |     let stressRollData = { | ||||||
|       alias: this.name, |       alias: this.getAlias(), | ||||||
|       selectedCarac: this.system.carac.reve, |       selectedCarac: this.system.carac.reve, | ||||||
|       rolled: stressRoll, |       rolled: stressRoll, | ||||||
|       stress: fromStress, |       stress: fromStress, | ||||||
| @@ -1498,7 +1517,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|         carac.value = niveauSuivant; |         carac.value = niveauSuivant; | ||||||
|  |  | ||||||
|         let checkXp = { |         let checkXp = { | ||||||
|           alias: this.name, |           alias: this.getAlias(), | ||||||
|           carac: caracName, |           carac: caracName, | ||||||
|           value: niveauSuivant, |           value: niveauSuivant, | ||||||
|           xp: carac.xp |           xp: carac.xp | ||||||
| @@ -1528,7 +1547,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|         newCompData.system.niveau += 1; |         newCompData.system.niveau += 1; | ||||||
|         newCompData.system.xp = newXP; |         newCompData.system.xp = newXP; | ||||||
|         let checkXp = { |         let checkXp = { | ||||||
|           alias: this.name, |           alias: this.getAlias(), | ||||||
|           competence: newCompData.name, |           competence: newCompData.name, | ||||||
|           niveau: newCompData.system.niveau, |           niveau: newCompData.system.niveau, | ||||||
|           xp: newCompData.system.xp, |           xp: newCompData.system.xp, | ||||||
| @@ -1548,7 +1567,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { |   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { | ||||||
|     if (!Misc.firstConnectedGM()){ |     if (!Misc.isFirstConnectedGM()) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM) |     hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM) | ||||||
| @@ -1765,7 +1784,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     } |     } | ||||||
|     const competence = this.getCompetence(compName); |     const competence = this.getCompetence(compName); | ||||||
|     let rollData = { |     let rollData = { | ||||||
|       alias: this.name, |       alias: this.getAlias(), | ||||||
|       caracValue: Number(carac.value), |       caracValue: Number(carac.value), | ||||||
|       selectedCarac: carac, |       selectedCarac: carac, | ||||||
|       competence: competence, |       competence: competence, | ||||||
| @@ -1838,7 +1857,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|       label: 'Jet ' + Grammar.apostrophe('de', competence.name), |       label: 'Jet ' + Grammar.apostrophe('de', competence.name), | ||||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html', |       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html', | ||||||
|       rollData: { |       rollData: { | ||||||
|         alias: this.name, |         alias: this.getAlias(), | ||||||
|         carac: this.system.carac, |         carac: this.system.carac, | ||||||
|         selectedCarac: this.getCaracByName(caracName), |         selectedCarac: this.getCaracByName(caracName), | ||||||
|         selectedCaracName: caracName, |         selectedCaracName: caracName, | ||||||
| @@ -2615,7 +2634,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async resetItemUse() { |   async resetItemUse() { | ||||||
|     await this.setFlag(SYSTEM_RDD, 'itemUse', {}); |     await this.unsetFlag(SYSTEM_RDD, 'itemUse'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -2911,7 +2930,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|     let newQuantite = herbeData.system.quantite - herbeData.nbBrins; |     let newQuantite = herbeData.system.quantite - herbeData.nbBrins; | ||||||
|     let messageData = { |     let messageData = { | ||||||
|       alias: this.name, |       alias: this.getAlias(), | ||||||
|       nbBrinsReste: newQuantite, |       nbBrinsReste: newQuantite, | ||||||
|       potion: newPotion, |       potion: newPotion, | ||||||
|       herbe: herbeData |       herbe: herbeData | ||||||
| @@ -3011,7 +3030,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onCreateOwnedDraconique(item, options, id) { |   async onCreateOwnedDraconique(item, options, id) { | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       let draconique = Draconique.all().find(it => it.match(item)); |       let draconique = Draconique.all().find(it => it.match(item)); | ||||||
|       if (draconique) { |       if (draconique) { | ||||||
|         await draconique.onActorCreateOwned(this, item) |         await draconique.onActorCreateOwned(this, item) | ||||||
| @@ -3023,7 +3042,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onDeleteOwnedDraconique(item, options, id) { |   async onDeleteOwnedDraconique(item, options, id) { | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       let draconique = Draconique.all().find(it => it.match(item)); |       let draconique = Draconique.all().find(it => it.match(item)); | ||||||
|       if (draconique) { |       if (draconique) { | ||||||
|         await draconique.onActorDeleteOwned(this, item) |         await draconique.onActorDeleteOwned(this, item) | ||||||
| @@ -3033,7 +3052,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onDeleteOwnedCaseTmr(item, options, id) { |   async onDeleteOwnedCaseTmr(item, options, id) { | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       let draconique = Draconique.all().find(it => it.isCase(item)); |       let draconique = Draconique.all().find(it => it.isCase(item)); | ||||||
|       if (draconique) { |       if (draconique) { | ||||||
|         await draconique.onActorDeleteCaseTmr(this, item) |         await draconique.onActorDeleteCaseTmr(this, item) | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ import { StatusEffects } from "../settings/status-effects.js"; | |||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../item.js"; | ||||||
| import { Targets } from "../targets.js"; | import { Targets } from "../targets.js"; | ||||||
| import { RdDPossession } from "../rdd-possession.js"; | import { RdDPossession } from "../rdd-possession.js"; | ||||||
| import { RdDCombat } from "../rdd-combat.js"; | import { RdDCombat, RdDCombatManager } from "../rdd-combat.js"; | ||||||
| import { RdDConfirm } from "../rdd-confirm.js"; | import { RdDConfirm } from "../rdd-confirm.js"; | ||||||
| import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js"; | import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js"; | ||||||
| import { RdDItemArme } from "../item-arme.js"; | import { RdDItemArme } from "../item-arme.js"; | ||||||
| @@ -78,8 +78,27 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   } |   } | ||||||
|   async jetEndurance(resteEndurance = undefined) { return { jetEndurance: 0, sonne: false } } |   async jetEndurance(resteEndurance = undefined) { return { jetEndurance: 0, sonne: false } } | ||||||
|   isDead() { return false } |   isDead() { return false } | ||||||
|  |   isSonne() { return false } | ||||||
|   blessuresASoigner() { return [] } |   blessuresASoigner() { return [] } | ||||||
|   getEtatGeneral(options = { ethylisme: false }) { return 0 } |   getEtatGeneral(options = { ethylisme: false }) { return 0 } | ||||||
|  |   isActorCombat() { return true } | ||||||
|  |  | ||||||
|  |   getCaracInit(competence) { | ||||||
|  |     if (!competence){ | ||||||
|  |       return 0 | ||||||
|  |     } | ||||||
|  |     if (competence.type == ITEM_TYPES.competencecreature) { | ||||||
|  |       return competence.system.carac_value | ||||||
|  |     } | ||||||
|  |     return this.system.carac[competence.system.defaut_carac].value; | ||||||
|  |   } | ||||||
|  |   listActionsCombat() { | ||||||
|  |     return this.itemTypes[ITEM_TYPES.competencecreature] | ||||||
|  |       .filter(it => RdDItemCompetenceCreature.isAttaque(it)) | ||||||
|  |       .map(it => RdDItemCompetenceCreature.armeCreature(it)) | ||||||
|  |       .filter(it => it != undefined); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   async computeArmure(attackerRoll) { return this.getProtectionNaturelle() } |   async computeArmure(attackerRoll) { return this.getProtectionNaturelle() } | ||||||
|   async remiseANeuf() { } |   async remiseANeuf() { } | ||||||
| @@ -98,7 +117,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     for (let effect of this.getEffects()) { |     for (let effect of this.getEffects()) { | ||||||
|       if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) { |       if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) { | ||||||
|         await effect.delete(); |         await effect.delete(); | ||||||
|         ChatMessage.create({ content: `${this.name} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` }); |         ChatMessage.create({ content: `${this.getAlias()} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` }); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -153,9 +172,6 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   getPossession(possessionId) { |   getPossession(possessionId) { | ||||||
|     return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId); |     return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId); | ||||||
|   } |   } | ||||||
|   getPossessions() { |  | ||||||
|     return this.itemTypes[ITEM_TYPES.possession]; |  | ||||||
|   } |  | ||||||
|   getEmpoignades() { |   getEmpoignades() { | ||||||
|     return this.itemTypes[ITEM_TYPES.empoignade]; |     return this.itemTypes[ITEM_TYPES.empoignade]; | ||||||
|   } |   } | ||||||
| @@ -272,7 +288,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|  |  | ||||||
|     await this.openRollDialog({ |     await this.openRollDialog({ | ||||||
|       name: `jet-${this.id}`, |       name: `jet-${this.id}`, | ||||||
|       label: `Jet de ${this.name}`, |       label: `Jet de ${this.getAlias()}`, | ||||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html', |       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html', | ||||||
|       rollData: { |       rollData: { | ||||||
|         carac: carac, |         carac: carac, | ||||||
| @@ -327,14 +343,15 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     const competence = this.getCompetence(idOrName); |     const competence = this.getCompetence(idOrName); | ||||||
|     let rollData = { carac: this.system.carac, competence: competence, arme: options.arme } |     let rollData = { carac: this.system.carac, competence: competence, arme: options.arme } | ||||||
|     if (competence.type == ITEM_TYPES.competencecreature) { |     if (competence.type == ITEM_TYPES.competencecreature) { | ||||||
|  |       const token = RdDUtility.getSelectedToken(this) | ||||||
|       const arme = RdDItemCompetenceCreature.armeCreature(competence) |       const arme = RdDItemCompetenceCreature.armeCreature(competence) | ||||||
|       if (arme && options.tryTarget && Targets.hasTargets()) { |       if (arme && options.tryTarget && Targets.hasTargets()) { | ||||||
|         Targets.selectOneToken(target => { |         Targets.selectOneTargetToken(target => { | ||||||
|           if (arme.action == "possession") { |           if (arme.action == "possession") { | ||||||
|             RdDPossession.onAttaquePossession(target, this, competence) |             RdDPossession.onAttaquePossession(target, this, competence) | ||||||
|           } |           } | ||||||
|           else { |           else { | ||||||
|             RdDCombat.rddCombatTarget(target, this).attaque(competence, arme) |             RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme) | ||||||
|           } |           } | ||||||
|         }); |         }); | ||||||
|         return; |         return; | ||||||
| @@ -364,9 +381,10 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|    * @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession |    * @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession | ||||||
|    * @returns  |    * @returns  | ||||||
|    */ |    */ | ||||||
|   rollArme(arme, categorieArme = "competence") { |   rollArme(arme, categorieArme, token) { | ||||||
|  |     token = token ?? RdDUtility.getSelectedToken(this) | ||||||
|     const compToUse = this.$getCompetenceArme(arme, categorieArme) |     const compToUse = this.$getCompetenceArme(arme, categorieArme) | ||||||
|     if (!RdDItemArme.isArmeUtilisable(arme)) { |     if (!RdDItemArme.isUtilisable(arme)) { | ||||||
|       ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`) |       ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`) | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
| @@ -385,7 +403,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|       return |       return | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Targets.selectOneToken(target => { |     Targets.selectOneTargetToken(target => { | ||||||
|       if (Targets.isTargetEntite(target)) { |       if (Targets.isTargetEntite(target)) { | ||||||
|         ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`); |         ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`); | ||||||
|         return |         return | ||||||
| @@ -395,7 +413,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|       if (competence.isCompetencePossession()) { |       if (competence.isCompetencePossession()) { | ||||||
|         return RdDPossession.onAttaquePossession(target, this, competence); |         return RdDPossession.onAttaquePossession(target, this, competence); | ||||||
|       } |       } | ||||||
|       RdDCombat.rddCombatTarget(target, this).attaque(competence, arme); |       RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme); | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -403,58 +421,52 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     return RdDItemArme.getCompetenceArme(arme, competenceName) |     return RdDItemArme.getCompetenceArme(arme, competenceName) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   verifierForceMin(item) { |   verifierForceMin(item) { } | ||||||
|   } |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async resetItemUse() { } |  | ||||||
|   async incDecItemUse(itemId, inc = 1) { } |  | ||||||
|   getItemUse(itemId) { return 0; } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async encaisser() { await RdDEncaisser.encaisser(this) } |   async encaisser() { await RdDEncaisser.encaisser(this) } | ||||||
|  |  | ||||||
|   async encaisserDommages(rollData, attacker = undefined, show = undefined) { |   async encaisserDommages(rollData, attacker = undefined, show = undefined, attackerToken = undefined, defenderToken = undefined) { | ||||||
|     if (attacker && !await attacker.accorder(this, 'avant-encaissement')) { |     if (attacker && !await attacker.accorder(this, 'avant-encaissement')) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     const armure = await this.computeArmure(rollData); |     const armure = await this.computeArmure(rollData); | ||||||
|     if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) { |     if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) { | ||||||
|       await this.encaisserDommagesValidationGR(rollData, armure, attacker?.id, show); |       await this.encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       const jet = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE }); |       const jet = await RdDUtility.jetEncaissement(this, rollData, armure, { showDice: SHOW_DICE }); | ||||||
|       await this.$onEncaissement(jet, show, attacker); |       await this.$onEncaissement(jet, show, attackerToken, defenderToken) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async encaisserDommagesValidationGR(rollData, armure, attackerId, show) { |   async encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken) { | ||||||
|     if (!game.user.isGM) { |     if (!game.user.isGM) { | ||||||
|       RdDBaseActor.remoteActorCall({ |       RdDBaseActor.remoteActorCall({ | ||||||
|         tokenId: this.token?.id, |         tokenId: this.token?.id, | ||||||
|         actorId: this.id, |         actorId: this.id, | ||||||
|         method: 'encaisserDommagesValidationGR', |         method: 'encaisserDommagesValidationGR', | ||||||
|         args: [rollData, armure, attackerId, show] |         args: [rollData, armure, show, attackerToken, defenderToken] | ||||||
|       }); |       }) | ||||||
|     } else { |     } else { | ||||||
|       const attacker = game.actors.get(attackerId); |  | ||||||
|       DialogValidationEncaissement.validerEncaissement(this, rollData, armure, |       DialogValidationEncaissement.validerEncaissement(this, rollData, armure, | ||||||
|         jet => this.$onEncaissement(jet, show, attacker)); |         jet => this.$onEncaissement(jet, show, attackerToken, defenderToken)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async $onEncaissement(jet, show, attacker) { |   async $onEncaissement(jet, show, attackerToken, defenderToken) { | ||||||
|     await this.onAppliquerJetEncaissement(jet, attacker); |     await this.onAppliquerJetEncaissement(jet, attackerToken); | ||||||
|     await this.$afficherEncaissement(jet, show); |     await this.$afficherEncaissement(jet, show, defenderToken); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async onAppliquerJetEncaissement(encaissement, attacker) { } |   async onAppliquerJetEncaissement(encaissement, attackerToken) { } | ||||||
|  |  | ||||||
|   async $afficherEncaissement(encaissement, show) { |   async $afficherEncaissement(encaissement, show, defenderToken) { | ||||||
|     foundry.utils.mergeObject(encaissement, { |     foundry.utils.mergeObject(encaissement, { | ||||||
|       alias: this.name, |       alias: defenderToken?.name ?? this.getAlias(), | ||||||
|       hasPlayerOwner: this.hasPlayerOwner, |       hasPlayerOwner: this.hasPlayerOwner, | ||||||
|       show: show ?? {} |       show: show ?? {} | ||||||
|     }); |     }, { overwrite: false }); | ||||||
|  |  | ||||||
|     await ChatUtility.createChatWithRollMode( |     await ChatUtility.createChatWithRollMode( | ||||||
|       { |       { | ||||||
| @@ -484,7 +496,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     } |     } | ||||||
|     const rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.system.carac.niveau.value)); |     const rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.system.carac.niveau.value)); | ||||||
|     const rollData = { |     const rollData = { | ||||||
|       alias: this.name, |       alias: this.getAlias(), | ||||||
|       rolled: rolled, |       rolled: rolled, | ||||||
|       entite: entite.name, |       entite: entite.name, | ||||||
|       selectedCarac: this.system.carac.reve |       selectedCarac: this.system.carac.reve | ||||||
| @@ -504,7 +516,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   isEntiteAccordee(attacker) { return true } |   isEntiteAccordee(attacker) { return true } | ||||||
|  |  | ||||||
|   async setEntiteReveAccordee(actor) { |   async setEntiteReveAccordee(actor) { | ||||||
|     ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entité incarnée"); |     ui.notifications.error("Impossible de s'accorder à " + this.getAlias() + ": ce n'est pas une entité incarnée"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -89,9 +89,9 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|  |  | ||||||
|   async onAppliquerJetEncaissement(encaissement, attacker) { |   async onAppliquerJetEncaissement(encaissement, attackerToken) { | ||||||
|     const santeOrig = foundry.utils.duplicate(this.system.sante); |     const santeOrig = foundry.utils.duplicate(this.system.sante); | ||||||
|     const blessure = await this.ajouterBlessure(encaissement, attacker); // Will update the result table |     const blessure = await this.ajouterBlessure(encaissement, attackerToken); // Will update the result table | ||||||
|     const perteVie = await this.santeIncDec("vie", -encaissement.vie); |     const perteVie = await this.santeIncDec("vie", -encaissement.vie); | ||||||
|     const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique()); |     const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique()); | ||||||
|  |  | ||||||
| @@ -169,7 +169,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async ajouterBlessure(encaissement, attacker = undefined) { |   async ajouterBlessure(encaissement, attackerToken = undefined) { | ||||||
|     if (encaissement.gravite < 0) return; |     if (encaissement.gravite < 0) return; | ||||||
|     if (encaissement.gravite > 0) { |     if (encaissement.gravite > 0) { | ||||||
|       while (this.countBlessures(it => it.system.gravite == encaissement.gravite) >= RdDItemBlessure.maxBlessures(encaissement.gravite) && encaissement.gravite <= 6) { |       while (this.countBlessures(it => it.system.gravite == encaissement.gravite) >= RdDItemBlessure.maxBlessures(encaissement.gravite) && encaissement.gravite <= 6) { | ||||||
| @@ -181,7 +181,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     const endActuelle = this.getEnduranceActuelle(); |     const endActuelle = this.getEnduranceActuelle(); | ||||||
|     const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg?.loc.label ?? '', attacker); |     const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken); | ||||||
|     if (blessure.isCritique()) { |     if (blessure.isCritique()) { | ||||||
|       encaissement.endurance = endActuelle; |       encaissement.endurance = endActuelle; | ||||||
|     } |     } | ||||||
| @@ -191,7 +191,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|       encaissement.mort = true; |       encaissement.mort = true; | ||||||
|       ChatMessage.create({ |       ChatMessage.create({ | ||||||
|         content: `<img class="chat-icon" src="icons/svg/skull.svg" data-tooltip="charge" /> |         content: `<img class="chat-icon" src="icons/svg/skull.svg" data-tooltip="charge" /> | ||||||
|         <strong>${this.name} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !</strong>` |         <strong>${this.getAlias()} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !</strong>` | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|     return blessure; |     return blessure; | ||||||
| @@ -218,7 +218,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|   async jetDeVie() { |   async jetDeVie() { | ||||||
|     if (this.isDead()) { |     if (this.isDead()) { | ||||||
|       ChatMessage.create({ |       ChatMessage.create({ | ||||||
|         content: `Jet de Vie: ${this.name} est déjà mort, ce n'est pas la peine d'en rajouter !!!!!`, |         content: `Jet de Vie: ${this.getAlias()} est déjà mort, ce n'est pas la peine d'en rajouter !!!!!`, | ||||||
|         whisper: ChatUtility.getOwners(this) |         whisper: ChatUtility.getOwners(this) | ||||||
|       }) |       }) | ||||||
|       return |       return | ||||||
| @@ -242,7 +242,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|       await this.santeIncDec("vie", -perte); |       await this.santeIncDec("vie", -perte); | ||||||
|     } |     } | ||||||
|     if (this.isDead()) { |     if (this.isDead()) { | ||||||
|       msgText += `<br><strong>${this.name} est mort !!!!</strong>`; |       msgText += `<br><strong>${this.getAlias()} est mort !!!!</strong>`; | ||||||
|     } |     } | ||||||
|     else if (prochainJet > 0) { |     else if (prochainJet > 0) { | ||||||
|       msgText += `<br>Prochain jet de vie dans ${prochainJet} ${isCritique ? 'round' : 'minute'}${prochainJet > 1 ? 's' : ''} ${isCritique ? '(état critique)' : '(état grave)'}` |       msgText += `<br>Prochain jet de vie dans ${prochainJet} ${isCritique ? 'round' : 'minute'}${prochainJet > 1 ? 's' : ''} ${isCritique ? '(état critique)' : '(état grave)'}` | ||||||
| @@ -273,14 +273,14 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|  |  | ||||||
|   async setSonne(sonne = true) { |   async setSonne(sonne = true) { | ||||||
|     if (!game.combat && sonne) { |     if (!game.combat && sonne) { | ||||||
|       ui.notifications.info(`${this.name} est hors combat, il ne reste donc pas sonné`); |       ui.notifications.info(`${this.getAlias()} est hors combat, il ne reste donc pas sonné`); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     await this.setEffect(STATUSES.StatusStunned, sonne); |     await this.setEffect(STATUSES.StatusStunned, sonne) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getSonne() { |   isSonne() { | ||||||
|     return this.getEffect(STATUSES.StatusStunned); |     return this.getEffect(STATUSES.StatusStunned) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isEffectAllowed(effectId) { return true } |   isEffectAllowed(effectId) { return true } | ||||||
|   | |||||||
| @@ -78,6 +78,13 @@ export class RdDBaseActor extends Actor { | |||||||
|     return game.actors.get(actorId) |     return game.actors.get(actorId) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   getAlias() { | ||||||
|  |     if (this.token?.name != null && this.token != this.prototypeToken) { | ||||||
|  |       return this.token.name | ||||||
|  |     } | ||||||
|  |     return this.name | ||||||
|  |   } | ||||||
|  |  | ||||||
|   isPersonnageJoueur() { return false } |   isPersonnageJoueur() { return false } | ||||||
|  |  | ||||||
|   static extractActorMin = (actor) => { return { id: actor?.id, type: actor?.type, name: actor?.name, img: actor?.img }; }; |   static extractActorMin = (actor) => { return { id: actor?.id, type: actor?.type, name: actor?.name, img: actor?.img }; }; | ||||||
| @@ -205,11 +212,8 @@ export class RdDBaseActor extends Actor { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onPreUpdateItem(item, change, options, id) { } |   async onPreUpdateItem(item, change, options, id) { } | ||||||
|  |  | ||||||
|   async onCreateItem(item, options, id) { } |   async onCreateItem(item, options, id) { } | ||||||
|  |  | ||||||
|   async onDeleteItem(item, options, id) { } |   async onDeleteItem(item, options, id) { } | ||||||
|  |  | ||||||
|   async onUpdateActor(update, options, actorId) { } |   async onUpdateActor(update, options, actorId) { } | ||||||
|  |  | ||||||
|   async onTimeChanging(oldTimestamp, newTimestamp) { |   async onTimeChanging(oldTimestamp, newTimestamp) { | ||||||
| @@ -218,7 +222,7 @@ export class RdDBaseActor extends Actor { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   async creerObjetParMJ(object) { |   async creerObjetParMJ(object) { | ||||||
|     if (!Misc.isUniqueConnectedGM()) { |     if (!Misc.isFirstConnectedGM()) { | ||||||
|       RdDBaseActor.remoteActorCall({ |       RdDBaseActor.remoteActorCall({ | ||||||
|         tokenId: this.token?.id, |         tokenId: this.token?.id, | ||||||
|         actorId: this.id, |         actorId: this.id, | ||||||
| @@ -317,7 +321,7 @@ export class RdDBaseActor extends Actor { | |||||||
|  |  | ||||||
|       RdDAudio.PlayContextAudio("argent"); // Petit son |       RdDAudio.PlayContextAudio("argent"); // Petit son | ||||||
|       ChatMessage.create({ |       ChatMessage.create({ | ||||||
|         whisper: ChatUtility.getOwners(this.name), |         whisper: ChatUtility.getOwners(this), | ||||||
|         content: `Vous avez reçu <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.` |         content: `Vous avez reçu <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.` | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
| @@ -335,7 +339,7 @@ export class RdDBaseActor extends Actor { | |||||||
|       ui.notifications.info("Inutile de se vendre à soi-même"); |       ui.notifications.info("Inutile de se vendre à soi-même"); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     if (!Misc.isUniqueConnectedGM()) { |     if (!Misc.isFirstConnectedGM()) { | ||||||
|       RdDBaseActor.remoteActorCall({ |       RdDBaseActor.remoteActorCall({ | ||||||
|         actorId: achat.vendeurId ?? achat.acheteurId, |         actorId: achat.vendeurId ?? achat.acheteurId, | ||||||
|         method: 'achatVente', |         method: 'achatVente', | ||||||
| @@ -370,7 +374,7 @@ export class RdDBaseActor extends Actor { | |||||||
|     chatAchatItem.quantiteTotal = quantite; |     chatAchatItem.quantiteTotal = quantite; | ||||||
|     ChatMessage.create({ |     ChatMessage.create({ | ||||||
|       user: achat.userId, |       user: achat.userId, | ||||||
|       speaker: { alias: (acheteur ?? vendeur).name }, |       speaker: { alias: (acheteur ?? vendeur).getAlias() }, | ||||||
|       whisper: ChatUtility.getOwners(this), |       whisper: ChatUtility.getOwners(this), | ||||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html', chatAchatItem) |       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html', chatAchatItem) | ||||||
|     }); |     }); | ||||||
| @@ -686,7 +690,7 @@ export class RdDBaseActor extends Actor { | |||||||
|       type: this.type, |       type: this.type, | ||||||
|       img: this.img, |       img: this.img, | ||||||
|       pack: this.pack, |       pack: this.pack, | ||||||
|       name: this.name, |       name: this.getAlias(), | ||||||
|       system: { description: this.system.description } |       system: { description: this.system.description } | ||||||
|     } |     } | ||||||
|     renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.html', chatData) |     renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.html', chatData) | ||||||
| @@ -694,10 +698,10 @@ export class RdDBaseActor extends Actor { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   actionImpossible(action) { |   actionImpossible(action) { | ||||||
|     ui.notifications.info(`${this.name} ne peut pas faire cette action: ${action}`) |     ui.notifications.info(`${this.getAlias()} ne peut pas faire cette action: ${action}`) | ||||||
|  |  | ||||||
|   } |   } | ||||||
|   async roll() { this.actionImpossible("jet de caractéristiques") } |  | ||||||
|   async jetEthylisme() { this.actionImpossible("jet d'éthylisme") } |   async jetEthylisme() { this.actionImpossible("jet d'éthylisme") } | ||||||
|   async rollAppelChance() { this.actionImpossible("appel à la chance") } |   async rollAppelChance() { this.actionImpossible("appel à la chance") } | ||||||
|   async jetDeMoral() { this.actionImpossible("jet de moral") } |   async jetDeMoral() { this.actionImpossible("jet de moral") } | ||||||
| @@ -708,5 +712,24 @@ export class RdDBaseActor extends Actor { | |||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
|   } |   } | ||||||
|  |   async resetItemUse() { } | ||||||
|  |   async incDecItemUse(itemId, inc = 1) { } | ||||||
|  |   getItemUse(itemId) { return 0; } | ||||||
|  |   async finDeRound(options = { terminer: false }) { } | ||||||
|  |   isActorCombat() { return false } | ||||||
|  |   getCaracInit(competence) { return 0 } | ||||||
|  |   listActionsCombat() { return [] } | ||||||
|  |   listActionsPossessions() { | ||||||
|  |     return this.itemTypes[ITEM_TYPES.possession] | ||||||
|  |       .map(p => { | ||||||
|  |         return { | ||||||
|  |           name: p.name, | ||||||
|  |           action: 'possession', | ||||||
|  |           system: { | ||||||
|  |             competence: p.name, | ||||||
|  |             possessionid: p.system.possessionid, | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |   } | ||||||
| } | } | ||||||
| @@ -73,7 +73,7 @@ export class RdDCommerceSheet extends RdDBaseActorSheet { | |||||||
|     } |     } | ||||||
|     const disponible = this.actor.getQuantiteDisponible(item) |     const disponible = this.actor.getQuantiteDisponible(item) | ||||||
|     if (disponible == 0) { |     if (disponible == 0) { | ||||||
|       ui.notifications.warn(`${this.name} n'a plus de ${item.name} en vente`); |       ui.notifications.warn(`${this.getAlias()} n'a plus de ${item.name} en vente`); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -74,7 +74,7 @@ export class RdDEntite extends RdDBaseActorReve { | |||||||
|     return [STATUSES.StatusComma].includes(effectId); |     return [STATUSES.StatusComma].includes(effectId); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async onAppliquerJetEncaissement(encaissement, attacker) { |   async onAppliquerJetEncaissement(encaissement, attackerToken) { | ||||||
|     const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance); |     const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance); | ||||||
|     foundry.utils.mergeObject(encaissement, { |     foundry.utils.mergeObject(encaissement, { | ||||||
|       resteEndurance: perteEndurance.newValue, |       resteEndurance: perteEndurance.newValue, | ||||||
|   | |||||||
| @@ -84,7 +84,7 @@ const MAPPING_BASE = [ | |||||||
|   { column: "malus_armure", getter: (actor, context) => Mapping.getMalusArmure(actor, context) }, |   { column: "malus_armure", getter: (actor, context) => Mapping.getMalusArmure(actor, context) }, | ||||||
|   { column: "reve_actuel", rollClass: 'roll-reve-actuel', colName: 'Rêve actuel', getter: (actor, context) => actor.system.reve.reve.value }, |   { column: "reve_actuel", rollClass: 'roll-reve-actuel', colName: 'Rêve actuel', getter: (actor, context) => actor.system.reve.reve.value }, | ||||||
|   { column: "vie_actuel", rollClass: 'jet-vie', getter: (actor, context) => actor.system.sante.vie.value }, |   { column: "vie_actuel", rollClass: 'jet-vie', getter: (actor, context) => actor.system.sante.vie.value }, | ||||||
|   { column: "endurance_actuel", rollClass: 'jet-vie', getter: (actor, context) => actor.system.sante.endurance.value }, |   { column: "endurance_actuel", rollClass: 'jet-endurance', getter: (actor, context) => actor.system.sante.endurance.value }, | ||||||
|   { column: "esquive", getter: (actor, context) => Mapping.getEsquive(context) }, |   { column: "esquive", getter: (actor, context) => Mapping.getEsquive(context) }, | ||||||
|   { column: "esquive_armure", getter: (actor, context) => Mapping.getEsquiveArmure(context) }, |   { column: "esquive_armure", getter: (actor, context) => Mapping.getEsquiveArmure(context) }, | ||||||
|   { column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) }, |   { column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) }, | ||||||
| @@ -140,36 +140,44 @@ export class Mapping { | |||||||
|  |  | ||||||
|   static prepareArmes(actor) { |   static prepareArmes(actor) { | ||||||
|     const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme) |     const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme) | ||||||
|     return armes.map(arme => |     armes.push(RdDItemArme.corpsACorps(actor)); | ||||||
|       [ |     armes.push(RdDItemArme.empoignade(actor)); | ||||||
|  |     return armes.map(arme => [ | ||||||
|       arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined, |       arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined, | ||||||
|       arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined, |       arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined, | ||||||
|       !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined, |       !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined, | ||||||
|       arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined, |       arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined, | ||||||
|         arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined |       arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined] | ||||||
|       ] |       .filter(it => it != undefined)) | ||||||
|         .filter(it => it != undefined) |       .reduce((a, b) => a.concat(b), []) | ||||||
|     ).reduce((a, b) => a.concat(b), []) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static prepareArme(actor, arme, maniement) { |   static prepareArme(actor, arme, maniement) { | ||||||
|     const nameCompArme = RdDItemArme.getCompetenceArme(arme, maniement) |     const nameCompetenceArme = RdDItemArme.getCompetenceArme(arme, maniement) | ||||||
|     const competence = actor.getCompetence(nameCompArme) |     const competence = actor.getCompetence(nameCompetenceArme) | ||||||
|     if (RdDItemCompetence.isNiveauBase(competence)) { |     if (RdDItemCompetence.isNiveauBase(competence)) { | ||||||
|       return undefined |       return undefined | ||||||
|     } |     } | ||||||
|     const dmgArme = RdDItemArme.dommagesReels(arme, maniement) |  | ||||||
|     const dommages = dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme) |  | ||||||
|     const categorie = Mapping.complementCategorie(arme, maniement) |     const categorie = Mapping.complementCategorie(arme, maniement) | ||||||
|  |     const dommages = Mapping.dommagesArme(actor, arme, maniement) | ||||||
|     return { |     return { | ||||||
|       name: arme.name + categorie, |       name: arme.name + categorie, | ||||||
|       niveau: Misc.toSignedString(competence.system.niveau), |       niveau: Misc.toSignedString(competence.system.niveau), | ||||||
|       init: Mapping.calculBaseInit(actor, competence.system.categorie) + competence.system.niveau, |       init: Mapping.calculBaseInit(actor, competence.system.categorie) + competence.system.niveau, | ||||||
|       dommages: Misc.toSignedString(dommages), |       dommages: dommages, | ||||||
|       competence: competence, |       competence: competence, | ||||||
|       arme: arme |       arme: arme | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |   static dommagesArme(actor, arme, maniement){ | ||||||
|  |     const dmgArme = RdDItemArme.dommagesReels(arme, maniement) | ||||||
|  |     const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)) | ||||||
|  |     switch(arme.system.mortalite) { | ||||||
|  |       case 'non-mortel': return `(${dommages})` | ||||||
|  |       case 'empoignade': return '-' | ||||||
|  |     } | ||||||
|  |     return dommages | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static complementCategorie(arme, maniement) { |   static complementCategorie(arme, maniement) { | ||||||
|     switch (maniement) { |     switch (maniement) { | ||||||
| @@ -253,7 +261,7 @@ export class Mapping { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static addSpaceToNonNumeric(value) { |   static addSpaceToNonNumeric(value) { | ||||||
|     return Number.isNumeric(value) ? value : ' ' + Mapping.toVar(value) |     return Number.isNumeric(value) || /[-\d].*/.match(String(value)) ? value : ' ' + Mapping.toVar(value) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static toVar(value) { |   static toVar(value) { | ||||||
| @@ -327,7 +335,8 @@ export class Mapping { | |||||||
|     const txtByCategories = Object.values(byCategories) |     const txtByCategories = Object.values(byCategories) | ||||||
|       .map(it => it.competencesParNiveau) |       .map(it => it.competencesParNiveau) | ||||||
|       .map(byNiveau => { |       .map(byNiveau => { | ||||||
|         const niveaux = Object.keys(byNiveau).map(it => Number(it)).sort(Misc.ascending()) |         const niveaux = Object.keys(byNiveau) | ||||||
|  |           .map(it => Number(it)).sort(Misc.ascending()) | ||||||
|         if (niveaux.length == 0) { |         if (niveaux.length == 0) { | ||||||
|           return '' |           return '' | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ const PATHS = [ | |||||||
|  |  | ||||||
| const RANDOM_VALUES = { | const RANDOM_VALUES = { | ||||||
|   'system.sexe': { 'masculin': 1, 'féminin': 1 }, |   'system.sexe': { 'masculin': 1, 'féminin': 1 }, | ||||||
|   'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidectre': 6 }, |   'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidextre': 6 }, | ||||||
|   'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains clair': 5, 'blonds': 4, 'blonds très clair': 1, 'roux carotte': 1, 'roux cuivré': 3 }, |   'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains clair': 5, 'blonds': 4, 'blonds très clair': 1, 'roux carotte': 1, 'roux cuivré': 3 }, | ||||||
|   'system.yeux': { 'noirs': 2, 'noisettes': 3, 'bruns vert': 4, 'verts': 3, 'bleus clair': 3, 'bleus gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 }, |   'system.yeux': { 'noirs': 2, 'noisettes': 3, 'bruns vert': 4, 'verts': 3, 'bleus clair': 3, 'bleus gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 }, | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										433
									
								
								module/apps/rdd-import-stats.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										433
									
								
								module/apps/rdd-import-stats.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,433 @@ | |||||||
|  | /************************************************************************************/ | ||||||
|  | import "./xregexp-all.js"; | ||||||
|  | import { SystemCompendiums } from "../settings/system-compendiums.js"; | ||||||
|  | import { RdDBaseActorReve } from "../actor/base-actor-reve.js"; | ||||||
|  |  | ||||||
|  | /************************************************************************************/ | ||||||
|  | // Some internal test strings | ||||||
|  | let statBlock01 = `+$16(/, baron de Sylvedire, né à l’heure du | ||||||
|  | Roseau, 40 ans, 1m78, 65 kg, Beauté 13. | ||||||
|  | TAILLE | ||||||
|  |  10 | ||||||
|  |  Mêlée | ||||||
|  |  14 | ||||||
|  | APPARENCE | ||||||
|  |  13 | ||||||
|  |  Tir | ||||||
|  |  11 | ||||||
|  | CONSTITUTION | ||||||
|  |  12 | ||||||
|  |  Lancer | ||||||
|  |  11 | ||||||
|  | FORCE | ||||||
|  |  12 | ||||||
|  |  Dérobée | ||||||
|  |  13 | ||||||
|  | AGILITÉ | ||||||
|  |  16 | ||||||
|  |  Vie | ||||||
|  |  11 | ||||||
|  | DEXTÉRITÉ | ||||||
|  |  13 | ||||||
|  |  Endurance | ||||||
|  |  25 | ||||||
|  | VUE | ||||||
|  |  10 | ||||||
|  |  +dom | ||||||
|  |  0 | ||||||
|  | OUÏE | ||||||
|  |  11 | ||||||
|  |  Protection | ||||||
|  |  2 ou 4 | ||||||
|  | ODO-GOÛT | ||||||
|  |  9 | ||||||
|  |  cuir souple | ||||||
|  | VOLONTÉ | ||||||
|  |  14 | ||||||
|  |  ou cuir / métal | ||||||
|  | INTELLECT | ||||||
|  |  9 | ||||||
|  | EMPATHIE | ||||||
|  |  11 | ||||||
|  | RÊVE | ||||||
|  |  13 | ||||||
|  | CHANCE | ||||||
|  |  10 | ||||||
|  | niv | ||||||
|  |  init | ||||||
|  |  +dom | ||||||
|  | Épée dragonne | ||||||
|  |  +5 | ||||||
|  |  12 | ||||||
|  |  +3 | ||||||
|  | Hache de bataille | ||||||
|  |  +6 | ||||||
|  |  13 | ||||||
|  |  +3 | ||||||
|  | Bouclier moyen | ||||||
|  |  +5 | ||||||
|  | Dague mêlée | ||||||
|  |  +4 | ||||||
|  |  11 | ||||||
|  |  +1 | ||||||
|  | Corps à corps | ||||||
|  |  +4 | ||||||
|  |  11 | ||||||
|  |  (0) | ||||||
|  | Esquive | ||||||
|  |  +8 | ||||||
|  | Escalade +4 / Saut +5 / Commerce +3 / Équitation | ||||||
|  | +6 / Chirurgie 0 / Survie en extérieur +4 / Survie fo- | ||||||
|  | rêt +6 / Acrobatie -2 / Métallurgie +2 / Natation +3 / | ||||||
|  | Légendes -1 / Écriture -4  | ||||||
|  | `; | ||||||
|  |  | ||||||
|  | let statBlock02 = `/HVJDUGHV | ||||||
|  | TAILLE | ||||||
|  |  11 | ||||||
|  |  Mêlée | ||||||
|  |  12 | ||||||
|  | CONSTITUTION | ||||||
|  |  11 | ||||||
|  |  Tir | ||||||
|  |  11 | ||||||
|  | FORCE | ||||||
|  |  12 | ||||||
|  |  Lancer | ||||||
|  |  11 | ||||||
|  | AGILITÉ | ||||||
|  |  12 | ||||||
|  |  Dérobée | ||||||
|  |  11 | ||||||
|  | DEXTERITÉ | ||||||
|  |  11 | ||||||
|  |  Vie | ||||||
|  |  11 | ||||||
|  | VUE | ||||||
|  |  11 | ||||||
|  |  Endurance | ||||||
|  |  22 | ||||||
|  | OUÏE | ||||||
|  |  11 | ||||||
|  |  Vitesse | ||||||
|  |  12 | ||||||
|  | VOLONTÉ | ||||||
|  |  10 | ||||||
|  |  +dom | ||||||
|  |  0 | ||||||
|  | Protection | ||||||
|  |  4 | ||||||
|  | cuir / métal | ||||||
|  | niv | ||||||
|  |  init | ||||||
|  |  +dom | ||||||
|  | Hache de bataille | ||||||
|  |  +4 | ||||||
|  |  10 | ||||||
|  |  +3 | ||||||
|  | Bouclier moyen | ||||||
|  |  +4 | ||||||
|  | Dague mêlée | ||||||
|  |  +3 | ||||||
|  |  9 | ||||||
|  |  +1 | ||||||
|  | Arc | ||||||
|  |  +5 | ||||||
|  |  10 | ||||||
|  |  +2 | ||||||
|  | Corps à corps | ||||||
|  |  +3 | ||||||
|  |  9 | ||||||
|  |  (0) | ||||||
|  | Esquive avec armure | ||||||
|  |  +2 | ||||||
|  | Course +1/ Vigilance +4 | ||||||
|  | `; | ||||||
|  |  | ||||||
|  | let statBlock03 = `rencontres sont laissées à /HVFKLHQVORXSVGXEDURQ | ||||||
|  |  chaque gardien des rêves. | ||||||
|  | TAILLE | ||||||
|  |  8 | ||||||
|  |  Vie | ||||||
|  |  10 | ||||||
|  | CONSTITUTION FORCE | ||||||
|  |  12 | ||||||
|  |  11 | ||||||
|  |  Endurance | ||||||
|  |  Vitesse | ||||||
|  |  12/38 | ||||||
|  |  21 | ||||||
|  |  /HVFKLHQV]RPELV | ||||||
|  | PERCEPTION 13 | ||||||
|  |  +dom | ||||||
|  |  0 | ||||||
|  | VOLONTÉ | ||||||
|  |  10 | ||||||
|  |  Protection | ||||||
|  |  0 | ||||||
|  |  Les « monstres » apparaîtront un soir, durant | ||||||
|  | RÊVE | ||||||
|  |  10 | ||||||
|  |  l’heure du Serpent, et attaqueront les voya- | ||||||
|  | niv | ||||||
|  |  init | ||||||
|  |  +dom | ||||||
|  |  geurs à leur campement. Si ces derniers ne | ||||||
|  | Morsure | ||||||
|  |  13 | ||||||
|  |  +4 | ||||||
|  |  10 | ||||||
|  |  +1 | ||||||
|  |  campent pas, ils apparaîtront tout de même à | ||||||
|  | Esquive | ||||||
|  |  11 | ||||||
|  |  +3 | ||||||
|  |  l’heure du Serpent. Le feu ne les effraie pas. Ils | ||||||
|  | Course, Saut | ||||||
|  |  12 | ||||||
|  |  +3 | ||||||
|  |  ne sont pas très rapides, mais en revanche, très | ||||||
|  | Discrétion | ||||||
|  |  12 | ||||||
|  |  +3 | ||||||
|  |  silencieux : ils n’aboient pas. Les voyageurs | ||||||
|  | Vigilance | ||||||
|  |  13 | ||||||
|  |  +3 | ||||||
|  |  ` | ||||||
|  | // Skill parser depending on the type of actor | ||||||
|  | const compParser = { personnage: "\\s+(?<value>[\\+\\-]?\\d+)", creature: "\\s+(?<carac>\\d+)\\s+(?<value>[\\+\\-]?\\d+)\\s?(?<init>\\d+)?\\s+?(?<dommages>\\+\\d+)?" }; | ||||||
|  |  | ||||||
|  | // Main class for parsing a stat block | ||||||
|  | export class RdDStatBlockParser { | ||||||
|  |    | ||||||
|  |   static openInputDialog() { | ||||||
|  |     let dialog = new Dialog({ | ||||||
|  |       title: "Import de stats de PNJ/Créatures", | ||||||
|  |       content: ` | ||||||
|  |         <div> | ||||||
|  |           <p>Coller le texte de la stat ici</p> | ||||||
|  |           <textarea id="statBlock" style="width: 100%; height: 200px;"></textarea> | ||||||
|  |         </div> | ||||||
|  |       `, | ||||||
|  |       buttons: { | ||||||
|  |         ok: { | ||||||
|  |           label: "OK", | ||||||
|  |           callback: async (html) => { | ||||||
|  |             let statBlock = html.find("#statBlock")[0].value; | ||||||
|  |             await RdDStatBlockParser.parseStatBlock(statBlock); | ||||||
|  |             dialog.close(); | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         cancel: { | ||||||
|  |           label: "Cancel" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |     dialog.render(true); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   static fixWeirdPDF(statString) { | ||||||
|  |     // Split the statString into lines | ||||||
|  |     let lines = statString.split("\n"); | ||||||
|  |     let newLines = []; | ||||||
|  |     let index = 0; | ||||||
|  |     let nextType = "string"; | ||||||
|  |     // Loop through each line | ||||||
|  |     for (let i = 0; i < lines.length; i++) { | ||||||
|  |       // remove trailing spaces | ||||||
|  |       lines[i] = lines[i].trim(); | ||||||
|  |       // Is it text ?       | ||||||
|  |       if (lines[i].match(/^[a-zA-Zéêè\s]+/)) { | ||||||
|  |         if ( nextType == "string" ) {  | ||||||
|  |           newLines[index] = lines[i]; | ||||||
|  |           nextType = "number";   | ||||||
|  |         } else { | ||||||
|  |           console.log("Wrong sequence string detected...", lines[i], nextType); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       // Is it a number ? | ||||||
|  |       if (lines[i].match(/^[\d\s]+/)) { | ||||||
|  |         if ( nextType == "number" ) { | ||||||
|  |           newLines[index] = newLines[index] + lines[i]; | ||||||
|  |           nextType = "string"; | ||||||
|  |           index++; | ||||||
|  |         } else { | ||||||
|  |           console.log("Wrong sequence number detected...", lines[i], nextType); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   }   | ||||||
|  |    | ||||||
|  |   static async parseStatBlock(statString, type = "npc") { | ||||||
|  |  | ||||||
|  |     //statString = statBlock03; | ||||||
|  |     if (!statString) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Special function to fix strange/weird copy/paste from PDF readers | ||||||
|  |     // Unused up to now : this.fixWeirdPDF(statString); | ||||||
|  |  | ||||||
|  |     // Replace all endline by space in the statString | ||||||
|  |     statString = statString.replace(/\n/g, " "); | ||||||
|  |     // Remove all multiple spaces | ||||||
|  |     statString = statString.replace(/\s{2,}/g, " "); | ||||||
|  |     // Remove all leading and trailing spaces | ||||||
|  |     statString = statString.trim(); | ||||||
|  |  | ||||||
|  |     let actorType = "personnage"; | ||||||
|  |     let perception = XRegExp.exec(statString.toLowerCase(), XRegExp("perception\\s+(?<value>\\d+)", 'gi')); | ||||||
|  |     if (perception?.value ) {  | ||||||
|  |       actorType = "creature"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Now start carac  | ||||||
|  |     let actorData = foundry.utils.deepClone(game.model.Actor[actorType]);  | ||||||
|  |     for (let key in game.model.Actor.personnage.carac) { | ||||||
|  |       let caracDef = game.model.Actor.personnage.carac[key]; | ||||||
|  |       // Parse the stat string for each caracteristic | ||||||
|  |       let carac = XRegExp.exec(statString.toLowerCase(), XRegExp(caracDef.label.toLowerCase()+"\\s+(?<value>\\d+)", 'gi')); | ||||||
|  |       if (carac?.value) { | ||||||
|  |         actorData.carac[key].value = Number(carac.value); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // If creature we need to setup additionnal fields  | ||||||
|  |     if (actorType == "creature") { | ||||||
|  |       let plusDom  = XRegExp.exec(statString.toLowerCase(), XRegExp("\\+dom\\s+(?<value>\\+\\d+)", 'gi')); | ||||||
|  |       if (plusDom?.values) { | ||||||
|  |         actorData.attributs.plusdom.value = Number(plusDom.value); | ||||||
|  |       } | ||||||
|  |       let protection  = XRegExp.exec(statString.toLowerCase(), XRegExp("protection\\s+(?<value>\\d+)", 'gi')); | ||||||
|  |       if (protection?.value) { | ||||||
|  |         actorData.attributs.protection.value = Number(protection.value); | ||||||
|  |       } | ||||||
|  |       let endurance = XRegExp.exec(statString.toLowerCase(), XRegExp("endurance\\s+(?<value>\\d+)", 'gi')); | ||||||
|  |       if (endurance?.value) { | ||||||
|  |         actorData.sante.endurance.value = Number(endurance.value); | ||||||
|  |         actorData.sante.endurance.max = Number(endurance.value); | ||||||
|  |       } | ||||||
|  |       let vie = XRegExp.exec(statString.toLowerCase(), XRegExp("vie\\s+(?<value>\\d+)", 'gi')); | ||||||
|  |       if (vie.value) { | ||||||
|  |         actorData.sante.vie.value = Number(vie.value); | ||||||
|  |         actorData.sante.vie.max = Number(vie.value); | ||||||
|  |       } | ||||||
|  |       let vitesse = XRegExp.exec(statString.toLowerCase(), XRegExp("vitesse\\s+(?<value>[\\d\\/]+)", 'gi')); | ||||||
|  |       if (vitesse?.value) { | ||||||
|  |         actorData.attributs.vitesse.value = vitesse.value; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     let items = []; | ||||||
|  |     // Get skills from compendium  | ||||||
|  |     const competences = await SystemCompendiums.getCompetences(actorType); | ||||||
|  |     //console.log("Competences : ", competences); | ||||||
|  |     let allComp = competences.map(i => i.toObject()) | ||||||
|  |     for (let comp of allComp) { | ||||||
|  |       let skill = XRegExp.exec(statString.toLowerCase(), XRegExp(comp.name.toLowerCase()+compParser[actorType], 'gi')); | ||||||
|  |       if (skill) { | ||||||
|  |         comp.system.niveau = Number(skill.value); | ||||||
|  |         if (actorType == "creature") { | ||||||
|  |           comp.system.carac_value = Number(skill.carac); | ||||||
|  |           if (skill.init) { | ||||||
|  |             comp.system.dommages = Number(skill.dommages); | ||||||
|  |             comp.system.iscombat = true; | ||||||
|  |           } | ||||||
|  |           items.push(comp); // Only selective push | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       if (actorType == "personnage") { | ||||||
|  |         items.push(comp); // Always push | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Now process weapons | ||||||
|  |     const weapons = await SystemCompendiums.getWorldOrCompendiumItems("arme", "equipement") | ||||||
|  |     //console.log("Equipement : ", equipment); | ||||||
|  |     for (let w of weapons) { | ||||||
|  |        | ||||||
|  |       let weapon = XRegExp.exec(statString.toLowerCase(), XRegExp(w.name.toLowerCase()+"\\s+(?<value>\\+\\d+)", 'gi')); | ||||||
|  |       if (weapon) { | ||||||
|  |         w.system.equipe = true | ||||||
|  |         items.push(w.toObject()); | ||||||
|  |         // now process the skill | ||||||
|  |         if ( w.system?.competence != "") { | ||||||
|  |           let wComp = items.find(i => i.name.toLowerCase() == w.system.competence.toLowerCase());   | ||||||
|  |           if (wComp) { | ||||||
|  |             wComp.system.niveau = Number(weapon.value); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         if ( w.system?.tir != "") { | ||||||
|  |           let wComp = items.find(i => i.name.toLowerCase() == w.system.tir.toLowerCase());   | ||||||
|  |           if (wComp) { | ||||||
|  |             wComp.system.niveau = Number(weapon.value); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         if ( w.system?.lancer != "") { | ||||||
|  |           let wComp = items.find(i => i.name.toLowerCase() == w.system.lancer.toLowerCase());   | ||||||
|  |           if (wComp) { | ||||||
|  |             wComp.system.niveau = Number(weapon.value); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Now process armors | ||||||
|  |     const armors = await SystemCompendiums.getWorldOrCompendiumItems("armure", "equipement") | ||||||
|  |     for (let a of armors) {     | ||||||
|  |       let armor = XRegExp.exec(statString.toLowerCase(), XRegExp(a.name.toLowerCase(), 'gi')); | ||||||
|  |       if (armor) { | ||||||
|  |         a.system.equipe = true | ||||||
|  |         items.push(a.toObject()); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Get hour name : heure du XXXXX | ||||||
|  |     let heure = XRegExp.exec(statString.toLowerCase(), XRegExp("heure du\\s+(?<value>\\w+)", 'gi')); | ||||||
|  |     if (heure?.value) { | ||||||
|  |       actorData.heure = heure.value;   | ||||||
|  |     } | ||||||
|  |     // Get age | ||||||
|  |     let age = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>\\d+) ans", 'gi')); | ||||||
|  |     if (age?.value) { | ||||||
|  |       actorData.age = Number(age.value);   | ||||||
|  |     } | ||||||
|  |     // Get height | ||||||
|  |     let taille = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>\\d+)m\\d+", 'gi')); | ||||||
|  |     if (taille?.value) { | ||||||
|  |       actorData.taille = taille.value;   | ||||||
|  |     } | ||||||
|  |     // Get weight | ||||||
|  |     let poids = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>\\d+) kg", 'gi')); | ||||||
|  |     if (poids?.value) { | ||||||
|  |       actorData.poids = poids.value;   | ||||||
|  |     } | ||||||
|  |     // Get beauty | ||||||
|  |     let beaute = XRegExp.exec(statString.toLowerCase(), XRegExp("beauté\\s+(?<value>\\d+)", 'gi')); | ||||||
|  |     if (beaute?.value) { | ||||||
|  |       actorData.beaute = Number(beaute.value);   | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Name is all string before ', né' | ||||||
|  |     let name | ||||||
|  |     if (actorType == "personnage") { | ||||||
|  |       name = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>[\\w\\s\\d]+),", 'gi')); | ||||||
|  |       if (!name?.value) { | ||||||
|  |         name = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>.+)\\s+taille", 'gi')); | ||||||
|  |       } | ||||||
|  |       name = name?.value || "Importé"; | ||||||
|  |     } | ||||||
|  |     if (actorType == "creature") { | ||||||
|  |       name = XRegExp.exec(statString.toLowerCase(), XRegExp("(?<value>.+)\\s+taille", 'gi')); | ||||||
|  |       name = name?.value || "Importé"; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     let newActor = RdDBaseActorReve.create({name: name || "Importé", type:actorType, system: actorData, items: items}); | ||||||
|  |  | ||||||
|  |     // DUmp.... | ||||||
|  |     console.log(actorData); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										8225
									
								
								module/apps/xregexp-all.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8225
									
								
								module/apps/xregexp-all.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -49,7 +49,7 @@ export class ChatUtility { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static onRemoveMessages(socketData) { |   static onRemoveMessages(socketData) { | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       if (socketData.part) { |       if (socketData.part) { | ||||||
|         const toDelete = game.messages.filter(it => it.content.includes(socketData.part)); |         const toDelete = game.messages.filter(it => it.content.includes(socketData.part)); | ||||||
|         toDelete.forEach(it => it.delete()); |         toDelete.forEach(it => it.delete()); | ||||||
| @@ -63,7 +63,7 @@ export class ChatUtility { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|  |  | ||||||
|   static removeMessages(socketData) { |   static removeMessages(socketData) { | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       ChatUtility.onRemoveMessages(socketData); |       ChatUtility.onRemoveMessages(socketData); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
| @@ -161,7 +161,7 @@ export class ChatUtility { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static handleGMChatMessage(socketData) { |   static handleGMChatMessage(socketData) { | ||||||
|     console.log("blindMessageToGM", socketData); |     console.log("blindMessageToGM", socketData); | ||||||
|     if (Misc.firstConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       ChatMessage.create({ |       ChatMessage.create({ | ||||||
|         user: game.user.id, |         user: game.user.id, | ||||||
|         whisper: ChatUtility.getGMs(), |         whisper: ChatUtility.getGMs(), | ||||||
|   | |||||||
| @@ -51,7 +51,7 @@ export class DialogCreateSigneDraconique extends Dialog { | |||||||
|       whisper: ChatUtility.getOwners(actor), |       whisper: ChatUtility.getOwners(actor), | ||||||
|       content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", { |       content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", { | ||||||
|         signe: signe, |         signe: signe, | ||||||
|         alias: actor.name |         alias: actor.getAlias() | ||||||
|       }) |       }) | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -8,14 +8,13 @@ import { RdDUtility } from "./rdd-utility.js"; | |||||||
| export class DialogValidationEncaissement extends Dialog { | export class DialogValidationEncaissement extends Dialog { | ||||||
|  |  | ||||||
|   static async validerEncaissement(actor, rollData, armure, onEncaisser) { |   static async validerEncaissement(actor, rollData, armure, onEncaisser) { | ||||||
|     let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE }); |     const encaissement = await RdDUtility.jetEncaissement(actor, rollData, armure, { showDice: HIDE_DICE }); | ||||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', { |     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', { | ||||||
|       actor: actor, |       actor: actor, | ||||||
|       rollData: rollData, |       rollData: rollData, | ||||||
|       encaissement: encaissement |       encaissement: encaissement | ||||||
|     }); |     }); | ||||||
|     const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser); |     new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser).render(true); | ||||||
|     dialog.render(true); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -56,14 +55,14 @@ export class DialogValidationEncaissement extends Dialog { | |||||||
|     this.html = html; |     this.html = html; | ||||||
|     this.html.find('input.encaissement-roll-result').keyup(async event => { |     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.actor, this.rollData, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult}); | ||||||
|       this.html.find('label.encaissement-total').text(this.encaissement.total); |       this.html.find('label.encaissement-total').text(this.encaissement.total); | ||||||
|       this.html.find('label.encaissement-blessure').text(this.encaissement.blessures) |       this.html.find('label.encaissement-blessure').text(this.encaissement.blessures) | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async onValider() { |   async onValider() { | ||||||
|     this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult}); |     this.encaissement = await RdDUtility.jetEncaissement(this.actor, this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult}); | ||||||
|     this.onEncaisser(this.encaissement) |     this.onEncaisser(this.encaissement) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ export class Grammar { | |||||||
|   } |   } | ||||||
|    |    | ||||||
|   static includesLowerCaseNoAccent(value, content) { |   static includesLowerCaseNoAccent(value, content) { | ||||||
|     return Grammar.toLowerCaseNoAccent(value).includes(Grammar.toLowerCaseNoAccent(content)); |     return Grammar.toLowerCaseNoAccent(value)?.includes(Grammar.toLowerCaseNoAccent(content)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -1,10 +1,11 @@ | |||||||
|  | import { Grammar } from "./grammar.js"; | ||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js" | import { RdDItemCompetenceCreature } from "./item-competencecreature.js" | ||||||
| import { ITEM_TYPES } from "./item.js"; | import { ITEM_TYPES } from "./item.js"; | ||||||
| import { RdDCombatManager } from "./rdd-combat.js"; | import { RdDCombatManager } from "./rdd-combat.js"; | ||||||
|  |  | ||||||
| const nomCategorieParade = { | const nomCategorieParade = { | ||||||
|   "sans-armes": "Sans arme", |   "sans-armes": "Sans arme", | ||||||
|   "armes-naturelles": "Sans arme", |   "armes-naturelles": "Armes naturelles", | ||||||
|   "hast": "Armes d'hast", |   "hast": "Armes d'hast", | ||||||
|   "batons": "Bâtons", |   "batons": "Bâtons", | ||||||
|   "boucliers": "Boucliers", |   "boucliers": "Boucliers", | ||||||
| @@ -30,7 +31,7 @@ export class RdDItemArme extends Item { | |||||||
|       case ITEM_TYPES.competencecreature: |       case ITEM_TYPES.competencecreature: | ||||||
|         return RdDItemCompetenceCreature.armeCreature(arme); |         return RdDItemCompetenceCreature.armeCreature(arme); | ||||||
|     } |     } | ||||||
|     return RdDItemArme.mainsNues(); |     return RdDItemArme.corpsACorps(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getCompetenceArme(arme, maniement) { |   static getCompetenceArme(arme, maniement) { | ||||||
| @@ -56,8 +57,8 @@ export class RdDItemArme extends Item { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static niveauCompetenceArme(arme, competences) { |   static niveauCompetenceArme(arme, competences) { | ||||||
|     const compArme = competences.find(it => it.name == arme.system.competence); |     const compArme = competences.find(it => Grammar.equalsInsensitive(it.name, arme.system.competence)) | ||||||
|     return compArme?.system.niveau ?? -8; |     return compArme?.system.niveau ?? -8 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -81,37 +82,59 @@ export class RdDItemArme extends Item { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static getCategorieParade(armeData) { |   static getCategorieParade(armeData) { | ||||||
|     if (armeData.system.categorie_parade) { |     if (armeData.system.categorie_parade) { | ||||||
|       return armeData.system.categorie_parade; |       return armeData.system.categorie_parade | ||||||
|     } |     } | ||||||
|     // pour compatibilité avec des personnages existants |     // pour compatibilité avec des personnages existants | ||||||
|     if (armeData.type == ITEM_TYPES.competencecreature || armeData.system.categorie == 'creature') { |     if (armeData.type == ITEM_TYPES.competencecreature || armeData.system.categorie == 'creature') { | ||||||
|       return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : ''); |       return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : '') | ||||||
|     } |     } | ||||||
|     if (!armeData.type.match(/arme|competencecreature/)) { |     if (!armeData.type.match(/arme|competencecreature/)) { | ||||||
|       return ''; |       return '' | ||||||
|     } |     } | ||||||
|     if (armeData.system.competence == undefined) { |     if (armeData.system.competence == undefined) { | ||||||
|       return ITEM_TYPES.competencecreature; |       return ITEM_TYPES.competencecreature; | ||||||
|     } |     } | ||||||
|     let compname = armeData.system.competence.toLowerCase(); |     let compname = armeData.system.competence.toLowerCase(); | ||||||
|     if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) return ''; |     if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) { | ||||||
|  |       return '' | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (compname.match('hache')) return 'haches'; |     if (compname.match('hache')) return 'haches' | ||||||
|     if (compname.match('hast')) return 'hast'; |     if (compname.match('hast')) return 'hast' | ||||||
|     if (compname.match('lance')) return 'lances'; |     if (compname.match('lance')) return 'lances' | ||||||
|     if (compname.match('bouclier')) return 'boucliers'; |     if (compname.match('bouclier')) return 'boucliers' | ||||||
|     if (compname.match('masse')) return 'masses'; |     if (compname.match('masse')) return 'masses' | ||||||
|     if (compname.match('epée') || compname.match('épée')) { |     if (compname.match('epée') || compname.match('épée')) { | ||||||
|       if (armeData.name.toLowerCase().match(/(gnome)/)) |       if (armeData.name.toLowerCase().match(/(gnome)/)) | ||||||
|         return 'epees-courtes'; |         return 'epees-courtes' | ||||||
|       if (armeData.name.toLowerCase().match(/((e|é)pée dragone|esparlongue|demi-dragonne)/)) |       if (armeData.name.toLowerCase().match(/((e|é)pée dragone|esparlongue|demi-dragonne)/)) | ||||||
|         return 'epees-longues'; |         return 'epees-longues' | ||||||
|       return 'epees-lourdes'; |       return 'epees-lourdes' | ||||||
|     } |     } | ||||||
|     if (compname.match('dague')) { |     if (compname.match('dague')) { | ||||||
|       return 'dagues'; |       return 'dagues' | ||||||
|  |     } | ||||||
|  |     return 'sans-armes' | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static defenseArmeParade(armeAttaque, armeParade) { | ||||||
|  |     const defCategory = RdDItemArme.getCategorieParade(armeParade) | ||||||
|  |     if (defCategory == 'bouclier') { | ||||||
|  |       return 'norm' | ||||||
|  |     } | ||||||
|  |     if (armeAttaque.system.competence.toLowerCase().match(/(fléau)/)) { | ||||||
|  |       return '' | ||||||
|  |     } | ||||||
|  |     if (armeParade.system.tir) { | ||||||
|  |       return '' | ||||||
|  |     } | ||||||
|  |     const attCategory = RdDItemArme.getCategorieParade(armeAttaque) | ||||||
|  |     switch (attCategory) { | ||||||
|  |       case 'armes-naturelles': case 'sans-armes': | ||||||
|  |         return defCategory == 'sans-armes' ? 'norm' : '' | ||||||
|  |       default: | ||||||
|  |         return RdDItemArme.needParadeSignificative(armeAttaque, armeParade) ? 'sign' : 'norm' | ||||||
|     } |     } | ||||||
|     return 'sans-armes'; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -120,8 +143,8 @@ export class RdDItemArme extends Item { | |||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|     // categories d'armes à la parade (cf. page 115 ) |     // categories d'armes à la parade (cf. page 115 ) | ||||||
|     let attCategory = RdDItemArme.getCategorieParade(armeAttaque); |     const attCategory = RdDItemArme.getCategorieParade(armeAttaque) | ||||||
|     let defCategory = RdDItemArme.getCategorieParade(armeParade); |     const defCategory = RdDItemArme.getCategorieParade(armeParade) | ||||||
|     // bouclier et mêmes catégorie: peuvent se parer sans difficulté |     // bouclier et mêmes catégorie: peuvent se parer sans difficulté | ||||||
|     if (defCategory == 'boucliers') { |     if (defCategory == 'boucliers') { | ||||||
|       return false; |       return false; | ||||||
| @@ -184,7 +207,7 @@ export class RdDItemArme extends Item { | |||||||
|     return arme.system.competence.replace(" 1 main", " 2 mains"); |     return arme.system.competence.replace(" 1 main", " 2 mains"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static isArmeUtilisable(arme) { |   static isUtilisable(arme) { | ||||||
|     switch (arme.type) { |     switch (arme.type) { | ||||||
|       case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0) |       case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0) | ||||||
|       case ITEM_TYPES.competencecreature: return true |       case ITEM_TYPES.competencecreature: return true | ||||||
| @@ -192,9 +215,24 @@ export class RdDItemArme extends Item { | |||||||
|     return false |     return false | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static ajoutCorpsACorps(armes, actor) { |   static isAttaque(arme) { | ||||||
|     armes.push(RdDItemArme.mainsNues(actor)); |     switch (arme.type) { | ||||||
|     armes.push(RdDItemArme.empoignade(actor)); |       case ITEM_TYPES.arme: | ||||||
|  |         return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0) | ||||||
|  |       case ITEM_TYPES.competencecreature: | ||||||
|  |         return arme.system.iscombat && RdDItemCompetenceCreature.isAttaque(item) | ||||||
|  |     } | ||||||
|  |     return false | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static isParade(arme) { | ||||||
|  |     switch (arme.type) { | ||||||
|  |       case ITEM_TYPES.arme: | ||||||
|  |         return arme.system.equipe && arme.system.resistance > 0 && true/* TODO: regarder la categorie d'arme?*/ | ||||||
|  |       case ITEM_TYPES.competencecreature: | ||||||
|  |         return arme.system.iscombat && RdDItemCompetenceCreature.isParade(arme) | ||||||
|  |     } | ||||||
|  |     return false | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static corpsACorps(actor) { |   static corpsACorps(actor) { | ||||||
| @@ -215,6 +253,8 @@ export class RdDItemArme extends Item { | |||||||
|         mortalite: 'non-mortel', |         mortalite: 'non-mortel', | ||||||
|         competence: 'Corps à corps', |         competence: 'Corps à corps', | ||||||
|         resistance: 1, |         resistance: 1, | ||||||
|  |         baseInit: 4, | ||||||
|  |         cac: 'pugilat', | ||||||
|         deuxmains: true, |         deuxmains: true, | ||||||
|         categorie_parade: 'sans-armes' |         categorie_parade: 'sans-armes' | ||||||
|       } |       } | ||||||
| @@ -224,8 +264,6 @@ export class RdDItemArme extends Item { | |||||||
|   static mainsNues(actor) { |   static mainsNues(actor) { | ||||||
|     const mainsNues = RdDItemArme.corpsACorps(actor) |     const mainsNues = RdDItemArme.corpsACorps(actor) | ||||||
|     mainsNues.name = 'Mains nues' |     mainsNues.name = 'Mains nues' | ||||||
|     mainsNues.system.cac = 'pugilat' |  | ||||||
|     mainsNues.system.baseInit = 4 |  | ||||||
|     return mainsNues; |     return mainsNues; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -190,7 +190,7 @@ export class RdDItemCompetence extends Item { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static isNiveauBase(item) { |   static isNiveauBase(item) { | ||||||
|     return Number(item.system.niveau) == RdDItemCompetence.getNiveauBase(item.system.categorie, item.type); |     return item.system.niveau == undefined || Number(item.system.niveau) == RdDItemCompetence.getNiveauBase(item.system.categorie, item.type); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -27,40 +27,29 @@ export class RdDItemCompetenceCreature extends Item { | |||||||
|   static armeCreature(item) { |   static armeCreature(item) { | ||||||
|     const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item) |     const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item) | ||||||
|     if (categorieAttaque != undefined) { |     if (categorieAttaque != undefined) { | ||||||
|       // si c'est un Item compétence: cloner pour ne pas modifier la compétence |       // cloner pour ne pas modifier la compétence | ||||||
|       let arme = item.clone(); |       return foundry.utils.mergeObject(item, { | ||||||
|       return foundry.utils.mergeObject(arme, { |  | ||||||
|           action: item.isCompetencePossession() ? 'possession' : 'attaque', |           action: item.isCompetencePossession() ? 'possession' : 'attaque', | ||||||
|           system: { |           system: { | ||||||
|             competence: arme.name, |             competence: item.name, | ||||||
|             cac: categorieAttaque == "naturelle" ? "naturelle" : "", |             cac: categorieAttaque == "naturelle" ? "naturelle" : "", | ||||||
|             niveau: item.system.niveau, |             niveau: item.system.niveau, | ||||||
|             initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value), |             initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value), | ||||||
|             equipe: true, |             equipe: true, | ||||||
|             resistance: 100, |             resistance: 100, | ||||||
|             dommagesReels: arme.system.dommages, |             dommagesReels: item.system.dommages, | ||||||
|             penetration: 0, |             penetration: 0, | ||||||
|             force: 0, |             force: 0, | ||||||
|             rapide: true, |             rapide: true, | ||||||
|           } |           } | ||||||
|         }, { inplace: false }); |         }, { inplace: false, }); | ||||||
|     } |     } | ||||||
|     return undefined; |     return undefined; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static isCompetenceAttaque(item) { |   static isAttaque(item) { | ||||||
|     if (item.type == ITEM_TYPES.competencecreature) { |     return RdDItemCompetenceCreature.getCategorieAttaque(item) != undefined | ||||||
|       switch (item.system.categorie) { |  | ||||||
|         case "melee": |  | ||||||
|         case "tir": |  | ||||||
|         case "lancer": |  | ||||||
|         case "naturelle": |  | ||||||
|         case "possession": |  | ||||||
|           return true |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     return undefined |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getCategorieAttaque(item) { |   static getCategorieAttaque(item) { | ||||||
| @@ -71,12 +60,12 @@ export class RdDItemCompetenceCreature extends Item { | |||||||
|         case "lancer": |         case "lancer": | ||||||
|         case "naturelle": |         case "naturelle": | ||||||
|         case "possession": |         case "possession": | ||||||
|         case "parade": |  | ||||||
|           return item.system.categorie |           return item.system.categorie | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static isDommages(item) { |   static isDommages(item) { | ||||||
|     if (item.type == ITEM_TYPES.competencecreature) { |     if (item.type == ITEM_TYPES.competencecreature) { | ||||||
|       switch (item.system.categorie) { |       switch (item.system.categorie) { | ||||||
| @@ -89,20 +78,12 @@ export class RdDItemCompetenceCreature extends Item { | |||||||
|     } |     } | ||||||
|     return false |     return false | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static isParade(item) { |   static isParade(item) { | ||||||
|     if (item.type == ITEM_TYPES.competencecreature) { |     if (item.type == ITEM_TYPES.competencecreature) { | ||||||
|       switch (item.system.categorie) { |       return armeData.system.categorie_parade || armeData.system.isparade | ||||||
|         case "melee": |  | ||||||
|         case "naturelle": |  | ||||||
|         case "parade": |  | ||||||
|           return true |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     return false |     return false | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static isCompetenceParade(item) { |  | ||||||
|     return item.type == 'competencecreature' && item.system.categorie_parade !== ""; |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -267,10 +267,17 @@ export class RdDItemSheet extends ItemSheet { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   /** @override */ |   /** @override */ | ||||||
|   _updateObject(event, formData) { |   _updateObject(event, formData) { | ||||||
|     if (this.item.type == 'sort') { |     switch (this.item.type) { | ||||||
|  |       case ITEM_TYPES.sort: | ||||||
|         // Données de bonus de cases ? |         // Données de bonus de cases ? | ||||||
|       formData['system.bonuscase'] = RdDItemSort.buildBonuscaseFromArrays(formData.bonusValue, formData.caseValue); |         formData['system.bonuscase'] = RdDItemSort.buildBonuscaseFromArrays(formData.bonusValue, formData.caseValue) | ||||||
|  |         break | ||||||
|  |       case ITEM_TYPES.competence: | ||||||
|  |         if (formData['system.niveau'] == undefined) { | ||||||
|  |           formData['system.niveau'] = formData['system.base'] | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     return this.item.update(formData); |     return this.item.update(formData); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,15 +16,17 @@ const VOIES_DRACONIC = [ | |||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RdDItemSort extends Item { | export class RdDItemSort extends Item { | ||||||
|  |  | ||||||
|   static getDraconicsSort(draconicList, sort) { |   static getDraconicsSort(competencesDraconic, sort) { | ||||||
|  |     // se baser sur la voie du sort? | ||||||
|     switch (Grammar.toLowerCaseNoAccent(sort.name)) { |     switch (Grammar.toLowerCaseNoAccent(sort.name)) { | ||||||
|       case "lecture d'aura": |       case "lecture d'aura": | ||||||
|       case "detection d'aura": |       case "detection d'aura": | ||||||
|         return draconicList; |         return competencesDraconic; | ||||||
|       case "annulation de magie": |       case "annulation de magie": | ||||||
|         return draconicList.filter(it => !RdDItemCompetence.isThanatos(it)); |         return competencesDraconic.filter(it => !RdDItemCompetence.isThanatos(it)); | ||||||
|     } |     } | ||||||
|     return [RdDItemCompetence.getVoieDraconic(draconicList, sort.system.draconic)]; |     const voies = sort.system.draconic.split('/') | ||||||
|  |     return voies.map(voie => RdDItemCompetence.getVoieDraconic(competencesDraconic, voie)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getOrdreCode(code) { |   static getOrdreCode(code) { | ||||||
| @@ -47,7 +49,6 @@ export class RdDItemSort extends Item { | |||||||
|     return voie?.code ?? sort.system.draconic |     return voie?.code ?? sort.system.draconic | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   static $voiesConnues(voiesSort, voies) { |   static $voiesConnues(voiesSort, voies) { | ||||||
|     const codes = voies.filter(it => voiesSort.includes(it)) |     const codes = voies.filter(it => voiesSort.includes(it)) | ||||||
|       .sort(Misc.ascending(it => RdDItemSort.getOrdreCode(it))) |       .sort(Misc.ascending(it => RdDItemSort.getOrdreCode(it))) | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async createBlessure(actor, gravite, localisation = '', attacker) { |   static async createBlessure(actor, gravite, localisation = '', attackerToken) { | ||||||
|     const definition = RdDItemBlessure.getDefinition(gravite) |     const definition = RdDItemBlessure.getDefinition(gravite) | ||||||
|     const blessure = { |     const blessure = { | ||||||
|       name: definition.label, |       name: definition.label, | ||||||
| @@ -77,7 +77,7 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|         gravite: gravite, |         gravite: gravite, | ||||||
|         difficulte: - gravite, |         difficulte: - gravite, | ||||||
|         localisation: localisation, |         localisation: localisation, | ||||||
|         origine: attacker?.name ?? "" |         origine: attackerToken?.name ?? "" | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) |     const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) | ||||||
|   | |||||||
| @@ -139,7 +139,7 @@ export class Misc { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static join(params, separator = '') { |   static join(params, separator = '') { | ||||||
|     return params?.reduce(Misc.joining(separator)) ?? ''; |     return (!params || params.length == 0) ? '' : params.reduce(Misc.joining(separator)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static joining(separator = '') { |   static joining(separator = '') { | ||||||
| @@ -189,13 +189,7 @@ export class Misc { | |||||||
|    *  and there is no connected GM |    *  and there is no connected GM | ||||||
|    */ |    */ | ||||||
|   static documentIfResponsible(document) { |   static documentIfResponsible(document) { | ||||||
|     if (foundry.utils.isNewerVersion(game.release.version, '12.0')) { |     if (Misc.isFirstConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isFirstOwnerPlayer(document))) { | ||||||
|       if (game.users.activeGM || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document))) |  | ||||||
|       { |  | ||||||
|         return document |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     else if (Misc.isUniqueConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document))) { |  | ||||||
|       return document |       return document | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
| @@ -205,15 +199,22 @@ export class Misc { | |||||||
|     return document.testUserPermission && document.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) |     return document.testUserPermission && document.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static isFirstOwnerPlayer(document) { | ||||||
|  |     if (!document.testUserPermission){ | ||||||
|  |       return false | ||||||
|  |     } | ||||||
|  |     return game.users.filter(u => document.testUserPermission(u, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) == game.user | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static isOwnerPlayerOrUniqueConnectedGM(actor) { |   static isOwnerPlayerOrUniqueConnectedGM(actor) { | ||||||
|     return Misc.isOwnerPlayer(actor) ?? Misc.isUniqueConnectedGM(); |     return Misc.isFirstOwnerPlayer(actor) ?? Misc.isFirstConnectedGM(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * @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 isFirstConnectedGM() { | ||||||
|     return game.user.id == Misc.firstConnectedGMId(); |     return game.user == Misc.firstConnectedGM(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static firstConnectedGMId() { |   static firstConnectedGMId() { | ||||||
|   | |||||||
| @@ -53,9 +53,14 @@ export class RdDCarac { | |||||||
|     return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/); |     return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * L’appel à la chance n’est possible que pour recommencer les jets d’actions physiques : | ||||||
|  |    * tous les jets de combat, de FORCE, d’AGILITÉ, de DEXTÉRITÉ, de Dérobée, d’APPARENCE, | ||||||
|  |    * ainsi que de Perception active et volontaire. | ||||||
|  |    */ | ||||||
|   static isActionPhysique(selectedCarac) { |   static isActionPhysique(selectedCarac) { | ||||||
|     return !selectedCarac || |     return Grammar.toLowerCaseNoAccent(selectedCarac?.label) | ||||||
|       selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/); |       ?.match(/(apparence|force|agilite|dexterite|vue|ouie|gout|odorat|empathie|melee|tir|lancer|derobee)/) != null | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getCaracDerivee(value) { |   static getCaracDerivee(value) { | ||||||
| @@ -90,15 +95,4 @@ export class RdDCarac { | |||||||
|   static getCaracXp(targetValue) { |   static getCaracXp(targetValue) { | ||||||
|     return RdDCarac.getCaracDerivee(targetValue)?.xp ?? 200; |     return RdDCarac.getCaracDerivee(targetValue)?.xp ?? 200; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * L’appel à la chance n’est possible que pour recommencer les jets d’actions physiques : |  | ||||||
|    * tous les jets de combat, de FORCE, d’AGILITÉ, de DEXTÉRITÉ, de Dérobée, d’APPARENCE, |  | ||||||
|    * ainsi que de Perception active et volontaire. |  | ||||||
|    */ |  | ||||||
|   static isActionPhysique(selectedCarac) { |  | ||||||
|     return Grammar.toLowerCaseNoAccent(selectedCarac?.label)?.match(/(apparence|force|agilite|dexterite|vue|ouie|odorat|empathie|melee|tir|lancer|derobee)/); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -42,7 +42,8 @@ export class RdDCombatManager extends Combat { | |||||||
|     /* -------------------------------------------- */ |     /* -------------------------------------------- */ | ||||||
|     Hooks.on("getCombatTrackerEntryContext", (html, options) => { RdDCombatManager.pushInitiativeOptions(html, options); }); |     Hooks.on("getCombatTrackerEntryContext", (html, options) => { RdDCombatManager.pushInitiativeOptions(html, options); }); | ||||||
|     Hooks.on("updateCombat", (combat, change, options, userId) => { RdDCombat.onUpdateCombat(combat, change, options, userId) }); |     Hooks.on("updateCombat", (combat, change, options, userId) => { RdDCombat.onUpdateCombat(combat, change, options, userId) }); | ||||||
|     Hooks.on("preDeleteCombat", (combat, html, id) => { combat.onPreDeleteCombat() }); |     Hooks.on("preDeleteCombat", (combat, html, id) => { combat.onPreDeleteCombat() }) | ||||||
|  |     Hooks.on("deleteCombat", (combat, html, id) => { combat.onDeleteCombat() }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -53,7 +54,7 @@ export class RdDCombatManager extends Combat { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onPreDeleteCombat() { |   async onPreDeleteCombat() { | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       await this.finDeRound({ terminer: true }) |       await this.finDeRound({ terminer: true }) | ||||||
|       ChatUtility.removeChatMessageContaining(`<div data-combatid="${this.id}" data-combatmessage="actor-turn-summary">`) |       ChatUtility.removeChatMessageContaining(`<div data-combatid="${this.id}" data-combatmessage="actor-turn-summary">`) | ||||||
|       game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined) |       game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined) | ||||||
| @@ -61,20 +62,40 @@ export class RdDCombatManager extends Combat { | |||||||
|       RdDEmpoignade.deleteAllEmpoignades() |       RdDEmpoignade.deleteAllEmpoignades() | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |   async onDeleteCombat() { | ||||||
|  |     if (Misc.isFirstConnectedGM()) { | ||||||
|  |       if (game.combats.size <= 1) { | ||||||
|  |         game.actors.forEach(actor => actor.resetItemUse()) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async finDeRound(options = { terminer: false }) { |   async finDeRound(options = { terminer: false }) { | ||||||
|     this.turns.forEach(turn => turn.actor.resetItemUse()); |     this.combatants.map(it => RdDCombatManager.getActorCombatant(it, { warning: false })) | ||||||
|  |       .filter(it => it != undefined) | ||||||
|     for (let combatant of this.combatants) { |       .forEach(async actor => { | ||||||
|       if (combatant.actor) { |         await actor.finDeRound(options) | ||||||
|         await combatant.actor.finDeRound(options); |         await actor.resetItemUse() | ||||||
|  |       }) | ||||||
|   } |   } | ||||||
|       else { |  | ||||||
|  |   static getActorCombatant(combatant, options = { warning: true }) { | ||||||
|  |     if (!combatant.actor) { | ||||||
|  |       if (options.warning) { | ||||||
|         ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur!`) |         ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur!`) | ||||||
|       } |       } | ||||||
|  |       return undefined | ||||||
|     } |     } | ||||||
|  |     else if (!combatant.actor.isActorCombat()) { | ||||||
|  |       if (options.warning) { | ||||||
|  |         ui.notifications.warn(`${combatant.name} ne peut pas combattre!`) | ||||||
|       } |       } | ||||||
|  |       return undefined | ||||||
|  |     } | ||||||
|  |     return combatant.actor | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static calculAjustementInit(actor, arme) { |   static calculAjustementInit(actor, arme) { | ||||||
|     const efficacite = (arme?.system.magique) ? arme.system.ecaille_efficacite : 0 |     const efficacite = (arme?.system.magique) ? arme.system.ecaille_efficacite : 0 | ||||||
|     const etatGeneral = actor.getEtatGeneral() ?? 0 |     const etatGeneral = actor.getEtatGeneral() ?? 0 | ||||||
| @@ -83,57 +104,27 @@ export class RdDCombatManager extends Combat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /************************************************************************************/ |   /************************************************************************************/ | ||||||
|   async rollInitiative(ids, formula = undefined, messageOptions = {}) { |   async rollInitiative(ids, messageOptions = {}) { | ||||||
|     console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions); |     console.log(`${game.system.title} | Combat.rollInitiative()`, ids, messageOptions) | ||||||
|  |     ids = typeof ids === "string" ? [ids] : ids | ||||||
|  |     ids.forEach(async id => | ||||||
|  |       await this.rollInitRdD(id, undefined, messageOptions) | ||||||
|  |     ) | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  |  | ||||||
|     ids = typeof ids === "string" ? [ids] : ids; |   async rollInitRdD(id, formula, messageOptions = {}) { | ||||||
|     // calculate initiative |     const combatant = this.combatants.get(id); | ||||||
|     for (let cId = 0; cId < ids.length; cId++) { |     const actor = RdDCombatManager.getActorCombatant(combatant) | ||||||
|       const combatant = this.combatants.get(ids[cId]); |     if (actor) { | ||||||
|       const ajustement = RdDCombatManager.calculAjustementInit(combatant.actor, undefined); |       const rollFormula = formula ?? RdDCombatManager.getFirstInitRollFormula(actor) | ||||||
|       let rollFormula = formula ?? RdDCombatManager.formuleInitiative(2, 10, 0, ajustement); |  | ||||||
|  |  | ||||||
|       if (!formula) { |  | ||||||
|         if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') { |  | ||||||
|           const competence = combatant.actor.items.find(it => RdDItemCompetenceCreature.isCompetenceAttaque(it)) |  | ||||||
|           if (competence) { |  | ||||||
|             rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, etatGeneral); |  | ||||||
|           } |  | ||||||
|         } else { |  | ||||||
|           const armeCombat = combatant.actor.itemTypes['arme'].find(it => it.system.equipe) |  | ||||||
|           let compName = "Corps à corps" |  | ||||||
|           if (armeCombat) { |  | ||||||
|             if (armeCombat.system.competence != "") { |  | ||||||
|               compName = armeCombat.system.competence |  | ||||||
|             } |  | ||||||
|             if (armeCombat.system.lancer != "") { |  | ||||||
|               compName = armeCombat.system.lancer |  | ||||||
|             } |  | ||||||
|             if (armeCombat.system.tir != "") { |  | ||||||
|               compName = armeCombat.system.tir |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|           const competence = RdDItemCompetence.findCompetence(combatant.actor.items, compName); |  | ||||||
|           if (competence && competence.system.defaut_carac) { |  | ||||||
|             const carac = combatant.actor.system.carac[competence.system.defaut_carac].value; |  | ||||||
|             const niveau = competence.system.niveau; |  | ||||||
|  |  | ||||||
|             const ajustement = RdDCombatManager.calculAjustementInit(combatant.actor, armeCombat) |  | ||||||
|             rollFormula = RdDCombatManager.formuleInitiative(2, carac, niveau, ajustement); |  | ||||||
|           } else { |  | ||||||
|             ui.notifications.warn(`Votre arme ${armeCombat.name} n'a pas de compétence renseignée`); |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       //console.log("Combatat", c); |  | ||||||
|       const roll = combatant.getInitiativeRoll(rollFormula); |       const roll = combatant.getInitiativeRoll(rollFormula); | ||||||
|       if (!roll.total) { |       if (!roll.total) { | ||||||
|         await roll.evaluate(); |         await roll.evaluate(); | ||||||
|       } |       } | ||||||
|       const total = Math.max(roll.total, 0.00); |       const total = Math.max(roll.total, 0.00); | ||||||
|       console.log("Compute init for", rollFormula, roll, total, combatant); |       console.log("Compute init for", rollFormula, roll, total, combatant); | ||||||
|       let id = combatant._id || combatant.id; |       await this.updateEmbeddedDocuments("Combatant", [{ _id: combatant._id || combatant.id, initiative: total }]); | ||||||
|       await this.updateEmbeddedDocuments("Combatant", [{ _id: id, initiative: total }]); |  | ||||||
|  |  | ||||||
|       // Send a chat message |       // Send a chat message | ||||||
|       let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode"); |       let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode"); | ||||||
| @@ -142,10 +133,10 @@ export class RdDCombatManager extends Combat { | |||||||
|           scene: canvas.scene._id, |           scene: canvas.scene._id, | ||||||
|           actor: combatant.actor?._id, |           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, | ||||||
|         }, |         }, | ||||||
|         flavor: `${combatant.token.name} a fait son jet d'Initiative (${messageOptions.initInfo})<br>`, |         flavor: `${combatant.token?.name} a fait son jet d'Initiative (${messageOptions.info})<br>` | ||||||
|       }, |       }, | ||||||
|         messageOptions); |         messageOptions); | ||||||
|       roll.toMessage(messageData, { rollMode, create: true }); |       roll.toMessage(messageData, { rollMode, create: true }); | ||||||
| @@ -153,7 +144,20 @@ export class RdDCombatManager extends Combat { | |||||||
|       RdDCombatManager.processPremierRoundInit(); |       RdDCombatManager.processPremierRoundInit(); | ||||||
|     } |     } | ||||||
|     return this; |     return this; | ||||||
|   }; |   } | ||||||
|  |  | ||||||
|  |   static getFirstInitRollFormula(actor) { | ||||||
|  |     const actions = actor.listActionsCombat() | ||||||
|  |     if (actions.length > 0) { | ||||||
|  |       const action = actions[0] | ||||||
|  |       const init = RdDCombatManager.getInitData(actor, action) | ||||||
|  |       const ajustement = RdDCombatManager.calculAjustementInit(actor, action) | ||||||
|  |       return RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     let ajustement = RdDCombatManager.calculAjustementInit(actor, undefined); | ||||||
|  |     return RdDCombatManager.formuleInitiative(2, 10, 0, ajustement); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static formuleInitiative(rang, carac, niveau, bonusMalus) { |   static formuleInitiative(rang, carac, niveau, bonusMalus) { | ||||||
|     return `${rang} +( (${RdDCombatManager.calculInitiative(niveau, carac, bonusMalus)} )/100)`; |     return `${rang} +( (${RdDCombatManager.calculInitiative(niveau, carac, bonusMalus)} )/100)`; | ||||||
| @@ -222,7 +226,7 @@ export class RdDCombatManager extends Combat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static $prepareAttaqueArme(infoAttaque) { |   static $prepareAttaqueArme(infoAttaque) { | ||||||
|     const comp = infoAttaque.competences.find(c => c.name == infoAttaque.competence); |     const comp = infoAttaque.competences.find(it => Grammar.equalsInsensitive(it.name, infoAttaque.competence)) | ||||||
|     const arme = infoAttaque.arme; |     const arme = infoAttaque.arme; | ||||||
|     const attaque = foundry.utils.duplicate(arme); |     const attaque = foundry.utils.duplicate(arme); | ||||||
|     attaque.action = 'attaque'; |     attaque.action = 'attaque'; | ||||||
| @@ -236,62 +240,10 @@ export class RdDCombatManager extends Combat { | |||||||
|     return attaque; |     return attaque; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static listActionsCreature(competences) { |  | ||||||
|     return competences |  | ||||||
|       .filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it)) |  | ||||||
|       .map(it => RdDItemCompetenceCreature.armeCreature(it)) |  | ||||||
|       .filter(it => it != undefined); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static listActionsPossessions(actor) { |  | ||||||
|     return RdDCombatManager._indexActions(actor.getPossessions().map(p => { |  | ||||||
|       return { |  | ||||||
|         name: p.name, |  | ||||||
|         action: 'possession', |  | ||||||
|         system: { |  | ||||||
|           competence: p.name, |  | ||||||
|           possessionid: p.system.possessionid, |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     })); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static listActionsCombat(combatant) { |  | ||||||
|     const actor = combatant.actor; |  | ||||||
|     let actions = RdDCombatManager.listActionsPossessions(actor); |  | ||||||
|     if (actions.length > 0) { |  | ||||||
|       return actions; |  | ||||||
|     } |  | ||||||
|     if (actor.isCreatureEntite()) { |  | ||||||
|       actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']); |  | ||||||
|     } else if (actor.isPersonnage()) { |  | ||||||
|       // Recupération des items 'arme' |  | ||||||
|       const competences = actor.itemTypes['competence']; |  | ||||||
|       const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it)) |  | ||||||
|         .concat(RdDItemArme.empoignade(actor)) |  | ||||||
|         .concat(RdDItemArme.mainsNues(actor)); |  | ||||||
|       actions = RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac); |  | ||||||
|  |  | ||||||
|       if (actor.system.attributs.hautrevant.value) { |  | ||||||
|         actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } }); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return RdDCombatManager._indexActions(actions); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static _indexActions(actions) { |  | ||||||
|     for (let index = 0; index < actions.length; index++) { |  | ||||||
|       actions[index].index = index; |  | ||||||
|     } |  | ||||||
|     return actions; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static processPremierRoundInit() { |   static processPremierRoundInit() { | ||||||
|     // Check if we have the whole init ! |     // Check if we have the whole init ! | ||||||
|     if (Misc.isUniqueConnectedGM() && game.combat.current.round == 1) { |     if (Misc.isFirstConnectedGM() && game.combat.current.round == 1) { | ||||||
|       let initMissing = game.combat.combatants.find(it => !it.initiative); |       let initMissing = game.combat.combatants.find(it => !it.initiative); | ||||||
|       if (!initMissing) { // Premier round ! |       if (!initMissing) { // Premier round ! | ||||||
|         for (let combatant of game.combat.combatants) { |         for (let combatant of game.combat.combatants) { | ||||||
| @@ -300,7 +252,7 @@ export class RdDCombatManager extends Combat { | |||||||
|           if (action && action.type == "arme") { |           if (action && action.type == "arme") { | ||||||
|             for (let initData of premierRoundInit) { |             for (let initData of premierRoundInit) { | ||||||
|               if (Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround).includes(initData.pattern)) { |               if (Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround).includes(initData.pattern)) { | ||||||
|                 let msg = `<h4>L'initiative de ${combatant.actor.name} a été modifiée !</h4> |                 let msg = `<h4>L'initiative de ${combatant.actor.getAlias()} a été modifiée !</h4> | ||||||
|                       <hr> |                       <hr> | ||||||
|                       <div> |                       <div> | ||||||
|                         Etant donné son ${action.name}, son initative pour ce premier round est désormais de ${initData.init}. |                         Etant donné son ${action.name}, son initative pour ce premier round est désormais de ${initData.init}. | ||||||
| @@ -325,13 +277,13 @@ export class RdDCombatManager extends Combat { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static pushInitiativeOptions(html, options) { |   static pushInitiativeOptions(html, options) { | ||||||
|     for (let i = 0; i < options.length; i++) { |     for (let i = 0; i < options.length; i++) { | ||||||
|       let option = options[i]; |       let option = options[i] | ||||||
|       if (option.name == 'COMBAT.CombatantReroll') { // Replace ! |       if (option.name == 'COMBAT.CombatantReroll') { // Replace ! | ||||||
|         option.name = "Sélectionner l'initiative..."; |         option.name = "Sélectionner l'initiative..." | ||||||
|         option.condition = true; |         option.condition = true | ||||||
|         option.icon = '<i class="far fa-question-circle"></i>'; |         option.icon = '<i class="far fa-question-circle"></i>' | ||||||
|         option.callback = target => { |         option.callback = target => { | ||||||
|           RdDCombatManager.displayInitiativeMenu(html, target.data('combatant-id')); |           RdDCombatManager.displayInitiativeMenu(html, target.data('combatant-id')) | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -342,95 +294,82 @@ export class RdDCombatManager extends Combat { | |||||||
|   } |   } | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static rollInitiativeAction(combatantId, action) { |   static rollInitiativeAction(combatantId, action) { | ||||||
|     const combatant = game.combat.combatants.get(combatantId); |     const combatant = game.combat.combatants.get(combatantId) | ||||||
|     if (combatant.actor == undefined) { |     const actor = RdDCombatManager.getActorCombatant(combatant) | ||||||
|       ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`) |     if (actor == undefined) { return [] } | ||||||
|       return []; |  | ||||||
|     } |  | ||||||
|     let initInfo = ""; |  | ||||||
|     let initOffset = 0; |  | ||||||
|     let caracForInit = 0; |  | ||||||
|     let compNiveau = 0; |  | ||||||
|     let compData = { name: "Aucune" }; |  | ||||||
|     if (combatant.actor.getSurprise() == "totale") { |  | ||||||
|       initOffset = -1; // To force 0 |  | ||||||
|       initInfo = "Surprise Totale" |  | ||||||
|     } else if (combatant.actor.getSurprise() == "demi") { |  | ||||||
|       initOffset = 0; |  | ||||||
|       initInfo = "Demi Surprise" |  | ||||||
|     } else if (action.action == 'possession') { |  | ||||||
|       initOffset = 10; |  | ||||||
|       caracForInit = combatant.actor.getReveActuel(); |  | ||||||
|       initInfo = "Possession" |  | ||||||
|     } else if (action.action == 'autre') { |  | ||||||
|       initOffset = 2; |  | ||||||
|       initInfo = "Autre Action" |  | ||||||
|     } else if (action.action == 'haut-reve') { |  | ||||||
|       initOffset = 9; |  | ||||||
|       initInfo = "Draconic" |  | ||||||
|     } else { |  | ||||||
|       compData = RdDItemCompetence.findCompetence(combatant.actor.items, action.system.competence); |  | ||||||
|       compNiveau = compData.system.niveau; |  | ||||||
|       initInfo = action.name + " / " + action.system.competence; |  | ||||||
|  |  | ||||||
|       if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') { |  | ||||||
|         caracForInit = compData.system.carac_value; |  | ||||||
|       } else { |  | ||||||
|         caracForInit = combatant.actor.system.carac[compData.system.defaut_carac].value; |  | ||||||
|       } |  | ||||||
|       initOffset = RdDCombatManager._baseInitOffset(compData.system.categorie, action); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Cas des créatures et entités vs personnages |  | ||||||
|     const ajustement = RdDCombatManager.calculAjustementInit(combatant.actor, action) |  | ||||||
|     let rollFormula = RdDCombatManager.formuleInitiative(initOffset, caracForInit, compNiveau, ajustement); |  | ||||||
|     // Garder la trace de l'arme/compétence utilisée pour l'iniative |  | ||||||
|     combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0 |     combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0 | ||||||
|     game.combat.rollInitiative(combatantId, rollFormula, { initInfo: initInfo }); |  | ||||||
|  |     const init = RdDCombatManager.getInitData(actor, action) | ||||||
|  |     const ajustement = RdDCombatManager.calculAjustementInit(actor, action) | ||||||
|  |     const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement); | ||||||
|  |  | ||||||
|  |     game.combat.rollInitRdD(combatantId, rollFormula, init); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   static getInitData(actor, action) { | ||||||
|   static _baseInitOffset(categorie, arme) { |     if (actor.getSurprise() == "totale") { return { offset: -1, info: "Surprise Totale", carac: 0, niveau: 0 } } | ||||||
|     if (categorie == "tir") { // Offset de principe pour les armes de jet |     if (actor.getSurprise() == "demi") { return { offset: 0, info: "Demi Surprise", carac: 0, niveau: 0 } } | ||||||
|       return 8; |     if (action.action == 'autre') { return { offset: 2, info: "Autre Action", carac: 0, niveau: 0 } } | ||||||
|  |     if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } } | ||||||
|  |     if (action.action == 'haut-reve') { return { offset: 9, info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } } | ||||||
|  |  | ||||||
|  |     const comp = RdDItemCompetence.findCompetence(actor.items, action.system.competence); | ||||||
|  |     return { | ||||||
|  |       offset: RdDCombatManager.initOffset(comp?.system.categorie, action), | ||||||
|  |       info: action.name + " / " + action.system.competence, | ||||||
|  |       carac: actor.getCaracInit(comp), | ||||||
|  |       niveau: comp?.system.niveau ?? -8 | ||||||
|     } |     } | ||||||
|     if (categorie == "lancer") { // Offset de principe pour les armes de jet |  | ||||||
|       return 7; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static initOffset(categorie, arme) { | ||||||
|  |     switch (categorie) { | ||||||
|  |       case "tir": return 8 | ||||||
|  |       case "lancer": return 7 | ||||||
|  |       default: | ||||||
|         switch (arme.system.cac) { |         switch (arme.system.cac) { | ||||||
|       case "empoignade": |           case "empoignade": return 3 | ||||||
|         return 3; |           case "pugilat": return 4 | ||||||
|       case "pugilat": |           case "naturelle": return 4 | ||||||
|       case "naturelle": |           default: return 5 | ||||||
|         return 4; |         } | ||||||
|     } |     } | ||||||
|     return 5; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static displayInitiativeMenu(html, combatantId) { |   static displayInitiativeMenu(html, combatantId) { | ||||||
|     console.log("Combatant ; ", combatantId); |     const combatant = game.combat.combatants.get(combatantId) | ||||||
|     const combatant = game.combat.combatants.get(combatantId); |     const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false }) | ||||||
|     if (!(combatant?.actor)) { |     if (actor) { | ||||||
|       ui.notifications.warn(`Le combatant ${combatant.name ?? combatantId} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`) |       const actions = RdDCombatManager.listActionsActorCombatant(actor) | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     let actions = RdDCombatManager.listActionsCombat(combatant); |  | ||||||
|  |  | ||||||
|       // Build the relevant submenu |       // Build the relevant submenu | ||||||
|     if (actions) { |       const menuItems = actions.map(action => { | ||||||
|       let menuItems = []; |         return { | ||||||
|       for (let action of actions) { |  | ||||||
|         menuItems.push({ |  | ||||||
|           name: action.system.competence, |           name: action.system.competence, | ||||||
|           icon: "<i class='fas fa-dice-d6'></i>", |           icon: "<i class='fas fa-dice-d6'></i>", | ||||||
|           callback: target => { RdDCombatManager.rollInitiativeAction(combatantId, action) } |           callback: target => { RdDCombatManager.rollInitiativeAction(combatantId, action) } | ||||||
|         }); |  | ||||||
|         } |         } | ||||||
|  |       }) | ||||||
|  |       if (menuItems.length > 0) { | ||||||
|         new ContextMenu(html, ".directory-list", menuItems).render(); |         new ContextMenu(html, ".directory-list", menuItems).render(); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   static listActionsActorCombatant( actor) { | ||||||
|  |     const possessions = actor.listActionsPossessions() | ||||||
|  |     const actions = possessions.length > 0 | ||||||
|  |       ? possessions | ||||||
|  |       : actor.listActionsCombat() | ||||||
|  |  | ||||||
|  |     for (let index = 0; index < actions.length; index++) { | ||||||
|  |       actions[index].index = index | ||||||
|  |     } | ||||||
|  |     return actions | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -454,11 +393,11 @@ export class RdDCombat { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static combatNouveauTour(combat) { |   static combatNouveauTour(combat) { | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId); |       let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId); | ||||||
|       if (turn?.actor) { |       if (turn?.actor) { | ||||||
|         RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token.id); |  | ||||||
|         // TODO Playaudio for player?? |         // TODO Playaudio for player?? | ||||||
|  |         RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -469,52 +408,50 @@ export class RdDCombat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static rddCombatTarget(target, attacker) { |   static rddCombatTarget(target, attacker, attackerToken) { | ||||||
|     const defender = target?.actor; |     return new RdDCombat(attacker, attackerToken?.id, target?.actor, target?.id, target) | ||||||
|     const defenderTokenId = target?.id; |  | ||||||
|     return new RdDCombat(attacker, defender, defenderTokenId, target) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static rddCombatForAttackerAndDefender(attackerId, defenderTokenId) { |   static rddCombatForAttackerAndDefender(attackerId, attackerTokenId, defenderTokenId) { | ||||||
|     const attacker = game.actors.get(attackerId); |     const attacker = game.actors.get(attackerId) | ||||||
|     let defender = defenderTokenId ? canvas.tokens.get(defenderTokenId)?.actor : undefined; |     const defenderToken = defenderTokenId ? canvas.tokens.get(defenderTokenId) : undefined | ||||||
|  |     let defender = defenderToken?.actor; | ||||||
|     let target = undefined |     let target = undefined | ||||||
|     if (!defenderTokenId || !defender) { |     if (!defenderTokenId || !defender) { | ||||||
|       console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`); |       console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`); | ||||||
|       target = Targets.getTarget() |       target = Targets.getTarget() | ||||||
|       if (!target) { |       if (!target) { | ||||||
|         return; |         return | ||||||
|       } |       } | ||||||
|       defenderTokenId = target.id; |       defenderTokenId = target.id; | ||||||
|       defender = target.actor; |       defender = target.actor; | ||||||
|       if (!defenderTokenId || !defender) { |       if (!defenderTokenId || !defender) { | ||||||
|         return; |         return | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return new RdDCombat(attacker, defender, defenderTokenId, target) |     return new RdDCombat(attacker, attackerTokenId, defender, defenderTokenId, target) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static onMsgEncaisser(msg) { |   static onMsgEncaisser(msg) { | ||||||
|     let defender = canvas.tokens.get(msg.defenderTokenId).actor; |     let defender = canvas.tokens.get(msg.defenderToken.id).actor; | ||||||
|     if (Misc.isOwnerPlayerOrUniqueConnectedGM()) { |     if (Misc.isOwnerPlayerOrUniqueConnectedGM(defender)) { | ||||||
|       let attackerRoll = msg.attackerRoll; |       let attackerRoll = msg.attackerRoll; | ||||||
|       let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined; |       let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined; | ||||||
|  |       defender.encaisserDommages(attackerRoll, attacker, msg.attackerToken); | ||||||
|       defender.encaisserDommages(attackerRoll, attacker); |       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id); | ||||||
|       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); |  | ||||||
|       rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme); |       rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static onMsgDefense(msg) { |   static onMsgDefense(msg) { | ||||||
|     let defenderToken = canvas.tokens.get(msg.defenderTokenId); |     let defenderToken = canvas.tokens.get(msg.defenderToken.id) | ||||||
|     if (defenderToken && Misc.isUniqueConnectedGM()) { |     if (defenderToken && Misc.isFirstConnectedGM()) { | ||||||
|       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); |       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id) | ||||||
|       rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme); |       rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme) | ||||||
|       rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll); |       rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -545,6 +482,7 @@ export class RdDCombat { | |||||||
|       html.on("click", button, event => { |       html.on("click", button, event => { | ||||||
|         const rddCombat = RdDCombat.rddCombatForAttackerAndDefender( |         const rddCombat = RdDCombat.rddCombatForAttackerAndDefender( | ||||||
|           event.currentTarget.attributes['data-attackerId']?.value, |           event.currentTarget.attributes['data-attackerId']?.value, | ||||||
|  |           event.currentTarget.attributes['data-attackerTokenId']?.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); | ||||||
| @@ -560,22 +498,38 @@ export class RdDCombat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   constructor(attacker, defender, defenderTokenId, target) { |   constructor(attacker, attackerTokenId, defender, defenderTokenId, target) { | ||||||
|     this.attacker = attacker |     this.attacker = attacker | ||||||
|     this.defender = defender |     this.defender = defender | ||||||
|     this.target = target |     this.target = target | ||||||
|     this.attackerId = this.attacker.id |     this.attackerId = this.attacker.id | ||||||
|     this.defenderId = this.defender.id |     this.defenderId = this.defender.id | ||||||
|  |     this.attackerTokenId = attackerTokenId | ||||||
|     this.defenderTokenId = defenderTokenId |     this.defenderTokenId = defenderTokenId | ||||||
|  |     this.attackerToken = RdDCombat.$extractAttackerTokenData(attacker, attackerTokenId) | ||||||
|  |     this.defenderToken = RdDCombat.$extractDefenderTokenData(defender, defenderTokenId, target) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static $extractAttackerTokenData(attacker, attackerTokenId) { | ||||||
|  |     const token = canvas.tokens.get(attackerTokenId); | ||||||
|  |     return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(attackerTokenId, attacker) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $extractDefenderTokenData(defender, defenderTokenId, target) { | ||||||
|  |     if (target) { | ||||||
|  |       return Targets.extractTokenData(target) | ||||||
|  |     } | ||||||
|  |     const token = canvas.tokens.get(defenderTokenId); | ||||||
|  |     return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(defenderTokenId, defender) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   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 armeParadeId = event.currentTarget.attributes['data-armeid']?.value; |     const armeParadeId = event.currentTarget.attributes['data-armeid']?.value; | ||||||
|     const competence = event.currentTarget.attributes['data-competence']?.value; |     const competence = event.currentTarget.attributes['data-competence']?.value; | ||||||
| @@ -585,7 +539,7 @@ export class RdDCombat { | |||||||
|       case '#particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); |       case '#particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); | ||||||
|       case '#parer-button': return this.parade(attackerRoll, armeParadeId); |       case '#parer-button': return this.parade(attackerRoll, armeParadeId); | ||||||
|       case '#esquiver-button': return this.esquive(attackerRoll, compId, competence); |       case '#esquiver-button': return this.esquive(attackerRoll, compId, competence); | ||||||
|       case '#encaisser-button': return this.encaisser(attackerRoll, defenderRoll, defenderTokenId); |       case '#encaisser-button': return this.encaisser(attackerRoll, defenderRoll); | ||||||
|       case '#echec-total-attaque': return this._onEchecTotal(attackerRoll); |       case '#echec-total-attaque': return this._onEchecTotal(attackerRoll); | ||||||
|  |  | ||||||
|       case '#appel-chance-attaque': return this.attacker.rollAppelChance( |       case '#appel-chance-attaque': return this.attacker.rollAppelChance( | ||||||
| @@ -702,7 +656,7 @@ export class RdDCombat { | |||||||
|         }) |         }) | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|         const defenderToken = canvas.tokens.get(this.defenderTokenId); |         const defenderToken = canvas.tokens.get(this.defenderTokenId) | ||||||
|         const dist = this.distance(_token, defenderToken) |         const dist = this.distance(_token, defenderToken) | ||||||
|         const isVisible = this.isVisible(_token, defenderToken) |         const isVisible = this.isVisible(_token, defenderToken) | ||||||
|         const portee = this._ajustementPortee(dist, rollData.arme) |         const portee = this._ajustementPortee(dist, rollData.arme) | ||||||
| @@ -769,7 +723,7 @@ export class RdDCombat { | |||||||
|     } |     } | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this.attacker) |     RdDEmpoignade.checkEmpoignadeEnCours(this.attacker) | ||||||
|  |  | ||||||
|     let rollData = this._prepareAttaque(competence, arme); |     let rollData = this._prepareAttaque(competence, arme) | ||||||
|     console.log("RdDCombat.attaque >>>", rollData); |     console.log("RdDCombat.attaque >>>", rollData); | ||||||
|     if (arme) { |     if (arme) { | ||||||
|       this.attacker.verifierForceMin(arme); |       this.attacker.verifierForceMin(arme); | ||||||
| @@ -795,15 +749,18 @@ export class RdDCombat { | |||||||
|     dialog.render(true); |     dialog.render(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _prepareAttaque(competence, arme) { |   _prepareAttaque(competence, arme) { | ||||||
|     let rollData = { |     let rollData = { | ||||||
|  |       alias: this.attacker?.getAlias(), | ||||||
|       passeArme: foundry.utils.randomID(16), |       passeArme: foundry.utils.randomID(16), | ||||||
|       mortalite: arme?.system.mortalite, |       mortalite: arme?.system.mortalite, | ||||||
|       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), |       sourceToken: this.attackerToken, | ||||||
|  |       targetToken: this.defenderToken, | ||||||
|       essais: {} |       essais: {} | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -816,9 +773,9 @@ export class RdDCombat { | |||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       // sans armes: à mains nues |       // sans armes: à mains nues | ||||||
|       const niveau = competence.system.niveau; |       rollData.arme = RdDItemArme.corpsACorps(this.attacker) | ||||||
|       const init = RdDCombatManager.calculInitiative(niveau, this.attacker.system.carac['melee'].value); |       rollData.arme.system.niveau = competence.system.niveau | ||||||
|       rollData.arme = RdDItemArme.mainsNues({ niveau: niveau, initiative: init }); |       rollData.arme.system.initiative = RdDCombatManager.calculInitiative(competence.system.niveau, this.attacker.system.carac['melee'].value); | ||||||
|     } |     } | ||||||
|     return rollData; |     return rollData; | ||||||
|   } |   } | ||||||
| @@ -845,12 +802,13 @@ export class RdDCombat { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     const choixParticuliere = await ChatMessage.create({ |     const choixParticuliere = await ChatMessage.create({ | ||||||
|       alias: this.attacker.name, |       alias: this.attacker.getAlias(), | ||||||
|       whisper: ChatUtility.getOwners(this.attacker), |       whisper: ChatUtility.getOwners(this.attacker), | ||||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', { |       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', { | ||||||
|         alias: this.attacker.name, |         alias: this.attacker.getAlias(), | ||||||
|         attackerId: this.attackerId, |         attackerId: this.attackerId, | ||||||
|         defenderTokenId: this.defenderTokenId, |         attackerToken: this.attackerToken, | ||||||
|  |         defenderToken: this.defenderToken, | ||||||
|         isForce: isForce, |         isForce: isForce, | ||||||
|         isFinesse: isFinesse, |         isFinesse: isFinesse, | ||||||
|         isRapide: isRapide, |         isRapide: isRapide, | ||||||
| @@ -867,7 +825,7 @@ export class RdDCombat { | |||||||
|     attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); |     attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); | ||||||
|     let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } |     let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } | ||||||
|     attackerRoll.show = { |     attackerRoll.show = { | ||||||
|       cible: this.target ? this.defender.name : 'la cible', |       cible: this.defender?.getAlias() ?? 'la cible', | ||||||
|       isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge') |       isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge') | ||||||
|     } |     } | ||||||
|     await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html'); |     await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html'); | ||||||
| @@ -898,7 +856,7 @@ export class RdDCombat { | |||||||
|     // # utilisation esquive |     // # utilisation esquive | ||||||
|     const corpsACorps = this.defender.getCompetenceCorpsACorps({ onMessage: it => console.info(it, this.defender) }); |     const corpsACorps = this.defender.getCompetenceCorpsACorps({ onMessage: it => console.info(it, this.defender) }); | ||||||
|     const esquives = foundry.utils.duplicate(this.defender.getCompetencesEsquive()) |     const esquives = foundry.utils.duplicate(this.defender.getCompetencesEsquive()) | ||||||
|     esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0); |     esquives.forEach(e => e.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0); | ||||||
|  |  | ||||||
|     const paramChatDefense = { |     const paramChatDefense = { | ||||||
|       passeArme: attackerRoll.passeArme, |       passeArme: attackerRoll.passeArme, | ||||||
| @@ -908,7 +866,8 @@ export class RdDCombat { | |||||||
|       attacker: this.attacker, |       attacker: this.attacker, | ||||||
|       attackerId: this.attackerId, |       attackerId: this.attackerId, | ||||||
|       esquives: esquives, |       esquives: esquives, | ||||||
|       defenderTokenId: this.defenderTokenId, |       attackerToken: this.attackerToken, | ||||||
|  |       defenderToken: this.defenderToken, | ||||||
|       mainsNues: attackerRoll.dmg.mortalite != 'mortel' && corpsACorps, |       mainsNues: attackerRoll.dmg.mortalite != 'mortel' && corpsACorps, | ||||||
|       armes: this._filterArmesParade(this.defender, attackerRoll.competence, attackerRoll.arme), |       armes: this._filterArmesParade(this.defender, attackerRoll.competence, attackerRoll.arme), | ||||||
|       diffLibre: attackerRoll.ajustements?.diffLibre?.value ?? 0, |       diffLibre: attackerRoll.ajustements?.diffLibre?.value ?? 0, | ||||||
| @@ -919,7 +878,7 @@ export class RdDCombat { | |||||||
|       dmg: attackerRoll.dmg, |       dmg: attackerRoll.dmg, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       await this._chatMessageDefense(paramChatDefense, defenderRoll); |       await this._chatMessageDefense(paramChatDefense, defenderRoll); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
| @@ -932,7 +891,7 @@ export class RdDCombat { | |||||||
|     const choixDefense = await ChatMessage.create({ |     const choixDefense = await ChatMessage.create({ | ||||||
|       // message privé: du défenseur à lui même (et aux GMs) |       // message privé: du défenseur à lui même (et aux GMs) | ||||||
|       speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), |       speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), | ||||||
|       alias: this.attacker.name, |       alias: this.attacker?.getAlias(), | ||||||
|       whisper: ChatUtility.getOwners(this.defender), |       whisper: ChatUtility.getOwners(this.defender), | ||||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense), |       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense), | ||||||
|     }); |     }); | ||||||
| @@ -946,8 +905,9 @@ export class RdDCombat { | |||||||
|     game.socket.emit(SYSTEM_SOCKET_ID, { |     game.socket.emit(SYSTEM_SOCKET_ID, { | ||||||
|       msg: "msg_defense", data: { |       msg: "msg_defense", data: { | ||||||
|         attackerId: this.attacker?.id, |         attackerId: this.attacker?.id, | ||||||
|  |         attackerToken: this.attackerToken, | ||||||
|         defenderId: this.defender?.id, |         defenderId: this.defender?.id, | ||||||
|         defenderTokenId: this.defenderTokenId, |         defenderToken: this.defenderToken, | ||||||
|         defenderRoll: defenderRoll, |         defenderRoll: defenderRoll, | ||||||
|         paramChatDefense: paramChatDefense, |         paramChatDefense: paramChatDefense, | ||||||
|         rollMode: true |         rollMode: true | ||||||
| @@ -956,20 +916,21 @@ export class RdDCombat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _filterArmesParade(defender, competence) { |   _filterArmesParade(defender, competence, armeAttaque) { | ||||||
|     let items = defender.items.filter(it => RdDItemArme.isArmeUtilisable(it) || RdDItemCompetenceCreature.isCompetenceParade(it)) |     let defenses = defender.items.filter(it => RdDItemArme.isParade(it)) | ||||||
|     items.forEach(item => item.system.nbUsage = defender.getItemUse(item.id)); // Ajout du # d'utilisation ce round   |     defenses = foundry.utils.duplicate(defenses) | ||||||
|  |     defenses.forEach(armeDefense => { | ||||||
|  |       // Ajout du # d'utilisation ce round   | ||||||
|  |       armeDefense.nbUsage = defender.getItemUse(armeDefense.id) | ||||||
|  |       armeDefense.typeParade = RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) | ||||||
|  |     }) | ||||||
|  |  | ||||||
|     switch (competence.system.categorie) { |     switch (competence.system.categorie) { | ||||||
|       case 'tir': |       case 'tir': | ||||||
|       case 'lancer': |       case 'lancer': | ||||||
|         return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers') |         return defenses.filter(armeDefense => RdDItemArme.getCategorieParade(armeDefense) == 'boucliers') | ||||||
|       default: |       default: | ||||||
|         // Le fléau ne peut être paré qu’au bouclier p115 |         return defenses.filter(armeDefense => armeDefense.typeParade != '') | ||||||
|         if (competence.name == "Fléau") { |  | ||||||
|           return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers') |  | ||||||
|         } |  | ||||||
|         return items.filter(item => RdDItemArme.getCategorieParade(item)); |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -980,7 +941,8 @@ export class RdDCombat { | |||||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', { |       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', { | ||||||
|         attackerId: this.attackerId, |         attackerId: this.attackerId, | ||||||
|         attacker: this.attacker, |         attacker: this.attacker, | ||||||
|         defenderTokenId: this.defenderTokenId, |         attackerToken: this.attackerToken, | ||||||
|  |         defenderToken: this.defenderToken, | ||||||
|         essais: attackerRoll.essais |         essais: attackerRoll.essais | ||||||
|       }) |       }) | ||||||
|     }); |     }); | ||||||
| @@ -1052,8 +1014,11 @@ export class RdDCombat { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _prepareParade(attackerRoll, armeParade, competenceParade) { |   _prepareParade(attackerRoll, armeParade, competenceParade) { | ||||||
|     let defenderRoll = { |     let defenderRoll = { | ||||||
|  |       alias: this.defender?.getAlias(), | ||||||
|       passeArme: attackerRoll.passeArme, |       passeArme: attackerRoll.passeArme, | ||||||
|       diffLibre: attackerRoll.diffLibre, |       diffLibre: attackerRoll.diffLibre, | ||||||
|  |       attackerToken: this.attackerToken, | ||||||
|  |       defenderToken: this.defenderToken, | ||||||
|       attackerRoll: attackerRoll, |       attackerRoll: attackerRoll, | ||||||
|       competence: this.defender.getCompetence(competenceParade), |       competence: this.defender.getCompetence(competenceParade), | ||||||
|       arme: armeParade, |       arme: armeParade, | ||||||
| @@ -1106,7 +1071,7 @@ export class RdDCombat { | |||||||
|   async esquive(attackerRoll, compId, compName) { |   async esquive(attackerRoll, compId, compName) { | ||||||
|     const esquive = this.defender.getCompetence(compId) ?? this.defender.getCompetence(compName) |     const esquive = this.defender.getCompetence(compId) ?? this.defender.getCompetence(compName) | ||||||
|     if (esquive == undefined) { |     if (esquive == undefined) { | ||||||
|       ui.notifications.error(this.defender.name + " n'a pas de compétence " + compName); |       ui.notifications.error(this.defender.getAlias() + " n'a pas de compétence " + compName); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     console.log("RdDCombat.esquive >>>", attackerRoll, esquive); |     console.log("RdDCombat.esquive >>>", attackerRoll, esquive); | ||||||
| @@ -1133,8 +1098,11 @@ export class RdDCombat { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _prepareEsquive(attackerRoll, competence) { |   _prepareEsquive(attackerRoll, competence) { | ||||||
|     let rollData = { |     let rollData = { | ||||||
|  |       alias: this.defender.getAlias(), | ||||||
|       passeArme: attackerRoll.passeArme, |       passeArme: attackerRoll.passeArme, | ||||||
|       diffLibre: attackerRoll.diffLibre, |       diffLibre: attackerRoll.diffLibre, | ||||||
|  |       attackerToken: this.attackerToken, | ||||||
|  |       defenderToken: this.defenderToken, | ||||||
|       attackerRoll: attackerRoll, |       attackerRoll: attackerRoll, | ||||||
|       competence: competence, |       competence: competence, | ||||||
|       surprise: this.defender.getSurprise(true), |       surprise: this.defender.getSurprise(true), | ||||||
| @@ -1276,9 +1244,8 @@ export class RdDCombat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async encaisser(attackerRoll, defenderRoll, defenderTokenId) { |   async encaisser(attackerRoll, defenderRoll) { | ||||||
|     defenderTokenId = defenderTokenId || this.defenderTokenId; |     console.log("RdDCombat.encaisser >>>", attackerRoll, defenderRoll); | ||||||
|     console.log("RdDCombat.encaisser >>>", attackerRoll, defenderTokenId); |  | ||||||
|  |  | ||||||
|     if (defenderRoll?.rolled && RdDCombat.isEchecTotal(defenderRoll)) { |     if (defenderRoll?.rolled && RdDCombat.isEchecTotal(defenderRoll)) { | ||||||
|       this._onEchecTotal(defenderRoll); |       this._onEchecTotal(defenderRoll); | ||||||
| @@ -1286,18 +1253,19 @@ export class RdDCombat { | |||||||
|  |  | ||||||
|     if (Misc.isOwnerPlayerOrUniqueConnectedGM(this.defender)) { |     if (Misc.isOwnerPlayerOrUniqueConnectedGM(this.defender)) { | ||||||
|       attackerRoll.attackerId = this.attackerId; |       attackerRoll.attackerId = this.attackerId; | ||||||
|       attackerRoll.defenderTokenId = defenderTokenId; |       attackerRoll.defenderTokenId = this.defenderToken.id; | ||||||
|  |  | ||||||
|       await this.computeRecul(defenderRoll); |       await this.computeRecul(defenderRoll); | ||||||
|       await this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show); |       await this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show, this.attackerToken, this.defenderToken); | ||||||
|     } |     } | ||||||
|     else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas |     else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas | ||||||
|       game.socket.emit(SYSTEM_SOCKET_ID, { |       game.socket.emit(SYSTEM_SOCKET_ID, { | ||||||
|         msg: "msg_encaisser", |         msg: "msg_encaisser", | ||||||
|         data: { |         data: { | ||||||
|           attackerId: this.attackerId, |           attackerId: this.attackerId, | ||||||
|           defenderTokenId: defenderTokenId, |           attackerRoll: attackerRoll, | ||||||
|           attackerRoll: attackerRoll |           attackerToken: this.attackerToken, | ||||||
|  |           defenderToken: this.defenderToken | ||||||
|         } |         } | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
| @@ -1305,28 +1273,32 @@ export class RdDCombat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async displayActorCombatStatus(combat, actor, tokenId) { |   static async displayActorCombatStatus(combat, actor, token) { | ||||||
|     let formData = { |     if (!actor?.isActorCombat()) { | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |     const alias = token?.name ?? actor.getAlias(); | ||||||
|  |     const formData = { | ||||||
|       combatId: combat._id, |       combatId: combat._id, | ||||||
|       alias: actor.name, |       alias: alias, | ||||||
|       etatGeneral: actor.getEtatGeneral(), |       etatGeneral: actor.getEtatGeneral(), | ||||||
|       isSonne: actor.getSonne(), |       isSonne: actor.isSonne(), | ||||||
|       blessuresStatus: actor.computeResumeBlessure(), |       blessuresStatus: actor.computeResumeBlessure(), | ||||||
|       SConst: actor.getSConst(), |       SConst: actor.getSConst(), | ||||||
|       actorId: actor.id, |       actorId: actor.id, | ||||||
|       actor: actor, |       actor: actor, | ||||||
|       tokenId: tokenId, |       tokenId: token.id, | ||||||
|       isGrave: actor.countBlessures(it => it.isGrave()) > 0, |       isGrave: actor.countBlessures(it => it.isGrave()) > 0, | ||||||
|       isCritique: actor.countBlessures(it => it.isCritique()) > 0 |       isCritique: actor.countBlessures(it => it.isCritique()) > 0 | ||||||
|     } |     } | ||||||
|     await ChatMessage.create({ |     await ChatMessage.create({ | ||||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData), |       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData), | ||||||
|       alias: actor.name |       alias: alias | ||||||
|     }) |     }) | ||||||
|     await ChatMessage.create({ |     await ChatMessage.create({ | ||||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData), |       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData), | ||||||
|       whisper: ChatUtility.getOwners(actor), |       whisper: ChatUtility.getOwners(actor), | ||||||
|       alias: actor.name |       alias: alias | ||||||
|     }); |     }) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -121,7 +121,7 @@ export class RdDHotbar { | |||||||
|         if (item.isCorpsACorps()) { |         if (item.isCorpsACorps()) { | ||||||
|           switch (categorieArme) { |           switch (categorieArme) { | ||||||
|             case 'pugilat': |             case 'pugilat': | ||||||
|               return actor.rollArme(RdDItemArme.mainsNues(actor), 'competence'); |               return actor.rollArme(RdDItemArme.corpsACorps(actor), 'competence'); | ||||||
|             case 'empoignade': |             case 'empoignade': | ||||||
|               return actor.rollArme(RdDItemArme.empoignade(actor), 'competence'); |               return actor.rollArme(RdDItemArme.empoignade(actor), 'competence'); | ||||||
|           } |           } | ||||||
|   | |||||||
| @@ -68,6 +68,7 @@ import { OptionsAvancees } from "./settings/options-avancees.js" | |||||||
| import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium.js" | import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium.js" | ||||||
| import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js" | import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js" | ||||||
| import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" | import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" | ||||||
|  | import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * RdD system |  * RdD system | ||||||
| @@ -87,6 +88,7 @@ export class SystemReveDeDragon { | |||||||
|     this.config = RDD_CONFIG |     this.config = RDD_CONFIG | ||||||
|     this.RdDUtility = RdDUtility |     this.RdDUtility = RdDUtility | ||||||
|     this.RdDHotbar = RdDHotbar |     this.RdDHotbar = RdDHotbar | ||||||
|  |     this.RdDStatBlockParser = RdDStatBlockParser | ||||||
|     this.itemClasses = { |     this.itemClasses = { | ||||||
|       armure: RdDItemArmure, |       armure: RdDItemArmure, | ||||||
|       blessure: RdDItemBlessure, |       blessure: RdDItemBlessure, | ||||||
| @@ -272,13 +274,23 @@ export class SystemReveDeDragon { | |||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static async setupAccueil() { | ||||||
|  |     let exists = game.scenes.find(j => j.name == "Accueil RdD"); | ||||||
|  |     if (!exists) { | ||||||
|  |       const scenes = await SystemCompendiums.loadCompendium("foundryvtt-reve-de-dragon.scenes-rdd") | ||||||
|  |       let newDocuments = scenes.filter(i => i.name == "Accueil RdD"); | ||||||
|  |       await game.scenes.documentClass.create(newDocuments); | ||||||
|  |       game.scenes.find(i => i.name == "Accueil RdD").activate(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   async onReady() { |   async onReady() { | ||||||
|  |  | ||||||
|     /* -------------------------------------------- */ |     /* -------------------------------------------- */ | ||||||
|     /*  Foundry VTT Initialization                  */ |     /*  Foundry VTT Initialization                  */ | ||||||
|     /* -------------------------------------------- */ |     /* -------------------------------------------- */ | ||||||
|     game.system.rdd.calendrier = new RdDCalendrier() |     game.system.rdd.calendrier = new RdDCalendrier() | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       new Migrations().migrate() |       new Migrations().migrate() | ||||||
|       this.messageDeBienvenue() |       this.messageDeBienvenue() | ||||||
|       import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter => { |       import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter => { | ||||||
| @@ -292,6 +304,8 @@ export class SystemReveDeDragon { | |||||||
|     StatusEffects.onReady() |     StatusEffects.onReady() | ||||||
|     RdDHerbes.onReady() |     RdDHerbes.onReady() | ||||||
|     RdDDice.onReady() |     RdDDice.onReady() | ||||||
|  |  | ||||||
|  |     RdDStatBlockParser.parseStatBlock() | ||||||
|     /* -------------------------------------------- */ |     /* -------------------------------------------- */ | ||||||
|     /* Affiche/Init le calendrier */ |     /* Affiche/Init le calendrier */ | ||||||
|     game.system.rdd.calendrier.display() |     game.system.rdd.calendrier.display() | ||||||
| @@ -303,6 +317,8 @@ export class SystemReveDeDragon { | |||||||
|         user: game.user.id |         user: game.user.id | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     SystemReveDeDragon.setupAccueil() | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -72,6 +72,6 @@ export class RdDEncaisser extends Dialog { | |||||||
|         encaisserSpecial: this.encaisserSpecial, |         encaisserSpecial: this.encaisserSpecial, | ||||||
|         mortalite: mortalite |         mortalite: mortalite | ||||||
|       } |       } | ||||||
|     }); |     }) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ 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 { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||||
|  | import { Grammar } from "./grammar.js"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Extend the base Dialog entity to select roll parameters |  * Extend the base Dialog entity to select roll parameters | ||||||
| @@ -32,7 +33,7 @@ export class RdDRoll extends Dialog { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static _setDefaultOptions(actor, rollData) { |   static _setDefaultOptions(actor, rollData) { | ||||||
|     let defaultRollData = { |     let defaultRollData = { | ||||||
|       alias: actor.name, |       alias: actor.getAlias(), | ||||||
|       ajustementsConditions: CONFIG.RDD.ajustementsConditions, |       ajustementsConditions: CONFIG.RDD.ajustementsConditions, | ||||||
|       difficultesLibres: CONFIG.RDD.difficultesLibres, |       difficultesLibres: CONFIG.RDD.difficultesLibres, | ||||||
|       etat: actor.getEtatGeneral(), |       etat: actor.getEtatGeneral(), | ||||||
| @@ -173,8 +174,8 @@ export class RdDRoll extends Dialog { | |||||||
|       this.html.find("[name='diffLibre']").val(this.rollData.diffLibre); |       this.html.find("[name='diffLibre']").val(this.rollData.diffLibre); | ||||||
|     }); |     }); | ||||||
|     this.html.find('.roll-carac-competence').change((event) => { |     this.html.find('.roll-carac-competence').change((event) => { | ||||||
|       const competence = event.currentTarget.value; |       const competence = event.currentTarget.value | ||||||
|       this.rollData.competence = this.rollData.competences.find(it => it.name == competence); |       this.rollData.competence = this.rollData.competences.find(it => Grammar.equalsInsensitive(it.name, competence)) | ||||||
|       this.updateRollResult(html); |       this.updateRollResult(html); | ||||||
|     }); |     }); | ||||||
|     this.html.find('.select-suivant-coeur').change((event) => { |     this.html.find('.select-suivant-coeur').change((event) => { | ||||||
| @@ -345,24 +346,25 @@ export class RdDRoll extends Dialog { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _getTitle(rollData) { |   _getTitle(rollData) { | ||||||
|  |     const alias = rollData.alias | ||||||
|     const carac = rollData.selectedCarac.label; |     const carac = rollData.selectedCarac.label; | ||||||
|     if (!rollData.competence) { |     if (!rollData.competence) { | ||||||
|       return carac; |       return `${alias}: ${carac}` | ||||||
|     } |     } | ||||||
|     const compName = rollData.competence.name; |     const compName = rollData.competence.name; | ||||||
|     const niveau = Misc.toSignedString(rollData.competence.system.niveau) |     const niveau = Misc.toSignedString(rollData.competence.system.niveau) | ||||||
|     if (compName == carac) { |     if (compName == carac) { | ||||||
|       // cas des créatures |       // cas des créatures | ||||||
|       return `${carac} Niveau ${niveau}` |       return `${alias}: ${carac} Niveau ${niveau}` | ||||||
|     } |     } | ||||||
|     if (rollData.draconicList && rollData.selectedSort) { |     if (rollData.draconicList && rollData.selectedSort) { | ||||||
|       // cas de lancer de sort |       // cas de lancer de sort | ||||||
|       return `${rollData.competence.name} Niveau ${niveau} ${rollData.selectedSort.name}` |       return `${alias}: ${rollData.competence.name} Niveau ${niveau} ${rollData.selectedSort.name}` | ||||||
|     } |     } | ||||||
|     if (rollData.arme && rollData.arme.name != compName) { |     if (rollData.arme && rollData.arme.name != compName) { | ||||||
|       // ajouter l'arme au titre si son nom n'est pas la compétence |       // ajouter l'arme au titre si son nom n'est pas la compétence | ||||||
|       return `${carac} /  ${compName} (${rollData.arme.name}) Niveau ${niveau}` |       return `${alias}: ${carac} /  ${compName} (${rollData.arme.name}) Niveau ${niveau}` | ||||||
|     } |     } | ||||||
|     return `${carac} / ${compName} Niveau ${niveau}` |     return `${alias}: ${carac} / ${compName} Niveau ${niveau}` | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| import { Grammar } from "./grammar.js"; |  | ||||||
| import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js"; | import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js"; | ||||||
|  |  | ||||||
| export class RdDRollTables { | export class RdDRollTables { | ||||||
|   | |||||||
| @@ -460,7 +460,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|     let rencontreData = { |     let rencontreData = { | ||||||
|       actor: this.actor, |       actor: this.actor, | ||||||
|       alias: this.actor.name, |       alias: this.actor.getAlias(), | ||||||
|       reveDepart: this.actor.getReveActuel(), |       reveDepart: this.actor.getReveActuel(), | ||||||
|       competence: this.actor.getBestDraconic(), |       competence: this.actor.getBestDraconic(), | ||||||
|       rencontre: this.currentRencontre, |       rencontre: this.currentRencontre, | ||||||
| @@ -641,7 +641,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     // simuler une rencontre |     // simuler une rencontre | ||||||
|     let rencontreData = { |     let rencontreData = { | ||||||
|       actor: this.actor, |       actor: this.actor, | ||||||
|       alias: this.actor.name, |       alias: this.actor.getAlias(), | ||||||
|       reveDepart: this.actor.getReveActuel(), |       reveDepart: this.actor.getReveActuel(), | ||||||
|       competence: this.actor.getBestDraconic(), |       competence: this.actor.getBestDraconic(), | ||||||
|       rencontre: this.currentRencontre, |       rencontre: this.currentRencontre, | ||||||
| @@ -1098,7 +1098,10 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     if (!this.viewOnly && this.actor.isResonanceSigneDraconique(coord)) { |     if (!this.viewOnly && this.actor.isResonanceSigneDraconique(coord)) { | ||||||
|       ChatMessage.create({ |       ChatMessage.create({ | ||||||
|         whisper: ChatUtility.getOwners(this.actor), |         whisper: ChatUtility.getOwners(this.actor), | ||||||
|         content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html`, { alias: this.actor.name, typeTMR: TMRUtility.getTMRType(coord) }) |         content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html`, { | ||||||
|  |           alias: this.actor.getAlias(), | ||||||
|  |           typeTMR: TMRUtility.getTMRType(coord) | ||||||
|  |         }) | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -28,16 +28,15 @@ export class RdDTokenHud { | |||||||
|     await RdDTokenHud.addExtensionHudSoins(html, actor); |     await RdDTokenHud.addExtensionHudSoins(html, actor); | ||||||
|  |  | ||||||
|     if (isCombat) { |     if (isCombat) { | ||||||
|       let combatant = game.combat.combatants.find(c => c.tokenId == tokenId); |       const combatant = game.combat.combatants.find(c => c.tokenId == tokenId) | ||||||
|       if (!(combatant?.actor)) { |       const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false }) | ||||||
|         ui.notifications.warn(`Le combatant ${token.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`) |       if (actor) { | ||||||
|         return; |         let actions = RdDCombatManager.listActionsActorCombatant(actor) | ||||||
|       } |  | ||||||
|       let actions = RdDCombatManager.listActionsCombat(combatant); |  | ||||||
|         // initiative |         // initiative | ||||||
|       await RdDTokenHud.addExtensionHudInit(html, combatant, actions); |         await RdDTokenHud.addExtensionHudInit(html, combatant, actions) | ||||||
|         // combat |         // combat | ||||||
|       await RdDTokenHud.addExtensionHudCombat(html, combatant, actions); |         await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions) | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -68,8 +67,8 @@ export class RdDTokenHud { | |||||||
|       }); |       }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async addExtensionHudCombat(html, combatant, actions) { |   static async addExtensionHudCombat(html, combatant, token, actions) { | ||||||
|     const hudData = { combatant, actions, commandes: [] }; |     const hudData = { combatant, token, actions, commandes: [] }; | ||||||
|     const controlIconTarget = html.find('.control-icon[data-action=target]'); |     const controlIconTarget = html.find('.control-icon[data-action=target]'); | ||||||
|     await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData, |     await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData, | ||||||
|       (event) => { |       (event) => { | ||||||
| @@ -80,7 +79,7 @@ export class RdDTokenHud { | |||||||
|           combatant.actor.conjurerPossession(possession); |           combatant.actor.conjurerPossession(possession); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|           combatant.actor.rollArme(action); |           combatant.actor.rollArme(action, 'competence', token) | ||||||
|         } |         } | ||||||
|       }); |       }); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -563,14 +563,14 @@ export class RdDUtility { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async jetEncaissement(rollData, armure, options = { showDice: HIDE_DICE }) { |   static async jetEncaissement(actor, rollData, armure, options = { showDice: HIDE_DICE }) { | ||||||
|     const diff = Math.abs(rollData.diffLibre); |     const diff = Math.abs(rollData.diffLibre); | ||||||
|     let formula = RdDUtility.formuleEncaissement(diff, options) |     let formula = RdDUtility.formuleEncaissement(diff, options) | ||||||
|     const roll = await RdDDice.roll(formula, options); |     const roll = await RdDDice.roll(formula, options); | ||||||
|  |  | ||||||
|     RdDUtility.remplaceDeMinParDifficulte(roll, diff, options); |     RdDUtility.remplaceDeMinParDifficulte(roll, diff, options); | ||||||
|  |  | ||||||
|     return await RdDUtility.prepareEncaissement(rollData, roll, armure); |     return await RdDUtility.prepareEncaissement(actor, rollData, roll, armure); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static remplaceDeMinParDifficulte(roll, diff, options) { |   static remplaceDeMinParDifficulte(roll, diff, options) { | ||||||
| @@ -602,15 +602,20 @@ export class RdDUtility { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async prepareEncaissement(rollData, roll, armure) { |   static async prepareEncaissement(actor, rollData, roll, armure) { | ||||||
|     // La difficulté d'ataque s'ajoute aux dégâts |     // La difficulté d'ataque s'ajoute aux dégâts | ||||||
|     const bonusDegatsDiffLibre = ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(rollData.diffLibre ?? 0) : 0 |     const bonusDegatsDiffLibre = ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(rollData.diffLibre ?? 0) : 0 | ||||||
|     const jetTotal = roll.total + rollData.dmg.total - armure + bonusDegatsDiffLibre |     const jetTotal = roll.total + rollData.dmg.total - armure + bonusDegatsDiffLibre | ||||||
|     const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite); |     const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite); | ||||||
|     const over20 = Math.max(jetTotal - 20, 0); |     const over20 = Math.max(jetTotal - 20, 0); | ||||||
|     encaissement.dmg = rollData.dmg; |     encaissement.dmg = rollData.dmg | ||||||
|     encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type); |     if (ReglesOptionnelles.isUsing('localisation-aleatoire')) { | ||||||
|     encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'; |       encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(actor.type) | ||||||
|  |       encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;' | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       encaissement.dmg.loc = { label: '' } | ||||||
|  |     } | ||||||
|     encaissement.dmg.bonusDegatsDiffLibre = bonusDegatsDiffLibre |     encaissement.dmg.bonusDegatsDiffLibre = bonusDegatsDiffLibre | ||||||
|     encaissement.roll = roll; |     encaissement.roll = roll; | ||||||
|     encaissement.armure = armure; |     encaissement.armure = armure; | ||||||
| @@ -741,6 +746,15 @@ export class RdDUtility { | |||||||
|     return undefined; |     return undefined; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static getSelectedToken(actor) { | ||||||
|  |     if (canvas.tokens.controlled.length > 0) { | ||||||
|  |       const tokens = canvas.tokens.controlled | ||||||
|  |         .filter(it => it.actor.id == actor.id) | ||||||
|  |       return tokens[0] | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static getSelectedActor(msgPlayer = undefined) { |   static getSelectedActor(msgPlayer = undefined) { | ||||||
|     if (canvas.tokens.controlled.length == 1) { |     if (canvas.tokens.controlled.length == 1) { | ||||||
|       let token = canvas.tokens.controlled[0]; |       let token = canvas.tokens.controlled[0]; | ||||||
| @@ -867,10 +881,10 @@ export class RdDUtility { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static afficherHeuresChanceMalchance(heureNaissance) { |   static afficherHeuresChanceMalchance(heureNaissance) { | ||||||
|     if (game.user.isGM) { |     if (game.user.isGM) { | ||||||
|       const heure = RdDTimestamp.findHeure(heureNaissance - 1); |       const heure = RdDTimestamp.findHeure(heureNaissance) | ||||||
|       if (heureNaissance && heure) { |       if (heureNaissance && heure) { | ||||||
|         let ajustement = game.system.rdd.calendrier.getAjustementAstrologique(heureNaissance); |         const ajustement = game.system.rdd.calendrier.getAjustementAstrologique(heureNaissance) | ||||||
|         const current = game.system.rdd.calendrier.heureCourante(); |         const current = game.system.rdd.calendrier.heureCourante() | ||||||
|         ChatMessage.create({ |         ChatMessage.create({ | ||||||
|           content: `A l'heure de <strong>${current.label}</strong>, le modificateur de Chance/Malchance est de <strong>${Misc.toSignedString(ajustement)}</strong> pour l'heure de naissance <strong>${heure.label}</strong>.`, |           content: `A l'heure de <strong>${current.label}</strong>, le modificateur de Chance/Malchance est de <strong>${Misc.toSignedString(ajustement)}</strong> pour l'heure de naissance <strong>${heure.label}</strong>.`, | ||||||
|           whisper: ChatUtility.getGMs() |           whisper: ChatUtility.getGMs() | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ const listeReglesOptionnelles = [ | |||||||
|   { group: 'Récupération', name: 'recuperation-moral',              descr: "Le moral revient vers 0 durant Château Dormant"}, |   { group: 'Récupération', name: 'recuperation-moral',              descr: "Le moral revient vers 0 durant Château Dormant"}, | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   { group: 'Règles de combat', name: 'localisation-aleatoire',      descr: "Proposer une localisation aléatoire des blessures" }, | ||||||
|   { 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" }, | ||||||
|   { group: 'Règles de combat', name: 'resistanceArmeParade',        descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" }, |   { group: 'Règles de combat', name: 'resistanceArmeParade',        descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" }, | ||||||
|   { group: 'Règles de combat', name: 'deteriorationArmure',         descr: "Tenir compte de la détérioration des armures" }, |   { group: 'Règles de combat', name: 'deteriorationArmure',         descr: "Tenir compte de la détérioration des armures" }, | ||||||
|   | |||||||
| @@ -15,17 +15,17 @@ export const STATUSES = { | |||||||
| } | } | ||||||
|  |  | ||||||
| const rddStatusEffects = [ | const rddStatusEffects = [ | ||||||
|   { rdd: true, id: STATUSES.StatusStunned, label: 'EFFECT.StatusStunned', icon: 'icons/svg/stoned.svg', "duration.rounds": 1 }, |   { rdd: true, id: STATUSES.StatusStunned, name:  'EFFECT.StatusStunned', img: 'icons/svg/stoned.svg', "duration.rounds": 1 }, | ||||||
|   { rdd: true, id: STATUSES.StatusBleeding, label: 'EFFECT.StatusBleeding', icon: 'icons/svg/blood.svg' }, |   { rdd: true, id: STATUSES.StatusBleeding, name:  'EFFECT.StatusBleeding', img: 'icons/svg/blood.svg' }, | ||||||
|   { rdd: true, id: STATUSES.StatusProne, label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg' }, |   { rdd: true, id: STATUSES.StatusProne, name:  'EFFECT.StatusProne', img: 'icons/svg/falling.svg' }, | ||||||
|   { rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' }, |   { rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', name:  'EFFECT.StatusGrappling', img: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' }, | ||||||
|   { rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' }, |   { rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', name:  'EFFECT.StatusGrappled', img: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' }, | ||||||
|   { rdd: true, id: STATUSES.StatusRestrained, label: 'EFFECT.StatusRestrained', icon: 'icons/svg/net.svg' }, |   { rdd: true, id: STATUSES.StatusRestrained, name:  'EFFECT.StatusRestrained', img: 'icons/svg/net.svg' }, | ||||||
|   { rdd: true, id: STATUSES.StatusUnconscious, label: 'EFFECT.StatusUnconscious', icon: 'icons/svg/unconscious.svg' }, |   { rdd: true, id: STATUSES.StatusUnconscious, name:  'EFFECT.StatusUnconscious', img: 'icons/svg/unconscious.svg' }, | ||||||
|   { rdd: true, id: STATUSES.StatusBlind, label: 'EFFECT.StatusBlind', icon: 'icons/svg/blind.svg' }, |   { rdd: true, id: STATUSES.StatusBlind, name:  'EFFECT.StatusBlind', img: 'icons/svg/blind.svg' }, | ||||||
|   { rdd: true, id: STATUSES.StatusComma, label: 'EFFECT.StatusComma', icon: 'icons/svg/skull.svg' }, |   { rdd: true, id: STATUSES.StatusComma, name:  'EFFECT.StatusComma', img: 'icons/svg/skull.svg' }, | ||||||
|   { rdd: true, id: STATUSES.StatusDead, label: 'EFFECT.StatusDead', icon: 'icons/svg/skull.svg' }, |   { rdd: true, id: STATUSES.StatusDead, name:  'EFFECT.StatusDead', img: 'icons/svg/skull.svg' }, | ||||||
|   { rdd: true, id: STATUSES.StatusDemiReve, label: 'EFFECT.StatusDemiReve', icon: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' } |   { rdd: true, id: STATUSES.StatusDemiReve, name:  'EFFECT.StatusDemiReve', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' } | ||||||
| ]; | ]; | ||||||
| const demiReveStatusEffect = rddStatusEffects.find(it => it.id == STATUSES.StatusDemiReve); | const demiReveStatusEffect = rddStatusEffects.find(it => it.id == STATUSES.StatusDemiReve); | ||||||
|  |  | ||||||
| @@ -57,7 +57,7 @@ export class StatusEffects extends FormApplication { | |||||||
|       restricted: true |       restricted: true | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     CONFIG.RDD.allEffects = rddStatusEffects.concat(CONFIG.statusEffects.filter(it => !rddEffectIds.includes(it.id))); |     CONFIG.RDD.allEffects = rddStatusEffects.concat(CONFIG.statusEffects.filter(it => !rddEffectIds.includes(it.id))) | ||||||
|  |  | ||||||
|     StatusEffects._setUseStatusEffects(StatusEffects._getUseStatusEffects()); |     StatusEffects._setUseStatusEffects(StatusEffects._getUseStatusEffects()); | ||||||
|     console.log('statusEffects', CONFIG.statusEffects); |     console.log('statusEffects', CONFIG.statusEffects); | ||||||
|   | |||||||
| @@ -112,6 +112,19 @@ export class SystemCompendiums extends FormApplication { | |||||||
|     return elements; |     return elements; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   static async loadCompendiumData(compendium) { | ||||||
|  |     const pack = game.packs.get(compendium); | ||||||
|  |     return await pack?.getDocuments() ?? []; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   static async loadCompendium(compendium, filter = item => true) { | ||||||
|  |     let compendiumData = await SystemCompendiums.loadCompendiumData(compendium); | ||||||
|  |     return compendiumData.filter(filter); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   static async getDefaultItems(compendium) { |   static async getDefaultItems(compendium) { | ||||||
|     const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium)); |     const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium)); | ||||||
|     if (pack.metadata.type == 'Item') { |     if (pack.metadata.type == 'Item') { | ||||||
|   | |||||||
| @@ -186,7 +186,7 @@ export class AppAstrologie extends Application { | |||||||
|       date: this.html.find('[name="joursAstrologie"]').val(), |       date: this.html.find('[name="joursAstrologie"]').val(), | ||||||
|       userId: game.user.id |       userId: game.user.id | ||||||
|     } |     } | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       game.system.rdd.calendrier.requestNombreAstral(socketData); |       game.system.rdd.calendrier.requestNombreAstral(socketData); | ||||||
|     } else { |     } else { | ||||||
|       game.socket.emit(SYSTEM_SOCKET_ID, { |       game.socket.emit(SYSTEM_SOCKET_ID, { | ||||||
|   | |||||||
| @@ -13,18 +13,21 @@ export class Targets { | |||||||
|   static extractTokenData(target) { |   static extractTokenData(target) { | ||||||
|     return { id: target?.id, name: target?.document.name, img: target?.document.texture.src ?? target?.actor.img ?? 'icons/svg/mystery-man.svg' }; |     return { id: target?.id, name: target?.document.name, img: target?.document.texture.src ?? target?.actor.img ?? 'icons/svg/mystery-man.svg' }; | ||||||
|   } |   } | ||||||
|  |   static buildActorTokenData(tokenId, actor) { | ||||||
|  |     return { id: tokenId, name: actor.name, img: actor.img ?? 'icons/svg/mystery-man.svg' }; | ||||||
|  |   } | ||||||
|   static isTargetEntite(target) { |   static isTargetEntite(target) { | ||||||
|     return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE; |     return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async selectOneToken(onSelectTarget = target => { }) { |   static async selectOneTargetToken(onSelectTarget = target => { }) { | ||||||
|     const targets = Targets.listTargets(); |     const targets = Targets.listTargets() | ||||||
|     switch (targets.length) { |     switch (targets.length) { | ||||||
|       case 0: return; |       case 0: | ||||||
|  |         return | ||||||
|       case 1: |       case 1: | ||||||
|         onSelectTarget(targets[0]); |         onSelectTarget(targets[0]) | ||||||
|         return; |         return | ||||||
|       default: |       default: | ||||||
|         { |         { | ||||||
|           const selectData = { |           const selectData = { | ||||||
| @@ -32,7 +35,7 @@ export class Targets { | |||||||
|             label: "Choisir une seule des cibles", |             label: "Choisir une seule des cibles", | ||||||
|             list: targets.map(it => Targets.extractTokenData(it)) |             list: targets.map(it => Targets.extractTokenData(it)) | ||||||
|           }; |           }; | ||||||
|           DialogSelect.select(selectData, onSelectTarget); |           DialogSelect.select(selectData, onSelectTarget) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ export class AutoAdjustDarkness { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async adjust(darkness) { |   static async adjust(darkness) { | ||||||
|     if (AutoAdjustDarkness.isAuto()) { |     if (game.user.isGM && AutoAdjustDarkness.isAuto()) { | ||||||
|       const scene = game.scenes.viewed; |       const scene = game.scenes.viewed; | ||||||
|       if (scene?.environment?.globalLight?.enabled && scene?.tokenVision) { |       if (scene?.environment?.globalLight?.enabled && scene?.tokenVision) { | ||||||
|         await scene.update({ darkness }); |         await scene.update({ darkness }); | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ export class RdDCalendrier extends Application { | |||||||
|   constructor() { |   constructor() { | ||||||
|     super(); |     super(); | ||||||
|     this.timestamp = RdDTimestamp.getWorldTime(); |     this.timestamp = RdDTimestamp.getWorldTime(); | ||||||
|     if (Misc.isUniqueConnectedGM()) { // Uniquement si GM |     if (Misc.isFirstConnectedGM()) { // Uniquement si GM | ||||||
|       RdDTimestamp.setWorldTime(this.timestamp); |       RdDTimestamp.setWorldTime(this.timestamp); | ||||||
|       this.rebuildNombresAstraux(); // Ensure always up-to-date |       this.rebuildNombresAstraux(); // Ensure always up-to-date | ||||||
|     } |     } | ||||||
| @@ -258,7 +258,7 @@ export class RdDCalendrier extends Application { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rebuildNombresAstraux() { |   async rebuildNombresAstraux() { | ||||||
|     if (Misc.isUniqueConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       const nombresAstraux = this.getNombresAstraux() |       const nombresAstraux = this.getNombresAstraux() | ||||||
|       let newNombresAstraux = []; |       let newNombresAstraux = []; | ||||||
|       for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) { |       for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) { | ||||||
| @@ -337,7 +337,7 @@ export class RdDCalendrier extends Application { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async requestNombreAstral(request) { |   async requestNombreAstral(request) { | ||||||
|     const actor = game.actors.get(request.id); |     const actor = game.actors.get(request.id); | ||||||
|     if (Misc.isUniqueConnectedGM()) { // Only once |     if (Misc.isFirstConnectedGM()) { // Only once | ||||||
|       console.log(request); |       console.log(request); | ||||||
|       let jourDiff = this.getLectureAstrologieDifficulte(request.date); |       let jourDiff = this.getLectureAstrologieDifficulte(request.date); | ||||||
|       let niveau = Number(request.astrologie.system.niveau) + Number(request.conditions) + Number(jourDiff) + Number(request.etat); |       let niveau = Number(request.astrologie.system.niveau) + Number(request.conditions) + Number(jourDiff) + Number(request.etat); | ||||||
|   | |||||||
| @@ -160,15 +160,21 @@ export class RdDTimestamp { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static findHeure(heure) { |   static findHeure(heure) { | ||||||
|     heure = Grammar.toLowerCaseNoAccentNoSpace(heure); |     let filtered | ||||||
|     let parHeureOuLabel = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure || it.heure == Misc.modulo(parseInt(heure), RDD_HEURES_PAR_JOUR)); |     if (Number.isInteger(Number(heure))) { | ||||||
|     if (parHeureOuLabel.length == 1) { |       filtered = DEFINITION_HEURES.filter(it => it.heure == Misc.modulo(Number(heure) - 1, RDD_HEURES_PAR_JOUR)) | ||||||
|       return parHeureOuLabel[0]; |  | ||||||
|     } |     } | ||||||
|     let parLabelPartiel = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label).includes(heure)); |     else { | ||||||
|     if (parLabelPartiel.length > 0) { |       heure = Grammar.toLowerCaseNoAccentNoSpace(heure); | ||||||
|       parLabelPartiel.sort(Misc.ascending(h => h.label.length)); |       filtered = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure || it.heure == Misc.modulo(parseInt(heure), RDD_HEURES_PAR_JOUR)); | ||||||
|       return parLabelPartiel[0]; |     } | ||||||
|  |     if (filtered.length == 1) { | ||||||
|  |       return filtered[0] | ||||||
|  |     } | ||||||
|  |     filtered = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label).includes(heure)); | ||||||
|  |     if (filtered.length > 0) { | ||||||
|  |       filtered.sort(Misc.ascending(h => h.label.length)); | ||||||
|  |       return filtered[0] | ||||||
|     } |     } | ||||||
|     return undefined; |     return undefined; | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/animaux/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/animaux/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								pack_ref/animaux/000023.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/animaux/000023.log
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								pack_ref/animaux/CURRENT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pack_ref/animaux/CURRENT
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | MANIFEST-000022 | ||||||
							
								
								
									
										0
									
								
								pack_ref/animaux/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/animaux/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								pack_ref/animaux/LOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pack_ref/animaux/LOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | 2024/11/10-18:39:00.183093 7fed63e006c0 Recovering log #21 | ||||||
|  | 2024/11/10-18:39:00.195436 7fed63e006c0 Delete type=0 #21 | ||||||
|  | 2024/11/10-18:39:00.195482 7fed63e006c0 Delete type=3 #20 | ||||||
							
								
								
									
										3
									
								
								pack_ref/animaux/LOG.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pack_ref/animaux/LOG.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | 2024/11/10-18:38:41.533242 7f4c0b8006c0 Recovering log #19 | ||||||
|  | 2024/11/10-18:38:41.547823 7f4c0b8006c0 Delete type=0 #19 | ||||||
|  | 2024/11/10-18:38:41.547917 7f4c0b8006c0 Delete type=3 #18 | ||||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/animaux/MANIFEST-000022
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/animaux/MANIFEST-000022
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								pack_ref/archetypes/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/archetypes/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								pack_ref/archetypes/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/archetypes/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								pack_ref/archetypes/CURRENT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pack_ref/archetypes/CURRENT
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | MANIFEST-000010 | ||||||
							
								
								
									
										0
									
								
								pack_ref/archetypes/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/archetypes/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								pack_ref/archetypes/LOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pack_ref/archetypes/LOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | 2024/11/10-18:39:00.253481 7fed62a006c0 Recovering log #8 | ||||||
|  | 2024/11/10-18:39:00.263751 7fed62a006c0 Delete type=3 #6 | ||||||
|  | 2024/11/10-18:39:00.263866 7fed62a006c0 Delete type=0 #8 | ||||||
							
								
								
									
										8
									
								
								pack_ref/archetypes/LOG.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pack_ref/archetypes/LOG.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | 2024/11/08-19:40:34.139501 7f9d7f4006c0 Recovering log #4 | ||||||
|  | 2024/11/08-19:40:34.182207 7f9d7f4006c0 Delete type=3 #2 | ||||||
|  | 2024/11/08-19:40:34.182311 7f9d7f4006c0 Delete type=0 #4 | ||||||
|  | 2024/11/08-19:56:45.129455 7f9d7d6006c0 Level-0 table #9: started | ||||||
|  | 2024/11/08-19:56:45.129487 7f9d7d6006c0 Level-0 table #9: 0 bytes OK | ||||||
|  | 2024/11/08-19:56:45.135738 7f9d7d6006c0 Delete type=0 #7 | ||||||
|  | 2024/11/08-19:56:45.142639 7f9d7d6006c0 Manual compaction at level-0 from '!actors!1Nng9d8r6lrPHCaJ' @ 72057594037927935 : 1 .. '!actors.items!ryUZTa17LzNv25UY.zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end) | ||||||
|  | 2024/11/08-19:56:45.142697 7f9d7d6006c0 Manual compaction at level-1 from '!actors!1Nng9d8r6lrPHCaJ' @ 72057594037927935 : 1 .. '!actors.items!ryUZTa17LzNv25UY.zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end) | ||||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/archetypes/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/archetypes/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								pack_ref/arts-et-divertissements/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/arts-et-divertissements/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								pack_ref/arts-et-divertissements/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/arts-et-divertissements/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								pack_ref/arts-et-divertissements/CURRENT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pack_ref/arts-et-divertissements/CURRENT
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | MANIFEST-000010 | ||||||
							
								
								
									
										0
									
								
								pack_ref/arts-et-divertissements/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/arts-et-divertissements/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								pack_ref/arts-et-divertissements/LOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pack_ref/arts-et-divertissements/LOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | 2024/11/10-18:39:00.448675 7fed63e006c0 Recovering log #8 | ||||||
|  | 2024/11/10-18:39:00.460061 7fed63e006c0 Delete type=3 #6 | ||||||
|  | 2024/11/10-18:39:00.460115 7fed63e006c0 Delete type=0 #8 | ||||||
							
								
								
									
										8
									
								
								pack_ref/arts-et-divertissements/LOG.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pack_ref/arts-et-divertissements/LOG.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | 2024/11/08-19:40:32.605216 7f9d7fe006c0 Recovering log #4 | ||||||
|  | 2024/11/08-19:40:32.664872 7f9d7fe006c0 Delete type=3 #2 | ||||||
|  | 2024/11/08-19:40:32.665020 7f9d7fe006c0 Delete type=0 #4 | ||||||
|  | 2024/11/08-19:56:44.948429 7f9d7d6006c0 Level-0 table #9: started | ||||||
|  | 2024/11/08-19:56:44.948495 7f9d7d6006c0 Level-0 table #9: 0 bytes OK | ||||||
|  | 2024/11/08-19:56:44.954943 7f9d7d6006c0 Delete type=0 #7 | ||||||
|  | 2024/11/08-19:56:44.975424 7f9d7d6006c0 Manual compaction at level-0 from '!items!240HPtZsgZQERFMF' @ 72057594037927935 : 1 .. '!items!zRQ5WnPI483CKm9Q' @ 0 : 0; will stop at (end) | ||||||
|  | 2024/11/08-19:56:44.975473 7f9d7d6006c0 Manual compaction at level-1 from '!items!240HPtZsgZQERFMF' @ 72057594037927935 : 1 .. '!items!zRQ5WnPI483CKm9Q' @ 0 : 0; will stop at (end) | ||||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/arts-et-divertissements/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/arts-et-divertissements/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								pack_ref/competences-creatures/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/competences-creatures/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								pack_ref/competences-creatures/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/competences-creatures/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								pack_ref/competences-creatures/CURRENT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pack_ref/competences-creatures/CURRENT
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | MANIFEST-000010 | ||||||
							
								
								
									
										0
									
								
								pack_ref/competences-creatures/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/competences-creatures/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								pack_ref/competences-creatures/LOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pack_ref/competences-creatures/LOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | 2024/11/10-18:39:00.493027 7fed63e006c0 Recovering log #8 | ||||||
|  | 2024/11/10-18:39:00.503119 7fed63e006c0 Delete type=3 #6 | ||||||
|  | 2024/11/10-18:39:00.503242 7fed63e006c0 Delete type=0 #8 | ||||||
							
								
								
									
										8
									
								
								pack_ref/competences-creatures/LOG.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pack_ref/competences-creatures/LOG.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | 2024/11/08-19:40:32.670029 7f9d7ea006c0 Recovering log #4 | ||||||
|  | 2024/11/08-19:40:32.734322 7f9d7ea006c0 Delete type=3 #2 | ||||||
|  | 2024/11/08-19:40:32.734474 7f9d7ea006c0 Delete type=0 #4 | ||||||
|  | 2024/11/08-19:56:44.968549 7f9d7d6006c0 Level-0 table #9: started | ||||||
|  | 2024/11/08-19:56:44.968601 7f9d7d6006c0 Level-0 table #9: 0 bytes OK | ||||||
|  | 2024/11/08-19:56:44.975299 7f9d7d6006c0 Delete type=0 #7 | ||||||
|  | 2024/11/08-19:56:44.975466 7f9d7d6006c0 Manual compaction at level-0 from '!items!0zRL8bOpCXNQnIR4' @ 72057594037927935 : 1 .. '!items!yDHZfK4RmwQW4YaW' @ 0 : 0; will stop at (end) | ||||||
|  | 2024/11/08-19:56:44.975488 7f9d7d6006c0 Manual compaction at level-1 from '!items!0zRL8bOpCXNQnIR4' @ 72057594037927935 : 1 .. '!items!yDHZfK4RmwQW4YaW' @ 0 : 0; will stop at (end) | ||||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/competences-creatures/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/competences-creatures/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								pack_ref/competences-entites/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/competences-entites/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								pack_ref/competences-entites/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/competences-entites/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								pack_ref/competences-entites/CURRENT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pack_ref/competences-entites/CURRENT
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | MANIFEST-000010 | ||||||
							
								
								
									
										0
									
								
								pack_ref/competences-entites/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/competences-entites/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								pack_ref/competences-entites/LOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pack_ref/competences-entites/LOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | 2024/11/10-18:39:00.509122 7fed634006c0 Recovering log #8 | ||||||
|  | 2024/11/10-18:39:00.519320 7fed634006c0 Delete type=3 #6 | ||||||
|  | 2024/11/10-18:39:00.519377 7fed634006c0 Delete type=0 #8 | ||||||
							
								
								
									
										8
									
								
								pack_ref/competences-entites/LOG.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pack_ref/competences-entites/LOG.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | 2024/11/08-19:40:32.738419 7f9d7f4006c0 Recovering log #4 | ||||||
|  | 2024/11/08-19:40:32.795459 7f9d7f4006c0 Delete type=3 #2 | ||||||
|  | 2024/11/08-19:40:32.795589 7f9d7f4006c0 Delete type=0 #4 | ||||||
|  | 2024/11/08-19:56:44.996588 7f9d7d6006c0 Level-0 table #9: started | ||||||
|  | 2024/11/08-19:56:44.996618 7f9d7d6006c0 Level-0 table #9: 0 bytes OK | ||||||
|  | 2024/11/08-19:56:45.003008 7f9d7d6006c0 Delete type=0 #7 | ||||||
|  | 2024/11/08-19:56:45.003203 7f9d7d6006c0 Manual compaction at level-0 from '!items!0Ms9iKxqigNNpZEx' @ 72057594037927935 : 1 .. '!items!wDHR5UHWq568lfGa' @ 0 : 0; will stop at (end) | ||||||
|  | 2024/11/08-19:56:45.003226 7f9d7d6006c0 Manual compaction at level-1 from '!items!0Ms9iKxqigNNpZEx' @ 72057594037927935 : 1 .. '!items!wDHR5UHWq568lfGa' @ 0 : 0; will stop at (end) | ||||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/competences-entites/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/competences-entites/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								pack_ref/competences/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/competences/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								pack_ref/competences/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/competences/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								pack_ref/competences/CURRENT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pack_ref/competences/CURRENT
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | MANIFEST-000010 | ||||||
							
								
								
									
										0
									
								
								pack_ref/competences/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/competences/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								pack_ref/competences/LOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pack_ref/competences/LOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | 2024/11/10-18:39:00.471288 7fed63e006c0 Recovering log #8 | ||||||
|  | 2024/11/10-18:39:00.481737 7fed63e006c0 Delete type=3 #6 | ||||||
|  | 2024/11/10-18:39:00.481786 7fed63e006c0 Delete type=0 #8 | ||||||
							
								
								
									
										8
									
								
								pack_ref/competences/LOG.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pack_ref/competences/LOG.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | 2024/11/08-19:40:32.544114 7f9d7e0006c0 Recovering log #4 | ||||||
|  | 2024/11/08-19:40:32.600711 7f9d7e0006c0 Delete type=3 #2 | ||||||
|  | 2024/11/08-19:40:32.600809 7f9d7e0006c0 Delete type=0 #4 | ||||||
|  | 2024/11/08-19:56:44.962085 7f9d7d6006c0 Level-0 table #9: started | ||||||
|  | 2024/11/08-19:56:44.962125 7f9d7d6006c0 Level-0 table #9: 0 bytes OK | ||||||
|  | 2024/11/08-19:56:44.968340 7f9d7d6006c0 Delete type=0 #7 | ||||||
|  | 2024/11/08-19:56:44.975455 7f9d7d6006c0 Manual compaction at level-0 from '!items!2JLK5e97WbTM5WxX' @ 72057594037927935 : 1 .. '!items!zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end) | ||||||
|  | 2024/11/08-19:56:44.975495 7f9d7d6006c0 Manual compaction at level-1 from '!items!2JLK5e97WbTM5WxX' @ 72057594037927935 : 1 .. '!items!zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end) | ||||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/competences/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/competences/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								pack_ref/entites-de-cauchemar/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/entites-de-cauchemar/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								pack_ref/entites-de-cauchemar/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/entites-de-cauchemar/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								pack_ref/entites-de-cauchemar/CURRENT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pack_ref/entites-de-cauchemar/CURRENT
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | MANIFEST-000010 | ||||||
							
								
								
									
										0
									
								
								pack_ref/entites-de-cauchemar/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/entites-de-cauchemar/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								pack_ref/entites-de-cauchemar/LOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pack_ref/entites-de-cauchemar/LOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | 2024/11/10-18:39:00.523722 7fed690006c0 Recovering log #8 | ||||||
|  | 2024/11/10-18:39:00.533930 7fed690006c0 Delete type=3 #6 | ||||||
|  | 2024/11/10-18:39:00.533977 7fed690006c0 Delete type=0 #8 | ||||||
							
								
								
									
										8
									
								
								pack_ref/entites-de-cauchemar/LOG.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pack_ref/entites-de-cauchemar/LOG.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | 2024/11/08-19:40:34.274388 7f9d7f4006c0 Recovering log #4 | ||||||
|  | 2024/11/08-19:40:34.331636 7f9d7f4006c0 Delete type=3 #2 | ||||||
|  | 2024/11/08-19:40:34.331841 7f9d7f4006c0 Delete type=0 #4 | ||||||
|  | 2024/11/08-19:56:45.135878 7f9d7d6006c0 Level-0 table #9: started | ||||||
|  | 2024/11/08-19:56:45.135910 7f9d7d6006c0 Level-0 table #9: 0 bytes OK | ||||||
|  | 2024/11/08-19:56:45.142458 7f9d7d6006c0 Delete type=0 #7 | ||||||
|  | 2024/11/08-19:56:45.142680 7f9d7d6006c0 Manual compaction at level-0 from '!actors!47YUryMgpq1UnLuB' @ 72057594037927935 : 1 .. '!actors.items!xngqS9HtwWOLf3Vo.iwfr7ekbLFzDCayP' @ 0 : 0; will stop at (end) | ||||||
|  | 2024/11/08-19:56:45.142706 7f9d7d6006c0 Manual compaction at level-1 from '!actors!47YUryMgpq1UnLuB' @ 72057594037927935 : 1 .. '!actors.items!xngqS9HtwWOLf3Vo.iwfr7ekbLFzDCayP' @ 0 : 0; will stop at (end) | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user