Merge branch 'cleanup-item-list' into 'master'

Rework item lists

See merge request dungeonslayers/ds4!86
This commit is contained in:
Oliver Rümpelein 2021-03-01 17:54:26 +01:00
commit 9dd48226b4
41 changed files with 646 additions and 635 deletions

View file

@ -1,26 +1,24 @@
// Import utilities.
@import "scss/utils/typography";
@import "scss/utils/colors";
@import "scss/utils/mixins";
@import "scss/utils/variables";
@use 'sass:meta';
/* Global styles */
@import "scss/global/window";
@import "scss/global/grid";
@import "scss/global/flex";
@import "scss/global/accessibility";
@include meta.load-css("scss/global/accessibility");
@include meta.load-css("scss/global/flex");
@include meta.load-css("scss/global/fonts");
@include meta.load-css("scss/global/grid");
@include meta.load-css("scss/global/window");
/* Styles limited to ds4 sheets */
.ds4 {
@import "scss/components/apps";
@import "scss/components/forms";
@import "scss/components/basic_property";
@import "scss/components/tabs";
@import "scss/components/items";
@import "scss/components/talents";
@import "scss/components/description";
@import "scss/components/character_values";
@import "scss/components/attributes_traits";
@import "scss/components/combat_values";
@import "scss/components/character_progression";
@include meta.load-css("scss/components/attributes_traits");
@include meta.load-css("scss/components/apps");
@include meta.load-css("scss/components/basic_property");
@include meta.load-css("scss/components/character_progression");
@include meta.load-css("scss/components/character_values");
@include meta.load-css("scss/components/combat_values");
@include meta.load-css("scss/components/description");
@include meta.load-css("scss/components/forms");
@include meta.load-css("scss/components/item_list");
@include meta.load-css("scss/components/tabs");
@include meta.load-css("scss/components/talent_rank_equation");
@include meta.load-css("scss/components/currency");
}

44
src/fonts/Lora/LICENSE Normal file
View file

@ -0,0 +1,44 @@
Copyright (c) 2011-2013, Cyreal (www.cyreal.org a@cyreal.org), with
Reserved Font Name Lora
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
—————————————————————————————-
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
—————————————————————————————-
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
DEFINITIONS
“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
“Reserved Font Name” refers to any names specified as such after the copyright statement(s).
“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s).
“Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/fonts/Lora/Lora.woff Normal file

Binary file not shown.

Binary file not shown.

View file

@ -143,6 +143,7 @@
"DS4.TalentRankMax": "Maximaler Rang",
"DS4.TalentRankMod": "Zusätzlicher Rang",
"DS4.TalentRankTotal": "Gesamter Rang",
"DS4.TalentRankOf": "von",
"DS4.CharacterLanguageLanguages": "Sprachen",
"DS4.CharacterLanguageAlphabets": "Schriftzeichen",
"DS4.SpecialCreatureAbilityExperiencePoints": "Erfahrungspunkte",

View file

@ -143,6 +143,7 @@
"DS4.TalentRankMax": "Maximum Ranks",
"DS4.TalentRankMod": "Additional Ranks",
"DS4.TalentRankTotal": "Total Ranks",
"DS4.TalentRankOf": "of",
"DS4.CharacterLanguageLanguages": "Languages",
"DS4.CharacterLanguageAlphabets": "Alphabets",
"DS4.SpecialCreatureAbilityExperiencePoints": "Experience Points",

View file

@ -58,12 +58,17 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Data<DS4Actor>> {
* @returns The data fed to the template of the actor sheet
*/
async getData(): Promise<ActorSheet.Data<DS4Actor>> {
const itemsByType = Object.fromEntries(
Object.entries(this.actor.itemTypes).map(([itemType, items]) => {
return [itemType, items.map((item) => item.data).sort((a, b) => (a.sort || 0) - (b.sort || 0))];
}),
);
const data = {
...this._addTooltipsToData(await super.getData()),
// Add the localization config to the data:
config: DS4,
// Add the items explicitly sorted by type to the data:
itemsByType: this.actor.itemTypes,
itemsByType,
};
return data;
}
@ -224,7 +229,7 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Data<DS4Actor>> {
// unsupported:
else {
throw TypeError("Binding of item property to this type of HTML element not supported; given: " + el);
throw new TypeError("Binding of item property to this type of HTML element not supported; given: " + el);
}
}

View file

@ -63,6 +63,10 @@ async function registerHandlebarsPartials() {
"systems/ds4/templates/actor/partials/special-creature-abilities-overview.hbs",
"systems/ds4/templates/actor/partials/character-inventory.hbs",
"systems/ds4/templates/actor/partials/creature-inventory.hbs",
"systems/ds4/templates/actor/partials/talent-rank-equation.hbs",
"systems/ds4/templates/actor/partials/item-list-header.hbs",
"systems/ds4/templates/actor/partials/item-list-entry.hbs",
"systems/ds4/templates/actor/partials/currency.hbs",
];
return loadTemplates(templatePaths);
}

View file

@ -1,6 +1,10 @@
export default { htmlToPlainText };
export default { htmlToPlainText, isEmpty };
function htmlToPlainText(input: string | null | undefined): string | null | undefined {
if (!input) return;
return $(input).text();
}
function isEmpty(input: Array<unknown> | null | undefined): boolean {
return (input?.length ?? 0) === 0;
}

View file

