Skip to content

Commit

Permalink
Merge pull request #2015 from arbron/advancement/item-choice-rework
Browse files Browse the repository at this point in the history
[#1401] Item Choice Advancement
  • Loading branch information
arbron authored Jan 25, 2023
2 parents 6f770d1 + b2992c1 commit 15fa75b
Show file tree
Hide file tree
Showing 23 changed files with 718 additions and 39 deletions.
39 changes: 31 additions & 8 deletions dnd5e.css
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,9 @@ h5 {
/* Two Column Configurations */
/* ----------------------------------------- */
/* ----------------------------------------- */
/* Item Choice */
/* ----------------------------------------- */
/* ----------------------------------------- */
/* Scale Value */
/* ----------------------------------------- */
}
Expand Down Expand Up @@ -1392,19 +1395,35 @@ h5 {
.dnd5e.advancement.two-column form .right-column {
grid-area: right;
}
.dnd5e.advancement.two-column form .right-column.level-list label {
flex: 0.5;
padding-right: 0.5rem;
text-align: end;
}
.dnd5e.advancement.two-column form .right-column.level-list :is(input[type="text"], input[type="number"])::placeholder {
opacity: 0.5;
}
.dnd5e.advancement.two-column form button[type="submit"] {
grid-column-end: span 2;
}
.dnd5e.advancement.scale-value {
--grid-two-column-right-size: 0.6fr;
.dnd5e.advancement.item-choice {
--grid-two-column-right-size: 0.5fr;
}
.dnd5e.advancement.scale-value .right-column label {
flex: 0.5;
padding-right: 0.5rem;
text-align: right;
.dnd5e.advancement.item-choice .level-list .hint {
text-align: end;
}
.dnd5e.advancement.scale-value :is(input[type="text"], input[type="number"])::placeholder {
opacity: 0.5;
.dnd5e.advancement.item-choice .form-group:has(textarea) {
align-items: flex-start;
}
.dnd5e.advancement.item-choice textarea {
margin-inline-start: 8px;
border: 1px solid var(--color-border-light-tertiary);
font-family: var(--font-primary);
font-size: var(--font-size-12);
height: 100px;
}
.dnd5e.advancement.scale-value {
--grid-two-column-right-size: 0.6fr;
}
.dnd5e.advancement.scale-value select.new-scale-value {
font-weight: bold;
Expand Down Expand Up @@ -1476,6 +1495,10 @@ h5 {
height: calc(var(--form-field-height) + 5px);
line-height: 1.5em;
}
.dnd5e.advancement.flow form[data-type="ItemChoice"] .item-name .item-delete {
flex: 0 0 20px;
margin-inline-end: 1px;
}
.dnd5e.advancement.flow input.error {
outline: 2px solid red;
}
Expand Down
1 change: 1 addition & 0 deletions icons/LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ SVG Icons from Game-Icons.net
The dnd5e system for Foundry Virtual Tabletop includes icon artwork licensed from Game-icons.net under the Creative Commons license. These icons are packaged with and provided for use in the dnd5e system under their respective licenses, as noted below.

/svg/hit-points.svg - "Heart plus" by Zeromancer under CC0 PDD
/svg/item-choice.svg - "Choice" by Delapouite under CC BY 3.0
/svg/item-grant.svg - "White book" by Willdabeast under CC BY 3.0
/svg/scale-value.svg - "Dice target" by Delapouite under CC BY 3.0
1 change: 1 addition & 0 deletions icons/svg/item-choice.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@
"DND5E.AdvancementConfigurationModeDisabled": "Configuration Disabled",
"DND5E.AdvancementConfigurationModeEnabled": "Configuration Enabled",
"DND5E.AdvancementConfigureTitle": "Configure {item} Advancement",
"DND5E.AdvancementConfigureAllowDrops": "Allow Drops",
"DND5E.AdvancementConfigureAllowDropsHint": "Should players be able to drop their own choices into this advancement?",
"DND5E.AdvancementConfigureDropAreaHint": "Drop Items here to add them to the pool from which a player can choose.",
"DND5E.AdvancementConfiguredComplete": "Fully Configured",
"DND5E.AdvancementConfiguredIncomplete": "Not Configured",
"DND5E.AdvancementControlCreate": "Create Advancement",
Expand All @@ -124,6 +127,8 @@
"DND5E.AdvancementDeleteConfirmationLabel": "Remove advancement changes",
"DND5E.AdvancementDeleteConfirmationMessage": "Deleting this item will also delete all advancement choices made for it. These changes will be removed from your character as long as the checkbox below is checked.",
"DND5E.AdvancementDeleteConfirmationTitle": "Confirm Deletion",
"DND5E.AdvancementFlowDropAreaHint": "Drop an Item here to choose it.",
"DND5E.AdvancementHint": "Hint",
"DND5E.AdvancementHitPointsTitle": "Hit Points",
"DND5E.AdvancementHitPointsHint": "Track the player's hit points for each level in the class.",
"DND5E.AdvancementHitPointsAverage": "Take Average",
Expand All @@ -132,6 +137,19 @@
"DND5E.AdvancementHitPointsMaxAtFirstLevel": "Max at 1st Level: <strong>{max}</strong>",
"DND5E.AdvancementHitPointsRollMessage": "Roll {class} Hit Points",
"DND5E.AdvancementHitPointsRollButton": "Roll {die}",
"DND5E.AdvancementItemChoiceTitle": "Choose Items",
"DND5E.AdvancementItemChoiceHint": "Present the player with a choice of items (such as equipment, features, or spells) that they can choose for their character at one or more levels.",
"DND5E.AdvancementItemChoiceChosen": "Chosen: {current} of {max}",
"DND5E.AdvancementItemChoiceLevelsHint": "Specify how many choices are allowed at each level.",
"DND5E.AdvancementItemChoicePreviouslyChosenWarning": "This item has already been chosen at a previous level.",
"DND5E.AdvancementItemChoiceSpellLevelAvailable": "Any Available Level",
"DND5E.AdvancementItemChoiceSpellLevelAvailableWarning": "Only {level} or lower spells can be chosen for this advancement.",
"DND5E.AdvancementItemChoiceSpellLevelSpecificWarning": "Only {level} spells can be chosen for this advancement.",
"DND5E.AdvancementItemChoiceSpellLevelHint": "Only allow choices from spells of this level.",
"DND5E.AdvancementItemChoiceType": "Item Type",
"DND5E.AdvancementItemChoiceTypeHint": "Restrict what Item types can be choosen.",
"DND5E.AdvancementItemChoiceTypeAny": "Anything",
"DND5E.AdvancementItemChoiceTypeWarning": "Only {type} items can be selected for this choice.",
"DND5E.AdvancementItemGrantTitle": "Grant Items",
"DND5E.AdvancementItemGrantHint": "Grant the character items (such as equipment, features, or spells) when they reach a certain level.",
"DND5E.AdvancementItemGrantDropHint": "Drop Items here to add them to the list granted by this advancement.",
Expand Down Expand Up @@ -980,6 +998,7 @@
"DND5E.SubclassDuplicateError": "A subclass with the identifier {identifier} already exists on this actor.",
"DND5E.SubclassMismatchWarn": "{name} subclass has no matching class with identifier '{class}'.",
"DND5E.SubclassName": "Subclass Name",
"DND5E.Subtype": "Subtype",
"DND5E.Supply": "Supply",
"DND5E.Target": "Target",
"DND5E.TargetAlly": "Ally",
Expand Down
50 changes: 41 additions & 9 deletions less/advancement.less
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@
}
.right-column {
grid-area: right;

&.level-list {
label {
flex: 0.5;
padding-right: 0.5rem;
text-align: end;
}
:is(input[type="text"], input[type="number"])::placeholder {
opacity: 0.5;
}
}
}
button[type="submit"] {
grid-column-end: span 2;
Expand All @@ -60,19 +71,33 @@
}

/* ----------------------------------------- */
/* Scale Value */
/* Item Choice */
/* ----------------------------------------- */
&.scale-value {
--grid-two-column-right-size: 0.6fr;
&.item-choice {
--grid-two-column-right-size: 0.5fr;

.right-column label {
flex: 0.5;
padding-right: 0.5rem;
text-align: right;
.level-list .hint {
text-align: end;
}
:is(input[type="text"], input[type="number"])::placeholder {
opacity: 0.5;

.form-group:has(textarea) {
align-items: flex-start;
}

textarea {
margin-inline-start: 8px;
border: 1px solid var(--color-border-light-tertiary);
font-family: var(--font-primary);
font-size: var(--font-size-12);
height: 100px;
}
}

/* ----------------------------------------- */
/* Scale Value */
/* ----------------------------------------- */
&.scale-value {
--grid-two-column-right-size: 0.6fr;

select {
&.new-scale-value {
Expand Down Expand Up @@ -160,6 +185,13 @@
}
}

form[data-type="ItemChoice"] {
.item-name .item-delete {
flex: 0 0 20px;
margin-inline-end: 1px;
}
}

input.error {
outline: 2px solid red;
}
Expand Down
2 changes: 2 additions & 0 deletions module/applications/advancement/_module.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export {default as AdvancementSelection} from "./advancement-selection.mjs";

export {default as HitPointsConfig} from "./hit-points-config.mjs";
export {default as HitPointsFlow} from "./hit-points-flow.mjs";
export {default as ItemChoiceConfig} from "./item-choice-config.mjs";
export {default as ItemChoiceFlow} from "./item-choice-flow.mjs";
export {default as ItemGrantConfig} from "./item-grant-config.mjs";
export {default as ItemGrantFlow} from "./item-grant-flow.mjs";
export {default as ScaleValueConfig} from "./scale-value-config.mjs";
Expand Down
4 changes: 2 additions & 2 deletions module/applications/advancement/advancement-config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export default class AdvancementConfig extends FormApplication {
* @param {object} configuration Configuration object.
* @returns {object} Modified configuration.
*/
prepareConfigurationUpdate(configuration) {
async prepareConfigurationUpdate(configuration) {
return configuration;
}

Expand Down Expand Up @@ -148,7 +148,7 @@ export default class AdvancementConfig extends FormApplication {
delete updates.data;
updates = { ...updates, ...data };
}
if ( updates.configuration ) updates.configuration = this.prepareConfigurationUpdate(updates.configuration);
if ( updates.configuration ) updates.configuration = await this.prepareConfigurationUpdate(updates.configuration);
await this.advancement.update(updates);
}

Expand Down
67 changes: 67 additions & 0 deletions module/applications/advancement/item-choice-config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import AdvancementConfig from "./advancement-config.mjs";

/**
* Configuration application for item choices.
*/
export default class ItemChoiceConfig extends AdvancementConfig {

/** @inheritdoc */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["dnd5e", "advancement", "item-choice", "two-column"],
dragDrop: [{ dropSelector: ".drop-target" }],
dropKeyPath: "pool",
template: "systems/dnd5e/templates/advancement/item-choice-config.hbs",
width: 540
});
}

/* -------------------------------------------- */

/** @inheritdoc */
getData(options={}) {
const context = {
...super.getData(options),
showSpellConfig: this.advancement.configuration.type === "spell",
validTypes: this.advancement.constructor.VALID_TYPES.reduce((obj, type) => {
obj[type] = game.i18n.localize(`ITEM.Type${type.capitalize()}`);
return obj;
}, {})
};
if ( this.advancement.configuration.type === "feat" ) {
const selectedType = CONFIG.DND5E.featureTypes[this.advancement.configuration.restriction.type];
context.typeRestriction = {
typeLabel: game.i18n.localize("DND5E.ItemFeatureType"),
typeOptions: CONFIG.DND5E.featureTypes,
subtypeLabel: game.i18n.format("DND5E.ItemFeatureSubtype", {category: selectedType?.label}),
subtypeOptions: selectedType?.subtypes
};
}
return context;
}

/* -------------------------------------------- */

/** @inheritdoc */
async prepareConfigurationUpdate(configuration) {
if ( configuration.choices ) configuration.choices = this.constructor._cleanedObject(configuration.choices);

// Ensure items are still valid if type restriction or spell restriction are changed
const pool = [];
for ( const uuid of (configuration.pool ?? this.advancement.configuration.pool) ) {
if ( this.advancement._validateItemType(await fromUuid(uuid), {
type: configuration.type, restriction: configuration.restriction ?? {}, strict: false
}) ) pool.push(uuid);
}
configuration.pool = pool;

return configuration;
}

/* -------------------------------------------- */

/** @inheritdoc */
_validateDroppedItem(event, item) {
this.advancement._validateItemType(item);
}
}
Loading

0 comments on commit 15fa75b

Please sign in to comment.