From c6ddc96148fbba3b93a52d429e4ea08b90db2621 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Sun, 26 Apr 2026 15:45:53 +0200 Subject: [PATCH] Fiche PNJ : Autorise multi-attaques --- less/actor-sheet.less | 34 +++++++++++ .../sheets/donjon-et-cie-pnj-sheet.mjs | 18 +++++- modules/donjon-et-cie-actor.mjs | 54 ++++++++++++++++-- modules/models/pnj.mjs | 12 ++-- packs/equipment/{000037.log => 000042.log} | 0 packs/equipment/CURRENT | 2 +- packs/equipment/LOG | 18 +++--- packs/equipment/LOG.old | 15 +++-- packs/equipment/MANIFEST-000035 | Bin 264 -> 0 bytes packs/equipment/MANIFEST-000040 | Bin 0 -> 173 bytes .../random-tables/{000024.log => 000029.log} | 0 packs/random-tables/CURRENT | 2 +- packs/random-tables/LOG | 18 +++--- packs/random-tables/LOG.old | 15 +++-- packs/random-tables/MANIFEST-000022 | Bin 340 -> 0 bytes packs/random-tables/MANIFEST-000027 | Bin 0 -> 224 bytes styles/donjon-et-cie.css | 28 +++++++++ styles/donjon-et-cie.css.map | 2 +- templates/actors/pnj-sheet.hbs | 39 +++++++------ 19 files changed, 197 insertions(+), 60 deletions(-) rename packs/equipment/{000037.log => 000042.log} (100%) delete mode 100644 packs/equipment/MANIFEST-000035 create mode 100644 packs/equipment/MANIFEST-000040 rename packs/random-tables/{000024.log => 000029.log} (100%) delete mode 100644 packs/random-tables/MANIFEST-000022 create mode 100644 packs/random-tables/MANIFEST-000027 diff --git a/less/actor-sheet.less b/less/actor-sheet.less index a17c8a8..a90afa2 100644 --- a/less/actor-sheet.less +++ b/less/actor-sheet.less @@ -265,3 +265,37 @@ .dnc-pnj-sheet .pnj-combat-grid .span-two { grid-column: 1 / -1; } + +.dnc-pnj-sheet .pnj-attack-list { + display: flex; + flex-direction: column; + gap: @spacing-md; +} + +.dnc-pnj-sheet .pnj-attack-list .section-header { + margin-bottom: 0; +} + +.dnc-pnj-sheet .pnj-attack-list h3 { + margin: 0; + font-size: 0.95rem; + color: @color-ink; +} + +.dnc-pnj-sheet .pnj-attack-rows { + display: flex; + flex-direction: column; + gap: @spacing-md; +} + +.dnc-pnj-sheet .pnj-attack-row { + display: grid; + grid-template-columns: minmax(0, 1fr) 4.5rem max-content; + gap: @spacing-md; + align-items: end; +} + +.dnc-pnj-sheet .pnj-attack-row .item-actions { + align-self: end; + gap: @spacing-sm; +} diff --git a/modules/applications/sheets/donjon-et-cie-pnj-sheet.mjs b/modules/applications/sheets/donjon-et-cie-pnj-sheet.mjs index 0f7aecd..7d57987 100644 --- a/modules/applications/sheets/donjon-et-cie-pnj-sheet.mjs +++ b/modules/applications/sheets/donjon-et-cie-pnj-sheet.mjs @@ -22,7 +22,9 @@ export default class DonjonEtCiePNJSheet extends DonjonEtCieActorSheet { ...super.DEFAULT_OPTIONS.actions, rollPnjArmor: DonjonEtCiePNJSheet.#onRollPnjArmor, rollPnjCourage: DonjonEtCiePNJSheet.#onRollPnjCourage, - rollPnjAttackDamage: DonjonEtCiePNJSheet.#onRollPnjAttackDamage + rollPnjAttackDamage: DonjonEtCiePNJSheet.#onRollPnjAttackDamage, + createPnjAttack: DonjonEtCiePNJSheet.#onCreatePnjAttack, + deletePnjAttack: DonjonEtCiePNJSheet.#onDeletePnjAttack } }; @@ -48,7 +50,7 @@ export default class DonjonEtCiePNJSheet extends DonjonEtCieActorSheet { armorDisplay: Number(system.defense?.armure?.delta ?? 0) ? `Δ${system.defense.armure.delta}` : "—", storedArmor: Number(system.defense?.armure?.resultatProtection ?? 0) > 0 ? system.defense.armure.resultatProtection : "—", courageDisplay: Number(system.defense?.courage?.delta ?? 0) ? `Δ${system.defense.courage.delta}` : "—", - hasAttackDamage: Boolean(system.attaque?.degats) + pnjAttacks: this.document.getPnjAttacks() }; } @@ -64,6 +66,16 @@ export default class DonjonEtCiePNJSheet extends DonjonEtCieActorSheet { static async #onRollPnjAttackDamage(event) { event.preventDefault(); - return this.document.rollPnjAttackDamage(); + return this.document.rollPnjAttackDamage(event.target.closest("[data-attack-index]")?.dataset.attackIndex ?? 0); + } + + static async #onCreatePnjAttack(event) { + event.preventDefault(); + return this.document.createPnjAttack(); + } + + static async #onDeletePnjAttack(event) { + event.preventDefault(); + return this.document.deletePnjAttack(event.target.closest("[data-attack-index]")?.dataset.attackIndex ?? 0); } } diff --git a/modules/donjon-et-cie-actor.mjs b/modules/donjon-et-cie-actor.mjs index a763ce4..35c3902 100644 --- a/modules/donjon-et-cie-actor.mjs +++ b/modules/donjon-et-cie-actor.mjs @@ -14,6 +14,12 @@ import { DonjonEtCieUtility } from "./donjon-et-cie-utility.mjs"; import { DonjonEtCieRollDialog } from "./applications/donjon-et-cie-roll-dialog.mjs"; export class DonjonEtCieActor extends Actor { + static defaultPnjAttack = { + nom: "Attaque", + degats: "1d6", + notes: "" + }; + prepareDerivedData() { super.prepareDerivedData(); @@ -163,6 +169,45 @@ export class DonjonEtCieActor extends Actor { if (item?.type === "entrainement") return item.resetUsageDie(); } + getPnjAttacks() { + if (this.type !== "pnj") return []; + + const attacks = Array.isArray(this.system.attaques) ? this.system.attaques : []; + if (attacks.length) return attacks.map((attack, index) => ({ + index, + nom: attack.nom || `Attaque ${index + 1}`, + degats: attack.degats || "", + notes: attack.notes || "" + })); + + const legacy = this.system.attaque; + if (legacy) { + return [{ + index: 0, + nom: legacy.nom || "Attaque", + degats: legacy.degats || "", + notes: legacy.notes || "" + }]; + } + + return [{ index: 0, ...foundry.utils.deepClone(this.constructor.defaultPnjAttack) }]; + } + + async createPnjAttack() { + if (this.type !== "pnj") return null; + const attaques = this.getPnjAttacks().map(({ nom, degats, notes }) => ({ nom, degats, notes })); + attaques.push(foundry.utils.deepClone(this.constructor.defaultPnjAttack)); + return this.update({ "system.attaques": attaques }); + } + + async deletePnjAttack(index) { + if (this.type !== "pnj") return null; + const attaques = this.getPnjAttacks().map(({ nom, degats, notes }) => ({ nom, degats, notes })); + attaques.splice(Number(index), 1); + if (!attaques.length) attaques.push(foundry.utils.deepClone(this.constructor.defaultPnjAttack)); + return this.update({ "system.attaques": attaques }); + } + #createPnjResourceProxy({ label, deltaPath, protectionPath = null }) { const delta = Number(foundry.utils.getProperty(this, deltaPath) ?? 0); const protection = protectionPath ? Number(foundry.utils.getProperty(this, protectionPath) ?? 0) : 0; @@ -203,9 +248,10 @@ export class DonjonEtCieActor extends Actor { })); } - async rollPnjAttackDamage() { - const attackName = this.system.attaque?.nom || "Attaque"; - const attackDamage = this.system.attaque?.degats || ""; + async rollPnjAttackDamage(index = 0) { + const attack = this.getPnjAttacks()[Number(index)] ?? null; + const attackName = attack?.nom || "Attaque"; + const attackDamage = attack?.degats || ""; if (!attackDamage) return null; return DonjonEtCieRollDialog.createDamage(this, { @@ -213,7 +259,7 @@ export class DonjonEtCieActor extends Actor { type: "attaque", system: { degats: attackDamage, - portee: this.system.attaque?.notes || "" + portee: attack?.notes || "" } }); } diff --git a/modules/models/pnj.mjs b/modules/models/pnj.mjs index e61c51d..8dad238 100644 --- a/modules/models/pnj.mjs +++ b/modules/models/pnj.mjs @@ -13,6 +13,11 @@ export default class PnjDataModel extends foundry.abstract.TypeDataModel { static defineSchema() { const fields = foundry.data.fields; + const makeAttack = () => new fields.SchemaField({ + nom: new fields.StringField({ initial: "Attaque" }), + degats: new fields.StringField({ initial: "1d6" }), + notes: new fields.StringField({ initial: "" }) + }); return { espece: new fields.StringField({ initial: "" }), @@ -35,10 +40,9 @@ export default class PnjDataModel extends foundry.abstract.TypeDataModel { delta: new fields.NumberField({ initial: 0, integer: true }) }) }), - attaque: new fields.SchemaField({ - nom: new fields.StringField({ initial: "Attaque" }), - degats: new fields.StringField({ initial: "1d6" }), - notes: new fields.StringField({ initial: "" }) + attaque: makeAttack(), + attaques: new fields.ArrayField(makeAttack(), { + initial: [{ nom: "Attaque", degats: "1d6", notes: "" }] }), pouvoirsSpeciaux: new fields.HTMLField({ initial: "" }), description: new fields.HTMLField({ initial: "" }), diff --git a/packs/equipment/000037.log b/packs/equipment/000042.log similarity index 100% rename from packs/equipment/000037.log rename to packs/equipment/000042.log diff --git a/packs/equipment/CURRENT b/packs/equipment/CURRENT index 29a53d8..e2c0c4b 100644 --- a/packs/equipment/CURRENT +++ b/packs/equipment/CURRENT @@ -1 +1 @@ -MANIFEST-000035 +MANIFEST-000040 diff --git a/packs/equipment/LOG b/packs/equipment/LOG index 2e2bea3..29bd0fd 100644 --- a/packs/equipment/LOG +++ b/packs/equipment/LOG @@ -1,11 +1,7 @@ -2026/04/19-18:55:51.456726 7ff1abfff6c0 Delete type=3 #1 -2026/04/19-19:06:36.056435 7ff1a9ffb6c0 Level-0 table #38: started -2026/04/19-19:06:36.056473 7ff1a9ffb6c0 Level-0 table #38: 0 bytes OK -2026/04/19-19:06:36.063121 7ff1a9ffb6c0 Delete type=0 #36 -2026/04/19-19:06:36.069412 7ff1a9ffb6c0 Manual compaction at level-0 from '!folders!K9aiFu0dE6UYiXBd' @ 72057594037927935 : 1 .. '!items!zyqLzmpbHxK3jt5q' @ 0 : 0; will stop at '!items!zyqLzmpbHxK3jt5q' @ 188 : 1 -2026/04/19-19:06:36.069420 7ff1a9ffb6c0 Compacting 1@0 + 0@1 files -2026/04/19-19:06:36.073487 7ff1a9ffb6c0 Generated table #39@0: 189 keys, 41244 bytes -2026/04/19-19:06:36.073509 7ff1a9ffb6c0 Compacted 1@0 + 0@1 files => 41244 bytes -2026/04/19-19:06:36.079534 7ff1a9ffb6c0 compacted to: files[ 0 1 0 0 0 0 0 ] -2026/04/19-19:06:36.079617 7ff1a9ffb6c0 Delete type=2 #14 -2026/04/19-19:06:36.106853 7ff1a9ffb6c0 Manual compaction at level-0 from '!items!zyqLzmpbHxK3jt5q' @ 188 : 1 .. '!items!zyqLzmpbHxK3jt5q' @ 0 : 0; will stop at (end) +2026/04/26-15:24:50.959107 7f57a5fef6c0 Recovering log #37 +2026/04/26-15:24:50.969309 7f57a5fef6c0 Delete type=3 #35 +2026/04/26-15:24:50.969397 7f57a5fef6c0 Delete type=0 #37 +2026/04/26-15:45:09.958844 7f57977fe6c0 Level-0 table #43: started +2026/04/26-15:45:09.959077 7f57977fe6c0 Level-0 table #43: 0 bytes OK +2026/04/26-15:45:09.966304 7f57977fe6c0 Delete type=0 #41 +2026/04/26-15:45:09.985022 7f57977fe6c0 Manual compaction at level-0 from '!folders!K9aiFu0dE6UYiXBd' @ 72057594037927935 : 1 .. '!items!zyqLzmpbHxK3jt5q' @ 0 : 0; will stop at (end) diff --git a/packs/equipment/LOG.old b/packs/equipment/LOG.old index e481656..2e2bea3 100644 --- a/packs/equipment/LOG.old +++ b/packs/equipment/LOG.old @@ -1,4 +1,11 @@ -2026/04/19-18:55:51.316755 7ff1abfff6c0 Log #33: 0 ops saved to Table #34 OK -2026/04/19-18:55:51.316821 7ff1abfff6c0 Archiving /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-donjon-et-cie/packs/equipment/000033.log: OK -2026/04/19-18:55:51.316935 7ff1abfff6c0 Table #14: 189 entries OK -2026/04/19-18:55:51.320226 7ff1abfff6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-donjon-et-cie/packs/equipment; recovered 1 files; 41244 bytes. Some data may have been lost. **** +2026/04/19-18:55:51.456726 7ff1abfff6c0 Delete type=3 #1 +2026/04/19-19:06:36.056435 7ff1a9ffb6c0 Level-0 table #38: started +2026/04/19-19:06:36.056473 7ff1a9ffb6c0 Level-0 table #38: 0 bytes OK +2026/04/19-19:06:36.063121 7ff1a9ffb6c0 Delete type=0 #36 +2026/04/19-19:06:36.069412 7ff1a9ffb6c0 Manual compaction at level-0 from '!folders!K9aiFu0dE6UYiXBd' @ 72057594037927935 : 1 .. '!items!zyqLzmpbHxK3jt5q' @ 0 : 0; will stop at '!items!zyqLzmpbHxK3jt5q' @ 188 : 1 +2026/04/19-19:06:36.069420 7ff1a9ffb6c0 Compacting 1@0 + 0@1 files +2026/04/19-19:06:36.073487 7ff1a9ffb6c0 Generated table #39@0: 189 keys, 41244 bytes +2026/04/19-19:06:36.073509 7ff1a9ffb6c0 Compacted 1@0 + 0@1 files => 41244 bytes +2026/04/19-19:06:36.079534 7ff1a9ffb6c0 compacted to: files[ 0 1 0 0 0 0 0 ] +2026/04/19-19:06:36.079617 7ff1a9ffb6c0 Delete type=2 #14 +2026/04/19-19:06:36.106853 7ff1a9ffb6c0 Manual compaction at level-0 from '!items!zyqLzmpbHxK3jt5q' @ 188 : 1 .. '!items!zyqLzmpbHxK3jt5q' @ 0 : 0; will stop at (end) diff --git a/packs/equipment/MANIFEST-000035 b/packs/equipment/MANIFEST-000035 deleted file mode 100644 index cfd20f9640a842b401e355ea0d2937511e1b9f42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 264 zcmb=d-~KR#fss)vC$%g!CnZVGsj?)sJhM2}IX|}`u_&=5zlfcIZ_XhmMa8uIoRrj} zVnuJu#7wtRgA`Y@(8$aPrxeCa1~8CU%q&UGEmo|mEcB_$ElBdH@HWmWF)d`=1CgKV zFs+i4fssjtlYv>4goD9rbEQc9yoxUFj;%fo 28120 bytes -2026/04/19-19:06:36.090555 7ff1a9ffb6c0 compacted to: files[ 0 1 0 0 0 0 0 ] -2026/04/19-19:06:36.090673 7ff1a9ffb6c0 Delete type=2 #5 -2026/04/19-19:06:36.106868 7ff1a9ffb6c0 Manual compaction at level-0 from '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 208 : 1 .. '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 0 : 0; will stop at (end) +2026/04/26-15:24:50.974308 7f57a57ee6c0 Recovering log #24 +2026/04/26-15:24:50.984638 7f57a57ee6c0 Delete type=3 #22 +2026/04/26-15:24:50.984738 7f57a57ee6c0 Delete type=0 #24 +2026/04/26-15:45:09.972734 7f57977fe6c0 Level-0 table #30: started +2026/04/26-15:45:09.972793 7f57977fe6c0 Level-0 table #30: 0 bytes OK +2026/04/26-15:45:09.978845 7f57977fe6c0 Delete type=0 #28 +2026/04/26-15:45:09.985047 7f57977fe6c0 Manual compaction at level-0 from '!tables!PPsxQgHwLCQ2gjSW' @ 72057594037927935 : 1 .. '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 0 : 0; will stop at (end) diff --git a/packs/random-tables/LOG.old b/packs/random-tables/LOG.old index ac56027..27d7878 100644 --- a/packs/random-tables/LOG.old +++ b/packs/random-tables/LOG.old @@ -1,4 +1,11 @@ -2026/04/19-18:55:51.460010 7ff1abfff6c0 Log #20: 0 ops saved to Table #21 OK -2026/04/19-18:55:51.460123 7ff1abfff6c0 Archiving /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-donjon-et-cie/packs/random-tables/000020.log: OK -2026/04/19-18:55:51.460233 7ff1abfff6c0 Table #5: 210 entries OK -2026/04/19-18:55:51.463454 7ff1abfff6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-donjon-et-cie/packs/random-tables; recovered 1 files; 39147 bytes. Some data may have been lost. **** +2026/04/19-18:55:51.477710 7ff1abfff6c0 Delete type=3 #1 +2026/04/19-19:06:36.063191 7ff1a9ffb6c0 Level-0 table #25: started +2026/04/19-19:06:36.063213 7ff1a9ffb6c0 Level-0 table #25: 0 bytes OK +2026/04/19-19:06:36.069246 7ff1a9ffb6c0 Delete type=0 #23 +2026/04/19-19:06:36.079744 7ff1a9ffb6c0 Manual compaction at level-0 from '!tables!PPsxQgHwLCQ2gjSW' @ 72057594037927935 : 1 .. '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 0 : 0; will stop at '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 208 : 1 +2026/04/19-19:06:36.079754 7ff1a9ffb6c0 Compacting 1@0 + 0@1 files +2026/04/19-19:06:36.084239 7ff1a9ffb6c0 Generated table #26@0: 120 keys, 28120 bytes +2026/04/19-19:06:36.084267 7ff1a9ffb6c0 Compacted 1@0 + 0@1 files => 28120 bytes +2026/04/19-19:06:36.090555 7ff1a9ffb6c0 compacted to: files[ 0 1 0 0 0 0 0 ] +2026/04/19-19:06:36.090673 7ff1a9ffb6c0 Delete type=2 #5 +2026/04/19-19:06:36.106868 7ff1a9ffb6c0 Manual compaction at level-0 from '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 208 : 1 .. '!tables.results!wJZXUo4q5b5vE3Dy.zFTPLMc9zOl5hISV' @ 0 : 0; will stop at (end) diff --git a/packs/random-tables/MANIFEST-000022 b/packs/random-tables/MANIFEST-000022 deleted file mode 100644 index 2b23eec2eab67bcb14015ef2ff4f8916f55a03a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmd;Nw|iB~z{n_-lUkOVlai$8R9TW*o>`pgoS$2eSd>_jU&PM9`g$Xif?`QxQch~I zVn9G~MPRx|xsP+8QF>NzIO7%uFtCIw&?`zUF3l+^RxJ05iU`d&DKt$oEps(?snn}- z3kmS?O}4D^&oRyL3=U(w0MWTB;RqKe10$0-Cj+wt%O%DQX-(%rd`pgoS$2eSd>_jU&P8_saTSjl#^PlSCm>@ znp0A&Snd@S5t?sOXqseN=4$LxsaNF|65!*TY+2=>W18U^9L9Ko0Swp~rEc72RDkMN z3Valeurs

ARM {{armorDisplay}} · COU {{courageDisplay}}

- -