From 114a6327801e75fffc5a209ff44b62429c5fbb0c Mon Sep 17 00:00:00 2001 From: mclemente Date: Mon, 17 Jan 2022 14:37:22 -0300 Subject: [PATCH] Proficiencies for DND5e and PF2e Proficiencies --- module/SystemProvider.js | 101 ++++++++++++++++++++++- style/party-overview.css | 26 ++++-- templates/dnd5e.hbs | 17 ++++ templates/parts/DND5E-Proficiencies.html | 26 +++--- templates/parts/PF2e-Proficiencies.html | 25 ++++++ templates/pf2e.hbs | 38 +++++---- 6 files changed, 197 insertions(+), 36 deletions(-) create mode 100644 templates/parts/PF2e-Proficiencies.html diff --git a/module/SystemProvider.js b/module/SystemProvider.js index 8345ae1..1cd4ba4 100644 --- a/module/SystemProvider.js +++ b/module/SystemProvider.js @@ -171,6 +171,17 @@ export class dnd35eProvider extends SystemProvider { } export class dnd5eProvider extends SystemProvider { + constructor(id) { + super(id); + Handlebars.registerHelper("partyOverviewGetSkillList", function (skill, actors, opt) { + return actors.map((actor) => { + return { + ...actor.skills[skill], + }; + }); + }); + } + get loadTemplates() { return ["modules/party-overview/templates/parts/DND5E-Proficiencies.html"]; } @@ -182,6 +193,7 @@ export class dnd5eProvider extends SystemProvider { background: { id: "background", visible: true, localization: "DND5E.Background" }, saves: { id: "saves", visible: true, localization: "DND5E.ClassSaves" }, proficiencies: { id: "proficiencies", visible: true, localization: "party-overview.PROFICIENCIES" }, + tools: { id: "tools", visible: true, localization: "DND5E.ItemTypeToolPl" }, }; } @@ -219,7 +231,11 @@ export class dnd5eProvider extends SystemProvider { }; const skills = {}; for (let skill in data.skills) { - skills[skill] = icons[data.skills[skill].proficient]; + skills[skill] = { + icon: icons[data.skills[skill].proficient], + proficient: CONFIG.DND5E.proficiencyLevels[data.skills[skill].proficient], + value: data.skills[skill].total, + }; } return skills; } @@ -237,6 +253,44 @@ export class dnd5eProvider extends SystemProvider { return str; } + getTools(data) { + function getBaseItem(identifier) { + let pack = CONFIG.DND5E.sourcePacks.ITEMS; + let [scope, collection, id] = identifier.split("."); + if (scope && collection) pack = `${scope}.${collection}`; + if (!id) id = identifier; + + const packObject = game.packs.get(pack); + + return packObject?.index.get(id); + } + const profs = CONFIG.DND5E.toolProficiencies; + const type = "tool"; + const itemTypes = CONFIG.DND5E[`${type}Ids`]; + + let values = []; + if (data.value) { + values = data.value instanceof Array ? data.value : [data.value]; + } + + data.selected = {}; + for (const key of values) { + if (profs[key]) { + data.selected[key] = profs[key]; + } else if (itemTypes && itemTypes[key]) { + const item = getBaseItem(itemTypes[key]); + if (item) data.selected[key] = item.name; + } else if (type === "tool" && CONFIG.DND5E.vehicleTypes[key]) { + data.selected[key] = CONFIG.DND5E.vehicleTypes[key]; + } + } + + // Add custom entries + if (data.custom) { + data.custom.split(";").forEach((c, i) => (data.selected[`custom${i + 1}`] = c.trim())); + } + return data.selected; + } getTotalGP(data) { const currency = foundry.utils.deepClone(data.currency); @@ -291,7 +345,9 @@ export class dnd5eProvider extends SystemProvider { skills: this.getSkills(data), inspiration: data.attributes.inspiration, languages: data.traits.languages ? data.traits.languages.value.map((code) => CONFIG.DND5E.languages[code]) : [], + tools: this.getTools(data.traits.toolProf) || {}, alignment: data.details.alignment, + currency: data.currency, totalGP: this.getTotalGP(data).toFixed(2), }; @@ -447,9 +503,22 @@ export class pf1Provider extends SystemProvider { } export class pf2eProvider extends SystemProvider { + constructor(id) { + super(id); + Handlebars.registerHelper("partyOverviewGetSkillList", function (skill, actors, opt) { + return actors.map((actor) => { + return { + rankLetter: actor.skills[skill].rankName[0], + ...actor.skills[skill], + }; + }); + }); + } + get loadTemplates() { return [ "modules/party-overview/templates/parts/PF2e-Lore.html", + "modules/party-overview/templates/parts/PF2e-Proficiencies.html", // "modules/party-overview/templates/parts/PF2e-Bulk.html" ]; } @@ -460,6 +529,7 @@ export class pf2eProvider extends SystemProvider { // bulk: { id: "bulk", visible: true, localization: "PF2E.BulkShortLabel" }, languages: { id: "languages", visible: true, localization: "PF2E.Languages" }, lore: { id: "lore", visible: true, localization: "PF2E.Lore" }, + proficiencies: { id: "skills", visible: true, localization: "PF2E.SkillsLabel" }, }; } @@ -501,6 +571,33 @@ export class pf2eProvider extends SystemProvider { return lore; } + getSkills(data) { + const proficiency = { + 0: game.i18n.localize("PF2E.ProficiencyLevel0"), + 1: game.i18n.localize("PF2E.ProficiencyLevel1"), + 2: game.i18n.localize("PF2E.ProficiencyLevel2"), + 3: game.i18n.localize("PF2E.ProficiencyLevel3"), + 4: game.i18n.localize("PF2E.ProficiencyLevel4"), + }; + const proficiencyColors = { + 0: "initial", + 1: "#171f69", + 2: "#3c005e", + 3: "#640", + 4: "#5e0000", + }; + const skills = {}; + for (let skill in data.skills) { + skills[skill] = { + color: proficiencyColors[data.skills[skill].rank], + rank: data.skills[skill].rank, + rankName: proficiency[data.skills[skill].rank], + value: data.skills[skill].value, + }; + } + return skills; + } + getTotalGP(currency) { return currency.cp / 100 + currency.sp / 10 + currency.gp + currency.pp * 10; } @@ -521,6 +618,7 @@ export class pf2eProvider extends SystemProvider { shieldAC: data.attributes.shield?.ac || 0, perception: data.attributes.perception?.value || 0, // speed: actor.type === "vehicle" ? data.details.speed : data.attributes.speed?.value || 0, + skills: this.getSkills(data), saves: { fortitude: data.saves?.fortitude?.value || 0, @@ -578,6 +676,7 @@ export class pf2eProvider extends SystemProvider { totalPartyGP: totalPartyGP, sumItemsGP: (Number(itemsValue) + Number(totalPartyGP)).toFixed(2), lore: lores, + skills: CONFIG.PF2E.skills, }, ]; } diff --git a/style/party-overview.css b/style/party-overview.css index 59b3c6f..d4a583b 100644 --- a/style/party-overview.css +++ b/style/party-overview.css @@ -92,6 +92,10 @@ div.party-overview-window .table-row .button { flex-shrink: 1; } +div.party-overview-window .table-row.header .button:not(:first-child) { + flex-basis: 27px; +} + button.btn-filter, button.btn-toggle-visibility { line-height: initial; @@ -145,20 +149,30 @@ button.party-overview-button:not(.wfrp4e) { flex-basis: 100%; } -.party-overview-window.dnd5e .proficiencies.tab .header .num { +.party-overview-window.dnd5e .proficiencies.tab .header .num, +.party-overview-window.pf2e .proficiencies.tab .header .num { flex: 1; } -.party-overview-ellipsis { - overflow: hidden; - white-space: nowrap; +.party-overview-no-ellipsis, +div.party-overview-window .table-row .text.party-overview-no-ellipsis, +div.party-overview-window .table-row .text.icon.party-overview-no-ellipsis, +div.party-overview-window .table-row .num.party-overview-no-ellipsis { + overflow: visible; + white-space: normal; text-overflow: clip; } -.party-overview-ellipsis { +.party-overview-ellipsis, +div.party-overview-window .table-row .text.party-overview-ellipsis, +div.party-overview-window .table-row .text.icon.party-overview-ellipsis, +div.party-overview-window .table-row .num.party-overview-ellipsis { + overflow: hidden; + white-space: nowrap; + text-overflow: clip; border-right: 1px solid black; } .party-overview-ellipsis:last-child { border-right: none; -} \ No newline at end of file +} diff --git a/templates/dnd5e.hbs b/templates/dnd5e.hbs index 97b411f..63cada8 100755 --- a/templates/dnd5e.hbs +++ b/templates/dnd5e.hbs @@ -139,5 +139,22 @@ {{/each}} + + +
+
+ {{> "modules/party-overview/templates/parts/FilterButton.html"}} +
{{localize "party-overview.NAME"}}
+
{{localize "DND5E.TraitToolProf"}}
+
+ + {{#each actors as | actor | }} +
+ {{> "modules/party-overview/templates/parts/ToggleVisibilityButton.html" actor=actor}} +
{{ actor.shortestName }}
+
{{#each actor.tools as | tool | }}{{tool}}{{#unless @last}}, {{/unless}}{{/each}}
+
+ {{/each}} +
diff --git a/templates/parts/DND5E-Proficiencies.html b/templates/parts/DND5E-Proficiencies.html index 610a4f7..45d9577 100644 --- a/templates/parts/DND5E-Proficiencies.html +++ b/templates/parts/DND5E-Proficiencies.html @@ -1,21 +1,25 @@ +
{{> "modules/party-overview/templates/parts/FilterButton.html"}}
{{localize "party-overview.NAME"}}
- {{#each skills as | s | }} -
{{s}}
+ {{#each actors as | actor | }} + {{> "modules/party-overview/templates/parts/ToggleVisibilityButton.html" actor=actor}} +
+ {{ actor.shortestName }} +
{{/each}}
- {{#each actors as | actor | }} -
- {{> "modules/party-overview/templates/parts/ToggleVisibilityButton.html"}} -
{{ actor.shortestName }}
- {{#each actor.skills as | skill| }} -
- + {{#each skills as | value key | }} +
+
+
{{localize value}}
+ {{#each (partyOverviewGetSkillList key ../actors)}} +
+ {{numberFormat this.value decimals=0 sign=true}} +
+ {{/each}}
- {{/each}} -
{{/each}}
diff --git a/templates/parts/PF2e-Proficiencies.html b/templates/parts/PF2e-Proficiencies.html new file mode 100644 index 0000000..7630b21 --- /dev/null +++ b/templates/parts/PF2e-Proficiencies.html @@ -0,0 +1,25 @@ + +
+
+ {{> "modules/party-overview/templates/parts/FilterButton.html"}} +
{{localize "party-overview.NAME"}}
+ {{#each actors as | actor | }} + {{> "modules/party-overview/templates/parts/ToggleVisibilityButton.html" actor=actor}} +
+ {{ actor.shortestName }} +
+ {{/each}} +
+ + {{#each skills as | value key | }} +
+
+
{{localize value}}
+ {{#each (partyOverviewGetSkillList key ../actors)}} +
+ {{numberFormat this.value decimals=0 sign=true}} +
+ {{/each}} +
+ {{/each}} +
diff --git a/templates/pf2e.hbs b/templates/pf2e.hbs index 9282e39..85b5967 100644 --- a/templates/pf2e.hbs +++ b/templates/pf2e.hbs @@ -5,30 +5,30 @@
{{> "modules/party-overview/templates/parts/FilterButton.html"}}
{{localize "party-overview.NAME"}}
-
Hero
-
-
-
-
- {{!--
--}} -
-
-
+
Hero
+
+
+
+
+ {{!--
--}} +
+
+
{{#each actors as | actor | }}
{{> "modules/party-overview/templates/parts/ToggleVisibilityButton.html" actor=actor}}
{{ actor.shortestName }}
-
{{ actor.heroPoints.value }}/{{ actor.heroPoints.max }}
-
{{ actor.hp.value }}/{{ actor.hp.max }}
-
{{ actor.armor }} {{#if actor.shieldAC}}({{numberFormat actor.shieldAC decimals=0 sign=true}}){{/if}}
-
{{ actor.focus.value }}/{{ actor.focus.max }}
-
{{ actor.perception }}
- {{!--
{{ actor.speed }}
--}} -
{{ actor.saves.fortitude }}
-
{{ actor.saves.reflex }}
-
{{ actor.saves.will }}
+
{{ actor.heroPoints.value }}/{{ actor.heroPoints.max }}
+
{{ actor.hp.value }}/{{ actor.hp.max }}
+
{{ actor.armor }} {{#if actor.shieldAC}}({{numberFormat actor.shieldAC decimals=0 sign=true}}){{/if}}
+
{{ actor.focus.value }}/{{ actor.focus.max }}
+
{{ actor.perception }}
+ {{!--
{{ actor.speed }}
--}} +
{{ actor.saves.fortitude }}
+
{{ actor.saves.reflex }}
+
{{ actor.saves.will }}
{{/each}}
@@ -82,5 +82,7 @@ {{!-- {{> "modules/party-overview/templates/parts/PF2e-Bulk.html"}} --}} + + {{> "modules/party-overview/templates/parts/PF2e-Proficiencies.html"}} \ No newline at end of file