Implement a button to create items of a specific subtype in the player inventory (closes #120)
This commit is contained in:
parent
b3e699bc32
commit
96f5b17785
9 changed files with 73 additions and 21 deletions
|
|
@ -49,7 +49,8 @@
|
|||
"v2": {
|
||||
"stat-not-chosen": "Select a dice to see the {name} skills",
|
||||
"skill-roll-locked": "@dotdungeon.trainingLevel.locked",
|
||||
"toggle-item-information": "Toggle the item's extra information visibility"
|
||||
"toggle-item-information": "Toggle the item's extra information visibility",
|
||||
"create-item": "Create @TYPES.Item.{type}"
|
||||
}
|
||||
},
|
||||
"item": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
export class DotDungeonActor extends Actor {
|
||||
async createEmbeddedItem(defaults, opts = {}) {
|
||||
let items = await this.createEmbeddedDocuments(`Item`, defaults);
|
||||
if (!Array.isArray(items)) items = items ? [items] : [];
|
||||
if (items.length == 0) {
|
||||
throw new Error(`Failed to create any items`);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { createArray } from "./createArray.mjs";
|
|||
import { detailsExpanded } from "./detailsExpanded.mjs";
|
||||
import { objectValue } from "./objectValue.mjs";
|
||||
import { toFriendlyDuration } from "./toFriendlyDuration.mjs";
|
||||
import { localizer } from "../utils/localizer.mjs";
|
||||
import { handlebarsLocalizer } from "../utils/localizer.mjs";
|
||||
import { options } from "./options.mjs";
|
||||
|
||||
export default {
|
||||
|
|
@ -14,7 +14,7 @@ export default {
|
|||
"dd-toFriendlyDuration": toFriendlyDuration,
|
||||
"dd-objectValue": objectValue,
|
||||
"dd-expanded": detailsExpanded,
|
||||
"dd-i18n": localizer,
|
||||
"dd-i18n": handlebarsLocalizer,
|
||||
"dd-options": options,
|
||||
|
||||
// Simple helpers
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ export class PlayerSheetv2 extends GenericActorSheet {
|
|||
filters[type] = {
|
||||
label: localizer(`TYPES.Item.${type}`),
|
||||
active: !this._itemTypesHidden.has(type),
|
||||
createLabel: localizer(`dotdungeon.sheet.actor.v2.create-item`, {type}),
|
||||
};
|
||||
};
|
||||
return filters;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { localizer } from "../utils/localizer.mjs";
|
||||
import DOTDUNGEON from "../config.mjs";
|
||||
|
||||
export class GenericActorSheet extends ActorSheet {
|
||||
|
|
@ -127,11 +128,11 @@ export class GenericActorSheet extends ActorSheet {
|
|||
async genericEmbeddedCreate($event) {
|
||||
const data = $event.currentTarget.dataset;
|
||||
if (!this[`createCustom${data.embeddedCreate}`]) {
|
||||
this.createEmbeddedItem({
|
||||
this.actor.createEmbeddedItem({
|
||||
type: data.embeddedCreate,
|
||||
name: localizer(
|
||||
`dotdungeon.default.name`,
|
||||
{ document: `Actor`, type: data.embeddedCreate }
|
||||
{ document: `Item`, type: data.embeddedCreate }
|
||||
),
|
||||
});
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
import { localizerConfig } from "../config.mjs";
|
||||
|
||||
export function localizer(key, args = {}, depth = 0) {
|
||||
export function handlebarsLocalizer(key, ...args) {
|
||||
let data = args[0]
|
||||
if (args.length === 1) data = args[0].hash;
|
||||
if (key instanceof Handlebars.SafeString) key = key.toString();
|
||||
const localized = localizer(key, data);
|
||||
return localized;
|
||||
};
|
||||
|
||||
export function localizer(key, args = {}, depth = 0) {
|
||||
/** @type {string} */
|
||||
let localized = game.i18n.format(key, args);
|
||||
const subkeys = localized.matchAll(localizerConfig.subKeyPattern);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,40 @@
|
|||
}
|
||||
}
|
||||
|
||||
.item-group {
|
||||
&__header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center
|
||||
}
|
||||
|
||||
&__create-item {
|
||||
@include material.elevate(2);
|
||||
color: var(--inventory-create-item-font-color);
|
||||
&:hover {
|
||||
@include material.elevate(4);
|
||||
}
|
||||
&:focus-visible, &:active {
|
||||
@include material.elevate(8);
|
||||
}
|
||||
}
|
||||
|
||||
&__list {
|
||||
&--material {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
&--untyped {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.panel {
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
|
|
@ -54,7 +88,7 @@
|
|||
background: hsl( from currentColor / 50% ); // probably gonna need color-mix
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
&:focus-visible, &:active {
|
||||
border-width: 2px;
|
||||
border-color: currentColor;
|
||||
background: var(--elevation-8dp-bg);
|
||||
|
|
@ -94,18 +128,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.material-list {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.untyped-list {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.material {
|
||||
@include material.elevate(1);
|
||||
padding: 8px;
|
||||
|
|
@ -174,6 +196,7 @@
|
|||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
|
|
@ -188,6 +211,7 @@
|
|||
}
|
||||
&__name {
|
||||
flex-grow: 1;
|
||||
cursor: inherit;
|
||||
font-family: var(--inventory-item-name-font);
|
||||
font-size: var(--inventory-item-name-font-size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ $body-font: sans-serif;
|
|||
--skill-training-select-text-color: #{$on-surface};
|
||||
--skill-roll-button-text-color: #{$on-surface};
|
||||
|
||||
/* General variables for inventory tab */
|
||||
--inventory-create-item-font-color: white;
|
||||
|
||||
/* Common Inventory Item Variables */
|
||||
--inventory-item-name-font: #{$body-font};
|
||||
--inventory-item-name-font-size: 0.875rem;
|
||||
|
|
|
|||
|
|
@ -7,9 +7,24 @@
|
|||
{{#each computed.itemFilters as | filter |}}
|
||||
{{#if filter.active}}
|
||||
<section class="item-list__group">
|
||||
<h2>{{filter.label}}</h2>
|
||||
<div class="item-group__header">
|
||||
<h2>{{filter.label}}</h2>
|
||||
<button
|
||||
type="button"
|
||||
class="item-group__create-item reduced-padding equal-padding"
|
||||
data-embedded-create="{{@key}}"
|
||||
aria-label="{{filter.createLabel}}"
|
||||
data-tooltip="{{filter.createLabel}}"
|
||||
data-tooltip-direction="LEFT"
|
||||
>
|
||||
<div aria-hidden="true" class="icon icon--16">
|
||||
{{{ @root.icons.create }}}
|
||||
</div>
|
||||
|
||||
</button>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="{{@key}}-list">
|
||||
<div class="item-group__list--{{@key}}">
|
||||
{{#each (lookup @root.items @key) as | item |}}
|
||||
{{> (concat "dotdungeon.pc.v2." @../key) @root item=item}}
|
||||
{{else}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue