diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aad3464..128f43a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,7 @@ build: - cp styles/* dist/styles/ - cp module.json dist - cd dist - - zip wfrp4e-actor-sheet-print.zip -r *.* src lang styles -x ".*" + - zip wfrp4e-actor-sheet-print.zip -r *.* elements lang styles -x ".*" artifacts: name: wfrp4e-actor-sheet-print when: on_success @@ -40,7 +40,7 @@ build_beta: - cp styles/* dist/styles/ - cp module-beta.json dist/module.json - cd dist - - zip wfrp4e-actor-sheet-print.zip -r *.* src lang styles -x ".*" + - zip wfrp4e-actor-sheet-print.zip -r *.* elements lang styles -x ".*" artifacts: name: wfrp4e-actor-sheet-print when: on_success diff --git a/src/elements/column.ts b/src/elements/column.ts index e325331..4a93ade 100644 --- a/src/elements/column.ts +++ b/src/elements/column.ts @@ -28,14 +28,16 @@ export class Column extends AbstractElement { } public getHeight(doc): number { - return this.elements - .map((e) => e.getHeight(doc)) - .reduce((p, c, i) => { - if (i === 0) { - return c; - } - return p + c + 2; - }); + return this.elements.length > 0 + ? this.elements + .map((e) => e.getHeight(doc)) + .reduce((p, c, i) => { + if (i === 0) { + return c; + } + return p + c + 2; + }) + : 0; } public getCheckNewPageHeight(doc?: jsPDF): number { diff --git a/src/elements/labelled-values.ts b/src/elements/labelled-values.ts index 6198203..b24d6f3 100644 --- a/src/elements/labelled-values.ts +++ b/src/elements/labelled-values.ts @@ -25,7 +25,7 @@ export class LabelledValues extends Row { const labelPercent = 100 - valuePercent; const widthPercent = [labelPercent, valuePercent]; let currentIndex = 0; - if (labelledValues.length >= this.nbrOfCol) { + if (this.nbrOfCol > 1) { const nbrPerCol = Math.floor(labelledValues.length / this.nbrOfCol); const rest = labelledValues.length - nbrPerCol * this.nbrOfCol; const nbrPerCols = [ diff --git a/src/elements/texts.ts b/src/elements/texts.ts index 5f3c62c..cfc6354 100644 --- a/src/elements/texts.ts +++ b/src/elements/texts.ts @@ -23,7 +23,7 @@ export class Texts extends Row { this.nbrOfCol = 4; } let currentIndex = 0; - if (texts.length >= this.nbrOfCol) { + if (this.nbrOfCol > 1) { const nbrPerCol = Math.floor(texts.length / this.nbrOfCol); const rest = texts.length - nbrPerCol * this.nbrOfCol; const nbrPerCols = [ diff --git a/src/main.ts b/src/main.ts index 38f7036..eb960c3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -88,7 +88,7 @@ Hooks.on( const weaponsMelee = new Texts( 0, 0, - actor.itemCategories.weapon + Util.getActorItems(actor, 'weapon') .filter((w) => w.isMelee) .map((item) => { return `${item.name} : ${item.WeaponGroup}, ${item.Reach}, ${ @@ -105,7 +105,7 @@ Hooks.on( const weaponsRanged = new Texts( 0, 0, - actor.itemCategories.weapon + Util.getActorItems(actor, 'weapon') .filter((w) => w.isRanged) .map((item) => { return `${item.name} : ${item.WeaponGroup}, ${ @@ -124,7 +124,7 @@ Hooks.on( const ammunitions = new Texts( 0, 0, - actor.itemCategories.ammunition + Util.getActorItems(actor, 'ammunition') .map((item) => { return `${item.data.data.quantity.value} ${item.name} : ${ item.data.data.range.value.length > 0 @@ -143,7 +143,7 @@ Hooks.on( const armourLocation: string[] = []; const armourLabels: { [key: string]: string[] } = {}; - for (const armour of actor.itemCategories.armour) { + for (const armour of Util.getActorItems(actor, 'armour')) { const maxAp = armour.data.data.maxAP; for (const key of Object.keys(maxAp)) { if (maxAp[key] > 0) { @@ -174,6 +174,160 @@ Hooks.on( true ); + const petty = new Texts( + 0, + 0, + actor.itemCategories.spell + .filter((s) => s.lore.value === 'petty') + .map((s) => { + return `${s.name} : ${s.cn.value}, ${s.Range}, ${s.Target}, ${s.Duration}`; + }), + 2, + true + ); + + const spell = new Texts( + 0, + 0, + actor.itemCategories.spell + .filter((s) => s.lore.value !== 'petty') + .map((s) => { + return `${s.name} : ${s.cn.value}, ${s.Range}, ${s.Target}, ${s.Duration}, ${s.ingredientList.length}`; + }), + 2, + true + ); + + const blessing = new Texts( + 0, + 0, + actor.itemCategories.prayer + .filter((s) => s.prayerType.value === 'blessing') + .map((s) => { + return `${s.name} : ${s.Range}, ${s.Target}, ${s.Duration}`; + }), + 2, + true + ); + + const miracle = new Texts( + 0, + 0, + actor.itemCategories.prayer + .filter((s) => s.prayerType.value !== 'blessing') + .map((s) => { + return `${s.name} : ${s.Range}, ${s.Target}, ${s.Duration}`; + }), + 2, + true + ); + + const allMoney = Util.getActorItems(actor, 'money'); + const moneyNames: string[] = []; + const moneyByName: { [name: string]: number } = {}; + for (const money of allMoney) { + if (!moneyNames.includes(money.name)) { + moneyNames.push(money.name); + } + if (moneyByName[money.name] == null) { + moneyByName[money.name] = 0; + } + moneyByName[money.name] = + moneyByName[money.name] + money.quantity.value; + } + + const trappingsHeader = new Texts( + 0, + 0, + [ + `${i18nLocalize('Trappings')} : ${i18nLocalize( + 'Money' + )} : ${moneyNames + .map((m) => { + return `${m} : ${moneyByName[m]}`; + }) + .join(', ')}`, + ], + 1, + true + ); + + const trappings = new Texts( + 0, + 0, + Util.getAllActorItems(actor, ['container', 'trapping']) + .map((t) => { + const location = t.location.value; + let prefix = ''; + if (location != null && location !== 0) { + prefix = `${actor.getEmbeddedDocument('Item', location).name} : `; + } + const qteLabel = t.quantity.value > 1 ? `${t.quantity.value} ` : ''; + return `${prefix}${qteLabel}${t.name}`; + }) + .sort((a, b) => a.localeCompare(b)), + 4, + true + ); + + const critical = new Texts( + 0, + 0, + actor.itemCategories.critical.map((i) => { + return i.name; + }), + 3 + ); + + const disease = new Texts( + 0, + 0, + actor.itemCategories.disease.map((i) => { + return i.name; + }), + 3 + ); + + const injury = new Texts( + 0, + 0, + actor.itemCategories.injury.map((i) => { + return i.name; + }), + 3 + ); + + const mutationP = new Texts( + 0, + 0, + actor.itemCategories.mutation + .filter((i) => i.mutationType.value === 'physical') + .map((i) => { + return i.name; + }), + 3 + ); + + const mutationM = new Texts( + 0, + 0, + actor.itemCategories.mutation + .filter((i) => i.mutationType.value === 'mental') + .map((i) => { + return i.name; + }), + 3 + ); + + const psychology = new Texts( + 0, + 0, + actor.itemCategories.psychology.map((i) => { + return i.name; + }), + 3 + ); + const imageWidth = 25; const imageY = labelledRowHeight + MARGINS.top + 2; const actorImageElement = @@ -353,6 +507,77 @@ Hooks.on( new Separator(0, 0), new Text(0, 0, 'Armour'), armours, + new Separator(0, 0), + new Text( + 0, + 0, + `${i18nLocalize('SHEET.PettySpell')} : ${i18nLocalize( + 'Casting Number' + )}, ${i18nLocalize('Range')}, ${i18nLocalize( + 'Target' + )}, ${i18nLocalize('Duration')}` + ), + petty, + new Separator(0, 0), + new Text( + 0, + 0, + `${i18nLocalize('SHEET.LoreSpell')} : ${i18nLocalize( + 'Casting Number' + )}, ${i18nLocalize('Range')}, ${i18nLocalize( + 'Target' + )}, ${i18nLocalize('Duration')}, ${i18nLocalize( + 'WFRP4E.TrappingType.Ingredients' + )}` + ), + spell, + new Separator(0, 0), + new Text( + 0, + 0, + `${i18nLocalize('Blessing')} : ${i18nLocalize( + 'Range' + )}, ${i18nLocalize('Target')}, ${i18nLocalize('Duration')}` + ), + blessing, + new Separator(0, 0), + new Text( + 0, + 0, + `${i18nLocalize('Miracle')} : ${i18nLocalize( + 'Range' + )}, ${i18nLocalize('Target')}, ${i18nLocalize('Duration')}` + ), + miracle, + new Separator(0, 0), + trappingsHeader, + trappings, + new Separator(0, 0), + new Text(0, 0, 'Psychology'), + psychology, + new Separator(0, 0), + new Text(0, 0, 'Criticals'), + critical, + new Separator(0, 0), + new Text(0, 0, 'Diseases'), + disease, + new Separator(0, 0), + new Text(0, 0, 'Injuries'), + injury, + new Separator(0, 0), + new Text( + 0, + 0, + `${i18nLocalize('Mutations')} (${i18nLocalize('Physical')})` + ), + mutationP, + new Separator(0, 0), + new Text( + 0, + 0, + `${i18nLocalize('Mutations')} (${i18nLocalize('Mental')})` + ), + mutationM, ]), ]); docBuilder.doc.save(`${app.actor.name}.pdf`); diff --git a/src/util.ts b/src/util.ts index 6a811af..5dc54a8 100644 --- a/src/util.ts +++ b/src/util.ts @@ -4,4 +4,28 @@ export class Util { public static getHeightFromPx(doc: jsPDF, size: number) { return size / doc.internal.scaleFactor; } + + public static getAllActorItems( + actor: Actor & any, + keys: string[] + ): (Item & any)[] { + const result: (Item & any)[] = []; + for (const key of keys) { + result.push(...this.getActorItems(actor, key)); + } + return result; + } + + public static getActorItems(actor: Actor & any, key: string): (Item & any)[] { + if (actor.itemCategories[key] == null) { + return []; + } + return actor.itemCategories[key].filter((it) => { + const location = it.location.value; + if (location != null && location !== 0) { + return actor.getEmbeddedDocument('Item', location) != null; + } + return true; + }); + } }