Skip to content

Commit

Permalink
[foundryvtt#1401] Add ability to restrict item choice by type
Browse files Browse the repository at this point in the history
  • Loading branch information
arbron committed Aug 22, 2022
1 parent bcf6432 commit 0b826fd
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 0 deletions.
3 changes: 3 additions & 0 deletions dnd5e.css
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,9 @@
.dnd5e.advancement.item-choice .level-list .hint {
text-align: end;
}
.dnd5e.advancement.item-choice textarea {
margin-inline-start: 9px;
}
.dnd5e.advancement.scale-value {
--grid-two-column-right-size: 0.6fr;
}
Expand Down
4 changes: 4 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@
"DND5E.AdvancementItemChoiceConfigDropHint": "Drop Items here to add them to the pool from which a player can choose.",
"DND5E.AdvancementItemChoiceFlowDropHint": "Drop an Item here to choose it.",
"DND5E.AdvancementItemChoiceLevelsHint": "Specify how many choices are allowed at each 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
4 changes: 4 additions & 0 deletions less/advancement.less
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@
.level-list .hint {
text-align: end;
}

textarea {
margin-inline-start: 9px;
}
}

/* ----------------------------------------- */
Expand Down
15 changes: 15 additions & 0 deletions module/advancement/advancement-config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ export default class AdvancementConfig extends FormApplication {
if ( data.type !== "Item" ) return false;
const item = await Item.implementation.fromDropData(data);

const verified = this._verifyDroppedItem(event, item);
if ( !verified ) return false;

const existingItems = foundry.utils.getProperty(this.advancement.data.configuration, this.options.dropKeyPath);

// Abort if this uuid is the parent item
Expand All @@ -178,4 +181,16 @@ export default class AdvancementConfig extends FormApplication {
this.render();
}

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

/**
* Called when an item is dropped to verify the Item before it is saved.
* @param {Event} event Triggering drop event.
* @param {Item5e} item The materialized Item that was dropped.
* @returns {boolean} Is the dropped Item valid?
*/
_verifyDroppedItem(event, item) {
return true;
}

}
40 changes: 40 additions & 0 deletions module/advancement/types/item-choice.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class ItemChoiceAdvancement extends Advancement {
hint: "",
choices: {},
allowDrops: true,
type: null,
pool: []
}
},
Expand All @@ -33,6 +34,15 @@ export class ItemChoiceAdvancement extends Advancement {
});
}

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

/**
* The item types that are supported in Item Choice. This order will be how they are displayed
* in the configuration interface.
* @enum {object}
*/
static VALID_TYPES = ["feat", "spell", "consumable", "backpack", "equipment", "loot", "tool", "weapon"];

/* -------------------------------------------- */
/* Instance Properties */
/* -------------------------------------------- */
Expand Down Expand Up @@ -150,12 +160,33 @@ export class ItemChoiceConfig extends AdvancementConfig {

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

getData() {
const data = { ...super.getData(), validTypes: {} };
for ( const type of this.advancement.constructor.VALID_TYPES ) {
data.validTypes[type] = game.i18n.localize(`ITEM.Type${type.capitalize()}`);
}
return data;
}

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

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

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

/** @inheritdoc */
_verifyDroppedItem(event, item) {
const type = this.advancement.data.configuration.type;
if ( !type || (type === item.type) ) return true;
const typeName = game.i18n.localize(`ITEM.Type${type.capitalize()}`);
ui.notifications.warn(game.i18n.format("DND5E.AdvancementItemChoiceTypeWarning", { type: typeName }));
return false;
}

}


Expand Down Expand Up @@ -209,6 +240,8 @@ export class ItemChoiceFlow extends AdvancementFlow {
const max = this.advancement.data.configuration.choices[this.level];
const choices = { max, current: this.selected.size, full: this.selected.size >= max };

// TODO: Display dropped items in list when returning to option

// TODO: Make any choices made at previous levels unavailable
// TODO: Make any items already on actor unavailable?
// TODO: Make sure selected works properly with retained data
Expand Down Expand Up @@ -296,6 +329,13 @@ export class ItemChoiceFlow extends AdvancementFlow {
if ( data.type !== "Item" ) return false;
const item = await Item.implementation.fromDropData(data);

// If there is a type restriction, verify it against the dropped type
const type = this.advancement.data.configuration.type;
if ( type && (type !== item.type) ) {
const typeName = game.i18n.localize(`ITEM.Type${type.capitalize()}`);
return ui.notifications.warn(game.i18n.format("DND5E.AdvancementItemChoiceTypeWarning", { type: typeName }));
}

// If the item is already been marked as selected, no need to go further
if ( this.selected.has(item.uuid) ) return false;

Expand Down
11 changes: 11 additions & 0 deletions templates/advancement/item-choice-config.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@
<p class="hint">{{localize "DND5E.AdvancementItemChoiceAllowDropsHint"}}</p>
</div>

<div class="form-group">
<label>{{localize "DND5E.AdvancementItemChoiceType"}}</label>
<div class="form-fields">
<select name="data.configuration.type">
{{selectOptions validTypes selected=data.configuration.type
blank=(localize "DND5E.AdvancementItemChoiceTypeAny")}}
</select>
</div>
<p class="hint">{{localize "DND5E.AdvancementItemChoiceTypeHint"}}</p>
</div>

<div class="drop-target">
<ol class="items-list">
<li class="items-header flexrow"><h3 class="item-name">{{localize "DOCUMENT.Items"}}</h3></li>
Expand Down

0 comments on commit 0b826fd

Please sign in to comment.