From 8a4346ec970c2c7cf57be75a393a507132df7ab6 Mon Sep 17 00:00:00 2001 From: Paul Maskelyne Date: Tue, 12 Nov 2024 18:58:12 +0000 Subject: [PATCH 1/2] closes #881 --- RELEASE_NOTES.md | 1 + i18n/en.yaml | 4 + system/src/apps/LevelUpSD.mjs | 65 ++++++++++- system/src/documents/ActorSD.mjs | 9 +- system/src/sheets/PlayerSheetSD.mjs | 2 +- system/src/templates.mjs | 5 +- system/templates/apps/level-up.hbs | 124 ++++----------------- system/templates/apps/level-up/hp.hbs | 32 ++++++ system/templates/apps/level-up/spells.hbs | 53 +++++++++ system/templates/apps/level-up/talents.hbs | 72 ++++++++++++ 10 files changed, 256 insertions(+), 111 deletions(-) create mode 100644 system/templates/apps/level-up/hp.hbs create mode 100644 system/templates/apps/level-up/spells.hbs create mode 100644 system/templates/apps/level-up/talents.hbs diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 07205448..7940748c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,7 @@ * [#847] Add support for Warlock class Boon which gives the ability to learn a Wizard spell * [#879] Add new Patron item class * [#880] Create a new Patron Boon type for Talents +* [#881] Support rolling on a character's Patron's Boon table if necessary in the Level Up app * [#901] Added Russian as a partially complete system language. * [#908] Add rollable dice to Cure Wounds spell that includes the necessary calculations *(Many thanks to **nschoenwald** for contributing to this issue)* * [#920] Show tooltips on weapon and armor properties when showing expanded inline view in inventory diff --git a/i18n/en.yaml b/i18n/en.yaml index 2c1cc746..60021263 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -89,12 +89,15 @@ SHADOWDARK.apps.item-importer.instruction2d: Features SHADOWDARK.apps.item-importer.instruction3: 3. Click Import Item. SHADOWDARK.apps.item-importer.title: Import Item SHADOWDARK.apps.level-up.dragdrop: Drag and Drop Here +SHADOWDARK.apps.level-up.errors.missing_boon_table: Unable to roll Patron Boon as the configured RollTable could not be loaded SHADOWDARK.apps.level-up.hit_points: Hit Points SHADOWDARK.apps.level-up.level_up: Level Up! SHADOWDARK.apps.level-up.leveling_to: Leveling up to level SHADOWDARK.apps.level-up.missing_selections: Missing Selections SHADOWDARK.apps.level-up.notalent: No talents gained at this level +SHADOWDARK.apps.level-up.or_boons: or Boons SHADOWDARK.apps.level-up.prompt: Not all required selections have been made. Continue with level up anyways? +SHADOWDARK.apps.level-up.roll_boon: Roll Boon SHADOWDARK.apps.level-up.roll_talent: Roll Talent SHADOWDARK.apps.level-up.title: Leveling Up SHADOWDARK.apps.monster-importer.import_button: Import Monster @@ -267,6 +270,7 @@ SHADOWDARK.dialog.general.no: "No" SHADOWDARK.dialog.general.select: Select SHADOWDARK.dialog.general.yes: "Yes" SHADOWDARK.dialog.gm: Gamemaster +SHADOWDARK.dialog.hp_re_roll.title: HP Re-roll SHADOWDARK.dialog.hp_roll.per_level: Roll HP for level {level} SHADOWDARK.dialog.hp_roll.previous_hp: "HP before rolling: {hp}" SHADOWDARK.dialog.hp_roll.roll_level_1: Rolled {hp} hp for level 1 (incl. con mod) diff --git a/system/src/apps/LevelUpSD.mjs b/system/src/apps/LevelUpSD.mjs index efd89c58..c5f32a87 100644 --- a/system/src/apps/LevelUpSD.mjs +++ b/system/src/apps/LevelUpSD.mjs @@ -57,9 +57,14 @@ export default class LevelUpSD extends FormApplication { event => this._onReRollHP(event) ); + html.find("[data-action='view-boon-table']").click( + event => this._viewBoonTable(event) + ); + html.find("[data-action='view-talent-table']").click( event => this._viewTalentTable(event) ); + html.find("[data-action='open-spellbook']").click( event => this._openSpellBook(event) ); @@ -72,6 +77,10 @@ export default class LevelUpSD extends FormApplication { event => this._onDeleteSpell(event) ); + html.find("[data-action='roll-boon']").click( + event => this._onRollBoon(event) + ); + html.find("[data-action='roll-talent']").click( event => this._onRollTalent(event) ); @@ -93,10 +102,27 @@ export default class LevelUpSD extends FormApplication { this.data.class = await fromUuid(this.data.actor.system.class); this.data.talentTable = await fromUuid(this.data.class.system.classTalentTable); this.data.currentLevel = this.data.actor.system.level.value; - this.data.targetLevel = this.data.currentLevel +1; + this.data.targetLevel = this.data.currentLevel + 1; this.data.talentGained = (this.data.targetLevel % 2 !== 0); this.data.totalSpellsToChoose = 0; + this.data.patron = await fromUuid(this.data.actor.system.patron); + + this.data.boonTable = this.data.patron + ? await fromUuid(this.data.patron.system.boonTable) + : undefined; + + this.data.startingBoons = 0; + const classData = this.data.class.system; + this.data.canRollBoons = classData.patron.required; + + const needsStartingBoons = classData.patron.required + && classData.patron.startingBoons > 0; + + if (this.data.targetLevel === 1 && needsStartingBoons) { + this.data.startingBoons = classData.patron.startingBoons; + } + if (await this.data.actor.isSpellCaster()) { this.data.spellcastingClass = this.data.class.system.spellcasting.class === "" @@ -129,6 +155,7 @@ export default class LevelUpSD extends FormApplication { } } + return this.data; } @@ -152,6 +179,10 @@ export default class LevelUpSD extends FormApplication { } } + async _viewBoonTable() { + this.data.boonTable.sheet.render(true); + } + async _viewTalentTable() { this.data.talentTable.sheet.render(true); } @@ -160,13 +191,17 @@ export default class LevelUpSD extends FormApplication { this.data.actor.openSpellBook(); } - async _onRollHP() { + async _onRollHP({isReroll = false}) { const data = { rollType: "hp", actor: this.data.actor, }; let options = {}; - options.title = game.i18n.localize("SHADOWDARK.dialog.hp_roll.title"); + + options.title = isReroll + ? game.i18n.localize("SHADOWDARK.dialog.hp_re_roll.title") + : game.i18n.localize("SHADOWDARK.dialog.hp_roll.title"); + options.flavor = options.title; options.chatCardTemplate = "systems/shadowdark/templates/chat/roll-hp.hbs"; options.fastForward = true; @@ -186,12 +221,30 @@ export default class LevelUpSD extends FormApplication { Dialog.confirm({ title: "Re-Roll HP", content: "Are you sure you want to re-roll hit points?", - yes: () => this._onRollHP(), + yes: () => this._onRollHP({isReroll: true}), no: () => null, defaultYes: false, }); } + async _onRollBoon() { + if (!this.data.boonTable) { + return ui.notifications.warn( + game.i18n.localize("SHADOWDARK.apps.level-up.errors.missing_boon_table") + ); + } + + await this.data.boonTable.draw(); + ui.sidebar.activateTab("chat"); + + if (this.data.targetLevel > 1) { + this.data.rolls.talent = true; + } + this.data.rolls.boon = true; + + this.render(); + } + async _onRollTalent() { await this.data.talentTable.draw(); ui.sidebar.activateTab("chat"); @@ -208,7 +261,11 @@ export default class LevelUpSD extends FormApplication { } } + if (this.data.targetLevel > 1) { + this.data.rolls.boon = true; + } this.data.rolls.talent = true; + this.render(); } diff --git a/system/src/documents/ActorSD.mjs b/system/src/documents/ActorSD.mjs index 2d1f0a75..1677002c 100644 --- a/system/src/documents/ActorSD.mjs +++ b/system/src/documents/ActorSD.mjs @@ -881,7 +881,14 @@ export default class ActorSD extends Actor { const spellcasterClasses = await shadowdark.compendiums.spellcastingBaseClasses(); - for (const bonusClass of this.system.bonuses.spellcastingClasses ?? []) { + // De-duplicate any bonus classes the Actor has + const bonusClasses = [ + ...new Set( + this.system.bonuses.spellcastingClasses ?? [] + ), + ]; + + for (const bonusClass of bonusClasses) { playerSpellClasses.push( spellcasterClasses.find(c => c.name.slugify() === bonusClass) ); diff --git a/system/src/sheets/PlayerSheetSD.mjs b/system/src/sheets/PlayerSheetSD.mjs index 56015a20..235b6efe 100644 --- a/system/src/sheets/PlayerSheetSD.mjs +++ b/system/src/sheets/PlayerSheetSD.mjs @@ -211,7 +211,7 @@ export default class PlayerSheetSD extends ActorSheetSD { ); context.characterClass = await this.actor.getClass(); - context.classHasPatron = context.characterClass.system.patron.required; + context.classHasPatron = context.characterClass?.system?.patron?.required ?? false; context.classTitle = await this.actor.getTitle(); context.characterPatron = await this.actor.getPatron(); diff --git a/system/src/templates.mjs b/system/src/templates.mjs index 31ca8380..8805b736 100644 --- a/system/src/templates.mjs +++ b/system/src/templates.mjs @@ -66,8 +66,8 @@ export default function() { "systems/shadowdark/templates/apps/character-generator/details/languages/language-choice.hbs", "systems/shadowdark/templates/apps/character-generator/details/languages/view.hbs", "systems/shadowdark/templates/apps/character-generator/details/patron.hbs", - "systems/shadowdark/templates/apps/character-generator/details/patron/view.hbs", "systems/shadowdark/templates/apps/character-generator/details/patron/edit.hbs", + "systems/shadowdark/templates/apps/character-generator/details/patron/view.hbs", "systems/shadowdark/templates/apps/character-generator/details/weapons.hbs", "systems/shadowdark/templates/apps/character-generator/gear.hbs", "systems/shadowdark/templates/apps/character-generator/gold.hbs", @@ -75,6 +75,9 @@ export default function() { "systems/shadowdark/templates/apps/character-generator/name.hbs", "systems/shadowdark/templates/apps/character-generator/stats.hbs", "systems/shadowdark/templates/apps/character-generator/type.hbs", + "systems/shadowdark/templates/apps/level-up/hp.hbs", + "systems/shadowdark/templates/apps/level-up/spells.hbs", + "systems/shadowdark/templates/apps/level-up/talents.hbs", "systems/shadowdark/templates/items/_partials/choice-selector.hbs", "systems/shadowdark/templates/items/_partials/cost.hbs", "systems/shadowdark/templates/items/_partials/description-tab.hbs", diff --git a/system/templates/apps/level-up.hbs b/system/templates/apps/level-up.hbs index f463d7cc..7be86c23 100644 --- a/system/templates/apps/level-up.hbs +++ b/system/templates/apps/level-up.hbs @@ -1,109 +1,25 @@
-
-
-

