Compare commits
	
		
			45 Commits
		
	
	
		
			foundryvtt
			...
			build-test
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 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}}/foundryvtt-reve-de-dragon-${{github.event.release.tag_name}}.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 ./foundryvtt-reve-de-dragon-${{github.event.release.tag_name}}.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: |- | ||||
|           ./foundryvtt-reve-de-dragon-${{github.event.release.tag_name}}.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 | 
							
								
								
									
										27
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,4 +1,31 @@ | ||||
| # 12.0 | ||||
| ## 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 | ||||
| - Correction des faces de dés personalisés dice-so-nice | ||||
| - Les messages de maladies ne sont plus publics | ||||
|   | ||||
| @@ -220,18 +220,18 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | ||||
|     // Points de reve actuel | ||||
|     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('.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 | ||||
|     this.html.find('.arme-initiative a').click(async event => { | ||||
|       let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id); | ||||
|     this.html.find('.roll-init-arme').click(async event => { | ||||
|       let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id) | ||||
|       if (combatant) { | ||||
|         let action = this._getEventArmeCombat(event); | ||||
|         RdDCombatManager.rollInitiativeAction(combatant._id, action); | ||||
|         RdDCombatManager.rollInitiativeAction(combatant._id, this._getEventArmeCombat(event)); | ||||
|       } else { | ||||
|         ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat."); | ||||
|       } | ||||
|     }); | ||||
|     }) | ||||
|     // Display TMR | ||||
|  | ||||
|     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 { RdDCoeur } from "./coeur/rdd-coeur.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'] | ||||
|  | ||||
| @@ -130,6 +132,23 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       .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.empoignade(this)) | ||||
|         .concat(RdDItemArme.mainsNues(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') } | ||||
|   getMeditation(id) { return this.findItemLike(id, 'meditation') } | ||||
| @@ -1548,7 +1567,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { | ||||
|     if (!Misc.firstConnectedGM()){ | ||||
|     if (!Misc.isFirstConnectedGM()) { | ||||
|       return | ||||
|     } | ||||
|     hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM) | ||||
| @@ -2615,7 +2634,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async resetItemUse() { | ||||
|     await this.setFlag(SYSTEM_RDD, 'itemUse', {}); | ||||
|     await this.unsetFlag(SYSTEM_RDD, 'itemUse'); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -3011,7 +3030,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async onCreateOwnedDraconique(item, options, id) { | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       let draconique = Draconique.all().find(it => it.match(item)); | ||||
|       if (draconique) { | ||||
|         await draconique.onActorCreateOwned(this, item) | ||||
| @@ -3023,7 +3042,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async onDeleteOwnedDraconique(item, options, id) { | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       let draconique = Draconique.all().find(it => it.match(item)); | ||||
|       if (draconique) { | ||||
|         await draconique.onActorDeleteOwned(this, item) | ||||
| @@ -3033,7 +3052,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async onDeleteOwnedCaseTmr(item, options, id) { | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       let draconique = Draconique.all().find(it => it.isCase(item)); | ||||
|       if (draconique) { | ||||
|         await draconique.onActorDeleteCaseTmr(this, item) | ||||
| @@ -3067,7 +3086,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     incarnation.name = 'Réincarnation de ' + incarnation.name | ||||
|     incarnation.system = { | ||||
|       carac: foundry.utils.duplicate(this.system.carac), | ||||
|       heure: RdDTimestamp.defHeure(await RdDDice.rollHeure( { rollMode: "selfroll", showDice: SHOW_DICE })).key, | ||||
|       heure: RdDTimestamp.defHeure(await RdDDice.rollHeure({ rollMode: "selfroll", showDice: SHOW_DICE })).key, | ||||
|       age: 18, | ||||
|       biographie: '', | ||||
|       notes: '', | ||||
|   | ||||
| @@ -15,7 +15,7 @@ import { StatusEffects } from "../settings/status-effects.js"; | ||||
| import { ITEM_TYPES } from "../item.js"; | ||||
| import { Targets } from "../targets.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 { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.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 } } | ||||
|   isDead() { return false } | ||||
|   isSonne() { return false } | ||||
|   blessuresASoigner() { return [] } | ||||
|   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 remiseANeuf() { } | ||||
| @@ -153,9 +172,6 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|   getPossession(possessionId) { | ||||
|     return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId); | ||||
|   } | ||||
|   getPossessions() { | ||||
|     return this.itemTypes[ITEM_TYPES.possession]; | ||||
|   } | ||||
|   getEmpoignades() { | ||||
|     return this.itemTypes[ITEM_TYPES.empoignade]; | ||||
|   } | ||||
| @@ -327,14 +343,15 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|     const competence = this.getCompetence(idOrName); | ||||
|     let rollData = { carac: this.system.carac, competence: competence, arme: options.arme } | ||||
|     if (competence.type == ITEM_TYPES.competencecreature) { | ||||
|       const token = RdDUtility.getSelectedToken(this) | ||||
|       const arme = RdDItemCompetenceCreature.armeCreature(competence) | ||||
|       if (arme && options.tryTarget && Targets.hasTargets()) { | ||||
|         Targets.selectOneToken(target => { | ||||
|         Targets.selectOneTargetToken(target => { | ||||
|           if (arme.action == "possession") { | ||||
|             RdDPossession.onAttaquePossession(target, this, competence) | ||||
|           } | ||||
|           else { | ||||
|             RdDCombat.rddCombatTarget(target, this).attaque(competence, arme) | ||||
|             RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme) | ||||
|           } | ||||
|         }); | ||||
|         return; | ||||
| @@ -364,9 +381,10 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|    * @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession | ||||
|    * @returns  | ||||
|    */ | ||||
|   rollArme(arme, categorieArme = "competence") { | ||||
|   rollArme(arme, categorieArme, token) { | ||||
|     token = token ?? RdDUtility.getSelectedToken(this) | ||||
|     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`) | ||||
|       return | ||||
|     } | ||||
| @@ -385,7 +403,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     Targets.selectOneToken(target => { | ||||
|     Targets.selectOneTargetToken(target => { | ||||
|       if (Targets.isTargetEntite(target)) { | ||||
|         ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`); | ||||
|         return | ||||
| @@ -395,7 +413,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|       if (competence.isCompetencePossession()) { | ||||
|         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) | ||||
|   } | ||||
|  | ||||
|   verifierForceMin(item) { | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   async resetItemUse() { } | ||||
|   async incDecItemUse(itemId, inc = 1) { } | ||||
|   getItemUse(itemId) { return 0; } | ||||
|   verifierForceMin(item) { } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   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')) { | ||||
|       return; | ||||
|     } | ||||
|     const armure = await this.computeArmure(rollData); | ||||
|     if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) { | ||||
|       await this.encaisserDommagesValidationGR(rollData, armure, attacker?.id, show); | ||||
|       await this.encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken); | ||||
|     } | ||||
|     else { | ||||
|       const jet = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE }); | ||||
|       await this.$onEncaissement(jet, show, attacker); | ||||
|       const jet = await RdDUtility.jetEncaissement(this, rollData, armure, { showDice: SHOW_DICE }); | ||||
|       await this.$onEncaissement(jet, show, attackerToken, defenderToken) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async encaisserDommagesValidationGR(rollData, armure, attackerId, show) { | ||||
|   async encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken) { | ||||
|     if (!game.user.isGM) { | ||||
|       RdDBaseActor.remoteActorCall({ | ||||
|         tokenId: this.token?.id, | ||||
|         actorId: this.id, | ||||
|         method: 'encaisserDommagesValidationGR', | ||||
|         args: [rollData, armure, attackerId, show] | ||||
|       }); | ||||
|         args: [rollData, armure, show, attackerToken, defenderToken] | ||||
|       }) | ||||
|     } else { | ||||
|       const attacker = game.actors.get(attackerId); | ||||
|       DialogValidationEncaissement.validerEncaissement(this, rollData, armure, | ||||
|         jet => this.$onEncaissement(jet, show, attacker)); | ||||
|         jet => this.$onEncaissement(jet, show, attackerToken, defenderToken)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async $onEncaissement(jet, show, attacker) { | ||||
|     await this.onAppliquerJetEncaissement(jet, attacker); | ||||
|     await this.$afficherEncaissement(jet, show); | ||||
|   async $onEncaissement(jet, show, attackerToken, defenderToken) { | ||||
|     await this.onAppliquerJetEncaissement(jet, attackerToken); | ||||
|     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, { | ||||
|       alias: this.name, | ||||
|       alias: defenderToken?.name ?? this.name, | ||||
|       hasPlayerOwner: this.hasPlayerOwner, | ||||
|       show: show ?? {} | ||||
|     }); | ||||
|     }, { overwrite: false }); | ||||
|  | ||||
|     await ChatUtility.createChatWithRollMode( | ||||
|       { | ||||
|   | ||||
| @@ -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 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 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) { | ||||
|       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 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()) { | ||||
|       encaissement.endurance = endActuelle; | ||||
|     } | ||||
| @@ -276,11 +276,11 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | ||||
|       ui.notifications.info(`${this.name} est hors combat, il ne reste donc pas sonné`); | ||||
|       return; | ||||
|     } | ||||
|     await this.setEffect(STATUSES.StatusStunned, sonne); | ||||
|     await this.setEffect(STATUSES.StatusStunned, sonne) | ||||
|   } | ||||
|  | ||||
|   getSonne() { | ||||
|     return this.getEffect(STATUSES.StatusStunned); | ||||
|   isSonne() { | ||||
|     return this.getEffect(STATUSES.StatusStunned) | ||||
|   } | ||||
|  | ||||
|   isEffectAllowed(effectId) { return true } | ||||
|   | ||||
| @@ -205,11 +205,8 @@ export class RdDBaseActor extends Actor { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async onPreUpdateItem(item, change, options, id) { } | ||||
|  | ||||
|   async onCreateItem(item, options, id) { } | ||||
|  | ||||
|   async onDeleteItem(item, options, id) { } | ||||
|  | ||||
|   async onUpdateActor(update, options, actorId) { } | ||||
|  | ||||
|   async onTimeChanging(oldTimestamp, newTimestamp) { | ||||
| @@ -218,7 +215,7 @@ export class RdDBaseActor extends Actor { | ||||
|   } | ||||
|  | ||||
|   async creerObjetParMJ(object) { | ||||
|     if (!Misc.isUniqueConnectedGM()) { | ||||
|     if (!Misc.isFirstConnectedGM()) { | ||||
|       RdDBaseActor.remoteActorCall({ | ||||
|         tokenId: this.token?.id, | ||||
|         actorId: this.id, | ||||
| @@ -317,7 +314,7 @@ export class RdDBaseActor extends Actor { | ||||
|  | ||||
|       RdDAudio.PlayContextAudio("argent"); // Petit son | ||||
|       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.` | ||||
|       }); | ||||
|     } | ||||
| @@ -335,7 +332,7 @@ export class RdDBaseActor extends Actor { | ||||
|       ui.notifications.info("Inutile de se vendre à soi-même"); | ||||
|       return; | ||||
|     } | ||||
|     if (!Misc.isUniqueConnectedGM()) { | ||||
|     if (!Misc.isFirstConnectedGM()) { | ||||
|       RdDBaseActor.remoteActorCall({ | ||||
|         actorId: achat.vendeurId ?? achat.acheteurId, | ||||
|         method: 'achatVente', | ||||
| @@ -708,5 +705,24 @@ export class RdDBaseActor extends Actor { | ||||
|     } | ||||
|     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, | ||||
|           } | ||||
|         } | ||||
|       }) | ||||
|   } | ||||
| } | ||||
| @@ -74,7 +74,7 @@ export class RdDEntite extends RdDBaseActorReve { | ||||
|     return [STATUSES.StatusComma].includes(effectId); | ||||
|   } | ||||
|  | ||||
|   async onAppliquerJetEncaissement(encaissement, attacker) { | ||||
|   async onAppliquerJetEncaissement(encaissement, attackerToken) { | ||||
|     const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance); | ||||
|     foundry.utils.mergeObject(encaissement, { | ||||
|       resteEndurance: perteEndurance.newValue, | ||||
|   | ||||
| @@ -84,7 +84,7 @@ const MAPPING_BASE = [ | ||||
|   { 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: "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_armure", getter: (actor, context) => Mapping.getEsquiveArmure(context) }, | ||||
|   { column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) }, | ||||
| @@ -140,45 +140,52 @@ export class Mapping { | ||||
|  | ||||
|   static prepareArmes(actor) { | ||||
|     const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme) | ||||
|     return armes.map(arme => | ||||
|       [ | ||||
|         arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined, | ||||
|         arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined, | ||||
|         !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined, | ||||
|         arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined, | ||||
|         arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined | ||||
|       ] | ||||
|         .filter(it => it != undefined) | ||||
|     ).reduce((a, b) => a.concat(b), []) | ||||
|     RdDItemArme.ajoutCorpsACorps(armes, actor) | ||||
|     return armes.map(arme => [ | ||||
|       arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined, | ||||
|       arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined, | ||||
|       !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined, | ||||
|       arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined, | ||||
|       arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined] | ||||
|       .filter(it => it != undefined)) | ||||
|       .reduce((a, b) => a.concat(b), []) | ||||
|   } | ||||
|  | ||||
|   static prepareArme(actor, arme, maniement) { | ||||
|     const nameCompArme = RdDItemArme.getCompetenceArme(arme, maniement) | ||||
|     const competence = actor.getCompetence(nameCompArme) | ||||
|     const nameCompetenceArme = RdDItemArme.getCompetenceArme(arme, maniement) | ||||
|     const competence = actor.getCompetence(nameCompetenceArme) | ||||
|     if (RdDItemCompetence.isNiveauBase(competence)) { | ||||
|       return undefined | ||||
|     } | ||||
|     const dmgArme = RdDItemArme.dommagesReels(arme, maniement) | ||||
|     const dommages = dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme) | ||||
|     const categorie = Mapping.complementCategorie(arme, maniement) | ||||
|     const dommages = Mapping.dommagesArme(actor, arme, maniement) | ||||
|     return { | ||||
|       name: arme.name + categorie, | ||||
|       niveau: Misc.toSignedString(competence.system.niveau), | ||||
|       init: Mapping.calculBaseInit(actor, competence.system.categorie) + competence.system.niveau, | ||||
|       dommages: Misc.toSignedString(dommages), | ||||
|       dommages: dommages, | ||||
|       competence: competence, | ||||
|       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) { | ||||
|     switch (maniement) { | ||||
|       case 'unemain': return (arme.system.deuxmains) ? ' 1 main' : (arme.system.lancer||arme.system.tir) ? ' mêlée': ''  | ||||
|       case 'deuxmains': return (arme.system.unemain) ? ' 2 mains' : (arme.system.lancer||arme.system.tir) ? ' mêlée': ''  | ||||
|       case 'unemain': return (arme.system.deuxmains) ? ' 1 main' : (arme.system.lancer || arme.system.tir) ? ' mêlée' : '' | ||||
|       case 'deuxmains': return (arme.system.unemain) ? ' 2 mains' : (arme.system.lancer || arme.system.tir) ? ' mêlée' : '' | ||||
|       case 'lancer': return (arme.system.unemain || arme.system.deuxmains || arme.system.tir) ? ' jet' : '' | ||||
|       case 'tir': return (arme.system.unemain || arme.system.deuxmains || arme.system.lancer) ? ' tir' : '' | ||||
|     } | ||||
|     return ''  | ||||
|     return '' | ||||
|   } | ||||
|  | ||||
|   static calculBaseInit(actor, categorie) { | ||||
| @@ -327,7 +334,8 @@ export class Mapping { | ||||
|     const txtByCategories = Object.values(byCategories) | ||||
|       .map(it => it.competencesParNiveau) | ||||
|       .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) { | ||||
|           return '' | ||||
|         } | ||||
|   | ||||
							
								
								
									
										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) { | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       if (socketData.part) { | ||||
|         const toDelete = game.messages.filter(it => it.content.includes(socketData.part)); | ||||
|         toDelete.forEach(it => it.delete()); | ||||
| @@ -63,7 +63,7 @@ export class ChatUtility { | ||||
|   /* -------------------------------------------- */ | ||||
|  | ||||
|   static removeMessages(socketData) { | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       ChatUtility.onRemoveMessages(socketData); | ||||
|     } | ||||
|     else { | ||||
| @@ -161,7 +161,7 @@ export class ChatUtility { | ||||
|   /* -------------------------------------------- */ | ||||
|   static handleGMChatMessage(socketData) { | ||||
|     console.log("blindMessageToGM", socketData); | ||||
|     if (Misc.firstConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       ChatMessage.create({ | ||||
|         user: game.user.id, | ||||
|         whisper: ChatUtility.getGMs(), | ||||
|   | ||||
| @@ -8,14 +8,13 @@ import { RdDUtility } from "./rdd-utility.js"; | ||||
| export class DialogValidationEncaissement extends Dialog { | ||||
|  | ||||
|   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', { | ||||
|       actor: actor, | ||||
|       rollData: rollData, | ||||
|       encaissement: encaissement | ||||
|     }); | ||||
|     const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser); | ||||
|     dialog.render(true); | ||||
|     new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser).render(true); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -56,14 +55,14 @@ export class DialogValidationEncaissement extends Dialog { | ||||
|     this.html = html; | ||||
|     this.html.find('input.encaissement-roll-result').keyup(async event => { | ||||
|       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-blessure').text(this.encaissement.blessures) | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   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) | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -81,37 +81,59 @@ export class RdDItemArme extends Item { | ||||
|   /* -------------------------------------------- */ | ||||
|   static getCategorieParade(armeData) { | ||||
|     if (armeData.system.categorie_parade) { | ||||
|       return armeData.system.categorie_parade; | ||||
|       return armeData.system.categorie_parade | ||||
|     } | ||||
|     // pour compatibilité avec des personnages existants | ||||
|     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/)) { | ||||
|       return ''; | ||||
|       return '' | ||||
|     } | ||||
|     if (armeData.system.competence == undefined) { | ||||
|       return ITEM_TYPES.competencecreature; | ||||
|     } | ||||
|     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('hast')) return 'hast'; | ||||
|     if (compname.match('lance')) return 'lances'; | ||||
|     if (compname.match('bouclier')) return 'boucliers'; | ||||
|     if (compname.match('masse')) return 'masses'; | ||||
|     if (compname.match('hache')) return 'haches' | ||||
|     if (compname.match('hast')) return 'hast' | ||||
|     if (compname.match('lance')) return 'lances' | ||||
|     if (compname.match('bouclier')) return 'boucliers' | ||||
|     if (compname.match('masse')) return 'masses' | ||||
|     if (compname.match('epée') || compname.match('épée')) { | ||||
|       if (armeData.name.toLowerCase().match(/(gnome)/)) | ||||
|         return 'epees-courtes'; | ||||
|         return 'epees-courtes' | ||||
|       if (armeData.name.toLowerCase().match(/((e|é)pée dragone|esparlongue|demi-dragonne)/)) | ||||
|         return 'epees-longues'; | ||||
|       return 'epees-lourdes'; | ||||
|         return 'epees-longues' | ||||
|       return 'epees-lourdes' | ||||
|     } | ||||
|     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 +142,8 @@ export class RdDItemArme extends Item { | ||||
|       return false; | ||||
|     } | ||||
|     // categories d'armes à la parade (cf. page 115 ) | ||||
|     let attCategory = RdDItemArme.getCategorieParade(armeAttaque); | ||||
|     let defCategory = RdDItemArme.getCategorieParade(armeParade); | ||||
|     const attCategory = RdDItemArme.getCategorieParade(armeAttaque) | ||||
|     const defCategory = RdDItemArme.getCategorieParade(armeParade) | ||||
|     // bouclier et mêmes catégorie: peuvent se parer sans difficulté | ||||
|     if (defCategory == 'boucliers') { | ||||
|       return false; | ||||
| @@ -184,7 +206,7 @@ export class RdDItemArme extends Item { | ||||
|     return arme.system.competence.replace(" 1 main", " 2 mains"); | ||||
|   } | ||||
|  | ||||
|   static isArmeUtilisable(arme) { | ||||
|   static isUtilisable(arme) { | ||||
|     switch (arme.type) { | ||||
|       case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0) | ||||
|       case ITEM_TYPES.competencecreature: return true | ||||
| @@ -192,6 +214,26 @@ export class RdDItemArme extends Item { | ||||
|     return false | ||||
|   } | ||||
|  | ||||
|   static isAttaque(arme) { | ||||
|     switch (arme.type) { | ||||
|       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 ajoutCorpsACorps(armes, actor) { | ||||
|     armes.push(RdDItemArme.mainsNues(actor)); | ||||
|     armes.push(RdDItemArme.empoignade(actor)); | ||||
|   | ||||
| @@ -190,7 +190,7 @@ export class RdDItemCompetence extends 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,29 +27,28 @@ export class RdDItemCompetenceCreature extends Item { | ||||
|   static armeCreature(item) { | ||||
|     const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item) | ||||
|     if (categorieAttaque != undefined) { | ||||
|       // si c'est un Item compétence: cloner pour ne pas modifier la compétence | ||||
|       let arme = item.clone(); | ||||
|       return foundry.utils.mergeObject(arme, { | ||||
|       // cloner pour ne pas modifier la compétence | ||||
|       return foundry.utils.mergeObject(item, { | ||||
|           action: item.isCompetencePossession() ? 'possession' : 'attaque', | ||||
|           system: { | ||||
|             competence: arme.name, | ||||
|             competence: item.name, | ||||
|             cac: categorieAttaque == "naturelle" ? "naturelle" : "", | ||||
|             niveau: item.system.niveau, | ||||
|             initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value), | ||||
|             equipe: true, | ||||
|             resistance: 100, | ||||
|             dommagesReels: arme.system.dommages, | ||||
|             dommagesReels: item.system.dommages, | ||||
|             penetration: 0, | ||||
|             force: 0, | ||||
|             rapide: true, | ||||
|           } | ||||
|         }, { inplace: false }); | ||||
|         }, { inplace: false, }); | ||||
|     } | ||||
|     return undefined; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static isCompetenceAttaque(item) { | ||||
|   static isAttaque(item) { | ||||
|     if (item.type == ITEM_TYPES.competencecreature) { | ||||
|       switch (item.system.categorie) { | ||||
|         case "melee": | ||||
| @@ -60,7 +59,7 @@ export class RdDItemCompetenceCreature extends Item { | ||||
|           return true | ||||
|       } | ||||
|     } | ||||
|     return undefined | ||||
|     return false | ||||
|   } | ||||
|  | ||||
|   static getCategorieAttaque(item) { | ||||
| @@ -77,6 +76,7 @@ export class RdDItemCompetenceCreature extends Item { | ||||
|     } | ||||
|     return undefined | ||||
|   } | ||||
|  | ||||
|   static isDommages(item) { | ||||
|     if (item.type == ITEM_TYPES.competencecreature) { | ||||
|       switch (item.system.categorie) { | ||||
| @@ -89,6 +89,7 @@ export class RdDItemCompetenceCreature extends Item { | ||||
|     } | ||||
|     return false | ||||
|   } | ||||
|  | ||||
|   static isParade(item) { | ||||
|     if (item.type == ITEM_TYPES.competencecreature) { | ||||
|       switch (item.system.categorie) { | ||||
| @@ -101,8 +102,4 @@ export class RdDItemCompetenceCreature extends Item { | ||||
|     return false | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static isCompetenceParade(item) { | ||||
|     return item.type == 'competencecreature' && item.system.categorie_parade !== ""; | ||||
|   } | ||||
| }   | ||||
| } | ||||
|   | ||||
| @@ -267,10 +267,17 @@ export class RdDItemSheet extends ItemSheet { | ||||
|   /* -------------------------------------------- */ | ||||
|   /** @override */ | ||||
|   _updateObject(event, formData) { | ||||
|     if (this.item.type == 'sort') { | ||||
|       // Données de bonus de cases ? | ||||
|       formData['system.bonuscase'] = RdDItemSort.buildBonuscaseFromArrays(formData.bonusValue, formData.caseValue); | ||||
|     switch (this.item.type) { | ||||
|       case ITEM_TYPES.sort: | ||||
|         // Données de bonus de cases ? | ||||
|         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); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -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 blessure = { | ||||
|       name: definition.label, | ||||
| @@ -77,7 +77,7 @@ export class RdDItemBlessure extends RdDItem { | ||||
|         gravite: gravite, | ||||
|         difficulte: - gravite, | ||||
|         localisation: localisation, | ||||
|         origine: attacker?.name ?? "" | ||||
|         origine: attackerToken?.name ?? "" | ||||
|       } | ||||
|     } | ||||
|     const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) | ||||
|   | ||||
| @@ -139,7 +139,7 @@ export class Misc { | ||||
|   } | ||||
|  | ||||
|   static join(params, separator = '') { | ||||
|     return params?.reduce(Misc.joining(separator)) ?? ''; | ||||
|     return (!params || params.length == 0) ? '' : params.reduce(Misc.joining(separator)) | ||||
|   } | ||||
|  | ||||
|   static joining(separator = '') { | ||||
| @@ -195,7 +195,7 @@ export class Misc { | ||||
|         return document | ||||
|       } | ||||
|     } | ||||
|     else if (Misc.isUniqueConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document))) { | ||||
|     else if (Misc.isFirstConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document))) { | ||||
|       return document | ||||
|     } | ||||
|     return undefined | ||||
| @@ -206,14 +206,14 @@ export class Misc { | ||||
|   } | ||||
|  | ||||
|   static isOwnerPlayerOrUniqueConnectedGM(actor) { | ||||
|     return Misc.isOwnerPlayer(actor) ?? Misc.isUniqueConnectedGM(); | ||||
|     return Misc.isOwnerPlayer(actor) ?? Misc.isFirstConnectedGM(); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * @returns true pour un seul utilisateur: le premier GM connecté par ordre d'id | ||||
|    */ | ||||
|   static isUniqueConnectedGM() { | ||||
|     return game.user.id == Misc.firstConnectedGMId(); | ||||
|   static isFirstConnectedGM() { | ||||
|     return game.user == Misc.firstConnectedGM(); | ||||
|   } | ||||
|  | ||||
|   static firstConnectedGMId() { | ||||
|   | ||||
| @@ -42,7 +42,8 @@ export class RdDCombatManager extends Combat { | ||||
|     /* -------------------------------------------- */ | ||||
|     Hooks.on("getCombatTrackerEntryContext", (html, options) => { RdDCombatManager.pushInitiativeOptions(html, options); }); | ||||
|     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() { | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       await this.finDeRound({ terminer: true }) | ||||
|       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) | ||||
| @@ -61,20 +62,40 @@ export class RdDCombatManager extends Combat { | ||||
|       RdDEmpoignade.deleteAllEmpoignades() | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async finDeRound(options = { terminer: false }) { | ||||
|     this.turns.forEach(turn => turn.actor.resetItemUse()); | ||||
|  | ||||
|     for (let combatant of this.combatants) { | ||||
|       if (combatant.actor) { | ||||
|         await combatant.actor.finDeRound(options); | ||||
|       } | ||||
|       else { | ||||
|         ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur!`) | ||||
|   async onDeleteCombat() { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       if (game.combats.size <= 1) { | ||||
|         game.actors.forEach(actor => actor.resetItemUse()) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async finDeRound(options = { terminer: false }) { | ||||
|     this.combatants.map(it => RdDCombatManager.getActorCombatant(it, { warning: false })) | ||||
|       .filter(it => it != undefined) | ||||
|       .forEach(async actor => { | ||||
|         await actor.finDeRound(options) | ||||
|         await actor.resetItemUse() | ||||
|       }) | ||||
|   } | ||||
|  | ||||
|   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!`) | ||||
|       } | ||||
|       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) { | ||||
|     const efficacite = (arme?.system.magique) ? arme.system.ecaille_efficacite : 0 | ||||
|     const etatGeneral = actor.getEtatGeneral() ?? 0 | ||||
| @@ -83,57 +104,27 @@ export class RdDCombatManager extends Combat { | ||||
|   } | ||||
|  | ||||
|   /************************************************************************************/ | ||||
|   async rollInitiative(ids, formula = undefined, messageOptions = {}) { | ||||
|     console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions); | ||||
|   async rollInitiative(ids, 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; | ||||
|     // calculate initiative | ||||
|     for (let cId = 0; cId < ids.length; cId++) { | ||||
|       const combatant = this.combatants.get(ids[cId]); | ||||
|       const ajustement = RdDCombatManager.calculAjustementInit(combatant.actor, undefined); | ||||
|       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); | ||||
|   async rollInitRdD(id, formula, messageOptions = {}) { | ||||
|     const combatant = this.combatants.get(id); | ||||
|     const actor = RdDCombatManager.getActorCombatant(combatant) | ||||
|     if (actor) { | ||||
|       const rollFormula = formula ?? RdDCombatManager.getFirstInitRollFormula(actor) | ||||
|       const roll = combatant.getInitiativeRoll(rollFormula); | ||||
|       if (!roll.total) { | ||||
|         await roll.evaluate(); | ||||
|       } | ||||
|       const total = Math.max(roll.total, 0.00); | ||||
|       console.log("Compute init for", rollFormula, roll, total, combatant); | ||||
|       let id = combatant._id || combatant.id; | ||||
|       await this.updateEmbeddedDocuments("Combatant", [{ _id: id, initiative: total }]); | ||||
|       await this.updateEmbeddedDocuments("Combatant", [{ _id: combatant._id || combatant.id, initiative: total }]); | ||||
|  | ||||
|       // Send a chat message | ||||
|       let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode"); | ||||
| @@ -145,7 +136,7 @@ export class RdDCombatManager extends Combat { | ||||
|           alias: combatant.token.name, | ||||
|           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); | ||||
|       roll.toMessage(messageData, { rollMode, create: true }); | ||||
| @@ -153,7 +144,20 @@ export class RdDCombatManager extends Combat { | ||||
|       RdDCombatManager.processPremierRoundInit(); | ||||
|     } | ||||
|     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) { | ||||
|     return `${rang} +( (${RdDCombatManager.calculInitiative(niveau, carac, bonusMalus)} )/100)`; | ||||
| @@ -236,62 +240,10 @@ export class RdDCombatManager extends Combat { | ||||
|     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() { | ||||
|     // 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); | ||||
|       if (!initMissing) { // Premier round ! | ||||
|         for (let combatant of game.combat.combatants) { | ||||
| @@ -325,13 +277,13 @@ export class RdDCombatManager extends Combat { | ||||
|   /* -------------------------------------------- */ | ||||
|   static pushInitiativeOptions(html, options) { | ||||
|     for (let i = 0; i < options.length; i++) { | ||||
|       let option = options[i]; | ||||
|       let option = options[i] | ||||
|       if (option.name == 'COMBAT.CombatantReroll') { // Replace ! | ||||
|         option.name = "Sélectionner l'initiative..."; | ||||
|         option.condition = true; | ||||
|         option.icon = '<i class="far fa-question-circle"></i>'; | ||||
|         option.name = "Sélectionner l'initiative..." | ||||
|         option.condition = true | ||||
|         option.icon = '<i class="far fa-question-circle"></i>' | ||||
|         option.callback = target => { | ||||
|           RdDCombatManager.displayInitiativeMenu(html, target.data('combatant-id')); | ||||
|           RdDCombatManager.displayInitiativeMenu(html, target.data('combatant-id')) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| @@ -342,96 +294,83 @@ export class RdDCombatManager extends Combat { | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   static rollInitiativeAction(combatantId, action) { | ||||
|     const combatant = game.combat.combatants.get(combatantId); | ||||
|     if (combatant.actor == undefined) { | ||||
|       ui.notifications.warn(`Le combatant ${combatant.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`) | ||||
|       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; | ||||
|     const combatant = game.combat.combatants.get(combatantId) | ||||
|     const actor = RdDCombatManager.getActorCombatant(combatant) | ||||
|     if (actor == undefined) { return [] } | ||||
|  | ||||
|       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 | ||||
|     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 _baseInitOffset(categorie, arme) { | ||||
|     if (categorie == "tir") { // Offset de principe pour les armes de jet | ||||
|       return 8; | ||||
|   static getInitData(actor, action) { | ||||
|     if (actor.getSurprise() == "totale") { return { offset: -1, info: "Surprise Totale", carac: 0, niveau: 0 } } | ||||
|     if (actor.getSurprise() == "demi") { return { offset: 0, info: "Demi Surprise", carac: 0, niveau: 0 } } | ||||
|     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) { | ||||
|           case "empoignade": return 3 | ||||
|           case "pugilat": return 4 | ||||
|           case "naturelle": return 4 | ||||
|           default: return 5 | ||||
|         } | ||||
|     } | ||||
|     switch (arme.system.cac) { | ||||
|       case "empoignade": | ||||
|         return 3; | ||||
|       case "pugilat": | ||||
|       case "naturelle": | ||||
|         return 4; | ||||
|     } | ||||
|     return 5; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static displayInitiativeMenu(html, combatantId) { | ||||
|     console.log("Combatant ; ", combatantId); | ||||
|     const combatant = game.combat.combatants.get(combatantId); | ||||
|     if (!(combatant?.actor)) { | ||||
|       ui.notifications.warn(`Le combatant ${combatant.name ?? combatantId} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`) | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     let actions = RdDCombatManager.listActionsCombat(combatant); | ||||
|  | ||||
|     // Build the relevant submenu | ||||
|     if (actions) { | ||||
|       let menuItems = []; | ||||
|       for (let action of actions) { | ||||
|         menuItems.push({ | ||||
|     const combatant = game.combat.combatants.get(combatantId) | ||||
|     const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false }) | ||||
|     if (actor) { | ||||
|       const actions = RdDCombatManager.listActionsActorCombatant(actor) | ||||
|       // Build the relevant submenu | ||||
|       const menuItems = actions.map(action => { | ||||
|         return { | ||||
|           name: action.system.competence, | ||||
|           icon: "<i class='fas fa-dice-d6'></i>", | ||||
|           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) { | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId); | ||||
|       if (turn?.actor) { | ||||
|         RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token.id); | ||||
|         // TODO Playaudio for player?? | ||||
|         RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| @@ -469,52 +408,51 @@ export class RdDCombat { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static rddCombatTarget(target, attacker) { | ||||
|     const defender = target?.actor; | ||||
|     const defenderTokenId = target?.id; | ||||
|     return new RdDCombat(attacker, defender, defenderTokenId, target) | ||||
|   static rddCombatTarget(target, attacker, attackerToken) { | ||||
|     return new RdDCombat(attacker, attackerToken?.id, target?.actor, target?.id, target) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static rddCombatForAttackerAndDefender(attackerId, defenderTokenId) { | ||||
|     const attacker = game.actors.get(attackerId); | ||||
|     let defender = defenderTokenId ? canvas.tokens.get(defenderTokenId)?.actor : undefined; | ||||
|   static rddCombatForAttackerAndDefender(attackerId, attackerTokenId, defenderTokenId) { | ||||
|     const attacker = game.actors.get(attackerId) | ||||
|     const defenderToken = defenderTokenId ? canvas.tokens.get(defenderTokenId) : undefined | ||||
|     let defender = defenderToken?.actor; | ||||
|     let target = undefined | ||||
|     if (!defenderTokenId || !defender) { | ||||
|       console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`); | ||||
|       target = Targets.getTarget() | ||||
|       if (!target) { | ||||
|         return; | ||||
|         return | ||||
|       } | ||||
|       defenderTokenId = target.id; | ||||
|       defender = target.actor; | ||||
|       if (!defenderTokenId || !defender) { | ||||
|         return; | ||||
|         return | ||||
|       } | ||||
|     } | ||||
|     return new RdDCombat(attacker, defender, defenderTokenId, target) | ||||
|     return new RdDCombat(attacker, attackerTokenId, defender, defenderTokenId, target) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static onMsgEncaisser(msg) { | ||||
|     let defender = canvas.tokens.get(msg.defenderTokenId).actor; | ||||
|     if (Misc.isOwnerPlayerOrUniqueConnectedGM()) { | ||||
|       let attackerRoll = msg.attackerRoll; | ||||
|       let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined; | ||||
|       let defender = canvas.tokens.get(msg.defenderToken.id).actor; | ||||
|  | ||||
|       defender.encaisserDommages(attackerRoll, attacker); | ||||
|       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); | ||||
|       defender.encaisserDommages(attackerRoll, attacker, msg.attackerToken); | ||||
|       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id); | ||||
|       rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static onMsgDefense(msg) { | ||||
|     let defenderToken = canvas.tokens.get(msg.defenderTokenId); | ||||
|     if (defenderToken && Misc.isUniqueConnectedGM()) { | ||||
|       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); | ||||
|       rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme); | ||||
|       rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll); | ||||
|     let defenderToken = canvas.tokens.get(msg.defenderToken.id) | ||||
|     if (defenderToken && Misc.isFirstConnectedGM()) { | ||||
|       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id) | ||||
|       rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme) | ||||
|       rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll) | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -545,6 +483,7 @@ export class RdDCombat { | ||||
|       html.on("click", button, event => { | ||||
|         const rddCombat = RdDCombat.rddCombatForAttackerAndDefender( | ||||
|           event.currentTarget.attributes['data-attackerId']?.value, | ||||
|           event.currentTarget.attributes['data-attackerTokenId']?.value, | ||||
|           event.currentTarget.attributes['data-defenderTokenId']?.value); | ||||
|         if (rddCombat) { | ||||
|           rddCombat.onEvent(button, event); | ||||
| @@ -560,22 +499,38 @@ export class RdDCombat { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   constructor(attacker, defender, defenderTokenId, target) { | ||||
|   constructor(attacker, attackerTokenId, defender, defenderTokenId, target) { | ||||
|     this.attacker = attacker | ||||
|     this.defender = defender | ||||
|     this.target = target | ||||
|     this.attackerId = this.attacker.id | ||||
|     this.defenderId = this.defender.id | ||||
|     this.attackerTokenId = attackerTokenId | ||||
|     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) { | ||||
|     const chatMessage = ChatUtility.getChatMessage(event); | ||||
|     const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll'); | ||||
|     const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll'); | ||||
|     console.log('RdDCombat', attackerRoll, defenderRoll); | ||||
|     const defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value; | ||||
|  | ||||
|     const armeParadeId = event.currentTarget.attributes['data-armeid']?.value; | ||||
|     const competence = event.currentTarget.attributes['data-competence']?.value; | ||||
| @@ -585,7 +540,7 @@ export class RdDCombat { | ||||
|       case '#particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); | ||||
|       case '#parer-button': return this.parade(attackerRoll, armeParadeId); | ||||
|       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 '#appel-chance-attaque': return this.attacker.rollAppelChance( | ||||
| @@ -702,7 +657,7 @@ export class RdDCombat { | ||||
|         }) | ||||
|       } | ||||
|       else { | ||||
|         const defenderToken = canvas.tokens.get(this.defenderTokenId); | ||||
|         const defenderToken = canvas.tokens.get(this.defenderTokenId) | ||||
|         const dist = this.distance(_token, defenderToken) | ||||
|         const isVisible = this.isVisible(_token, defenderToken) | ||||
|         const portee = this._ajustementPortee(dist, rollData.arme) | ||||
| @@ -769,7 +724,7 @@ export class RdDCombat { | ||||
|     } | ||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this.attacker) | ||||
|  | ||||
|     let rollData = this._prepareAttaque(competence, arme); | ||||
|     let rollData = this._prepareAttaque(competence, arme) | ||||
|     console.log("RdDCombat.attaque >>>", rollData); | ||||
|     if (arme) { | ||||
|       this.attacker.verifierForceMin(arme); | ||||
| @@ -795,15 +750,18 @@ export class RdDCombat { | ||||
|     dialog.render(true); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   _prepareAttaque(competence, arme) { | ||||
|     let rollData = { | ||||
|       alias: this.attackerToken.name, | ||||
|       passeArme: foundry.utils.randomID(16), | ||||
|       mortalite: arme?.system.mortalite, | ||||
|       competence: competence, | ||||
|       surprise: this.attacker.getSurprise(true), | ||||
|       surpriseDefenseur: this.defender.getSurprise(true), | ||||
|       targetToken: Targets.extractTokenData(this.target), | ||||
|       sourceToken: this.attackerToken, | ||||
|       targetToken: this.defenderToken, | ||||
|       essais: {} | ||||
|     }; | ||||
|  | ||||
| @@ -848,9 +806,10 @@ export class RdDCombat { | ||||
|       alias: this.attacker.name, | ||||
|       whisper: ChatUtility.getOwners(this.attacker), | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', { | ||||
|         alias: this.attacker.name, | ||||
|         alias: this.attackerToken.name, | ||||
|         attackerId: this.attackerId, | ||||
|         defenderTokenId: this.defenderTokenId, | ||||
|         attackerToken: this.attackerToken, | ||||
|         defenderToken: this.defenderToken, | ||||
|         isForce: isForce, | ||||
|         isFinesse: isFinesse, | ||||
|         isRapide: isRapide, | ||||
| @@ -867,7 +826,7 @@ export class RdDCombat { | ||||
|     attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); | ||||
|     let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } | ||||
|     attackerRoll.show = { | ||||
|       cible: this.target ? this.defender.name : 'la cible', | ||||
|       cible: this.defenderToken?.name ?? 'la cible', | ||||
|       isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge') | ||||
|     } | ||||
|     await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html'); | ||||
| @@ -898,7 +857,7 @@ export class RdDCombat { | ||||
|     // # utilisation esquive | ||||
|     const corpsACorps = this.defender.getCompetenceCorpsACorps({ onMessage: it => console.info(it, this.defender) }); | ||||
|     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 = { | ||||
|       passeArme: attackerRoll.passeArme, | ||||
| @@ -908,7 +867,8 @@ export class RdDCombat { | ||||
|       attacker: this.attacker, | ||||
|       attackerId: this.attackerId, | ||||
|       esquives: esquives, | ||||
|       defenderTokenId: this.defenderTokenId, | ||||
|       attackerToken: this.attackerToken, | ||||
|       defenderToken: this.defenderToken, | ||||
|       mainsNues: attackerRoll.dmg.mortalite != 'mortel' && corpsACorps, | ||||
|       armes: this._filterArmesParade(this.defender, attackerRoll.competence, attackerRoll.arme), | ||||
|       diffLibre: attackerRoll.ajustements?.diffLibre?.value ?? 0, | ||||
| @@ -919,7 +879,7 @@ export class RdDCombat { | ||||
|       dmg: attackerRoll.dmg, | ||||
|     }; | ||||
|  | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       await this._chatMessageDefense(paramChatDefense, defenderRoll); | ||||
|     } | ||||
|     else { | ||||
| @@ -932,7 +892,7 @@ export class RdDCombat { | ||||
|     const choixDefense = await ChatMessage.create({ | ||||
|       // message privé: du défenseur à lui même (et aux GMs) | ||||
|       speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), | ||||
|       alias: this.attacker.name, | ||||
|       alias: this.attackerToken.name, | ||||
|       whisper: ChatUtility.getOwners(this.defender), | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense), | ||||
|     }); | ||||
| @@ -946,8 +906,9 @@ export class RdDCombat { | ||||
|     game.socket.emit(SYSTEM_SOCKET_ID, { | ||||
|       msg: "msg_defense", data: { | ||||
|         attackerId: this.attacker?.id, | ||||
|         attackerToken: this.attackerToken, | ||||
|         defenderId: this.defender?.id, | ||||
|         defenderTokenId: this.defenderTokenId, | ||||
|         defenderToken: this.defenderToken, | ||||
|         defenderRoll: defenderRoll, | ||||
|         paramChatDefense: paramChatDefense, | ||||
|         rollMode: true | ||||
| @@ -956,20 +917,21 @@ export class RdDCombat { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   _filterArmesParade(defender, competence) { | ||||
|     let items = defender.items.filter(it => RdDItemArme.isArmeUtilisable(it) || RdDItemCompetenceCreature.isCompetenceParade(it)) | ||||
|     items.forEach(item => item.system.nbUsage = defender.getItemUse(item.id)); // Ajout du # d'utilisation ce round   | ||||
|   _filterArmesParade(defender, competence, armeAttaque) { | ||||
|     let defenses = defender.items.filter(it => RdDItemArme.isParade(it)) | ||||
|     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) { | ||||
|       case 'tir': | ||||
|       case 'lancer': | ||||
|         return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers') | ||||
|         return defenses.filter(armeDefense => RdDItemArme.getCategorieParade(armeDefense) == 'boucliers') | ||||
|       default: | ||||
|         // Le fléau ne peut être paré qu’au bouclier p115 | ||||
|         if (competence.name == "Fléau") { | ||||
|           return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers') | ||||
|         } | ||||
|         return items.filter(item => RdDItemArme.getCategorieParade(item)); | ||||
|         return defenses.filter(armeDefense => armeDefense.typeParade != '') | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -980,7 +942,8 @@ export class RdDCombat { | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', { | ||||
|         attackerId: this.attackerId, | ||||
|         attacker: this.attacker, | ||||
|         defenderTokenId: this.defenderTokenId, | ||||
|         attackerToken: this.attackerToken, | ||||
|         defenderToken: this.defenderToken, | ||||
|         essais: attackerRoll.essais | ||||
|       }) | ||||
|     }); | ||||
| @@ -1052,8 +1015,11 @@ export class RdDCombat { | ||||
|   /* -------------------------------------------- */ | ||||
|   _prepareParade(attackerRoll, armeParade, competenceParade) { | ||||
|     let defenderRoll = { | ||||
|       alias: this.defenderToken?.name, | ||||
|       passeArme: attackerRoll.passeArme, | ||||
|       diffLibre: attackerRoll.diffLibre, | ||||
|       attackerToken: this.attackerToken, | ||||
|       defenderToken: this.defenderToken, | ||||
|       attackerRoll: attackerRoll, | ||||
|       competence: this.defender.getCompetence(competenceParade), | ||||
|       arme: armeParade, | ||||
| @@ -1133,8 +1099,11 @@ export class RdDCombat { | ||||
|   /* -------------------------------------------- */ | ||||
|   _prepareEsquive(attackerRoll, competence) { | ||||
|     let rollData = { | ||||
|       alias: this.defenderToken?.name, | ||||
|       passeArme: attackerRoll.passeArme, | ||||
|       diffLibre: attackerRoll.diffLibre, | ||||
|       attackerToken: this.attackerToken, | ||||
|       defenderToken: this.defenderToken, | ||||
|       attackerRoll: attackerRoll, | ||||
|       competence: competence, | ||||
|       surprise: this.defender.getSurprise(true), | ||||
| @@ -1276,9 +1245,8 @@ export class RdDCombat { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async encaisser(attackerRoll, defenderRoll, defenderTokenId) { | ||||
|     defenderTokenId = defenderTokenId || this.defenderTokenId; | ||||
|     console.log("RdDCombat.encaisser >>>", attackerRoll, defenderTokenId); | ||||
|   async encaisser(attackerRoll, defenderRoll) { | ||||
|     console.log("RdDCombat.encaisser >>>", attackerRoll, defenderRoll); | ||||
|  | ||||
|     if (defenderRoll?.rolled && RdDCombat.isEchecTotal(defenderRoll)) { | ||||
|       this._onEchecTotal(defenderRoll); | ||||
| @@ -1286,18 +1254,19 @@ export class RdDCombat { | ||||
|  | ||||
|     if (Misc.isOwnerPlayerOrUniqueConnectedGM(this.defender)) { | ||||
|       attackerRoll.attackerId = this.attackerId; | ||||
|       attackerRoll.defenderTokenId = defenderTokenId; | ||||
|       attackerRoll.defenderTokenId = this.defenderToken.id; | ||||
|  | ||||
|       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 | ||||
|       game.socket.emit(SYSTEM_SOCKET_ID, { | ||||
|         msg: "msg_encaisser", | ||||
|         data: { | ||||
|           attackerId: this.attackerId, | ||||
|           defenderTokenId: defenderTokenId, | ||||
|           attackerRoll: attackerRoll | ||||
|           attackerRoll: attackerRoll, | ||||
|           attackerToken: this.attackerToken, | ||||
|           defenderToken: this.defenderToken | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
| @@ -1305,28 +1274,31 @@ export class RdDCombat { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async displayActorCombatStatus(combat, actor, tokenId) { | ||||
|     let formData = { | ||||
|   static async displayActorCombatStatus(combat, actor, token) { | ||||
|     if (!actor?.isActorCombat()) { | ||||
|       return | ||||
|     } | ||||
|     const formData = { | ||||
|       combatId: combat._id, | ||||
|       alias: actor.name, | ||||
|       alias: token.name ?? actor.name, | ||||
|       etatGeneral: actor.getEtatGeneral(), | ||||
|       isSonne: actor.getSonne(), | ||||
|       isSonne: actor.isSonne(), | ||||
|       blessuresStatus: actor.computeResumeBlessure(), | ||||
|       SConst: actor.getSConst(), | ||||
|       actorId: actor.id, | ||||
|       actor: actor, | ||||
|       tokenId: tokenId, | ||||
|       tokenId: token.id, | ||||
|       isGrave: actor.countBlessures(it => it.isGrave()) > 0, | ||||
|       isCritique: actor.countBlessures(it => it.isCritique()) > 0 | ||||
|     } | ||||
|     await ChatMessage.create({ | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData), | ||||
|       alias: actor.name | ||||
|       alias: token.name ?? actor.name | ||||
|     }) | ||||
|     await ChatMessage.create({ | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData), | ||||
|       whisper: ChatUtility.getOwners(actor), | ||||
|       alias: actor.name | ||||
|     }); | ||||
|       alias: token.name ?? actor.name | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| @@ -68,6 +68,7 @@ import { OptionsAvancees } from "./settings/options-avancees.js" | ||||
| import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium.js" | ||||
| import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js" | ||||
| import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" | ||||
| import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" | ||||
|  | ||||
| /** | ||||
|  * RdD system | ||||
| @@ -87,6 +88,7 @@ export class SystemReveDeDragon { | ||||
|     this.config = RDD_CONFIG | ||||
|     this.RdDUtility = RdDUtility | ||||
|     this.RdDHotbar = RdDHotbar | ||||
|     this.RdDStatBlockParser = RdDStatBlockParser | ||||
|     this.itemClasses = { | ||||
|       armure: RdDItemArmure, | ||||
|       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() { | ||||
|  | ||||
|     /* -------------------------------------------- */ | ||||
|     /*  Foundry VTT Initialization                  */ | ||||
|     /* -------------------------------------------- */ | ||||
|     game.system.rdd.calendrier = new RdDCalendrier() | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       new Migrations().migrate() | ||||
|       this.messageDeBienvenue() | ||||
|       import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter => { | ||||
| @@ -292,6 +304,8 @@ export class SystemReveDeDragon { | ||||
|     StatusEffects.onReady() | ||||
|     RdDHerbes.onReady() | ||||
|     RdDDice.onReady() | ||||
|  | ||||
|     RdDStatBlockParser.parseStatBlock() | ||||
|     /* -------------------------------------------- */ | ||||
|     /* Affiche/Init le calendrier */ | ||||
|     game.system.rdd.calendrier.display() | ||||
| @@ -303,6 +317,8 @@ export class SystemReveDeDragon { | ||||
|         user: game.user.id | ||||
|       }) | ||||
|     } | ||||
|  | ||||
|     SystemReveDeDragon.setupAccueil() | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
| @@ -72,6 +72,6 @@ export class RdDEncaisser extends Dialog { | ||||
|         encaisserSpecial: this.encaisserSpecial, | ||||
|         mortalite: mortalite | ||||
|       } | ||||
|     }); | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -28,16 +28,15 @@ export class RdDTokenHud { | ||||
|     await RdDTokenHud.addExtensionHudSoins(html, actor); | ||||
|  | ||||
|     if (isCombat) { | ||||
|       let combatant = game.combat.combatants.find(c => c.tokenId == tokenId); | ||||
|       if (!(combatant?.actor)) { | ||||
|         ui.notifications.warn(`Le combatant ${token.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`) | ||||
|         return; | ||||
|       const combatant = game.combat.combatants.find(c => c.tokenId == tokenId) | ||||
|       const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false }) | ||||
|       if (actor) { | ||||
|         let actions = RdDCombatManager.listActionsActorCombatant(actor) | ||||
|         // initiative | ||||
|         await RdDTokenHud.addExtensionHudInit(html, combatant, actions) | ||||
|         // combat | ||||
|         await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions) | ||||
|       } | ||||
|       let actions = RdDCombatManager.listActionsCombat(combatant); | ||||
|       // initiative | ||||
|       await RdDTokenHud.addExtensionHudInit(html, combatant, actions); | ||||
|       // combat | ||||
|       await RdDTokenHud.addExtensionHudCombat(html, combatant, actions); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @@ -68,8 +67,8 @@ export class RdDTokenHud { | ||||
|       }); | ||||
|   } | ||||
|  | ||||
|   static async addExtensionHudCombat(html, combatant, actions) { | ||||
|     const hudData = { combatant, actions, commandes: [] }; | ||||
|   static async addExtensionHudCombat(html, combatant, token, actions) { | ||||
|     const hudData = { combatant, token, actions, commandes: [] }; | ||||
|     const controlIconTarget = html.find('.control-icon[data-action=target]'); | ||||
|     await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData, | ||||
|       (event) => { | ||||
| @@ -80,7 +79,7 @@ export class RdDTokenHud { | ||||
|           combatant.actor.conjurerPossession(possession); | ||||
|         } | ||||
|         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); | ||||
|     let formula = RdDUtility.formuleEncaissement(diff, options) | ||||
|     const roll = await RdDDice.roll(formula, 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) { | ||||
| @@ -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 | ||||
|     const bonusDegatsDiffLibre = ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(rollData.diffLibre ?? 0) : 0 | ||||
|     const jetTotal = roll.total + rollData.dmg.total - armure + bonusDegatsDiffLibre | ||||
|     const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite); | ||||
|     const over20 = Math.max(jetTotal - 20, 0); | ||||
|     encaissement.dmg = rollData.dmg; | ||||
|     encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type); | ||||
|     encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'; | ||||
|     encaissement.dmg = rollData.dmg | ||||
|     if (ReglesOptionnelles.isUsing('localisation-aleatoire')) { | ||||
|       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.roll = roll; | ||||
|     encaissement.armure = armure; | ||||
| @@ -741,6 +746,15 @@ export class RdDUtility { | ||||
|     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) { | ||||
|     if (canvas.tokens.controlled.length == 1) { | ||||
|       let token = canvas.tokens.controlled[0]; | ||||
| @@ -867,10 +881,10 @@ export class RdDUtility { | ||||
|   /* -------------------------------------------- */ | ||||
|   static afficherHeuresChanceMalchance(heureNaissance) { | ||||
|     if (game.user.isGM) { | ||||
|       const heure = RdDTimestamp.findHeure(heureNaissance - 1); | ||||
|       const heure = RdDTimestamp.findHeure(heureNaissance) | ||||
|       if (heureNaissance && heure) { | ||||
|         let ajustement = game.system.rdd.calendrier.getAjustementAstrologique(heureNaissance); | ||||
|         const current = game.system.rdd.calendrier.heureCourante(); | ||||
|         const ajustement = game.system.rdd.calendrier.getAjustementAstrologique(heureNaissance) | ||||
|         const current = game.system.rdd.calendrier.heureCourante() | ||||
|         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>.`, | ||||
|           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è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: '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" }, | ||||
|   | ||||
| @@ -112,6 +112,19 @@ export class SystemCompendiums extends FormApplication { | ||||
|     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) { | ||||
|     const pack = game.packs.get(SystemCompendiums._getDefaultCompendium(compendium)); | ||||
|     if (pack.metadata.type == 'Item') { | ||||
|   | ||||
| @@ -186,7 +186,7 @@ export class AppAstrologie extends Application { | ||||
|       date: this.html.find('[name="joursAstrologie"]').val(), | ||||
|       userId: game.user.id | ||||
|     } | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       game.system.rdd.calendrier.requestNombreAstral(socketData); | ||||
|     } else { | ||||
|       game.socket.emit(SYSTEM_SOCKET_ID, { | ||||
|   | ||||
| @@ -13,18 +13,21 @@ export class Targets { | ||||
|   static extractTokenData(target) { | ||||
|     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) { | ||||
|     return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE; | ||||
|   } | ||||
|  | ||||
|   static async selectOneToken(onSelectTarget = target => { }) { | ||||
|     const targets = Targets.listTargets(); | ||||
|   static async selectOneTargetToken(onSelectTarget = target => { }) { | ||||
|     const targets = Targets.listTargets() | ||||
|     switch (targets.length) { | ||||
|       case 0: return; | ||||
|       case 0: | ||||
|         return | ||||
|       case 1: | ||||
|         onSelectTarget(targets[0]); | ||||
|         return; | ||||
|         onSelectTarget(targets[0]) | ||||
|         return | ||||
|       default: | ||||
|         { | ||||
|           const selectData = { | ||||
| @@ -32,7 +35,7 @@ export class Targets { | ||||
|             label: "Choisir une seule des cibles", | ||||
|             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) { | ||||
|     if (AutoAdjustDarkness.isAuto()) { | ||||
|     if (game.user.isGM && AutoAdjustDarkness.isAuto()) { | ||||
|       const scene = game.scenes.viewed; | ||||
|       if (scene?.environment?.globalLight?.enabled && scene?.tokenVision) { | ||||
|         await scene.update({ darkness }); | ||||
|   | ||||
| @@ -48,7 +48,7 @@ export class RdDCalendrier extends Application { | ||||
|   constructor() { | ||||
|     super(); | ||||
|     this.timestamp = RdDTimestamp.getWorldTime(); | ||||
|     if (Misc.isUniqueConnectedGM()) { // Uniquement si GM | ||||
|     if (Misc.isFirstConnectedGM()) { // Uniquement si GM | ||||
|       RdDTimestamp.setWorldTime(this.timestamp); | ||||
|       this.rebuildNombresAstraux(); // Ensure always up-to-date | ||||
|     } | ||||
| @@ -258,7 +258,7 @@ export class RdDCalendrier extends Application { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rebuildNombresAstraux() { | ||||
|     if (Misc.isUniqueConnectedGM()) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       const nombresAstraux = this.getNombresAstraux() | ||||
|       let newNombresAstraux = []; | ||||
|       for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) { | ||||
| @@ -337,7 +337,7 @@ export class RdDCalendrier extends Application { | ||||
|   /* -------------------------------------------- */ | ||||
|   async requestNombreAstral(request) { | ||||
|     const actor = game.actors.get(request.id); | ||||
|     if (Misc.isUniqueConnectedGM()) { // Only once | ||||
|     if (Misc.isFirstConnectedGM()) { // Only once | ||||
|       console.log(request); | ||||
|       let jourDiff = this.getLectureAstrologieDifficulte(request.date); | ||||
|       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) { | ||||
|     heure = Grammar.toLowerCaseNoAccentNoSpace(heure); | ||||
|     let parHeureOuLabel = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure || it.heure == Misc.modulo(parseInt(heure), RDD_HEURES_PAR_JOUR)); | ||||
|     if (parHeureOuLabel.length == 1) { | ||||
|       return parHeureOuLabel[0]; | ||||
|     let filtered | ||||
|     if (Number.isInteger(Number(heure))) { | ||||
|       filtered = DEFINITION_HEURES.filter(it => it.heure == Misc.modulo(Number(heure) - 1, RDD_HEURES_PAR_JOUR)) | ||||
|     } | ||||
|     let parLabelPartiel = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label).includes(heure)); | ||||
|     if (parLabelPartiel.length > 0) { | ||||
|       parLabelPartiel.sort(Misc.ascending(h => h.label.length)); | ||||
|       return parLabelPartiel[0]; | ||||
|     else { | ||||
|       heure = Grammar.toLowerCaseNoAccentNoSpace(heure); | ||||
|       filtered = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure || it.heure == Misc.modulo(parseInt(heure), RDD_HEURES_PAR_JOUR)); | ||||
|     } | ||||
|     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; | ||||
|   } | ||||
|   | ||||
							
								
								
									
										
											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) | ||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/entites-de-cauchemar/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/entites-de-cauchemar/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -64,6 +64,7 @@ | ||||
| {"_id":"MGvyXFQJpv6nNynl","name":"Masse lourde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/masse_lourde.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.MGvyXFQJpv6nNynl"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":3,"quantite":1,"qualite":0,"cout":4,"milieu":"","environnement":[{"milieu":"Villages","rarete":"Rare","frequence":6},{"milieu":"Villes","rarete":"Frequente","frequence":18}],"resistance":10,"categorie_parade":"","dommages":"3/4","penetration":0,"force":"12/11","competence":"Masse à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":0,"resistance_magique":0,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"masse"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.6.15","coreVersion":"10.291","createdTime":1668808206023,"modifiedTime":1676074487966,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} | ||||
| {"_id":"MQxgfYTEQEUhG116","name":"Épée bâtarde","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_batarde.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.MQxgfYTEQEUhG116"}},"system":{"description":"<p>Comme son nom l’indique, c’est une <em>bâtarde </em>de l'épée longue et de l'épée sorde, à la fois longue et large, pouvant s’utiliser à une ou deux mains.</p>","descriptionmj":"","equipe":false,"encombrement":3,"quantite":1,"qualite":0,"cout":30,"milieu":"","environnement":[{"milieu":"Villages","rarete":"Rarissime","frequence":2},{"milieu":"Villes","rarete":"Rare","frequence":6}],"resistance":14,"categorie_parade":"epees-lourdes","dommages":"4/5","penetration":0,"force":"13/12","competence":"Epée à 1 main","lancer":"","tir":"","portee_courte":0,"portee_moyenne":0,"portee_extreme":0,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":false,"deuxmains":true,"unemain":true,"initpremierround":"epeebatarde"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.6.15","coreVersion":"10.291","createdTime":1668808206023,"modifiedTime":1676074487966,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} | ||||
| {"_id":"Mbh2M8JS1Rf0vxEX","name":"Harpe","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/harpe.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.Mbh2M8JS1Rf0vxEX"}},"system":{"description":"","descriptionmj":"","encombrement":1,"quantite":1,"qualite":0,"cout":5,"milieu":"","environnement":[{"milieu":"Villages","rarete":"Rarissime","frequence":2},{"milieu":"Villes","rarete":"Rare","frequence":6}],"equipe":false,"resistance":1},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.6.15","coreVersion":"10.291","createdTime":1668808206023,"modifiedTime":1676074487966,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} | ||||
| {"_id":"NCp2kdTKmJVdFuit","name":"Dague mêlée","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/dague.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sheetClass":"","sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.NCp2kdTKmQGyAh1U"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":0.5,"quantite":1,"qualite":0,"cout":3,"milieu":"","environnement":[{"milieu":"Villages","rarete":"Frequente","frequence":18},{"milieu":"Villes","rarete":"Frequente","frequence":18}],"resistance":8,"categorie_parade":"dagues","dommages":"1","penetration":0,"force":"7","competence":"Dague","lancer":"Dague de jet","tir":"","portee_courte":3,"portee_moyenne":8,"portee_extreme":15,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"dague"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.6.15","coreVersion":"10.291","createdTime":1668808206023,"modifiedTime":1676074487966,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} | ||||
| {"_id":"NCp2kdTKmQGyAh1U","name":"Dague","type":"arme","img":"systems/foundryvtt-reve-de-dragon/icons/armes_armures/dague.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sheetClass":"","sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.NCp2kdTKmQGyAh1U"}},"system":{"description":"","descriptionmj":"","equipe":false,"encombrement":0.5,"quantite":1,"qualite":0,"cout":3,"milieu":"","environnement":[{"milieu":"Villages","rarete":"Frequente","frequence":18},{"milieu":"Villes","rarete":"Frequente","frequence":18}],"resistance":8,"categorie_parade":"dagues","dommages":"1","penetration":0,"force":"7","competence":"Dague","lancer":"Dague de jet","tir":"","portee_courte":3,"portee_moyenne":8,"portee_extreme":15,"magique":false,"ecaille_efficacite":null,"resistance_magique":null,"rapide":true,"deuxmains":false,"unemain":true,"initpremierround":"dague"},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.6.15","coreVersion":"10.291","createdTime":1668808206023,"modifiedTime":1676074487966,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} | ||||
| {"_id":"NNLhxjFsoJVdFuit","name":"Bouteille de verre (1 litre)","type":"conteneur","img":"systems/foundryvtt-reve-de-dragon/icons/objets/bouteille_verre.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.NNLhxjFsoJVdFuit"}},"system":{"description":"","descriptionmj":"","encombrement":0.2,"quantite":1,"qualite":0,"cout":0.7,"milieu":"","environnement":[{"milieu":"Villages","rarete":"Rare","frequence":6},{"milieu":"Villes","rarete":"Frequente","frequence":18}],"contenu":[],"capacite":0.5,"equipe":false},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.6.15","coreVersion":"10.291","createdTime":1668808206023,"modifiedTime":1676074487966,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} | ||||
| {"_id":"OXFFRZOqlhZDJas3","name":"Béret de velours","type":"objet","img":"systems/foundryvtt-reve-de-dragon/icons/objets/beret_velours.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.equipement.OXFFRZOqlhZDJas3"}},"system":{"description":"","descriptionmj":"","encombrement":0.05,"quantite":1,"qualite":0,"cout":3,"milieu":"","environnement":[{"milieu":"Villages","rarete":"Rare","frequence":6},{"milieu":"Villes","rarete":"Frequente","frequence":18}],"equipe":false,"resistance":1},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.6.15","coreVersion":"10.291","createdTime":1668808206023,"modifiedTime":1676074487966,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} | ||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/equipement/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/equipement/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								pack_ref/equipement/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/equipement/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								pack_ref/equipement/CURRENT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pack_ref/equipement/CURRENT
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| MANIFEST-000010 | ||||
							
								
								
									
										0
									
								
								pack_ref/equipement/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/equipement/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								pack_ref/equipement/LOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pack_ref/equipement/LOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| 2024/11/10-18:39:00.544474 7fed690006c0 Recovering log #8 | ||||
| 2024/11/10-18:39:00.555177 7fed690006c0 Delete type=3 #6 | ||||
| 2024/11/10-18:39:00.555255 7fed690006c0 Delete type=0 #8 | ||||
							
								
								
									
										8
									
								
								pack_ref/equipement/LOG.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pack_ref/equipement/LOG.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| 2024/11/08-19:40:33.076530 7f9d7e0006c0 Recovering log #4 | ||||
| 2024/11/08-19:40:33.128870 7f9d7e0006c0 Delete type=3 #2 | ||||
| 2024/11/08-19:40:33.128972 7f9d7e0006c0 Delete type=0 #4 | ||||
| 2024/11/08-19:56:45.003377 7f9d7d6006c0 Level-0 table #9: started | ||||
| 2024/11/08-19:56:45.003402 7f9d7d6006c0 Level-0 table #9: 0 bytes OK | ||||
| 2024/11/08-19:56:45.009778 7f9d7d6006c0 Delete type=0 #7 | ||||
| 2024/11/08-19:56:45.031135 7f9d7d6006c0 Manual compaction at level-0 from '!items!0I30m9qcYJk6UR6o' @ 72057594037927935 : 1 .. '!items!zlDa1vwmls6Uf4pt' @ 0 : 0; will stop at (end) | ||||
| 2024/11/08-19:56:45.031185 7f9d7d6006c0 Manual compaction at level-1 from '!items!0I30m9qcYJk6UR6o' @ 72057594037927935 : 1 .. '!items!zlDa1vwmls6Uf4pt' @ 0 : 0; will stop at (end) | ||||
							
								
								
									
										
											BIN
										
									
								
								pack_ref/equipement/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/equipement/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								pack_ref/extrait-poetique/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pack_ref/extrait-poetique/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								pack_ref/extrait-poetique/000011.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pack_ref/extrait-poetique/000011.log
									
									
									
									
									
										Normal file
									
								
							Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user