@ -1,13 +1,17 @@
@use "../utils/colors";
@use "../utils/typography";
@use "../utils/variables";
.attributes-traits {
margin-top: $margin-sm;
margin-top: variables.$margin-sm;
.attribute {
.attribute-label {
@include font-heading-upper;
@include typography.font-heading-upper;
font-size: 2em;
text-align: center;
}
.attribute-value {
border: 2px groove $c-border-groove;
border: variables.$border-groove;
font-size: 1.5em;
text-align: center;
padding-left: 2px;
@ -16,7 +20,7 @@
input,
.attribute-value-total {
grid-column: span 2;
line-height: $default-input-height;
line-height: variables.$default-input-height;
}
.attribute-value-arrow {
padding: 0 5px;
@ -26,14 +30,14 @@
.trait {
.trait-label {
color: transparent;
@include font-heading-upper;
@include typography.font-heading-upper;
font-size: 2em;
text-align: center;
//text-shadow: -1px 1px 0 $c-black, 1px 1px 0 $c-black, 1px -1px 0 $c-black, -1px -1px 0 $c-black;
-webkit-text-stroke: 1px $c-black;
-webkit-text-stroke: 1px colors.$c-black;
}
.trait-value {
border: 2px groove $c-border-groove;
border: variables.$border-groove;
font-size: 1.5em;
text-align: center;
padding-left: 2px;
@ -42,7 +46,7 @@
input,
.trait-value-total {
grid-column: span 2;
line-height: $default-input-height;
line-height: variables.$default-input-height;
}
.trait-value-arrow {
padding: 0 5px;

View file

@ -1,3 +1,5 @@
@use "../utils/mixins";
.basic-properties {
flex: 0 0 100%;
grid-gap: 2px;
@ -21,6 +23,6 @@
text-align: center;
}
@include mark-invalid-or-disabled-input;
@include mixins.mark-invalid-or-disabled-input;
}
}

View file

@ -1,3 +1,7 @@
@use "../utils/colors";
@use "../utils/typography";
@use "../utils/variables";
.progression {
.progression-entry {
display: flex;
@ -8,16 +12,15 @@
padding-right: 3px;
h2.progression-label {
@include font-heading-upper;
@include typography.font-heading-upper;
display: block;
height: 50px;
padding: 0;
color: $c-light-grey;
color: colors.$c-light-grey;
border: none;
line-height: 50px;
margin: $header-top-margin 0;
margin: variables.$margin-sm 0;
text-align: right;
//flex: 0;
}
input.progression-value {
margin-left: 5px;

View file

@ -1,13 +1,16 @@
@use "../utils/mixins";
@use "../utils/variables";
.combat-values {
margin-top: $margin-sm;
margin-top: variables.$margin-sm;
.combat-value-with-formula {
$size: 60px;
display: grid;
place-items: center;
$size: 60px;
row-gap: $margin-sm;
row-gap: variables.$margin-sm;
.combat-value {
$combat-values-icons-path: "#{$official-icons-path}/combat-values";
@include centered-content;
$combat-values-icons-path: "#{variables.$official-icons-path}/combat-values";
@include mixins.centered-content;
height: $size;
width: $size;
flex: 0 0 auto;
@ -43,7 +46,7 @@
width: $size;
text-align: center;
span {
line-height: $default-input-height;
line-height: variables.$default-input-height;
}
}
}

View file

@ -0,0 +1,16 @@
@use "../utils/variables";
.ds4-currency {
align-items: center;
display: flex;
gap: 1em;
margin: 0.5em 0;
}
.ds4-currency-title {
border-bottom: variables.$border-groove;
font-weight: bold;
margin-bottom: 0;
margin-top: 1em;
padding-left: 1em;
}

View file

@ -1,10 +1,13 @@
@use "../utils/mixins";
@use "../utils/variables";
.side-properties {
flex: 0;
min-width: fit-content;
max-width: 50%;
margin: 5px 5px 5px 0;
padding-right: 5px;
border-right: 2px groove $c-border-groove;
border-right: variables.$border-groove;
.side-property {
margin: 2px 0;
@ -13,7 +16,7 @@
justify-content: left;
label {
line-height: $default-input-height;
line-height: variables.$default-input-height;
font-weight: bold;
padding-right: 3pt;
}
@ -27,7 +30,7 @@
text-overflow: ellipsis;
}
@include mark-invalid-or-disabled-input;
@include mixins.mark-invalid-or-disabled-input;
input[type="checkbox"] {
width: auto;

View file

@ -1,8 +1,10 @@
.item-form {
font-family: $font-primary;
}
@use "../utils/colors";
@use "../utils/typography";
@use "../utils/variables";
$header-top-margin: 5px;
.item-form {
font-family: typography.$font-primary;
}
header.sheet-header {
flex: 0 0 auto;
@ -16,7 +18,7 @@ header.sheet-header {
.profile-img {
flex: 0 0 100px;
height: 100px;
margin: $header-top-margin 10px $header-top-margin 0;
margin: variables.$margin-sm 10px variables.$margin-sm 0;
}
.header-fields {
@ -26,9 +28,9 @@ header.sheet-header {
h1.charname {
height: 50px;
padding: 0px;
margin: $header-top-margin 10px $header-top-margin 0;
margin: variables.$margin-sm 10px variables.$margin-sm 0;
border-bottom: 0;
@include font-heading-upper;
@include typography.font-heading-upper;
display: block;
input {
width: 100%;
@ -36,19 +38,19 @@ header.sheet-header {
margin: 0;
border: none;
background-color: transparent;
@include font-heading-upper;
@include typography.font-heading-upper;
}
}
h2.item-type {
@include font-heading-upper;
@include typography.font-heading-upper;
display: block;
height: 50px;
padding: 0px;
flex: 0 0 auto;
color: $c-light-grey;
color: colors.$c-light-grey;
border: none;
line-height: 50px;
margin: $header-top-margin 0;
margin: variables.$margin-sm 0;
text-align: right;
}
}

View file

@ -0,0 +1,100 @@
@use "../utils/mixins";
@use "../utils/variables";
.ds4-item-list {
@include mixins.mark-invalid-or-disabled-input;
$row-height: 1.75em;
align-items: center;
display: grid;
grid-column-gap: 0.5em;
grid-row-gap: 0.2em;
margin: 0.5em 0;
overflow-y: auto;
padding: 0;
&--weapon {
grid-template-columns: $row-height $row-height 3ch 3fr $row-height 1fr 3ch 5fr 4ch;
}
&--armor {
grid-template-columns: $row-height $row-height 3ch 3fr 1fr 1fr 3ch 5fr 4ch;
}
&--shield {
grid-template-columns: $row-height $row-height 3ch 1fr 3ch 3fr 4ch;
}
&--equipment {
grid-template-columns: $row-height $row-height 3ch 1fr 10ch 3fr 4ch;
}
&--loot {
grid-template-columns: $row-height 3ch 1fr 10ch 3fr 4ch;
}
&--spell {
grid-template-columns: $row-height $row-height 2fr $row-height 1fr 1fr 1fr 1fr 4ch;
}
&--talent {
grid-template-columns: $row-height 1fr 1fr 3fr 4ch;
}
&--racial-ability,
&--language,
&--alphabet,
&--special-creature-ability {
grid-template-columns: $row-height 1fr 3fr 4ch;
}
&__row {
display: contents; // TODO: Once chromium supports `grid-template-columns: subgrid` (https://bugs.chromium.org/p/chromium/issues/detail?id=618969), switch to `display: grid; grid: 1/-1; grid-template-columns: subgrid`
&--header {
font-weight: bold;
}
> * {
height: $row-height;
line-height: $row-height;
white-space: nowrap;
}
}
&__image {
background-position: center;
background-repeat: no-repeat;
background-size: 100%;
}
&__editable {
background-color: transparent;
border: 0;
padding: 0;
&--checkbox {
width: 100%;
height: 100%;
margin: 0px;
}
}
&__description {
overflow: hidden;
text-overflow: ellipsis;
:not(:first-child) {
display: none;
}
> * {
font-size: 0.75em;
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
.ds4-item-list-title {
border-bottom: variables.$border-groove;
font-weight: bold;
margin-bottom: 0;
margin-top: 1em;
padding-left: 1em;
}

View file

@ -1,84 +0,0 @@
@use "sass:color";
.items-list {
list-style: none;
margin: 7px 0;
padding: 0;
overflow-y: auto;
.item-header {
font-weight: bold;
}
.item {
height: 30px;
line-height: 24px;
padding: 3px 0;
border-bottom: 1px solid #bbb;
.item-image {
flex: 0 0 24px;
height: 100%;
//margin-right: 5px;
@include centered-content;
}
img {
display: block;
border: none;
}
input {
border: 0;
padding: 0;
background-color: transparent;
}
input[type="checkbox"] {
width: auto;
height: 100%;
margin: 0px;
}
@include mark-invalid-or-disabled-input;
}
.item-name {
margin: 0;
}
.item-controls {
flex: 0 0 86px;
text-align: right;
}
.item-num-val {
text-align: center;
width: 2.5em;
padding: 0;
}
.item-description {
font-size: 75%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: 100%;
p {
text-overflow: ellipsis;
overflow: hidden;
}
p:first-child {
margin-top: 0px;
padding-top: 0px;
}
}
}
.items-list-title {
margin-top: 2em;
margin-bottom: 0px;
padding-left: 1em;
border-bottom: 2px groove $c-border-groove;
font-weight: bold;
}

View file

@ -1,10 +1,12 @@
@use "../utils/variables";
nav.tabs {
height: auto;
border-top: 2px groove $c-border-groove;
border-bottom: 2px groove $c-border-groove;
border-top: variables.$border-groove;
border-bottom: variables.$border-groove;
.item {
font-weight: bold;
white-space: nowrap;
}
.item.active {

View file

@ -0,0 +1,12 @@
.ds4-talent-rank-equation {
display: flex;
gap: 0.5em;
&__value {
background-color: transparent;
border: 0;
height: auto;
padding: 0;
text-align: center;
}
}

View file

@ -1,3 +0,0 @@
.talent-ranks-equation {
text-align: center;
}

View file

@ -0,0 +1,34 @@
@font-face {
font-family: "Lora";
font-style: normal;
font-weight: normal;
src: local("Lora"), url("fonts/Lora/Lora.woff") format("woff");
}
@font-face {
font-family: "Lora";
font-style: normal;
font-weight: bold;
src: local("Lora"), url("fonts/Lora/Lora-Bold.woff") format("woff");
}
@font-face {
font-family: "Lora";
font-style: italic;
font-weight: normal;
src: local("Lora"), url("fonts/Lora/Lora-Italic.woff") format("woff");
}
@font-face {
font-family: "Lora";
font-style: italic;
font-weight: bold;
src: local("Lora"), url("fonts/Lora/Lora-BoldItalic.woff") format("woff");
}
@font-face {
font-family: "Wood Stamp";
font-style: normal;
font-weight: normal;
src: local("Wood Stamp"), url("fonts/Woodstamp/Woodstamp.woff") format("woff");
}

View file

@ -1,5 +1,7 @@
@use "../utils/typography";
.window-app {
font-family: $font-primary;
font-family: typography.$font-primary;
input[type="text"],
input[type="number"],
input[type="password"],

View file

@ -1,3 +1,5 @@
@use "./colors";
@mixin element-invisible {
position: absolute;
@ -22,14 +24,9 @@
@mixin mark-invalid-or-disabled-input {
input:invalid {
background-color: $c-invalid-input;
background-color: colors.$c-invalid-input;
}
input:disabled {
background-color: transparent;
}
}
@mixin font-heading-upper {
font-family: $font-heading;
text-transform: uppercase;
}

View file

@ -1,12 +1,8 @@
@import url("https://fonts.googleapis.com/css2?family=Lora:wght@400;700&display=swap");
@font-face {
font-family: "Wood Stamp";
font-style: normal;
font-weight: normal;
src: local("Wood Stamp"), url("fonts/Woodstamp.woff") format("woff");
}
$font-primary: "Lora", sans-serif;
$font-secondary: "Lora", sans-serif;
$font-primary: "Lora", serif;
$font-secondary: "Lora", serif;
$font-heading: "Wood Stamp", sans-serif;
@mixin font-heading-upper {
font-family: $font-heading;
text-transform: uppercase;
}

View file

@ -1,3 +1,5 @@
@use "./colors";
$padding-sm: 5px;
$padding-md: 10px;
$padding-lg: 20px;
@ -8,3 +10,5 @@ $margin-lg: $padding-lg;
$default-input-height: 26px;
$official-icons-path: "assets/icons/official";
$border-groove: 2px groove colors.$c-border-groove;

View file

@ -1,21 +1,4 @@
<div class="tab inventory" data-group="primary" data-tab="inventory">
{{!-- Money--}}
<h4 class="items-list-title">{{localize 'DS4.CharacterCurrency'}}</h4>
<ol class="items-list">
<li class="item flexrow item-header">
<label for="data.currency.gold" class="flex05">{{config.i18n.characterCurrency.gold}}</label>
<input class="flex3 item-num-val item-change" type="number" min="0" step="1" name="data.currency.gold"
id="data.currency.gold" value="{{data.currency.gold}}" data-dtype="Number" />
<label for="data.currency.silver" class="flex05">{{config.i18n.characterCurrency.silver}}</label>
<input class="flex3 item-num-val item-change" type="number" min="0" step="1" name="data.currency.silver"
id="data.currency.silver" value="{{data.currency.silver}}" data-dtype="Number" />
<label for="data.currency.copper" class="flex05">{{config.i18n.characterCurrency.copper}}</label>
<input class="flex3 item-num-val item-change" type="number" min="0" step="1" name="data.currency.copper"
id="data.currency.copper" value="{{data.currency.copper}}" data-dtype="Number" />
</li>
</ol>
{{> systems/ds4/templates/actor/partials/currency.hbs}}
{{> systems/ds4/templates/actor/partials/items-overview.hbs}}
</div>
</div>

View file

@ -0,0 +1,8 @@
<h4 class="ds4-currency-title">{{localize 'DS4.CharacterCurrency'}}</h4>
<div class="ds4-currency">
{{#each data.currency as |value key|}}
<label for="data.currency.{{key}}" class="flex05">{{lookup ../config.i18n.characterCurrency key}}</label>
<input class="ds4-currency__value ds4-currency__value--{{key}} item-change" type="number" min="0" step="1"
name="data.currency.{{key}}" id="data.currency.{{key}}" value="{{value}}" data-dtype="Number" />
{{/each}}
</div>

View file

@ -0,0 +1,45 @@
{{!--
!-- Render an item list entry row.
!-- If the partial is called with a partial block, the partial block
!-- content is inserted before the description.
!-- @param itemData: The data of the item.
!-- @param isEquipable: A flag to enable the equipped column.
!-- @param hasQuantity: A flag to enable the quantity column.
!-- @param hideDescription: A flag to disable the description column.
!-- @param @partial-block: Custom column headers can be passed using the partial block.
--}}
<li class="ds4-item-list__row item" data-item-id="{{itemData._id}}">
{{!-- equipped --}}
{{#if isEquipable}}
<input class="ds4-item-list__editable ds4-item-list__editable--checkbox item-change" type="checkbox" {{checked
itemData.data.equipped}} data-dtype="Boolean" data-property="data.equipped"
title="{{localize 'DS4.ItemEquipped'}}">
{{/if}}
{{!-- image --}}
<div class="ds4-item-list__image" style="background-image: url('{{itemData.img}}')" title="{{itemData.name}}"></div>
{{!-- amount --}}
{{#if hasQuantity}}
<input class="ds4-item-list__editable item-change" type="number" min="0" step="1" value="{{itemData.data.quantity}}"
data-dtype="Number" data-property="data.quantity" title="{{localize 'DS4.Quantity'}}" />
{{/if}}
{{!-- name --}}
<input class="ds4-item-list__editable item-change" type="text" value="{{itemData.name}}" data-dtype="String"
data-property="name" title="{{htmlToPlainText itemData.data.description}}" />
{{!-- item type specifics --}}
{{#if @partial-block }}
{{> @partial-block}}
{{/if}}
{{!-- description --}}
{{#unless hideDescription}}
<div class="ds4-item-list__description" title="{{htmlToPlainText itemData.data.description}}">
{{{itemData.data.description}}}</div>
{{/unless}}
{{!-- control buttons --}}
{{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
</li>

View file

@ -0,0 +1,39 @@
{{!--
!-- Render an item list header row.
!-- If the partial is called with a partial block, the partial block
!-- content is inserted before the description heading.
!-- @param isEquipable: A flag to enable the equipped column.
!-- @param hasQuantity: A flag to enable the quantity column.
!-- @param hideDescription: A flag to disable the description column.
!-- @param @partial-block: Custom column headers can be passed using the partial block.
--}}
<li class="ds4-item-list__row ds4-item-list__row--header">
{{!-- equipped --}}
{{#if isEquipable}}
<div title="{{localize 'DS4.ItemEquipped'}}">{{localize 'DS4.ItemEquippedAbbr'}}</div>
{{/if}}
{{!-- image --}}
<div></div>
{{!-- amount --}}
{{#if hasQuantity}}
<div title="{{localize 'DS4.Quantity'}}">#</div>
{{/if}}
{{!-- name --}}
<div>{{localize 'DS4.ItemName'}}</div>
{{!-- item type specifics --}}
{{#if @partial-block }}
{{> @partial-block }}
{{/if}}
{{!-- description --}}
{{#unless hideDescription}}
<div>{{localize 'DS4.Description'}}</div>
{{/unless}}
{{!-- control buttons placeholder --}}
<div></div>
</li>

View file

@ -1,198 +1,132 @@
{{!-- TODO: Refactor to avoid code duplication with special-creature-abilites-overview and talents-overview --}}
{{!-- ======================================================================== --}}
{{!-- INLINE PARTIAL DEFINITIONS --}}
{{!-- ======================================================================== --}}
{{!--
!-- Render the given partial block only if the given itemsArray has length > 0,
!-- else only an add button.
!--
!-- @param itemsArray: the array with the items to check the length of
!-- @param dataType: the string type of the item
--}}
{{#*inline "ifHasItemOfType"}}
{{#if (and (ne itemsArray undefined) (gt itemsArray.length 0))}}
{{> @partial-block}}
{{/if}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType=dataType }}
{{/inline}}
{{!--
!-- Render a header row for a given data type.
!-- It is a flexbox with a child for each column head.
!-- An "equipped" heading is rendered except for the case dataType==='loot'.
!-- The partial assumes a variable dataType to be given in the context.
!-- If the partial is called with a partial block, the partial block
!-- content is inserted before the description heading.
!-- @param datType: hand over the dataType to the partial as hash parameter
!-- @param partial-block: hand over custom children of the flexbox in the partial block.
--}}
{{#*inline "itemListHeader" }}
<li class="item flexrow item-header">
{{!-- equipped --}}
{{#if (ne dataType 'loot')}}
<div class="flex05" title="{{localize 'DS4.ItemEquipped'}}">{{localize 'DS4.ItemEquippedAbbr'}}</div>
{{/if}}
{{!-- image --}}
<div class="flex05 item-image"></div>
{{!-- amount --}}
<div class="flex05 item-num-val" title="{{localize 'DS4.Quantity'}}">#</div>
{{!-- name --}}
<div class="flex3 item-name">{{localize 'DS4.ItemName'}}</div>
{{!-- item type specifics --}}
{{> @partial-block }}
{{!-- description --}}
<div class="flex4">{{localize 'DS4.Description'}}</div>
{{!-- control buttons placeholder --}}
<div></div>
</li>
{{/inline}}
{{!--
!-- Render a list row from a given item.
!-- It is a flexbox with a child for each item value of interest.
!-- An equipped checkbox is rendered except for the case item.data.type==='loot'.
!-- The partial assumes a variable item to be given in the context.
!-- If the partial is called with a partial block, the partial block
!-- content is inserted before the description.
!-- @param item: hand over the item to the partial as hash parameter
!-- @param partial-block: hand over custom children of the flexbox in the partial block.
--}}
{{#*inline "itemListEntry"}}
<li class="item flexrow" data-item-id="{{item._id}}">
{{!-- equipped --}}
{{#if (ne item.data.type 'loot')}}
<input class="flex05 item-change" type="checkbox" {{checked item.data.data.equipped}} data-dtype="Boolean"
data-property="data.equipped" title="{{localize 'DS4.ItemEquipped'}}">
{{/if}}
{{!-- image --}}
<div class="flex05 item-image">
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
</div>
{{!-- amount --}}
<input class="flex05 item-num-val item-change" type="number" min="0" step="1" value="{{item.data.data.quantity}}"
data-dtype="Number" data-property="data.quantity" title="{{localize 'DS4.Quantity'}}" />
{{!-- name --}}
<input class="flex3 item-name item-change" type="text" value="{{item.name}}" data-dtype="String"
data-property="name" title="{{htmlToPlainText item.data.data.description}}" />
{{!-- item type specifics --}}
{{> @partial-block}}
{{!-- description --}}
<div class="flex4 item-description" title="{{htmlToPlainText item.data.data.description}}">
{{{item.data.data.description}}}</div>
{{!-- control buttons --}}
{{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
</li>
{{/inline}}
{{!-- ======================================================================== --}}
{{!-- WEAPONS --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeWeaponPlural'}}</h4>
{{!-- {{#if (and (ne itemsByType.weapon undefined) (gt itemsByType.weapon.length 0)) }} --}}
{{#> ifHasItemOfType itemsArray=itemsByType.weapon dataType='weapon' }}
<ol class="items-list">
{{#> itemListHeader dataType='weapon'}}
<div class="flex05 item-image" title="{{localize 'DS4.AttackType'}}">{{localize 'DS4.AttackTypeAbbr'}}</div>
<div class="flex05 item-num-val" title="{{localize 'DS4.WeaponBonus'}}">
<h4 class="ds4-item-list-title">{{localize 'DS4.ItemTypeWeaponPlural'}}</h4>
{{#unless (isEmpty itemsByType.weapon)}}
<ol class="ds4-item-list ds4-item-list--weapon item-list">
{{#> systems/ds4/templates/actor/partials/item-list-header.hbs isEquipable=true hasQuantity=true}}
{{!-- attack type --}}
<div class="ds4-item-list__image" title="{{localize 'DS4.AttackType'}}">{{localize 'DS4.AttackTypeAbbr'}}</div>
{{!-- weapon bonus --}}
<div title="{{localize 'DS4.WeaponBonus'}}">
{{localize 'DS4.WeaponBonusAbbr'}}
</div>
<div class="flex05 item-num-val" title="{{localize 'DS4.OpponentDefense'}}">
{{!-- opponent defense --}}
<div title="{{localize 'DS4.OpponentDefense'}}">
{{localize 'DS4.OpponentDefenseAbbr'}}
</div>
{{/itemListHeader}}
{{#each itemsByType.weapon as |item id|}}
{{#> itemListEntry item=item}}
<div class="flex05 item-image">
<img src="{{lookup ../../config.icons.attackTypes item.data.data.attackType}}"
title="{{lookup ../../config.i18n.attackTypes item.data.data.attackType}}" width="24" height="24" />
{{/systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.weapon as |itemData id|}}
{{#> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData isEquipable=true hasQuantity=true}}
{{!-- attack type --}}
<div class="ds4-item-list__image"
style="background-image: url('{{lookup ../../config.icons.attackTypes itemData.data.attackType}}')"
title="{{lookup ../../config.i18n.attackTypes itemData.data.attackType}}">
</div>
<div class="flex05 item-num-val">{{ item.data.data.weaponBonus}}</div>
<div class="flex05 item-num-val">{{ item.data.data.opponentDefense}}</div>
{{/itemListEntry}}
{{!-- weapon bonus --}}
<div>{{ itemData.data.weaponBonus}}</div>
{{!-- opponent defense --}}
<div>{{ itemData.data.opponentDefense}}</div>
{{/systems/ds4/templates/actor/partials/item-list-entry.hbs}}
{{/each}}
</ol>
{{!-- {{else}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='weapon' }} --}}
{{/ifHasItemOfType}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='weapon'}}
{{!-- ARMOR --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeArmorPlural'}}</h4>
{{#> ifHasItemOfType itemsArray=itemsByType.armor dataType='armor' }}
<ol class="items-list">
{{#> itemListHeader dataType='armor'}}
<h4 class="ds4-item-list-title">{{localize 'DS4.ItemTypeArmorPlural'}}</h4>
{{#unless (isEmpty itemsByType.armor)}}
<ol class="ds4-item-list ds4-item-list--armor item-list">
{{#> systems/ds4/templates/actor/partials/item-list-header.hbs isEquipable=true hasQuantity=true}}
{{!-- armor material type --}}
<div title="{{localize 'DS4.ArmorMaterialType'}}">{{localize 'DS4.ArmorMaterialTypeAbbr'}}</div>
{{!-- armor type --}}
<div title="{{localize 'DS4.ArmorType'}}">{{localize 'DS4.ArmorTypeAbbr'}}</div>
<div class="flex05 item-num-val" title="{{localize 'DS4.ArmorValue'}}">
{{!-- armor value --}}
<div title="{{localize 'DS4.ArmorValue'}}">
{{localize 'DS4.ArmorValueAbbr'}}
</div>
{{/itemListHeader}}
{{#each itemsByType.armor as |item id|}}
{{#> itemListEntry item=item }}
<div title="{{lookup ../../config.i18n.armorMaterialTypes item.data.data.armorMaterialType}}">
{{lookup ../../config.i18n.armorMaterialTypesAbbr item.data.data.armorMaterialType}}
{{/systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.armor as |itemData id|}}
{{#> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData isEquipable=true hasQuantity=true}}
{{!-- armor material type --}}
<div title="{{lookup ../../config.i18n.armorMaterialTypes itemData.data.armorMaterialType}}">
{{lookup ../../config.i18n.armorMaterialTypesAbbr itemData.data.armorMaterialType}}
</div>
<div title="{{lookup ../../config.i18n.armorTypes item.data.data.armorType}}">
{{lookup ../../config.i18n.armorTypesAbbr item.data.data.armorType}}
{{!-- armor type --}}
<div title="{{lookup ../../config.i18n.armorTypes itemData.dataData.armorType}}">
{{lookup ../../config.i18n.armorTypesAbbr itemData.dataData.armorType}}
</div>
<div class="flex05 item-num-val">{{ item.data.data.armorValue}}</div>
{{/itemListEntry}}
{{!-- armor value --}}
<div>{{ itemData.data.armorValue}}</div>
{{/systems/ds4/templates/actor/partials/item-list-entry.hbs}}
{{/each}}
</ol>
{{/ifHasItemOfType}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='armor'}}
{{!-- SHIELD --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeShieldPlural'}}</h4> {{!-- SPECIFIC --}}
{{#> ifHasItemOfType itemsArray=itemsByType.shield dataType='shield' }}
<ol class="items-list">
{{#> itemListHeader dataType='shield' }}
<div class="flex05 item-num-val" title="{{localize 'DS4.ArmorValue'}}">
<h4 class="ds4-item-list-title">{{localize 'DS4.ItemTypeShieldPlural'}}</h4>
{{#unless (isEmpty itemsByType.shield)}}
<ol class="ds4-item-list ds4-item-list--shield item-list">
{{#> systems/ds4/templates/actor/partials/item-list-header.hbs isEquipable=true hasQuantity=true}}
{{!-- armor value --}}
<div title="{{localize 'DS4.ArmorValue'}}">
{{localize 'DS4.ArmorValueAbbr'}}
</div>
{{/itemListHeader}}
{{#each itemsByType.shield as |item id|}}
{{#> itemListEntry item=item }}
<div class="flex05 item-num-val">{{item.data.data.armorValue}}</div> {{!-- SPECIFIC --}}
{{/itemListEntry}}
{{/systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.shield as |itemData id|}}
{{#> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData isEquipable=true hasQuantity=true}}
{{!-- armor value --}}
<div>{{itemData.data.armorValue}}</div>
{{/systems/ds4/templates/actor/partials/item-list-entry.hbs}}
{{/each}}
</ol>
{{/ifHasItemOfType}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='shield'}}
{{!-- EQUIPMENT --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeEquipmentPlural'}}</h4>
{{#> ifHasItemOfType itemsArray=itemsByType.equipment dataType='equipment' }}
<ol class="items-list">
{{#> itemListHeader dataType='equipment'}}
<div class="flex2">{{localize 'DS4.StorageLocation'}}</div>
{{/itemListHeader}}
{{#each itemsByType.equipment as |item id|}}
{{#> itemListEntry item=item }}
<input class="flex2 item-change" type="text" value="{{item.data.data.storageLocation}}" data-dtype="String"
data-property="data.storageLocation" title="{{localize 'DS4.StorageLocation'}}">
{{/itemListEntry}}
<h4 class="ds4-item-list-title">{{localize 'DS4.ItemTypeEquipmentPlural'}}</h4>
{{#unless (isEmpty itemsByType.equipment)}}
<ol class="ds4-item-list ds4-item-list--equipment item-list">
{{#> systems/ds4/templates/actor/partials/item-list-header.hbs isEquipable=true hasQuantity=true}}
{{!-- storage location --}}
<div>{{localize 'DS4.StorageLocation'}}</div>
{{/systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.equipment as |itemData id|}}
{{#> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData isEquipable=true hasQuantity=true}}
{{!-- storage location --}}
<input class="ds4-item-list__editable item-change" type="text" value="{{itemData.data.storageLocation}}"
data-dtype="String" data-property="data.storageLocation" title="{{localize 'DS4.StorageLocation'}}">
{{/systems/ds4/templates/actor/partials/item-list-entry.hbs}}
{{/each}}
</ol>
{{/ifHasItemOfType}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='equipment'}}
{{!-- LOOT --}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeLootPlural'}}</h4>
{{#> ifHasItemOfType itemsArray=itemsByType.loot dataType='loot' }}
<ol class="items-list">
{{#> itemListHeader dataType='loot'}}
<div class="flex2">{{localize 'DS4.StorageLocation'}}</div>
{{/itemListHeader}}
{{#each itemsByType.loot as |item id|}}
{{#> itemListEntry item=item }}
<input class="flex2 item-change" type="text" value="{{item.data.data.storageLocation}}" data-dtype="String"
data-property="data.storageLocation" title="{{localize 'DS4.StorageLocation'}}">
{{/itemListEntry}}
<h4 class="ds4-item-list-title">{{localize 'DS4.ItemTypeLootPlural'}}</h4>
{{#unless (isEmpty itemsByType.loot)}}
<ol class="ds4-item-list ds4-item-list--loot item-list">
{{#> systems/ds4/templates/actor/partials/item-list-header.hbs hasQuantity=true}}
{{!-- storage location --}}
<div>{{localize 'DS4.StorageLocation'}}</div>
{{/systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.loot as |itemData id|}}
{{#> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData hasQuantity=true}}
{{!-- storage location --}}
<input class="ds4-item-list__editable item-change" type="text" value="{{itemData.data.storageLocation}}"
data-dtype="String" data-property="data.storageLocation" title="{{localize 'DS4.StorageLocation'}}">
{{/systems/ds4/templates/actor/partials/item-list-entry.hbs}}
{{/each}}
</ol>
{{/ifHasItemOfType}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='loot'}}

View file

@ -1,11 +1,10 @@
{{!
!-- Render an "add" button for adding an item of given data type.
!--
!-- @param datType: hand over the dataType to the partial as hash parameter
!-- @param dataType: hand over the dataType to the partial as hash parameter
}}
<div class="item-controls">
<a class="item-control item-create" title="Create item" data-type="{{dataType}}">
<i class="fas fa-plus"></i>
{{localize "DS4.UserInteractionAddItem"}}
</a>
</div>
</div>

View file

@ -1,63 +1,11 @@
{{!-- TODO: Refactor to avoid code duplication with items-overview and talents-overview --}}
{{!-- ======================================================================== --}}
{{!-- INLINE PARTIAL DEFINITIONS --}}
{{!-- ======================================================================== --}}
{{!--
!-- Render a list row for a base item from a given item.
!-- Base item means it just has an image, a description, and a name (and effects).
!-- It is a flexbox with a child for each item value of interest.
!-- The partial assumes a variable item to be given in the context.
!--
!-- @param item: hand over the item to the partial as hash parameter
--}}
{{#*inline "baseItemListEntry"}}
<li class="item flexrow" data-item-id="{{item._id}}">
{{!-- image --}}
<div class="flex05 item-image">
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
</div>
{{!-- name --}}
<input class="flex1 item-name item-change" type="text" value="{{item.name}}" data-dtype="String"
data-property="name" title="{{htmlToPlainText item.data.data.description}}">
{{!-- description --}}
<div class="flex3 item-description" title="{{htmlToPlainText item.data.data.description}}">
{{{item.data.data.description}}}</div>
{{!-- control buttons --}}
{{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
</li>
{{/inline}}
{{!--
!-- Render a list header for a base item list entries from a given item.
!-- The partial assumes a variable dataType to be given in the context.
!--
!-- @param dataType: the string item type for the list
--}}
{{#*inline "baseItemListHeader"}}
<li class="item flexrow item-header">
{{!-- image --}}
<div class="flex05 item-image"></div>
{{!-- name --}}
<div class="flex1 item-name">{{localize 'DS4.ItemName'}}</div>
{{!-- description --}}
<div class="flex3">{{localize 'DS4.Description'}}</div>
{{!-- control buttons placeholder --}}
<div></div>
</li>
{{/inline}}
{{!-- ======================================================================== --}}
<div class="tab special-creature-abilities" data-group="primary" data-tab="special-creature-abilities">
<ol class="items-list">
{{> baseItemListHeader dataType='specialCreatureAbility' }}
{{#each itemsByType.specialCreatureAbility as |item id|}}
{{> baseItemListEntry item=item}}
{{#unless (isEmpty itemsByType.specialCreatureAbility)}}
<ol class="ds4-item-list ds4-item-list--special-creature-ability item-list">
{{> systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.specialCreatureAbility as |itemData id|}}
{{> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData}}
{{/each}}
</ol>
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='specialCreatureAbility' }}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='specialCreatureAbility'}}
</div>

View file

@ -5,30 +5,32 @@
{{!--
!-- Base template to display a value with unit.
!-- @param unitDatum: the object to display; must have a value and a unit attribute
!-- @param localizationString
!-- @param titleKey: The key of the localized title to use.
!-- @param unitNames: mapping of allowed unitDatum.unit values to localized unit name
!-- @param unitAbbrs: mapping of allowed unitDatum.unit values to unit abbreviation
--}}
{{#*inline "unit"}}
<div class="unit-data-pair item-num-val" title="{{localize localizationString}} [{{lookup unitNames unitDatum.unit}}]">
<div title="{{localize titleKey}} [{{lookup unitNames unitDatum.unit}}]">
{{#if unitDatum.value }}
{{unitDatum.value}}&thinsp;{{lookup unitAbbrs unitDatum.unit}}
{{else}}-{{/if}}
</div>
{{/inline}}
{{!--
!-- Two templates based on the "unit" template for displaying values with unit.
!-- Both accept a `config` object holding the unitNames and unitAbbr instead of
!-- directly handing over the latter two.
!-- @param titleKey: The key of the localized title to use.
--}}
{{#*inline "temporalUnit"}}
{{> unit unitNames=config.i18n.temporalUnits unitAbbrs=config.i18n.temporalUnitsAbbr unitDatum=unitDatum
localizationString=localizationString}}
titleKey=titleKey}}
{{/inline}}
{{#*inline "distanceUnit"}}
{{> unit unitNames=config.i18n.distanceUnits unitAbbrs=config.i18n.distanceUnitsAbbr unitDatum=unitDatum
localizationString=localizationString}}
titleKey=titleKey}}
{{/inline}}
@ -36,65 +38,50 @@ localizationString=localizationString}}
<div class="tab spells" data-group="primary" data-tab="spells">
<ol class="items-list">
<li class="item flexrow item-header">
{{!-- equipped --}}
<div class="flex05 item-image" title="{{localize 'DS4.ItemEquipped'}}">{{localize 'DS4.ItemEquippedAbbr'}}
</div>
{{!-- image --}}
<div class="flex05 item-image"></div>
{{!-- name --}}
<div class="flex2 item-name">{{localize 'DS4.ItemName'}}</div>
{{!-- spell type --}}
<div class="item-image" title="{{localize 'DS4.SpellType'}}">{{localize 'DS4.SpellTypeAbbr'}}</div>
{{!-- spell bonus --}}
<div class="item-num-val" title="{{localize 'DS4.SpellBonus'}}">{{localize 'DS4.SpellBonusAbbr'}}</div>
{{!-- max. distance --}}
<div class="item-num-val" title="{{localize 'DS4.SpellMaxDistance'}}"><i class="fas fa-ruler"></i></div>
{{!-- duration --}}
<div class="item-num-val" title="{{localize 'DS4.SpellDuration'}}"><i class="far fa-clock"></i></div>
{{!-- cooldown duration --}}
<div class="item-num-val" title="{{localize 'DS4.SpellCooldownDuration'}}"><i
class="fas fa-hourglass-half"></i></div>
{{!-- description --}}
{{!-- <div class="flex3">{{localize 'DS4.Description'}}</div> --}}
{{!-- control buttons placeholder --}}
<div></div>
</li>
{{#each itemsByType.spell as |item id|}}
<li class="item flexrow" data-item-id="{{item._id}}">
<input class="flex05 item-image item-change" type="checkbox" {{checked item.data.data.equipped}}
data-dtype="Boolean" data-property="data.equipped" title="{{localize 'DS4.ItemEquipped'}}">
{{!-- image --}}
<div class="flex05 item-image">
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
</div>
{{!-- name --}}
<input class="flex2 item-name item-change" type="text" value="{{item.name}}" data-dtype="String"
data-property="name" title="{{htmlToPlainText item.data.data.description}}" />
{{!-- spell type --}}
<div class="flex05 item-image">
<img src="{{lookup ../config.icons.spellTypes item.data.data.spellType}}"
title="{{lookup ../config.i18n.spellTypes item.data.data.spellType}}" width="24" height="24" />
</div>
{{!-- spell bonus --}}
<input class="item-num-val item-change" type="text" data-dtype="String" data-property="data.bonus"
value="{{item.data.data.bonus}}" title="{{localize 'DS4.SpellBonus'}}" />
{{!-- max. distance --}}
{{> distanceUnit localizationString='DS4.SpellMaxDistance' unitDatum=item.data.data.maxDistance
config=../config}}
{{!-- duration --}}
{{> temporalUnit localizationString='DS4.SpellDuration' unitDatum=item.data.data.duration config=../config}}
{{!-- cooldown duration --}}
{{> temporalUnit localizationString='DS4.SpellCooldownDuration' unitDatum=item.data.data.cooldownDuration
config=../config}}
{{!-- description --}}
{{!-- <div class="flex3 item-description">{{{item.data.data.description}}}</div> --}}
{{!-- control buttons --}}
{{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
</li>
{{#unless (isEmpty itemsByType.spell)}}
<ol class="ds4-item-list ds4-item-list--spell item-list">
{{#> systems/ds4/templates/actor/partials/item-list-header.hbs isEquipable=true hideDescription=true}}
{{!-- spell type --}}
<div title="{{localize 'DS4.SpellType'}}">{{localize 'DS4.SpellTypeAbbr'}}</div>
{{!-- spell bonus --}}
<div title="{{localize 'DS4.SpellBonus'}}">{{localize 'DS4.SpellBonusAbbr'}}</div>
{{!-- max. distance --}}
<div title="{{localize 'DS4.SpellMaxDistance'}}"><i class="fas fa-ruler"></i></div>
{{!-- duration --}}
<div title="{{localize 'DS4.SpellDuration'}}"><i class="far fa-clock"></i></div>
{{!-- cooldown duration --}}
<div title="{{localize 'DS4.SpellCooldownDuration'}}"><i class="fas fa-hourglass-half"></i></div>
{{/systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.spell as |itemData id|}}
{{#> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData isEquipable=true
hideDescription=true}}
{{!-- spell type --}}
<div class="ds4-item-list__image"
style="background-image: url('{{lookup ../../config.icons.spellTypes itemData.data.spellType}}')"
title="{{lookup ../../config.i18n.spellTypes itemData.data.spellType}}">
</div>
{{!-- spell bonus --}}
<input class="ds4-item-list__editable item-change" type="text" data-dtype="String" data-property="data.bonus"
value="{{itemData.data.bonus}}" title="{{localize 'DS4.SpellBonus'}}" />
{{!-- max. distance --}}
{{> distanceUnit titleKey='DS4.SpellMaxDistance' unitDatum=itemData.data.maxDistance
config=../../config}}
{{!-- duration --}}
{{> temporalUnit titleKey='DS4.SpellDuration' unitDatum=itemData.data.duration config=../../config}}
{{!-- cooldown duration --}}
{{> temporalUnit titleKey='DS4.SpellCooldownDuration' unitDatum=itemData.data.cooldownDuration
config=../../config}}
{{/systems/ds4/templates/actor/partials/item-list-entry.hbs}}
{{/each}}
</ol>
{{!-- add button --}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='spell' }}
</div>

View file

@ -0,0 +1,38 @@
{{!-- ======================================================================== --}}
{{!-- INLINE PARTIAL DEFINITIONS --}}
{{!-- ======================================================================== --}}
{{!--
!-- Render an input element for a rank value property of an item.
!-- @param talentRank: The talentRank
!-- @param property: The key of the property in item.data (if 'base', the max value is set automatically)
!-- @param disabled: If given, is placed plainly into the input as HTML property; meant to be set to "disabled" to
disable the input element
!-- @param localizeString: The string to use as key for the localized tooltip
--}}
{{#*inline "talentRankValue"}}
<input class="ds4-talent-rank-equation__value item-change" data-dtype="Number" type="number" min="0" step="1" {{#if (eq
property 'base' ) }}max="{{talentRank.max}}" {{/if}} {{disabled}} data-property="data.rank.{{property}}"
value="{{lookup talentRank property}}" title="{{localize localizeString}}" />
{{/inline}}
{{!-- ======================================================================== --}}
{{!--
!-- Render an input element for a rank value property of an item.
!-- @param talentRank: The talent rank
--}}
<div class="ds4-talent-rank-equation">
{{!-- acquired rank --}}
{{> talentRankValue talentRank=talentRank property='base' localizeString='DS4.TalentRankBase'}}
<div> ( {{localize "DS4.TalentRankOf"}} </div>
{{!-- maximum acquirable rank --}}
{{> talentRankValue talentRank=talentRank property='max' localizeString='DS4.TalentRankMax'}}
<div>) + </div>
{{!-- additional ranks --}}
{{> talentRankValue talentRank=talentRank property='mod' localizeString='DS4.TalentRankMod'}}
<div> = </div>
{{!-- derived total rank --}}
{{> talentRankValue talentRank=talentRank property='total' localizeString='DS4.TalentRankTotal'
disabled='disabled'}}
</div>

View file

@ -1,175 +1,55 @@
{{!-- TODO: Refactor to avoid code duplication with creature-special-abilities-overview and talents-overview --}}
{{!-- ======================================================================== --}}
{{!-- INLINE PARTIAL DEFINITIONS --}}
{{!-- ======================================================================== --}}
{{!--
!-- Render the given partial block only if the given itemsArray has length > 0,
!-- else only an add button.
!--
!-- @param itemsArray: the array with the items to check the length of
!-- @param dataType: the string type of the item
--}}
{{#*inline "ifHasItemOfType"}}
{{#if (and (ne itemsArray undefined) (gt itemsArray.length 0))}}
{{> @partial-block}}
{{/if}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType=dataType }}
{{/inline}}
{{!--
!-- Render an input element for a rank value property of an item.
!--
!-- @param item: the item
!-- @param property: the key of the property in item.data.data (if 'base', the max value is set automatically)
!-- @param disabled: if given, is placed plainly into the input as HTML property;
!-- meant to be set to "disabled" to disable the input element
--}}
{{#*inline "talentRankValue"}}
<input class="item-num-val item-change" data-dtype="Number" type="number" min="0" step="1" {{#if (eq property 'base' )
}}max="{{item.data.data.rank.max}}" {{/if}} {{disabled}} data-property="data.rank.{{property}}"
value="{{lookup item.data.data.rank property}}" title="{{localize localizeString}}" />
{{/inline}}
{{!--
!-- Render a talent list row from a given item.
!-- It is a flexbox with a child for each item value of interest.
!-- The partial assumes a variable item to be given in the context.
!--
!-- @param item: hand over the item to the partial as hash parameter
--}}
{{#*inline "talentListEntry"}}
<li class="item flexrow" data-item-id="{{item._id}}">
{{!-- image --}}
<div class="flex05 item-image">
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
</div>
{{!-- name --}}
<input class="flex2 item-name item-change" type="text" value="{{item.name}}" data-dtype="String"
data-property="name" title="{{htmlToPlainText item.data.data.description}}">
<div class="flex3 flexrow talent-ranks-equation">
{{!-- acquired rank --}}
{{> talentRankValue item=item property='base' localizeString='DS4.TalentRankBase'}}
<span> ( of </span>
{{!-- maximum acquirable rank --}}
{{> talentRankValue item=item property='max' localizeString='DS4.TalentRankMax'}}
<span>) + </span>
{{!-- additional ranks --}}
{{> talentRankValue item=item property='mod' localizeString='DS4.TalentRankMod'}}
<span> = </span>
{{!-- derived total rank --}}
{{> talentRankValue item=item property='total' localizeString='DS4.TalentRankTotal' disabled='disabled'}}
</div>
{{!-- description --}}
<div class="flex4 item-description" title="{{htmlToPlainText item.data.data.description}}">
{{{item.data.data.description}}}</div>
{{!-- control buttons --}}
{{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
</li>
{{/inline}}
{{!--
!-- Render a list row for a base item from a given item.
!-- Base item means it just has an image, a description, and a name (and effects).
!-- It is a flexbox with a child for each item value of interest.
!-- The partial assumes a variable item to be given in the context.
!--
!-- @param item: hand over the item to the partial as hash parameter
--}}
{{#*inline "baseItemListEntry"}}
<li class="item flexrow" data-item-id="{{item._id}}">
{{!-- image --}}
<div class="flex05 item-image">
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
</div>
{{!-- name --}}
<input class="flex1 item-name item-change" type="text" value="{{item.name}}" data-dtype="String"
data-property="name" title="{{htmlToPlainText item.data.data.description}}"">
{{!-- description --}}
<div class=" flex3 item-description" title="{{htmlToPlainText item.data.data.description}}">
{{{item.data.data.description}}}</div>
{{!-- control buttons --}}
{{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
</li>
{{/inline}}
{{!--
!-- Render a list header for a base item list entry from a given item.
!-- The partial assumes a variable dataType to be given in the context.
!--
!-- @param dataType: the string item type for the list
--}}
{{#*inline "baseItemListHeader"}}
<li class="item flexrow item-header">
{{!-- image --}}
<div class="flex05 item-image"></div>
{{!-- name --}}
<div class="flex1 item-name">{{localize 'DS4.ItemName'}}</div>
{{!-- description --}}
<div class="flex3">{{localize 'DS4.Description'}}</div>
{{!-- control buttons placeholder --}}
<div></div>
</li>
{{/inline}}
{{!-- ======================================================================== --}}
<div class="tab talents-abilities" data-group="primary" data-tab="talents-abilities">
<h4 class="items-list-title">{{localize 'DS4.ItemTypeTalentPlural'}}</h4>
{{#> ifHasItemOfType itemsArray=itemsByType.talent dataType='talent' }}
<ol class="items-list">
<li class="item flexrow item-header">
{{!-- image --}}
<div class="flex05 item-image"></div>
{{!-- name --}}
<div class="flex2 item-name">{{localize 'DS4.ItemName'}}</div>
{{!-- rank info --}}
<div class="flex3">{{localize 'DS4.TalentRank'}}</div>
{{!-- description --}}
<div class="flex4">{{localize 'DS4.Description'}}</div>
{{!-- control buttons placeholder --}}
<div></div>
</li>
{{#each itemsByType.talent as |item id|}}
{{> talentListEntry item=item}}
{{!-- TALENT --}}
<h4 class="ds4-item-list-title">{{localize 'DS4.ItemTypeTalentPlural'}}</h4>
{{#unless (isEmpty itemsByType.talent)}}
<ol class="ds4-item-list ds4-item-list--talent item-list">
{{#> systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{!-- rank --}}
<div>{{localize 'DS4.TalentRank'}}</div>
{{/systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.talent as |itemData id|}}
{{#> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData}}
{{!-- rank --}}
{{> systems/ds4/templates/actor/partials/talent-rank-equation.hbs talentRank=itemData.data.rank}}
{{/systems/ds4/templates/actor/partials/item-list-entry.hbs}}
{{/each}}
</ol>
{{/ifHasItemOfType}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='talent'}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeRacialAbilityPlural'}}</h4>
{{#> ifHasItemOfType itemsArray=itemsByType.racialAbility dataType='racialAbility' }}
<ol class="items-list">
{{> baseItemListHeader dataType='racialAbility' }}
{{#each itemsByType.racialAbility as |item id|}}
{{> baseItemListEntry item=item}}
{{!-- RACIAL ABILITY --}}
<h4 class="ds4-item-list-title">{{localize 'DS4.ItemTypeRacialAbilityPlural'}}</h4>
{{#unless (isEmpty itemsByType.racialAbility)}}
<ol class="ds4-item-list ds4-item-list--racial-ability item-list">
{{> systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.racialAbility as |itemData id|}}
{{> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData}}
{{/each}}
</ol>
{{/ifHasItemOfType}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='racialAbility'}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeLanguagePlural'}}</h4>
{{#> ifHasItemOfType itemsArray=itemsByType.language dataType='language' }}
<ol class="items-list">
{{> baseItemListHeader dataType='language' }}
{{#each itemsByType.language as |item id|}}
{{> baseItemListEntry item=item}}
{{!-- LANGUAGE --}}
<h4 class="ds4-item-list-title">{{localize 'DS4.ItemTypeLanguagePlural'}}</h4>
{{#unless (isEmpty itemsByType.language)}}
<ol class="ds4-item-list ds4-item-list--language item-list">
{{> systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.language as |itemData id|}}
{{> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData}}
{{/each}}
</ol>
{{/ifHasItemOfType}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='language'}}
<h4 class="items-list-title">{{localize 'DS4.ItemTypeAlphabetPlural'}}</h4>
{{#> ifHasItemOfType itemsArray=itemsByType.alphabet dataType='alphabet' }}
<ol class="items-list">
{{> baseItemListHeader dataType='alphabet' }}
{{#each itemsByType.alphabet as |item id|}}
{{> baseItemListEntry item=item}}
{{!-- ALPHABET --}}
<h4 class="ds4-item-list-title">{{localize 'DS4.ItemTypeAlphabetPlural'}}</h4>
{{#unless (isEmpty itemsByType.alphabet)}}
<ol class="ds4-item-list ds4-item-list--alphabet item-list">
{{> systems/ds4/templates/actor/partials/item-list-header.hbs}}
{{#each itemsByType.alphabet as |itemData id|}}
{{> systems/ds4/templates/actor/partials/item-list-entry.hbs itemData=itemData}}
{{/each}}
</ol>
{{/ifHasItemOfType}}
{{/unless}}
{{> systems/ds4/templates/actor/partials/overview-add-button.hbs dataType='alphabet'}}
</div>