{{actor.name}}

-

{{localize "SHADOWDARK.apps.level-up.leveling_to"}} {{targetLevel}}

-
- - {{!-- Hit Points --}} -
-
- - {{class.system.hitPoints}} - {{#if rolls.hp}} - - {{/if}} - -
-
- {{#if rolls.hp}} - {{rolls.hp}} - {{#ifEq targetLevel 1}} - ({{numberFormat actor.system.abilities.con.mod decimals=0 sign=true}}) - {{/ifEq}} - {{/if}} - {{#unless rolls.hp}} - - {{/unless}} +
+
+

+ {{actor.name}} +

+

+ {{localize "SHADOWDARK.apps.level-up.leveling_to"}} + {{targetLevel}} +

-
- {{!-- Talents --}} -
-
- - -
-
- {{#unless talentGained}} - {{localize "SHADOWDARK.apps.level-up.notalent"}} - {{/unless}} - {{#if talentGained}} - {{#unless rolls.talent}} - - {{/unless}} - {{#if rolls.talent}} -
- {{#unless talents}}
{{localize "SHADOWDARK.apps.level-up.dragdrop"}}
{{/unless}} - {{#each talents}} - - {{/each}} -
- {{/if}} - {{/if}} -
-
+ {{> apps/level-up/hp}} + {{> apps/level-up/talents}} + {{> apps/level-up/spells}} - {{!-- Spells --}} - {{#ifCond totalSpellsToChoose ">" 0}} -
-
- - -
-
- {{#each spells}} - {{#if this.max}} -
-

{{this.name}}

-
- {{#each (addEmptySlots this.objects this.max)}} -
- {{#if this}} - - {{/if}} - {{#unless this}} -
{{localize "SHADOWDARK.apps.level-up.dragdrop"}}
- {{/unless}} -
- {{/each}} -
-
- {{/if}} - {{/each}} -
-
- {{/ifCond}} - -
+ +
diff --git a/system/templates/apps/level-up/hp.hbs b/system/templates/apps/level-up/hp.hbs new file mode 100644 index 00000000..f47209f0 --- /dev/null +++ b/system/templates/apps/level-up/hp.hbs @@ -0,0 +1,32 @@ +
+
+ + + {{class.system.hitPoints}} + {{#if rolls.hp}} + + {{/if}} + +
+ +
+ {{#if rolls.hp}} + {{rolls.hp}} + {{#ifEq targetLevel 1}} + + ({{numberFormat actor.system.abilities.con.mod + decimals=0 + sign=true + }}) + + {{/ifEq}} + {{/if}} + {{#unless rolls.hp}} + + {{/unless}} +
+
diff --git a/system/templates/apps/level-up/spells.hbs b/system/templates/apps/level-up/spells.hbs new file mode 100644 index 00000000..965813e2 --- /dev/null +++ b/system/templates/apps/level-up/spells.hbs @@ -0,0 +1,53 @@ +{{#ifCond totalSpellsToChoose ">" 0}} +
+
+ + + + +
+ +
+ {{#each spells}} + {{#if this.max}} +
+

+ {{this.name}} +

+
+ {{#each (addEmptySlots this.objects this.max)}} +
+ {{#if this}} + + {{/if}} + {{#unless this}} +
+ {{localize "SHADOWDARK.apps.level-up.dragdrop"}} +
+ {{/unless}} +
+ {{/each}} +
+
+ {{/if}} + {{/each}} +
+
+{{/ifCond}} diff --git a/system/templates/apps/level-up/talents.hbs b/system/templates/apps/level-up/talents.hbs new file mode 100644 index 00000000..ba821ac8 --- /dev/null +++ b/system/templates/apps/level-up/talents.hbs @@ -0,0 +1,72 @@ +{{!-- Talents --}} +
+
+ + + + {{#if canRollBoons}} + + {{/if}} + +
+ +
+ {{#unless talentGained}} + {{localize "SHADOWDARK.apps.level-up.notalent"}} + {{/unless}} + + {{#if talentGained}} + {{#unless rolls.talent}} + + {{/unless}} + {{#if canRollBoons}} + {{#unless rolls.boon}} + + {{/unless}} + {{/if}} + +
+ {{#unless talents}} +
+ {{localize "SHADOWDARK.apps.level-up.dragdrop"}} +
+ {{/unless}} + + {{#each talents}} + + {{/each}} +
+ {{/if}} +
+
From 3f9884e413ebfae25e10867a162cb005d9801f6b Mon Sep 17 00:00:00 2001 From: Paul Maskelyne Date: Sat, 16 Nov 2024 21:14:10 +0000 Subject: [PATCH 2/2] closes #881 --- .../talents.db/patron__4pcEgD8oLA5euovK.json | 1 - .../talents.db/patron__P4y8Bovr14XbN0PO.json | 33 ---------- scss/apps/_level-up.scss | 7 --- system/src/apps/LevelUpSD.mjs | 6 ++ system/templates/actors/player/details.hbs | 2 +- system/templates/apps/level-up.hbs | 2 +- system/templates/apps/level-up/talents.hbs | 61 ++++++++++--------- 7 files changed, 39 insertions(+), 73 deletions(-) delete mode 100644 data/packs/talents.db/patron__P4y8Bovr14XbN0PO.json diff --git a/data/packs/talents.db/patron__4pcEgD8oLA5euovK.json b/data/packs/talents.db/patron__4pcEgD8oLA5euovK.json index 0af7850b..8be7f50c 100644 --- a/data/packs/talents.db/patron__4pcEgD8oLA5euovK.json +++ b/data/packs/talents.db/patron__4pcEgD8oLA5euovK.json @@ -2,7 +2,6 @@ "_id": "4pcEgD8oLA5euovK", "_key": "!items!4pcEgD8oLA5euovK", "effects": [ - "P4y8Bovr14XbN0PO" ], "folder": "8t1Gmpgn1Q6HXJAz", "img": "icons/magic/unholy/silhouette-light-fire-blue.webp", diff --git a/data/packs/talents.db/patron__P4y8Bovr14XbN0PO.json b/data/packs/talents.db/patron__P4y8Bovr14XbN0PO.json deleted file mode 100644 index c80347c4..00000000 --- a/data/packs/talents.db/patron__P4y8Bovr14XbN0PO.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "_id": "P4y8Bovr14XbN0PO", - "_key": "!items.effects!4pcEgD8oLA5euovK.P4y8Bovr14XbN0PO", - "changes": [ - { - "key": "", - "mode": 2, - "priority": null, - "value": "REPLACEME" - } - ], - "description": "", - "disabled": false, - "duration": { - "combat": null, - "rounds": null, - "seconds": null, - "startRound": null, - "startTime": null, - "startTurn": null, - "turns": null - }, - "img": "icons/magic/unholy/silhouette-light-fire-blue.webp", - "name": "Patron", - "origin": "Compendium.shadowdark.talents.Item.4pcEgD8oLA5euovK", - "statuses": [ - ], - "system": { - }, - "tint": "#ffffff", - "transfer": true, - "type": "base" -} diff --git a/scss/apps/_level-up.scss b/scss/apps/_level-up.scss index 5dd77422..0d2a090d 100644 --- a/scss/apps/_level-up.scss +++ b/scss/apps/_level-up.scss @@ -20,13 +20,6 @@ line-height: 1.7; } - .level-up-grid { - display: grid; - gap: 8px; - grid-template-columns: 1fr; - grid-template-rows: auto 75px 105px auto; - } - .hit-points { text-align: center; font-size: 24px; diff --git a/system/src/apps/LevelUpSD.mjs b/system/src/apps/LevelUpSD.mjs index 86c0a36d..8fd06a21 100644 --- a/system/src/apps/LevelUpSD.mjs +++ b/system/src/apps/LevelUpSD.mjs @@ -8,10 +8,13 @@ export default class LevelUpSD extends FormApplication { hp: 0, hpEdit: false, talent: false, + boon: false, }; this.data.actor = game.actors.get(uid); this.data.talents = []; this.data.spells = {}; + this.data.talentsRolled = false; + this.data.talentsChosen = false; for (let i = 1; i <= 5; i++) { this.data.spells[i] = { @@ -26,6 +29,7 @@ export default class LevelUpSD extends FormApplication { static get defaultOptions() { return foundry.utils.mergeObject(super.defaultOptions, { classes: ["shadowdark", "level-up"], + height: "auto", width: 300, resizable: false, closeOnSubmit: true, @@ -155,6 +159,8 @@ export default class LevelUpSD extends FormApplication { } } + this.data.talentsRolled = this.data.rolls.talent || this.data.rolls.boon; + this.data.talentsChosen = this.data.talents.length > 0; return this.data; } diff --git a/system/templates/actors/player/details.hbs b/system/templates/actors/player/details.hbs index 46eead71..eff1eb9d 100644 --- a/system/templates/actors/player/details.hbs +++ b/system/templates/actors/player/details.hbs @@ -19,7 +19,7 @@ {{> actors/player/details/patron }}
{{else}} -
+
{{> actors/player/details/alignment }} {{> actors/player/details/deity }}
diff --git a/system/templates/apps/level-up.hbs b/system/templates/apps/level-up.hbs index 7be86c23..8d42cfa9 100644 --- a/system/templates/apps/level-up.hbs +++ b/system/templates/apps/level-up.hbs @@ -1,5 +1,5 @@
-
+

{{actor.name}} diff --git a/system/templates/apps/level-up/talents.hbs b/system/templates/apps/level-up/talents.hbs index ba821ac8..632b107c 100644 --- a/system/templates/apps/level-up/talents.hbs +++ b/system/templates/apps/level-up/talents.hbs @@ -23,11 +23,7 @@

-
- {{#unless talentGained}} - {{localize "SHADOWDARK.apps.level-up.notalent"}} - {{/unless}} - +
{{#if talentGained}} {{#unless rolls.talent}}