Compare commits
61 commits
main
...
feature/fo
Author | SHA1 | Date | |
---|---|---|---|
d7b8834481 | |||
bdfba8cacc | |||
f643999573 | |||
d020822012 | |||
40e14d1196 | |||
2c4dbb2620 | |||
e021fedcdf | |||
7fcdcf8a5c | |||
f807b59c9a | |||
3eaf69f558 | |||
1358bfad93 | |||
3c5e24a646 | |||
bcf43f1bd6 | |||
dfb2a4a781 | |||
9ea6bfac84 | |||
651310446d | |||
a1cda785e9 | |||
796cbd4d53 | |||
a0c77ef7b8 | |||
76d223db0f | |||
6037a8dcd4 | |||
590045405b | |||
970f69be53 | |||
07fa1487f1 | |||
686dc6b1f5 | |||
e9c223731d | |||
e30ce8947e | |||
f6ccd63e78 | |||
4479cdc4de | |||
7faadf6583 | |||
9e4dcee3c3 | |||
916dc096df | |||
97ea5e8cc4 | |||
e40c201dce | |||
792f15dc57 | |||
6e1b043e4f | |||
251cfa100b | |||
27f40b1d96 | |||
0f464f6081 | |||
c1f9db6095 | |||
3efbac9e84 | |||
372a2f718c | |||
3284b132b4 | |||
093c94961d | |||
f46a89f470 | |||
e001102278 | |||
8252a354cb | |||
aa9cbee8b4 | |||
6c72605156 | |||
76a0df49e8 | |||
c363295e0f | |||
4821eba0a9 | |||
f0c5fa07dd | |||
1b7b9f1e8e | |||
bcc263cc5e | |||
df8c94a21f | |||
9ed959337d | |||
bfbd327e51 | |||
cd44db079f | |||
2a797ed8ed | |||
c26574d2d1 |
79 changed files with 2199 additions and 1013 deletions
|
@ -8,6 +8,6 @@ root = true
|
|||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
"DS4.UserInteractionAddItemTitle": "Item Erstellen",
|
||||
"DS4.UserInteractionEditItemTitle": "Item Bearbeiten",
|
||||
"DS4.UserInteractionDeleteItemTitle": "Item Löschen",
|
||||
"DS4.UserInteractionDeleteItemContent": "Sind Sie sicher, dass Sie {item} löschen möchten?",
|
||||
"DS4.UserInteractionAddEffectTitle": "Effekt Erstellen",
|
||||
"DS4.UserInteractionEditEffectTitle": "Effekt Bearbeiten",
|
||||
"DS4.UserInteractionDeleteEffectTitle": "Effekt Löschen",
|
||||
"DS4.UserInteractionDeleteEffectContent": "Sind Sie sicher, dass Sie {effect} löschen möchten?",
|
||||
"DS4.DocumentImageAltText": "Bild von {name}",
|
||||
"DS4.RollableImageRollableTitle": "Für {name} würfeln",
|
||||
"DS4.DiceOverlayImageAltText": "Bild eines W20",
|
||||
|
@ -182,7 +184,9 @@
|
|||
"DS4.EffectFactor": "Faktor (wie oft der Effekt angewendet wird)",
|
||||
"DS4.EffectFactorAbbr": "F",
|
||||
"DS4.ActorName": "Name",
|
||||
"DS4.ActorSheet": "Aktorbogen",
|
||||
"DS4.ActorImageAltText": "Bild des Aktors",
|
||||
"DS4.ItemSheet": "Itembogen",
|
||||
"DS4.ActorTypeCharacter": "Charakter",
|
||||
"DS4.ActorTypeCreature": "Kreatur",
|
||||
"DS4.Attribute": "Attribut",
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
"DS4.UserInteractionAddItemTitle": "Create Item",
|
||||
"DS4.UserInteractionEditItemTitle": "Edit Item",
|
||||
"DS4.UserInteractionDeleteItemTitle": "Delete Item",
|
||||
"DS4.UserInteractionDeleteItemContent": "Are you sure you want to delete {item}?",
|
||||
"DS4.UserInteractionAddEffectTitle": "Create Effect",
|
||||
"DS4.UserInteractionEditEffectTitle": "Edit Effect",
|
||||
"DS4.UserInteractionDeleteEffectTitle": "Delete Effect",
|
||||
"DS4.UserInteractionDeleteEffectContent": "Are you sure you want to delete {effect}?",
|
||||
"DS4.DocumentImageAltText": "Image of {name}",
|
||||
"DS4.RollableImageRollableTitle": "Roll for {name}",
|
||||
"DS4.DiceOverlayImageAltText": "Image of a d20",
|
||||
|
@ -182,7 +184,9 @@
|
|||
"DS4.EffectFactor": "Factor (the number of times the effect is being applied)",
|
||||
"DS4.EffectFactorAbbr": "F",
|
||||
"DS4.ActorName": "Name",
|
||||
"DS4.ActorSheet": "Actor Sheet",
|
||||
"DS4.ActorImageAltText": "Image of the Actor",
|
||||
"DS4.ItemSheet": "Item Sheet",
|
||||
"DS4.ActorTypeCharacter": "Character",
|
||||
"DS4.ActorTypeCreature": "Creature",
|
||||
"DS4.Attribute": "Attribute",
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
align-items: center;
|
||||
border-bottom: 0;
|
||||
margin: 0;
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
&__name-input[type="text"] {
|
||||
|
@ -49,7 +50,10 @@
|
|||
background-color: transparent;
|
||||
border: none;
|
||||
flex: 1;
|
||||
font-size: 1.25em;
|
||||
font-size: clamp(0.75em, 8cqi, 1.25em);
|
||||
height: auto;
|
||||
|
||||
// Use lighter font weight for better readability
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,10 +29,11 @@
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
text-align: right;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
&__input {
|
||||
flex: 0 0 5ch;
|
||||
flex: 0 0 8ch;
|
||||
|
||||
&--slayer-points {
|
||||
&::-webkit-inner-spin-button,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
&__property-select {
|
||||
width: 100%;
|
||||
height: var(--form-field-height);
|
||||
height: var(--input-height);
|
||||
}
|
||||
|
||||
&__property-multi-input {
|
||||
|
|
|
@ -8,4 +8,10 @@
|
|||
display: grid;
|
||||
grid-template-columns: 1fr 3fr;
|
||||
column-gap: 1em;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ds4-biography {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
|
@ -71,3 +71,13 @@
|
|||
flex: 1 1 4em;
|
||||
}
|
||||
}
|
||||
|
||||
// Dark mode filter for combat value backgrounds when in dark theme
|
||||
.theme-dark .ds4-combat-value__value {
|
||||
filter: brightness(0) invert(1) brightness(0.8);
|
||||
|
||||
// Counter-invert the text to keep it normal
|
||||
.ds4-combat-value__text {
|
||||
filter: brightness(1.25) invert(1) brightness(0.8);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
&--trait {
|
||||
.ds4-core-value__label {
|
||||
-webkit-text-stroke: 1px colors.$c-black;
|
||||
-webkit-text-stroke: 1px light-dark(colors.$c-black, colors.$c-white);
|
||||
color: transparent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
&__name {
|
||||
border: none;
|
||||
margin: 0;
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
&__name-label {
|
||||
|
@ -43,9 +44,10 @@
|
|||
@include mixins.font-heading-upper;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
font-size: 1.25em;
|
||||
font-size: clamp(0.75em, 8cqi, 1.25em);
|
||||
height: auto;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,3 +16,38 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// General ProseMirror editor styles
|
||||
prose-mirror {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
// Edit mode with editor container
|
||||
&.active {
|
||||
.editor-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.editor-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// View mode - direct editor-content
|
||||
&.inactive {
|
||||
.editor-content {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
inset: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,3 +150,8 @@
|
|||
margin-top: 1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
// Dark mode filter for embedded document list images when in dark theme
|
||||
.theme-dark .ds4-embedded-document-list__image {
|
||||
filter: brightness(0) invert(1) brightness(0.8);
|
||||
}
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
.ds4-form-group {
|
||||
.ds4-form-group,
|
||||
.ds4-item-sheet .form-group {
|
||||
clear: both;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 3px 0;
|
||||
margin: 8px 0;
|
||||
align-items: center;
|
||||
|
||||
&--start {
|
||||
|
@ -22,6 +23,107 @@
|
|||
|
||||
&__label {
|
||||
flex: 2;
|
||||
line-height: var(--form-field-height);
|
||||
line-height: var(--input-height);
|
||||
}
|
||||
|
||||
// Add spacing between form groups
|
||||
& + & {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
// Style for slim form groups (input + select combinations)
|
||||
&.slim {
|
||||
margin: 6px 0;
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
select {
|
||||
flex: 0 0 auto;
|
||||
min-width: 120px;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
label {
|
||||
flex: 0 0 auto;
|
||||
margin-right: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Style standard Foundry form-fields containers
|
||||
.ds4-item-sheet .form-fields {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex: 1;
|
||||
|
||||
input, select, textarea {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 3px;
|
||||
padding: 4px 8px;
|
||||
color: var(--color-text-primary);
|
||||
|
||||
&:focus {
|
||||
border-color: var(--color-text-accent);
|
||||
box-shadow: 0 0 3px var(--color-text-accent);
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
appearance: none;
|
||||
background-image: url("data:image/svg+xml;charset=US-ASCII,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'><path fill='%23efe6d8' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 8px center;
|
||||
background-size: 8px;
|
||||
padding-right: 24px;
|
||||
width: auto !important;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Dark mode: try to achieve dark background for select options
|
||||
.theme-dark .ds4-item-sheet .form-fields select {
|
||||
color-scheme: dark;
|
||||
|
||||
option {
|
||||
background-color: var(--color-cool-4) !important;
|
||||
background: var(--color-cool-4) !important;
|
||||
color: var(--color-light-2) !important;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
option:checked {
|
||||
background-color: var(--color-cool-3) !important;
|
||||
background: var(--color-cool-3) !important;
|
||||
color: var(--color-light-1) !important;
|
||||
}
|
||||
|
||||
option:hover {
|
||||
background-color: var(--color-cool-3) !important;
|
||||
background: var(--color-cool-3) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Improve label styling
|
||||
.ds4-item-sheet .form-group > label {
|
||||
flex: 0 0 160px;
|
||||
font-weight: bold;
|
||||
color: var(--color-form-label);
|
||||
line-height: var(--input-height);
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
|
63
scss/components/shared/_ruler.scss
Normal file
63
scss/components/shared/_ruler.scss
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/* Token Ruler Waypoint Styling with Color-Coded Movement Ranges */
|
||||
|
||||
.system-ds4 .waypoint-label {
|
||||
font-size: 1.5em;
|
||||
|
||||
// Main icon styling for movement types
|
||||
&.move-range > i.fa-person-walking {
|
||||
color: var(--color-level-success);
|
||||
}
|
||||
|
||||
&.dash-range > i.fa-person-running {
|
||||
color: var(--color-level-warning);
|
||||
}
|
||||
|
||||
&.out-of-range > i.fa-person-rays {
|
||||
color: var(--color-level-error);
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
.distance {
|
||||
&.move-range {
|
||||
color: var(--color-level-success);
|
||||
}
|
||||
|
||||
&.dash-range {
|
||||
color: var(--color-level-warning);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&.out-of-range {
|
||||
color: var(--color-level-error);
|
||||
font-weight: bold;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
}
|
||||
|
||||
.delta {
|
||||
opacity: 0.8;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.elevation {
|
||||
font-style: italic;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
/* Icon animations */
|
||||
@keyframes pulse {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,14 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
.ds4-sheet-body {
|
||||
.ds4-sheet-body,
|
||||
.sheet-body {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
// Prevent double scrollbars on biography tab
|
||||
.ds4-sheet-tab.tab.biography.active,
|
||||
.tab[data-tab="biography"].active {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
.ds4-sheet-tab {
|
||||
.ds4-sheet-tab,
|
||||
.tab {
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
height: 100%;
|
||||
|
|
|
@ -6,20 +6,31 @@
|
|||
|
||||
@use "../../utils/variables";
|
||||
|
||||
.ds4-sheet-tab-nav {
|
||||
.ds4-sheet-tab-nav,
|
||||
nav.tabs {
|
||||
border-bottom: variables.$border-groove;
|
||||
border-top: variables.$border-groove;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
height: calc(2 * var(--line-height-16));
|
||||
height: calc(2.5 * var(--line-height-16));
|
||||
justify-content: space-around;
|
||||
line-height: calc(2 * var(--line-height-16));
|
||||
margin: variables.$margin-sm 0;
|
||||
|
||||
&__item {
|
||||
.ds4-sheet-tab-nav__item,
|
||||
.item {
|
||||
flex: 0 1 auto !important; // necessary to override the styling from lang-de, see https://gitlab.com/henry4k/foundryvtt-lang-de/-/issues/9
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.25rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
line-height: 1;
|
||||
|
||||
i {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
&.active {
|
||||
text-shadow: 0 0 variables.$padding-md var(--color-shadow-primary);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
@import "components/shared/embedded_document_list";
|
||||
@import "components/shared/form_group";
|
||||
@import "components/shared/rollable_image";
|
||||
@import "components/shared/ruler";
|
||||
@import "components/shared/sheet_body";
|
||||
@import "components/shared/sheet_form";
|
||||
@import "components/shared/sheet_tab_nav";
|
||||
|
|
|
@ -58,3 +58,27 @@
|
|||
--ds4-font-primary: Lora, serif;
|
||||
--ds4-font-heading: "Wood Stamp", sans-serif;
|
||||
}
|
||||
|
||||
// Apply Wood Stamp font only to DS4 sheet-specific elements (excluding window titles)
|
||||
.ds4-actor-sheet h2,
|
||||
.ds4-actor-sheet h4,
|
||||
.ds4-actor-sheet h5,
|
||||
.ds4-actor-sheet h6,
|
||||
.ds4-item-sheet h2,
|
||||
.ds4-item-sheet h4,
|
||||
.ds4-item-sheet h5,
|
||||
.ds4-item-sheet h6,
|
||||
.ds4-currency-title,
|
||||
.ds4-embedded-document-list-title {
|
||||
font-family: var(--ds4-font-heading) !important;
|
||||
text-transform: uppercase;
|
||||
font-weight: 100 !important;
|
||||
}
|
||||
|
||||
// Keep window titles readable with standard font
|
||||
.ds4-actor-sheet .window-title,
|
||||
.ds4-item-sheet .window-title {
|
||||
font-family: var(--font-sans) !important;
|
||||
text-transform: none !important;
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
|
|
@ -2,31 +2,55 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
export class DS4ActiveEffectConfig extends ActiveEffectConfig {
|
||||
/**
|
||||
* DS4 Active Effect Configuration Sheet
|
||||
*/
|
||||
export class DS4ActiveEffectConfig extends foundry.applications.sheets.ActiveEffectConfig {
|
||||
static DEFAULT_OPTIONS = {
|
||||
...super.DEFAULT_OPTIONS,
|
||||
classes: ["sheet", "ds4-active-effect-config", "themed"],
|
||||
};
|
||||
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
template: "systems/ds4/templates/sheets/active-effect/active-effect-config.hbs",
|
||||
});
|
||||
get template() {
|
||||
return "systems/ds4/templates/sheets/active-effect/active-effect-config.hbs";
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {JQuery} html
|
||||
*/
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
const checkbox = html[0]?.querySelector('input[name="flags.ds4.itemEffectConfig.applyToItems"]');
|
||||
checkbox?.addEventListener("change", () => this.#toggleItemEffectConfig(checkbox.checked));
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
|
||||
// Add DS4-specific context
|
||||
context.itemEffectConfig = this.document.flags?.ds4?.itemEffectConfig || {};
|
||||
context.applyToItems = context.itemEffectConfig.applyToItems || false;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
|
||||
// Set up initial visibility of item effect config section
|
||||
const applyToItems = this.document.flags?.ds4?.itemEffectConfig?.applyToItems || false;
|
||||
this._toggleItemEffectConfigVisibility(applyToItems);
|
||||
|
||||
// Add event listener for the checkbox
|
||||
const checkbox = this.element.querySelector('input[name="flags.ds4.itemEffectConfig.applyToItems"]');
|
||||
if (checkbox) {
|
||||
checkbox.addEventListener("change", (event) => {
|
||||
this._toggleItemEffectConfigVisibility(event.target.checked);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the visibility of the item effect config section
|
||||
* @param {boolean} active The target state
|
||||
* @param {boolean} active - The target state
|
||||
*/
|
||||
#toggleItemEffectConfig(active) {
|
||||
const elements = this.element[0]?.querySelectorAll(".ds4-item-effect-config");
|
||||
elements?.forEach((element) => {
|
||||
_toggleItemEffectConfigVisibility(active) {
|
||||
const elements = this.element.querySelectorAll(".ds4-item-effect-config");
|
||||
elements.forEach((element) => {
|
||||
if (active) {
|
||||
element.classList.remove("ds4-hidden");
|
||||
} else {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,25 +1,34 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActorSheet } from "./base-sheet";
|
||||
import { DS4ActorSheet } from "./base-sheet.js";
|
||||
|
||||
/**
|
||||
* The Sheet class for DS4 Character Actors
|
||||
*/
|
||||
export class DS4CharacterActorSheet extends DS4ActorSheet {
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["sheet", "ds4-actor-sheet", "ds4-character-sheet"],
|
||||
});
|
||||
}
|
||||
static DEFAULT_OPTIONS = {
|
||||
...super.DEFAULT_OPTIONS,
|
||||
classes: ["sheet", "ds4-actor-sheet", "ds4-character-sheet", "themed"],
|
||||
};
|
||||
|
||||
/** @override */
|
||||
async getData(options = {}) {
|
||||
const context = await super.getData(options);
|
||||
context.data.system.profile.biography = await TextEditor.enrichHTML(context.data.system.profile.biography, {
|
||||
async: true,
|
||||
});
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
|
||||
// Enrich biography HTML content
|
||||
if (context.data.system.profile.biography) {
|
||||
context.data.system.profile.biography = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
context.data.system.profile.biography,
|
||||
{
|
||||
async: true,
|
||||
relativeTo: this.document,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,51 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActorSheet } from "./base-sheet";
|
||||
import { DS4ActorSheet } from "./base-sheet.js";
|
||||
|
||||
/**
|
||||
* The Sheet class for DS4 Creature Actors
|
||||
*/
|
||||
export class DS4CreatureActorSheet extends DS4ActorSheet {
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["sheet", "ds4-actor-sheet", "ds4-creature-sheet"],
|
||||
});
|
||||
}
|
||||
static DEFAULT_OPTIONS = {
|
||||
...super.DEFAULT_OPTIONS,
|
||||
classes: ["sheet", "ds4-actor-sheet", "ds4-creature-sheet", "themed"],
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
primary: {
|
||||
initial: "values",
|
||||
tabs: [
|
||||
{ id: "values", label: "DS4.HeadingValues", icon: "fas fa-chart-bar" },
|
||||
{ id: "inventory", label: "DS4.HeadingInventory", icon: "fas fa-backpack" },
|
||||
{ id: "spells", label: "DS4.HeadingSpells", icon: "fas fa-magic" },
|
||||
{ id: "abilities", label: "DS4.HeadingAbilities", icon: "fas fa-fist-raised" },
|
||||
{ id: "effects", label: "DS4.HeadingEffects", icon: "fas fa-sparkles" },
|
||||
{ id: "description", label: "DS4.HeadingDescription", icon: "fas fa-file-text" }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
/** @override */
|
||||
async getData(options = {}) {
|
||||
const context = await super.getData(options);
|
||||
context.data.system.baseInfo.description = await TextEditor.enrichHTML(context.data.system.baseInfo.description, {
|
||||
async: true,
|
||||
});
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
|
||||
// Enrich description HTML content
|
||||
if (context.data.system.baseInfo.description) {
|
||||
context.data.system.baseInfo.description = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
context.data.system.baseInfo.description,
|
||||
{
|
||||
async: true,
|
||||
relativeTo: this.document,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Add tabs configuration using ApplicationTab typedef
|
||||
context.tabs = this._prepareTabs("primary");
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,19 +3,129 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/**
|
||||
* @typedef {DialogOptions} DialogWithListenersOptions
|
||||
* @property {(html: JQuery, app: DialogWithListeners) => void} [activateAdditionalListeners] An optional function to attach additional listeners to the dialog
|
||||
* A simple extension to the DialogV2 class that allows attaching additional listeners.
|
||||
*/
|
||||
export class DialogWithListeners extends foundry.applications.api.DialogV2 {
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
this.activateAdditionalListeners = options.activateAdditionalListeners;
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
...super.DEFAULT_OPTIONS,
|
||||
classes: ["dialog", "dialog-with-listeners"],
|
||||
tag: "dialog",
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple extension to the {@link Dialog} class that allows attaching additional listeners.
|
||||
*/
|
||||
export class DialogWithListeners extends Dialog {
|
||||
/** @override */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
if (this.options.activateAdditionalListeners !== undefined) {
|
||||
this.options.activateAdditionalListeners(html, this);
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
|
||||
// Attach additional listeners if provided
|
||||
if (this.activateAdditionalListeners && typeof this.activateAdditionalListeners === "function") {
|
||||
this.activateAdditionalListeners(this.element, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a confirmation dialog using the V2 framework with additional listeners support
|
||||
* @param {object} options - Dialog options
|
||||
* @param {string} options.title - Dialog title (deprecated, use window.title)
|
||||
* @param {object} options.window - Window configuration
|
||||
* @param {string} options.window.title - Dialog title
|
||||
* @param {string} options.content - Dialog content HTML
|
||||
* @param {boolean} options.defaultYes - Whether "Yes" is the default button
|
||||
* @param {Function} options.activateAdditionalListeners - Function to attach additional listeners
|
||||
* @returns {Promise<boolean>} True if confirmed, false if cancelled
|
||||
*/
|
||||
static async confirm(options = {}) {
|
||||
const { title, window = {}, content, defaultYes = true, activateAdditionalListeners, ...rest } = options;
|
||||
|
||||
// Handle backward compatibility with title parameter
|
||||
if (title && !window.title) {
|
||||
window.title = title;
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const dialog = new DialogWithListeners({
|
||||
window: {
|
||||
title: window.title || "Confirm",
|
||||
...window,
|
||||
},
|
||||
content,
|
||||
activateAdditionalListeners,
|
||||
buttons: [
|
||||
{
|
||||
action: "yes",
|
||||
label: game.i18n.localize("Yes"),
|
||||
icon: "fas fa-check",
|
||||
default: defaultYes,
|
||||
callback: () => resolve(true),
|
||||
},
|
||||
{
|
||||
action: "no",
|
||||
label: game.i18n.localize("No"),
|
||||
icon: "fas fa-times",
|
||||
default: !defaultYes,
|
||||
callback: () => resolve(false),
|
||||
},
|
||||
],
|
||||
close: () => resolve(false),
|
||||
...rest,
|
||||
});
|
||||
|
||||
dialog.render(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a prompt dialog using the V2 framework with additional listeners support
|
||||
* @param {object} options - Dialog options
|
||||
* @param {string} options.title - Dialog title (deprecated, use window.title)
|
||||
* @param {object} options.window - Window configuration
|
||||
* @param {string} options.window.title - Dialog title
|
||||
* @param {string} options.content - Dialog content HTML
|
||||
* @param {object} options.buttons - Button configuration
|
||||
* @param {Function} options.activateAdditionalListeners - Function to attach additional listeners
|
||||
* @returns {Promise} Promise that resolves with the result
|
||||
*/
|
||||
static async prompt(options = {}) {
|
||||
const { title, window = {}, content, buttons = {}, activateAdditionalListeners, ...rest } = options;
|
||||
|
||||
// Handle backward compatibility with title parameter
|
||||
if (title && !window.title) {
|
||||
window.title = title;
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
// Convert V1 button format to V2 format
|
||||
const v2Buttons = Object.entries(buttons).map(([key, button]) => ({
|
||||
action: key,
|
||||
label: button.label || key,
|
||||
icon: button.icon || "",
|
||||
default: button.default || false,
|
||||
callback: (event) => {
|
||||
const result = button.callback ? button.callback(event) : key;
|
||||
resolve(result);
|
||||
},
|
||||
}));
|
||||
|
||||
const dialog = new DialogWithListeners({
|
||||
window: {
|
||||
title: window.title || "Dialog",
|
||||
...window,
|
||||
},
|
||||
content,
|
||||
activateAdditionalListeners,
|
||||
buttons: v2Buttons,
|
||||
close: () => resolve(null),
|
||||
...rest,
|
||||
});
|
||||
|
||||
dialog.render(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,63 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2021 Oliver Rümpelein
|
||||
// SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
||||
// SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../config";
|
||||
import { DS4ActiveEffect } from "../documents/active-effect";
|
||||
import { enforce, getGame } from "../utils/utils";
|
||||
import { disableOverriddenFields } from "./sheet-helpers";
|
||||
|
||||
/**
|
||||
* The Sheet class for DS4 Items
|
||||
*/
|
||||
export class DS4ItemSheet extends ItemSheet {
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["sheet", "ds4-item-sheet"],
|
||||
export class DS4ItemSheet extends foundry.applications.api.HandlebarsApplicationMixin(
|
||||
foundry.applications.sheets.ItemSheetV2,
|
||||
) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["sheet", "ds4-item-sheet", "themed"],
|
||||
tag: "form",
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
},
|
||||
position: {
|
||||
width: 560,
|
||||
height: 400,
|
||||
scrollY: [".ds4-sheet-body"],
|
||||
tabs: [{ navSelector: ".ds4-sheet-tab-nav", contentSelector: ".ds4-sheet-body", initial: "description" }],
|
||||
width: 540,
|
||||
});
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
actions: {
|
||||
controlEffect: DS4ItemSheet.prototype._onControlEffect,
|
||||
createEffect: DS4ItemSheet.prototype._onCreateEffect,
|
||||
editEffect: DS4ItemSheet.prototype._onEditEffect,
|
||||
deleteEffect: DS4ItemSheet.prototype._onDeleteEffect,
|
||||
editImage: DS4ItemSheet.prototype._onEditImage,
|
||||
},
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
primary: {
|
||||
initial: "description",
|
||||
tabs: [
|
||||
{ id: "description", label: "DS4.HeadingDescription", icon: "fas fa-book" },
|
||||
{ id: "effects", label: "DS4.HeadingEffects", icon: "fas fa-sparkles" }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
// Initialize tabGroups with default values
|
||||
if (!this.tabGroups) {
|
||||
this.tabGroups = {};
|
||||
}
|
||||
// Set default tab for primary group
|
||||
if (!this.tabGroups.primary) {
|
||||
this.tabGroups.primary = this.constructor.TABS.primary?.initial || "description";
|
||||
}
|
||||
}
|
||||
|
||||
get title() {
|
||||
return `${this.item.name} [${game.i18n.localize("DS4.ItemSheet")}]`;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
|
@ -31,120 +67,358 @@ export class DS4ItemSheet extends ItemSheet {
|
|||
}
|
||||
|
||||
/** @override */
|
||||
async getData(options = {}) {
|
||||
const superContext = await super.getData(options);
|
||||
superContext.data.system.description = await TextEditor.enrichHTML(superContext.data.system.description, {
|
||||
async: true,
|
||||
});
|
||||
const context = {
|
||||
...superContext,
|
||||
config: DS4,
|
||||
isOwned: this.item.isOwned,
|
||||
actor: this.item.actor,
|
||||
};
|
||||
async _renderHTML(context) {
|
||||
return await foundry.applications.handlebars.renderTemplate(this.template, context);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
_replaceHTML(result, content) {
|
||||
content.innerHTML = result;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
|
||||
// Validate document exists
|
||||
if (!this.item) {
|
||||
throw new Error("Item not available for sheet rendering");
|
||||
}
|
||||
|
||||
// Add document data
|
||||
context.data = this.item;
|
||||
context.system = this.item.system;
|
||||
context.source = this.item.toObject();
|
||||
context.cssClass = this.item.constructor.name.toLowerCase();
|
||||
context.editable = this.isEditable;
|
||||
context.owner = this.item.isOwner;
|
||||
context.isOwned = this.item.isOwned;
|
||||
context.actor = this.actor;
|
||||
|
||||
// Add configuration
|
||||
context.config = CONFIG.DS4;
|
||||
|
||||
// Add tabs configuration using ApplicationTab typedef
|
||||
context.tabs = this._prepareTabs("primary");
|
||||
|
||||
// Add enriched effects
|
||||
context.enrichedEffects = [];
|
||||
if (this.item.effects && this.item.effects.size > 0) {
|
||||
for (const effect of this.item.effects) {
|
||||
const enrichedEffect = effect.toObject();
|
||||
enrichedEffect.id = effect.id;
|
||||
enrichedEffect.uuid = effect.uuid;
|
||||
enrichedEffect.sourceName = effect.sourceName;
|
||||
context.enrichedEffects.push(enrichedEffect);
|
||||
}
|
||||
}
|
||||
|
||||
// Enrich description content for display
|
||||
if (this.item.system.description) {
|
||||
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
this.item.system.description,
|
||||
{
|
||||
secrets: this.item.isOwner,
|
||||
relativeTo: this.item,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
context.enrichedDescription = "";
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
_getSubmitData(updateData = {}) {
|
||||
const data = super._getSubmitData(updateData);
|
||||
/**
|
||||
* Process form data for submission
|
||||
* @param {Event} event - The form submission event
|
||||
* @param {HTMLFormElement} form - The form element
|
||||
* @param {FormDataExtended} formData - The form data
|
||||
* @returns {object} The processed form data
|
||||
*/
|
||||
_processFormData(event, form, formData) {
|
||||
const submitData = foundry.utils.expandObject(formData.object);
|
||||
|
||||
// Prevent submitting overridden values
|
||||
const overrides = foundry.utils.flattenObject(this.item.overrides);
|
||||
for (const k of Object.keys(overrides)) {
|
||||
delete data[k];
|
||||
foundry.utils.setProperty(submitData, k, undefined);
|
||||
delete submitData[k];
|
||||
}
|
||||
return data;
|
||||
|
||||
return submitData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle effect control actions
|
||||
* @param {Event} event - The triggering event
|
||||
* @param {HTMLElement} target - The target element
|
||||
*/
|
||||
async _onControlEffect(event, target) {
|
||||
const action = target.dataset.action;
|
||||
const effectId = target.closest("[data-effect-id]")?.dataset.effectId;
|
||||
|
||||
if (!effectId) return;
|
||||
|
||||
const effect = this.item.effects.get(effectId);
|
||||
if (!effect) return;
|
||||
|
||||
switch (action) {
|
||||
case "edit":
|
||||
await this._onEditEffect(event, target);
|
||||
break;
|
||||
case "delete":
|
||||
await this._onDeleteEffect(event, target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle creating a new effect
|
||||
*/
|
||||
async _onCreateEffect() {
|
||||
const effectData = {
|
||||
name: game.i18n.localize("DS4.NewEffectName"),
|
||||
icon: "icons/svg/aura.svg",
|
||||
};
|
||||
|
||||
await this.item.createEmbeddedDocuments("ActiveEffect", [effectData]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle editing an effect
|
||||
* @param {Event} event - The triggering event
|
||||
* @param {HTMLElement} target - The target element
|
||||
*/
|
||||
async _onEditEffect(event, target) {
|
||||
const effectId = target.closest("[data-effect-id]")?.dataset.effectId;
|
||||
if (!effectId) return;
|
||||
|
||||
const effect = this.item.effects.get(effectId);
|
||||
if (!effect) {
|
||||
throw new Error(
|
||||
game.i18n.format("DS4.ErrorItemDoesNotHaveEffect", {
|
||||
id: effectId,
|
||||
item: this.item.name,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
await effect.sheet.render(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle deleting an effect
|
||||
* @param {Event} event - The triggering event
|
||||
* @param {HTMLElement} target - The target element
|
||||
*/
|
||||
async _onDeleteEffect(event, target) {
|
||||
const effectId = target.closest("[data-effect-id]")?.dataset.effectId;
|
||||
if (!effectId) return;
|
||||
|
||||
const effect = this.item.effects.get(effectId);
|
||||
if (!effect) return;
|
||||
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: { title: game.i18n.localize("DS4.UserInteractionDeleteEffectTitle") },
|
||||
content: game.i18n.format("DS4.UserInteractionDeleteEffectContent", { effect: effect.name }),
|
||||
defaultYes: false,
|
||||
});
|
||||
|
||||
if (confirmed) {
|
||||
await effect.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handle editing the items's image
|
||||
* @param {Event} event - The triggering event
|
||||
* @param {HTMLElement} target - The target element
|
||||
*/
|
||||
async _onEditImage(event, target) {
|
||||
const field = target.dataset.field || "img";
|
||||
const current = foundry.utils.getProperty(this.item, field);
|
||||
|
||||
const fp = new foundry.applications.apps.FilePicker({
|
||||
type: "image",
|
||||
current: current,
|
||||
callback: (path) => this.item.update({ [field]: path }),
|
||||
});
|
||||
return fp.browse();
|
||||
}
|
||||
|
||||
/** @override */
|
||||
setPosition(options = {}) {
|
||||
const position = super.setPosition(options);
|
||||
if (position) {
|
||||
const sheetBody = this.element.find(".sheet-body");
|
||||
const bodyHeight = position.height - 192;
|
||||
sheetBody.css("height", bodyHeight);
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
this._initializeTabHandlers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize tab event handlers manually since ApplicationV2 doesn't do this automatically
|
||||
*/
|
||||
_initializeTabHandlers() {
|
||||
const tabNavigation = this.element.querySelector('.tabs[data-group="primary"]');
|
||||
if (!tabNavigation) {
|
||||
return;
|
||||
}
|
||||
|
||||
return position;
|
||||
// Remove existing event listeners to prevent memory leaks
|
||||
this._removeTabHandlers();
|
||||
|
||||
// Store tab navigation reference for cleanup
|
||||
this._tabNavigation = tabNavigation;
|
||||
|
||||
// Create bound handler function for later removal
|
||||
this._tabClickHandler = (event) => {
|
||||
event.preventDefault();
|
||||
const item = event.target.closest('.item[data-tab]');
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tabId = item.dataset.tab;
|
||||
const groupId = item.dataset.group;
|
||||
if (tabId && groupId) {
|
||||
this.changeTab(tabId, groupId);
|
||||
}
|
||||
};
|
||||
|
||||
// Add single delegated event listener to the navigation container
|
||||
tabNavigation.addEventListener('click', this._tabClickHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {JQuery} html
|
||||
* Override form submission to prevent re-rendering
|
||||
*/
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
if (!this.options.editable) return;
|
||||
|
||||
html.find(".control-effect").on("click", this.onControlEffect.bind(this));
|
||||
|
||||
disableOverriddenFields(this.form, this.item.overrides, (key) => `[name="${key}"]`);
|
||||
async _processSubmitData(event, form, submitData, options = {}) {
|
||||
// Always prevent re-rendering on form updates
|
||||
options.render = false;
|
||||
return super._processSubmitData(event, form, submitData, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a click on an element of this sheet to control an embedded effect of the item corresponding to this
|
||||
* sheet.
|
||||
*
|
||||
* @param {JQuery.ClickEvent} event The originating click event
|
||||
* @protected
|
||||
* Remove tab event handlers to prevent memory leaks
|
||||
*/
|
||||
onControlEffect(event) {
|
||||
event.preventDefault();
|
||||
const a = event.currentTarget;
|
||||
switch (a.dataset["action"]) {
|
||||
case "create":
|
||||
return this.onCreateEffect();
|
||||
case "edit":
|
||||
return this.onEditEffect(event);
|
||||
case "delete":
|
||||
return this.onDeleteEffect(event);
|
||||
_removeTabHandlers() {
|
||||
if (this._tabNavigation && this._tabClickHandler) {
|
||||
this._tabNavigation.removeEventListener('click', this._tabClickHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new embedded effect.
|
||||
* @protected
|
||||
* Override changeTab to ensure proper tab switching without forced re-render
|
||||
*/
|
||||
onCreateEffect() {
|
||||
DS4ActiveEffect.createDefault(this.item);
|
||||
changeTab(tab, group, options = {}) {
|
||||
// Call parent changeTab method
|
||||
const result = super.changeTab(tab, group, options);
|
||||
|
||||
// Update tab display without full re-render
|
||||
this._updateTabDisplay(tab, group);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the sheet of the embedded effect corresponding to the clicked element.
|
||||
*
|
||||
* @param {JQuery.ClickEvent} event The originating click event
|
||||
* @porotected
|
||||
* Update tab display without full re-render for better performance
|
||||
*/
|
||||
onEditEffect(event) {
|
||||
const id = $(event.currentTarget)
|
||||
.parents(embeddedDocumentListEntryProperties.ActiveEffect.selector)
|
||||
.data(embeddedDocumentListEntryProperties.ActiveEffect.idDataAttribute);
|
||||
const effect = this.item.effects.get(id);
|
||||
enforce(effect, getGame().i18n.format("DS4.ErrorItemDoesNotHaveEffect", { id, item: this.item.name }));
|
||||
effect.sheet?.render(true);
|
||||
_updateTabDisplay(activeTab, group) {
|
||||
const tabNavigation = this.element.querySelector(`.tabs[data-group="${group}"]`);
|
||||
const tabContent = this.element.querySelector('.sheet-body');
|
||||
|
||||
if (!tabNavigation || !tabContent) return;
|
||||
|
||||
// Update navigation active states
|
||||
const navItems = tabNavigation.querySelectorAll('.item[data-tab]');
|
||||
navItems.forEach(item => {
|
||||
if (item.dataset.tab === activeTab) {
|
||||
item.classList.add('active');
|
||||
} else {
|
||||
item.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Update content tab visibility
|
||||
const contentTabs = tabContent.querySelectorAll('.tab[data-tab]');
|
||||
contentTabs.forEach(tab => {
|
||||
if (tab.dataset.tab === activeTab) {
|
||||
tab.classList.add('active');
|
||||
} else {
|
||||
tab.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the embedded item corresponding to the clicked element.
|
||||
*
|
||||
* @param {JQuery.ClickEvent} event The originating click event
|
||||
* @protected
|
||||
* Override _onClose to cleanup event listeners
|
||||
*/
|
||||
onDeleteEffect(event) {
|
||||
const li = $(event.currentTarget).parents(embeddedDocumentListEntryProperties.ActiveEffect.selector);
|
||||
const id = li.data(embeddedDocumentListEntryProperties.ActiveEffect.idDataAttribute);
|
||||
this.item.deleteEmbeddedDocuments("ActiveEffect", [id]);
|
||||
li.slideUp(200, () => this.render(false));
|
||||
async _onClose(options) {
|
||||
this._removeTabHandlers();
|
||||
return super._onClose(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare tabs for a given group using ApplicationTab typedef
|
||||
* @param {string} group - The tab group identifier
|
||||
* @returns {Record<string, ApplicationTab>} Prepared tab data
|
||||
*/
|
||||
_prepareTabs(group) {
|
||||
const config = this._getTabsConfigForItemType();
|
||||
if (!config) return {};
|
||||
|
||||
// Ensure tabGroups is initialized
|
||||
if (!this.tabGroups[group]) {
|
||||
this.tabGroups[group] = config.initial || "description";
|
||||
}
|
||||
|
||||
const tabs = {};
|
||||
for (const tabConfig of config.tabs) {
|
||||
const isActive = this.tabGroups[group] === tabConfig.id;
|
||||
tabs[tabConfig.id] = {
|
||||
id: tabConfig.id,
|
||||
group: group,
|
||||
icon: tabConfig.icon,
|
||||
label: game.i18n.localize(tabConfig.label),
|
||||
active: isActive,
|
||||
cssClass: isActive ? "active" : ""
|
||||
};
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tab configuration based on item type
|
||||
* @returns {Object} Tab configuration for this item type
|
||||
*/
|
||||
_getTabsConfigForItemType() {
|
||||
const tabs = [
|
||||
{ id: "description", label: "DS4.HeadingDescription", icon: "fas fa-book" }
|
||||
];
|
||||
|
||||
// Item types that have properties tabs
|
||||
const itemsWithProperties = [
|
||||
"weapon", "armor", "shield", "equipment", "loot",
|
||||
"spell", "talent", "specialCreatureAbility"
|
||||
];
|
||||
|
||||
if (itemsWithProperties.includes(this.item.type)) {
|
||||
tabs.push({
|
||||
id: "properties",
|
||||
label: "DS4.HeadingProperties",
|
||||
icon: "fas fa-cogs"
|
||||
});
|
||||
}
|
||||
|
||||
// All items can have effects
|
||||
tabs.push({
|
||||
id: "effects",
|
||||
label: "DS4.HeadingEffects",
|
||||
icon: "fas fa-sparkles"
|
||||
});
|
||||
|
||||
return { tabs, initial: "description" };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This object contains information about specific properties embedded document list entries for each different type.
|
||||
*/
|
||||
const embeddedDocumentListEntryProperties = Object.freeze({
|
||||
ActiveEffect: {
|
||||
selector: ".effect",
|
||||
idDataAttribute: "effectId",
|
||||
},
|
||||
});
|
||||
|
|
44
src/apps/ruler/token-ruler.js
Normal file
44
src/apps/ruler/token-ruler.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
// SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/**
|
||||
* DS4 Token Ruler implementation with color-coded movement ranges
|
||||
* Based on actor movement combat value
|
||||
*/
|
||||
export class DS4TokenRuler extends foundry.canvas.placeables.tokens.TokenRuler {
|
||||
static WAYPOINT_LABEL_TEMPLATE = "systems/ds4/templates/partials/waypoint-label.hbs";
|
||||
|
||||
/**
|
||||
* Enhance waypoint label context with movement range information
|
||||
* @param {object} waypoint - The waypoint data
|
||||
* @param {object} state - The current ruler state
|
||||
* @returns {object} Enhanced context with range class
|
||||
*/
|
||||
_getWaypointLabelContext(waypoint, state) {
|
||||
const context = super._getWaypointLabelContext(waypoint, state);
|
||||
|
||||
// Only apply movement coloring for distance measurements in meters
|
||||
if (context?.cost?.units === "m" || context?.distance?.units === "m") {
|
||||
const movement = this.token?.actor?.system?.combatValues?.movement?.total;
|
||||
|
||||
if (movement) {
|
||||
const total = Number(context.cost?.total || context.distance?.total || 0);
|
||||
|
||||
// DS4 movement rules:
|
||||
// - Normal movement: up to movement value
|
||||
// - Dash: up to 2x movement value (requires action)
|
||||
// - Beyond 2x: impossible in single turn
|
||||
if (total > 2 * movement) {
|
||||
context.rangeClass = "out-of-range";
|
||||
} else if (total <= movement) {
|
||||
context.rangeClass = "move-range";
|
||||
} else {
|
||||
context.rangeClass = "dash-range";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
|
@ -111,6 +111,11 @@ export async function createCheckRoll(checkTargetNumber, options = {}) {
|
|||
// Ask for additional required data;
|
||||
const interactiveRollData = await askForInteractiveRollData(checkTargetNumber, options);
|
||||
|
||||
// Handle cancelled dialog
|
||||
if (!interactiveRollData) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const newTargetValue = interactiveRollData.checkTargetNumber ?? checkTargetNumber;
|
||||
const checkModifier = interactiveRollData.checkModifier ?? 0;
|
||||
/** @type {Partial<DS4CheckFactoryOptions>} */
|
||||
|
@ -166,63 +171,69 @@ async function askForInteractiveRollData(checkTargetNumber, options = {}, { temp
|
|||
}),
|
||||
id,
|
||||
};
|
||||
const renderedHtml = await renderTemplate(usedTemplate, templateData);
|
||||
const renderedHtml = await foundry.applications.handlebars.renderTemplate(usedTemplate, templateData);
|
||||
|
||||
const dialogPromise = new Promise((resolve) => {
|
||||
new DialogWithListeners(
|
||||
{
|
||||
new DialogWithListeners({
|
||||
window: {
|
||||
title: usedTitle,
|
||||
content: renderedHtml,
|
||||
buttons: {
|
||||
ok: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
callback: (html) => {
|
||||
if (!("jquery" in html)) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedHtmlType", {
|
||||
exType: "JQuery",
|
||||
realType: "HTMLElement",
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
const innerForm = html[0]?.querySelector("form");
|
||||
if (!innerForm) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorCouldNotFindHtmlElement", {
|
||||
htmlElement: "form",
|
||||
}),
|
||||
);
|
||||
}
|
||||
resolve(innerForm);
|
||||
}
|
||||
},
|
||||
},
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: getGame().i18n.localize("DS4.GenericCancelButton"),
|
||||
},
|
||||
content: renderedHtml,
|
||||
buttons: [
|
||||
{
|
||||
action: "ok",
|
||||
icon: "fas fa-check",
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
default: true,
|
||||
callback: (event) => {
|
||||
const dialog = event.target.closest("dialog");
|
||||
const innerForm = dialog?.querySelector("form");
|
||||
if (!innerForm) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorCouldNotFindHtmlElement", {
|
||||
htmlElement: "form",
|
||||
}),
|
||||
);
|
||||
}
|
||||
resolve(innerForm);
|
||||
},
|
||||
},
|
||||
default: "ok",
|
||||
},
|
||||
{
|
||||
activateAdditionalListeners: (html, app) => {
|
||||
const checkModifierCustomFormGroup = html.find(`#check-modifier-custom-${id}`).parent(".form-group");
|
||||
html.find(`#check-modifier-${id}`).on("change", (event) => {
|
||||
if (event.currentTarget.value === "custom" && checkModifierCustomFormGroup.hasClass("ds4-hidden")) {
|
||||
checkModifierCustomFormGroup.removeClass("ds4-hidden");
|
||||
{
|
||||
action: "cancel",
|
||||
icon: "fas fa-times",
|
||||
label: getGame().i18n.localize("DS4.GenericCancelButton"),
|
||||
callback: () => resolve(null),
|
||||
},
|
||||
],
|
||||
close: () => resolve(null),
|
||||
activateAdditionalListeners: (html, app) => {
|
||||
const checkModifierCustomFormGroup = html.querySelector(`#check-modifier-custom-${id}`)?.closest(".form-group");
|
||||
const checkModifierSelect = html.querySelector(`#check-modifier-${id}`);
|
||||
|
||||
if (checkModifierSelect) {
|
||||
checkModifierSelect.addEventListener("change", (event) => {
|
||||
if (
|
||||
event.currentTarget.value === "custom" &&
|
||||
checkModifierCustomFormGroup?.classList.contains("ds4-hidden")
|
||||
) {
|
||||
checkModifierCustomFormGroup.classList.remove("ds4-hidden");
|
||||
app.setPosition({ height: "auto" });
|
||||
} else if (!checkModifierCustomFormGroup.hasClass("ds4-hidden")) {
|
||||
checkModifierCustomFormGroup.addClass("ds4-hidden");
|
||||
} else if (checkModifierCustomFormGroup && !checkModifierCustomFormGroup.classList.contains("ds4-hidden")) {
|
||||
checkModifierCustomFormGroup.classList.add("ds4-hidden");
|
||||
app.setPosition({ height: "auto" });
|
||||
}
|
||||
});
|
||||
},
|
||||
id,
|
||||
}
|
||||
},
|
||||
).render(true);
|
||||
}).render(true);
|
||||
});
|
||||
const dialogForm = await dialogPromise;
|
||||
|
||||
// Handle cancelled dialog
|
||||
if (!dialogForm) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parseDialogFormData(dialogForm);
|
||||
}
|
||||
|
||||
|
@ -232,6 +243,11 @@ async function askForInteractiveRollData(checkTargetNumber, options = {}, { temp
|
|||
* @returns {Partial<IntermediateInteractiveRollData>}
|
||||
*/
|
||||
function parseDialogFormData(formData) {
|
||||
// Handle cancelled dialog
|
||||
if (!formData) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const chosenCheckTargetNumber = parseInt(formData["check-target-number"]?.value);
|
||||
const chosenCheckModifier = formData["check-modifier"]?.value;
|
||||
|
||||
|
|
|
@ -29,6 +29,6 @@ export class DS4Roll extends Roll {
|
|||
isCoup: isPrivate ? null : isCoup,
|
||||
isFumble: isPrivate ? null : isFumble,
|
||||
};
|
||||
return renderTemplate(template, chatData);
|
||||
return foundry.applications.handlebars.renderTemplate(template, chatData);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2021 Oliver RÜmpelein
|
||||
// SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
|
@ -463,60 +464,65 @@ export class DS4Actor extends Actor {
|
|||
async selectAttributeAndTrait() {
|
||||
const attributeIdentifier = "attribute-trait-selection-attribute";
|
||||
const traitIdentifier = "attribute-trait-selection-trait";
|
||||
return Dialog.prompt({
|
||||
title: getGame().i18n.localize("DS4.DialogAttributeTraitSelection"),
|
||||
content: await renderTemplate("systems/ds4/templates/dialogs/simple-select-form.hbs", {
|
||||
selects: [
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.Attribute"),
|
||||
identifier: attributeIdentifier,
|
||||
options: Object.fromEntries(
|
||||
Object.entries(DS4.i18n.attributes).map(([attribute, translation]) => [
|
||||
attribute,
|
||||
`${translation} (${this.system.attributes[attribute].total})`,
|
||||
]),
|
||||
),
|
||||
},
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.Trait"),
|
||||
identifier: traitIdentifier,
|
||||
options: Object.fromEntries(
|
||||
Object.entries(DS4.i18n.traits).map(([trait, translation]) => [
|
||||
trait,
|
||||
`${translation} (${this.system.traits[trait].total})`,
|
||||
]),
|
||||
),
|
||||
},
|
||||
],
|
||||
}),
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
callback: (html) => {
|
||||
const selectedAttribute = html.find(`#${attributeIdentifier}`).val();
|
||||
if (!isAttribute(selectedAttribute)) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedAttribute", {
|
||||
actualAttribute: selectedAttribute,
|
||||
expectedTypes: Object.keys(DS4.i18n.attributes)
|
||||
.map((attribute) => `'${attribute}'`)
|
||||
.join(", "),
|
||||
}),
|
||||
);
|
||||
}
|
||||
const selectedTrait = html.find(`#${traitIdentifier}`).val();
|
||||
if (!isTrait(selectedTrait)) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedTrait", {
|
||||
actualTrait: selectedTrait,
|
||||
expectedTypes: Object.keys(DS4.i18n.traits)
|
||||
.map((attribute) => `'${attribute}'`)
|
||||
.join(", "),
|
||||
}),
|
||||
);
|
||||
}
|
||||
return {
|
||||
attribute: selectedAttribute,
|
||||
trait: selectedTrait,
|
||||
};
|
||||
return foundry.applications.api.DialogV2.prompt({
|
||||
window: { title: getGame().i18n.localize("DS4.DialogAttributeTraitSelection") },
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
"systems/ds4/templates/dialogs/simple-select-form.hbs",
|
||||
{
|
||||
selects: [
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.Attribute"),
|
||||
identifier: attributeIdentifier,
|
||||
options: Object.fromEntries(
|
||||
Object.entries(DS4.i18n.attributes).map(([attribute, translation]) => [
|
||||
attribute,
|
||||
`${translation} (${this.system.attributes[attribute].total})`,
|
||||
]),
|
||||
),
|
||||
},
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.Trait"),
|
||||
identifier: traitIdentifier,
|
||||
options: Object.fromEntries(
|
||||
Object.entries(DS4.i18n.traits).map(([trait, translation]) => [
|
||||
trait,
|
||||
`${translation} (${this.system.traits[trait].total})`,
|
||||
]),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
ok: {
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
callback: (_event, button) => {
|
||||
const selectedAttribute = button.form.elements[attributeIdentifier].value;
|
||||
if (!isAttribute(selectedAttribute)) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedAttribute", {
|
||||
actualAttribute: selectedAttribute,
|
||||
expectedTypes: Object.keys(DS4.i18n.attributes)
|
||||
.map((attribute) => `'${attribute}'`)
|
||||
.join(", "),
|
||||
}),
|
||||
);
|
||||
}
|
||||
const selectedTrait = button.form.elements[traitIdentifier].value;
|
||||
if (!isTrait(selectedTrait)) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedTrait", {
|
||||
actualTrait: selectedTrait,
|
||||
expectedTypes: Object.keys(DS4.i18n.traits)
|
||||
.map((attribute) => `'${attribute}'`)
|
||||
.join(", "),
|
||||
}),
|
||||
);
|
||||
}
|
||||
return {
|
||||
attribute: selectedAttribute,
|
||||
trait: selectedTrait,
|
||||
};
|
||||
},
|
||||
},
|
||||
rejectClose: false,
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
|
@ -83,29 +84,34 @@ export class DS4Weapon extends DS4Item {
|
|||
|
||||
const { melee, ranged } = { ...DS4.i18n.attackTypes };
|
||||
const identifier = `attack-type-selection-${foundry.utils.randomID()}`;
|
||||
return Dialog.prompt({
|
||||
title: getGame().i18n.localize("DS4.DialogAttackTypeSelection"),
|
||||
content: await renderTemplate("systems/ds4/templates/dialogs/simple-select-form.hbs", {
|
||||
selects: [
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.AttackType"),
|
||||
identifier,
|
||||
options: { melee, ranged },
|
||||
},
|
||||
],
|
||||
}),
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
callback: (html) => {
|
||||
const selectedAttackType = html.find(`#${identifier}`).val();
|
||||
if (selectedAttackType !== "melee" && selectedAttackType !== "ranged") {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedAttackType", {
|
||||
actualType: selectedAttackType,
|
||||
expectedTypes: "'melee', 'ranged'",
|
||||
}),
|
||||
);
|
||||
}
|
||||
return selectedAttackType;
|
||||
return foundry.applications.api.DialogV2.prompt({
|
||||
window: { title: getGame().i18n.localize("DS4.DialogAttackTypeSelection") },
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
"systems/ds4/templates/dialogs/simple-select-form.hbs",
|
||||
{
|
||||
selects: [
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.AttackType"),
|
||||
identifier,
|
||||
options: { melee, ranged },
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
ok: {
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
callback: (_event, button) => {
|
||||
const selectedAttackType = button.form.elements[identifier].value;
|
||||
if (selectedAttackType !== "melee" && selectedAttackType !== "ranged") {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedAttackType", {
|
||||
actualType: selectedAttackType,
|
||||
expectedTypes: "'melee', 'ranged'",
|
||||
}),
|
||||
);
|
||||
}
|
||||
return selectedAttackType;
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,6 +14,11 @@ const helpers = {
|
|||
|
||||
isEmpty: (input: Array<unknown> | null | undefined): boolean => (input?.length ?? 0) === 0,
|
||||
|
||||
capitalize: (str: string): string => {
|
||||
if (typeof str !== "string") return "";
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
},
|
||||
|
||||
toRomanNumerals,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2021 Oliver Rümpelein
|
||||
// SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
||||
// SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
|
@ -55,6 +56,7 @@ export async function registerHandlebarsPartials() {
|
|||
"systems/ds4/templates/sheets/shared/components/add-button.hbs",
|
||||
"systems/ds4/templates/sheets/shared/components/control-button-group.hbs",
|
||||
"systems/ds4/templates/sheets/shared/components/rollable-image.hbs",
|
||||
"systems/ds4/templates/partials/waypoint-label.hbs",
|
||||
];
|
||||
await loadTemplates(templatePaths);
|
||||
await foundry.applications.handlebars.loadTemplates(templatePaths);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
// SPDX-FileCopyrightText: 2021 Oliver Rümpelein
|
||||
// SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
||||
// SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
|
@ -8,6 +9,7 @@ import { DS4ActiveEffectConfig } from "../apps/active-effect-config";
|
|||
import { DS4CharacterActorSheet } from "../apps/actor/character-sheet";
|
||||
import { DS4CreatureActorSheet } from "../apps/actor/creature-sheet";
|
||||
import { DS4ItemSheet } from "../apps/item-sheet";
|
||||
import { DS4TokenRuler } from "../apps/ruler/token-ruler";
|
||||
import { DS4 } from "../config";
|
||||
import { DS4Check } from "../dice/check";
|
||||
import { createCheckRoll } from "../dice/check-factory";
|
||||
|
@ -51,6 +53,8 @@ async function init() {
|
|||
CONFIG.ChatMessage.documentClass = DS4ChatMessage;
|
||||
CONFIG.Token.documentClass = DS4TokenDocument;
|
||||
|
||||
CONFIG.Token.rulerClass = DS4TokenRuler;
|
||||
|
||||
CONFIG.ActiveEffect.legacyTransferral = false;
|
||||
|
||||
CONFIG.Actor.typeLabels = DS4.i18n.actorTypes;
|
||||
|
@ -65,16 +69,23 @@ async function init() {
|
|||
|
||||
registerSystemSettings();
|
||||
|
||||
DocumentSheetConfig.unregisterSheet(Actor, "core", ActorSheet);
|
||||
DocumentSheetConfig.registerSheet(Actor, "ds4", DS4CharacterActorSheet, {
|
||||
foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, "ds4", DS4CharacterActorSheet, {
|
||||
types: ["character"],
|
||||
makeDefault: true,
|
||||
});
|
||||
DocumentSheetConfig.registerSheet(Actor, "ds4", DS4CreatureActorSheet, { types: ["creature"], makeDefault: true });
|
||||
DocumentSheetConfig.unregisterSheet(Item, "core", ItemSheet);
|
||||
DocumentSheetConfig.registerSheet(Item, "ds4", DS4ItemSheet, { makeDefault: true });
|
||||
DocumentSheetConfig.unregisterSheet(ActiveEffect, "core", ActiveEffectConfig);
|
||||
DocumentSheetConfig.registerSheet(ActiveEffect, "ds4", DS4ActiveEffectConfig, { makeDefault: true });
|
||||
foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, "ds4", DS4CreatureActorSheet, {
|
||||
types: ["creature"],
|
||||
makeDefault: true,
|
||||
});
|
||||
foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, "ds4", DS4ItemSheet, { makeDefault: true });
|
||||
foundry.applications.apps.DocumentSheetConfig.unregisterSheet(
|
||||
ActiveEffect,
|
||||
"core",
|
||||
foundry.applications.sheets.ActiveEffectConfig,
|
||||
);
|
||||
foundry.applications.apps.DocumentSheetConfig.registerSheet(ActiveEffect, "ds4", DS4ActiveEffectConfig, {
|
||||
makeDefault: true,
|
||||
});
|
||||
|
||||
preloadFonts();
|
||||
await registerHandlebarsPartials();
|
||||
|
|
|
@ -17,10 +17,18 @@ export function registerForRenderHooks() {
|
|||
* Select the text of input elements in given application when focused via an on focus listener.
|
||||
*
|
||||
* @param {Application} app The application in which to activate the listener.
|
||||
* @param {JQuery} html The {@link JQuery} representing the HTML of the application.
|
||||
* @param {HTMLElement} element The HTML element representing the HTML of the application.
|
||||
*/
|
||||
function selectTargetInputOnFocus(app, html) {
|
||||
html.find("input").on("focus", (ev) => {
|
||||
ev.currentTarget.select();
|
||||
function selectTargetInputOnFocus(app, element) {
|
||||
// V13: element is always a plain DOM element
|
||||
if (!element || typeof element.querySelectorAll !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
const inputs = element.querySelectorAll("input");
|
||||
inputs.forEach((input) => {
|
||||
input.addEventListener("focus", (ev) => {
|
||||
ev.currentTarget.select();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -30,7 +30,10 @@ export function enforce(value, message) {
|
|||
* @returns {Canvas}
|
||||
*/
|
||||
export function getCanvas() {
|
||||
enforce(canvas instanceof Canvas && canvas.ready, getGame().i18n.localize("DS4.ErrorCanvasIsNotInitialized"));
|
||||
enforce(
|
||||
canvas instanceof foundry.canvas.Canvas && canvas.ready,
|
||||
getGame().i18n.localize("DS4.ErrorCanvasIsNotInitialized"),
|
||||
);
|
||||
return canvas;
|
||||
}
|
||||
|
||||
|
@ -40,7 +43,7 @@ export function getCanvas() {
|
|||
* @returns {Game}
|
||||
*/
|
||||
export function getGame() {
|
||||
enforce(game instanceof Game, "Game is not initialized yet.");
|
||||
enforce(game instanceof foundry.Game, "Game is not initialized yet.");
|
||||
return game;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
"readme": "https://git.f3l.de/dungeonslayers/ds4/raw/tag/2.0.5/README.md",
|
||||
"bugs": "https://git.f3l.de/dungeonslayers/ds4/issues",
|
||||
"changelog": "https://git.f3l.de/dungeonslayers/ds4/releases/tag/2.0.5",
|
||||
"version": "2.0.5",
|
||||
"version": "3.0.0",
|
||||
"flags": {
|
||||
"hotReload": {
|
||||
"extensions": ["css", "hbs", "json"],
|
||||
|
@ -40,8 +40,8 @@
|
|||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"minimum": "12.331",
|
||||
"verified": "12"
|
||||
"minimum": "13",
|
||||
"verified": "13.346"
|
||||
},
|
||||
"esmodules": ["ds4.js"],
|
||||
"styles": ["css/ds4.css"],
|
||||
|
|
|
@ -4,7 +4,7 @@ SPDX-FileCopyrightText: 2021 Johannes Loher
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="dice-roll">
|
||||
<div class="dice-roll" data-action="expandRoll">
|
||||
{{#if flavor}}
|
||||
<div class="dice-flavor">{{flavor}}</div>
|
||||
{{/if}}
|
||||
|
|
43
templates/partials/waypoint-label.hbs
Normal file
43
templates/partials/waypoint-label.hbs
Normal file
|
@ -0,0 +1,43 @@
|
|||
{{!--
|
||||
SPDX-FileCopyrightText: 2025 Alexander Minges
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
{{!--
|
||||
!-- Waypoint label template with color-coded movement ranges
|
||||
!-- Based on DS4 movement combat values
|
||||
--}}
|
||||
<div class="waypoint-label {{rangeClass}}">
|
||||
{{#if (eq rangeClass "dash-range")}}
|
||||
<i class="fas fa-person-running"></i>
|
||||
{{else if (eq rangeClass "out-of-range")}}
|
||||
<i class="fas fa-person-rays"></i>
|
||||
{{else if action.icon}}
|
||||
<i class="{{action.icon}}"></i>
|
||||
{{else if action.label}}
|
||||
{{localize action.label}}
|
||||
{{/if}}
|
||||
{{#if cost}}
|
||||
<span class="distance {{rangeClass}}">{{cost.total}} {{cost.units}}</span>
|
||||
{{#if cost.delta}}
|
||||
<span class="delta">({{cost.delta}})</span>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<span class="distance {{rangeClass}}">{{distance.total}} {{units}}</span>
|
||||
{{#if distance.delta}}
|
||||
<span class="delta">({{distance.delta}})</span>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if (and elevation (not elevation.hidden))}}
|
||||
<span class="elevation">
|
||||
{{elevation.total}} {{units}}
|
||||
{{#if elevation.delta}}
|
||||
({{elevation.delta}})
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/if}}
|
||||
{{#if secret}}
|
||||
<i class="fas fa-eye-slash"></i>
|
||||
{{/if}}
|
||||
</div>
|
|
@ -32,8 +32,18 @@ SPDX-License-Identifier: MIT
|
|||
|
||||
<div class="form-group stacked">
|
||||
<label>{{ localize "EFFECT.Description" }}</label>
|
||||
{{editor descriptionHTML target="description" button=false editable=editable engine="prosemirror"
|
||||
collaborate=false}}
|
||||
{{#if editable}}
|
||||
<prose-mirror
|
||||
name="description"
|
||||
button="false"
|
||||
editable="{{editable}}"
|
||||
toggled="false"
|
||||
value="{{data.description}}">
|
||||
{{{descriptionHTML}}}
|
||||
</prose-mirror>
|
||||
{{else}}
|
||||
{{{descriptionHTML}}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
|
@ -13,38 +13,47 @@ SPDX-License-Identifier: MIT
|
|||
{{/systems/ds4/templates/sheets/actor/components/actor-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="values">{{localize 'DS4.HeadingValues'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="inventory">{{localize 'DS4.HeadingInventory'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="spells">{{localize 'DS4.HeadingSpells'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="abilities">{{localize 'DS4.HeadingAbilities'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="biography">{{localize 'DS4.HeadingBiography'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
<!-- beautify ignore:start -->
|
||||
<!-- prettier-ignore-start -->
|
||||
{{!-- Sheet Body (remove indentation to avoid annoying Handlebars auto-indent) --}}
|
||||
<section class="ds4-sheet-body">
|
||||
{{!-- Values Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/values.hbs}}
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="sheet-body">
|
||||
{{!-- Values Tab --}}
|
||||
<div class="tab {{#if tabs.values}}{{tabs.values.cssClass}}{{/if}}" data-tab="values" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/components/core-values.hbs}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/combat-values.hbs}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/checks.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Inventory Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/character-inventory.hbs}}
|
||||
{{!-- Inventory Tab --}}
|
||||
<div class="tab {{#if tabs.inventory}}{{tabs.inventory.cssClass}}{{/if}}" data-tab="inventory" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/character-inventory.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Spells Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/spells.hbs}}
|
||||
{{!-- Spells Tab --}}
|
||||
<div class="tab {{#if tabs.spells}}{{tabs.spells.cssClass}}{{/if}}" data-tab="spells" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/spells.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Abilities Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/character-abilities.hbs}}
|
||||
{{!-- Abilities Tab --}}
|
||||
<div class="tab {{#if tabs.abilities}}{{tabs.abilities.cssClass}}{{/if}}" data-tab="abilities" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/character-abilities.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/effects.hbs}}
|
||||
{{!-- Effects Tab --}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/effects.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Biography Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/biography.hbs}}
|
||||
|
||||
</section>
|
||||
<!-- prettier-ignore-end -->
|
||||
<!-- beautify ignore:end -->
|
||||
{{!-- Biography Tab --}}
|
||||
<div class="tab {{#if tabs.biography}}{{tabs.biography.cssClass}}{{/if}}" data-tab="biography" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/biography.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -11,7 +11,7 @@ SPDX-License-Identifier: MIT
|
|||
!-- @param @partial-block: Properties to render in the second header row.
|
||||
--}}
|
||||
<header class="ds4-actor-header">
|
||||
<img class="ds4-actor-header__img{{#if editable}} ds4-actor-header__img--editable{{/if}}" src="{{data.img}}" data-edit="img" alt="{{localize 'DS4.ActorImageAltText'}}"
|
||||
<img class="ds4-actor-header__img{{#if editable}} ds4-actor-header__img--editable{{/if}}" src="{{data.img}}" data-action="editImage" alt="{{localize 'DS4.ActorImageAltText'}}"
|
||||
title="{{data.name}}" height="100" width="100" />
|
||||
<div class="ds4-actor-header__data">
|
||||
<div class="ds4-actor-header__data-row">
|
||||
|
|
|
@ -5,6 +5,16 @@ SPDX-License-Identifier: MIT
|
|||
--}}
|
||||
|
||||
<div class="ds4-biography">
|
||||
{{editor data.system.profile.biography target="system.profile.biography" button=true owner=owner
|
||||
editable=editable engine="prosemirror"}}
|
||||
{{#if editable}}
|
||||
<prose-mirror
|
||||
name="system.profile.biography"
|
||||
button="true"
|
||||
editable="{{editable}}"
|
||||
toggled="false"
|
||||
value="{{data.system.profile.biography}}">
|
||||
{{{data.system.profile.biography}}}
|
||||
</prose-mirror>
|
||||
{{else}}
|
||||
{{{data.system.profile.biography}}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -12,7 +12,7 @@ SPDX-License-Identifier: MIT
|
|||
!-- @param check-label: The label for the check
|
||||
--}}
|
||||
|
||||
<button class="ds4-check rollable-check" data-check="{{check-key}}"
|
||||
<button class="ds4-check" data-action="rollCheck" data-check="{{check-key}}"
|
||||
title="{{localize 'DS4.CheckTooltip' check=check-label}}">
|
||||
<span>{{check-label}}</span>
|
||||
<span>{{check-target-number}}</span>
|
||||
|
|
|
@ -17,7 +17,7 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-combat-value">
|
||||
<div class="ds4-combat-value__value ds4-combat-value__value--{{combat-value-key}}"
|
||||
title="{{combat-value-title}}: {{combat-value-data.tooltip}}">
|
||||
{{combat-value-data.total}}
|
||||
<span class="ds4-combat-value__text">{{combat-value-data.total}}</span>
|
||||
</div>
|
||||
<span title="{{combat-value-title}}" class="ds4-combat-value__label">{{combat-value-label}}</span>
|
||||
<div class="ds4-combat-value__formula">
|
||||
|
|
|
@ -5,6 +5,16 @@ SPDX-License-Identifier: MIT
|
|||
--}}
|
||||
|
||||
<div class="ds4-description">
|
||||
{{editor data.system.baseInfo.description target="system.baseInfo.description" button=true owner=owner
|
||||
editable=editable engine="prosemirror"}}
|
||||
{{#if editable}}
|
||||
<prose-mirror
|
||||
name="system.baseInfo.description"
|
||||
button="true"
|
||||
editable="{{editable}}"
|
||||
toggled="false"
|
||||
value="{{data.system.baseInfo.description}}">
|
||||
{{{data.system.baseInfo.description}}}
|
||||
</prose-mirror>
|
||||
{{else}}
|
||||
{{{data.system.baseInfo.description}}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -9,11 +9,11 @@ SPDX-License-Identifier: MIT
|
|||
!-- Render an effect list entry row.
|
||||
!-- @param effectData: The data of the item.
|
||||
--}}
|
||||
<li class="ds4-embedded-document-list__row effect" data-effect-uuid="{{effectData.uuid}}" data-effect-id="{{effectData.id}}">
|
||||
<li class="ds4-embedded-document-list__row effect draggable" data-effect-uuid="{{effectData.uuid}}" data-effect-id="{{effectData.id}}">
|
||||
{{!-- enabled --}}
|
||||
<input class="ds4-embedded-document-list__editable ds4-embedded-document-list__editable--checkbox change-effect"
|
||||
<input class="ds4-embedded-document-list__editable ds4-embedded-document-list__editable--checkbox"
|
||||
type="checkbox" {{checked (ne effectData.disabled true)}} data-dtype="Boolean" data-property="disabled"
|
||||
data-inverted="true" title="{{localize 'DS4.EffectEnabled'}}">
|
||||
data-inverted="true" data-action="changeEffect" title="{{localize 'DS4.EffectEnabled'}}">
|
||||
|
||||
{{!-- active --}}
|
||||
{{#if effectData.active}}<i class="fas fa-check"></i>{{else}}<i class="fas fa-ban"></i>{{/if}}
|
||||
|
|
|
@ -15,30 +15,30 @@ SPDX-License-Identifier: MIT
|
|||
!-- @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-embedded-document-list__row item" data-item-uuid="{{item.uuid}}" data-item-id="{{item.id}}">
|
||||
<li class="ds4-embedded-document-list__row item draggable" data-item-uuid="{{item.uuid}}" data-item-id="{{item.id}}">
|
||||
{{!-- equipped --}}
|
||||
{{#if isEquipable}}
|
||||
<input class="ds4-embedded-document-list__editable ds4-embedded-document-list__editable--checkbox change-item"
|
||||
<input class="ds4-embedded-document-list__editable ds4-embedded-document-list__editable--checkbox"
|
||||
type="checkbox" {{checked item.system.equipped}} data-dtype="Boolean" data-property="system.equipped"
|
||||
title="{{localize 'DS4.ItemEquipped'}}">
|
||||
data-action="changeItem" title="{{localize 'DS4.ItemEquipped'}}">
|
||||
{{/if}}
|
||||
|
||||
{{!-- image --}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/rollable-image.hbs rollable=(and item.system.rollable
|
||||
@root/editable)
|
||||
src=item.img alt=(localize "DS4.DocumentImageAltText" name=item.name) title=item.name
|
||||
rollableTitle=(localize "DS4.RollableImageRollableTitle" name=item.name) rollableClass="rollable-item"}}
|
||||
rollableTitle=(localize "DS4.RollableImageRollableTitle" name=item.name) rollableAction="rollItem"}}
|
||||
|
||||
{{!-- amount --}}
|
||||
{{#if hasQuantity}}
|
||||
<input class="ds4-embedded-document-list__editable change-item" type="number" min="0" step="1"
|
||||
<input class="ds4-embedded-document-list__editable" type="number" min="0" step="1"
|
||||
value="{{item.system.quantity}}" data-dtype="Number" data-property="system.quantity"
|
||||
title="{{localize 'DS4.Quantity'}}" />
|
||||
data-action="changeItem" title="{{localize 'DS4.Quantity'}}" />
|
||||
{{/if}}
|
||||
|
||||
{{!-- name --}}
|
||||
<input class="ds4-embedded-document-list__editable change-item" type="text" value="{{item.name}}"
|
||||
data-dtype="String" data-property="name" title="{{htmlToPlainText item.system.description}}" />
|
||||
<input class="ds4-embedded-document-list__editable" type="text" value="{{item.name}}"
|
||||
data-dtype="String" data-property="name" data-action="changeItem" title="{{htmlToPlainText item.system.description}}" />
|
||||
|
||||
{{!-- item type specifics --}}
|
||||
{{#if @partial-block }}
|
||||
|
|
|
@ -18,7 +18,7 @@ SPDX-License-Identifier: MIT
|
|||
<li class="ds4-embedded-document-list__row ds4-embedded-document-list__row--header" data-type={{type}}>
|
||||
{{!-- equipped --}}
|
||||
{{#if isEquipable}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.equipped"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.equipped"
|
||||
title="{{localize 'DS4.SortByItemEquipped'}}">
|
||||
{{localize 'DS4.ItemEquippedAbbr'}}</div>
|
||||
{{/if}}
|
||||
|
@ -28,12 +28,12 @@ SPDX-License-Identifier: MIT
|
|||
|
||||
{{!-- amount --}}
|
||||
{{#if hasQuantity}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.quantity"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.quantity"
|
||||
title="{{localize 'DS4.SortByQuantity'}}">#</div>
|
||||
{{/if}}
|
||||
|
||||
{{!-- name --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="name"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="name"
|
||||
title="{{localize 'DS4.SortByItemName'}}">{{localize 'DS4.ItemName'}}
|
||||
</div>
|
||||
|
||||
|
@ -44,7 +44,7 @@ SPDX-License-Identifier: MIT
|
|||
|
||||
{{!-- description --}}
|
||||
{{#unless hideDescription}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.description"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.description"
|
||||
title="{{localize 'DS4.SortByDescription'}}">{{localize
|
||||
'DS4.Description'}}</div>
|
||||
{{/unless}}
|
||||
|
|
|
@ -13,19 +13,19 @@ SPDX-License-Identifier: MIT
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hasQuantity=true
|
||||
type='weapon'}}
|
||||
{{!-- attack type --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.attackType"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.attackType"
|
||||
title="{{localize 'DS4.SortByAttackType'}}">
|
||||
{{localize
|
||||
'DS4.AttackTypeAbbr'}}</div>
|
||||
|
||||
{{!-- weapon bonus --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.weaponBonus"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.weaponBonus"
|
||||
title="{{localize 'DS4.SortByWeaponBonus'}}">
|
||||
{{localize 'DS4.WeaponBonusAbbr'}}
|
||||
</div>
|
||||
|
||||
{{!-- opponent defense --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.opponentDefense"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.opponentDefense"
|
||||
title="{{localize 'DS4.SortByOpponentDefense'}}">
|
||||
{{localize 'DS4.OpponentDefenseAbbr'}}
|
||||
</div>
|
||||
|
@ -70,15 +70,15 @@ documentType='item' type='weapon'}}
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hasQuantity=true
|
||||
type="armor"}}
|
||||
{{!-- armor material type --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.armorMaterialType"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.armorMaterialType"
|
||||
title="{{localize 'DS4.SortByArmorMaterialType'}}">{{localize 'DS4.ArmorMaterialTypeAbbr'}}</div>
|
||||
|
||||
{{!-- armor type --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.armorType"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.armorType"
|
||||
title="{{localize 'DS4.SortByArmorType'}}">{{localize 'DS4.ArmorTypeAbbr'}}</div>
|
||||
|
||||
{{!-- armor value --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.armorValue"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.armorValue"
|
||||
title="{{localize 'DS4.SortByArmorValue'}}">
|
||||
{{localize 'DS4.ArmorValueAbbr'}}
|
||||
</div>
|
||||
|
@ -113,7 +113,7 @@ documentType='item' type='armor'}}
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hasQuantity=true
|
||||
type='shield'}}
|
||||
{{!-- armor value --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.armorValue"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.armorValue"
|
||||
title="{{localize 'DS4.SortByArmorValue'}}">
|
||||
{{localize 'DS4.ArmorValueAbbr'}}
|
||||
</div>
|
||||
|
@ -137,15 +137,15 @@ documentType='item' type='shield'}}
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hasQuantity=true
|
||||
type='equipment'}}
|
||||
{{!-- storage location --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.storageLocation"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.storageLocation"
|
||||
title="{{localize 'DS4.SortByStorageLocation'}}">{{localize 'DS4.StorageLocation'}}</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-header.hbs}}
|
||||
{{#each itemsByType.equipment as |item id|}}
|
||||
{{#> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs item=item isEquipable=true
|
||||
hasQuantity=true}}
|
||||
{{!-- storage location --}}
|
||||
<input class="ds4-embedded-document-list__editable change-item" type="text" value="{{item.system.storageLocation}}"
|
||||
data-dtype="String" data-property="system.storageLocation" title="{{localize 'DS4.StorageLocation'}}">
|
||||
<input class="ds4-embedded-document-list__editable" type="text" value="{{item.system.storageLocation}}"
|
||||
data-dtype="String" data-property="system.storageLocation" data-action="changeItem" title="{{localize 'DS4.StorageLocation'}}">
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
|
@ -159,14 +159,14 @@ documentType='item' type='equipment'}}
|
|||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--loot item-list">
|
||||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs hasQuantity=true type='loot'}}
|
||||
{{!-- storage location --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.storageLocation"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.storageLocation"
|
||||
title="{{localize 'DS4.SortByStorageLocation'}}">{{localize 'DS4.StorageLocation'}}</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-header.hbs}}
|
||||
{{#each itemsByType.loot as |item id|}}
|
||||
{{#> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs item=item hasQuantity=true}}
|
||||
{{!-- storage location --}}
|
||||
<input class="ds4-embedded-document-list__editable change-item" type="text" value="{{item.system.storageLocation}}"
|
||||
data-dtype="String" data-property="system.storageLocation" title="{{localize 'DS4.StorageLocation'}}">
|
||||
<input class="ds4-embedded-document-list__editable" type="text" value="{{item.system.storageLocation}}"
|
||||
data-dtype="String" data-property="system.storageLocation" data-action="changeItem" title="{{localize 'DS4.StorageLocation'}}">
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
|
|
|
@ -12,35 +12,46 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/actor/components/creature-properties.hbs}}
|
||||
{{/systems/ds4/templates/sheets/actor/components/actor-header.hbs}}
|
||||
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="values">{{localize 'DS4.HeadingValues'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="inventory">{{localize 'DS4.HeadingInventory'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="spells">{{localize 'DS4.HeadingSpells'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="abilities">{{localize 'DS4.HeadingAbilities'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Values Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/values.hbs}}
|
||||
<div class="tab {{#if tabs.values}}{{tabs.values.cssClass}}{{/if}}" data-tab="values" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/values.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Inventory Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/creature-inventory.hbs}}
|
||||
<div class="tab {{#if tabs.inventory}}{{tabs.inventory.cssClass}}{{/if}}" data-tab="inventory" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/creature-inventory.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Spells Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/spells.hbs}}
|
||||
<div class="tab {{#if tabs.spells}}{{tabs.spells.cssClass}}{{/if}}" data-tab="spells" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/spells.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Abilities Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/creature-abilities.hbs}}
|
||||
<div class="tab {{#if tabs.abilities}}{{tabs.abilities.cssClass}}{{/if}}" data-tab="abilities" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/creature-abilities.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/effects.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/actor/tabs/description.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -9,7 +9,6 @@ SPDX-License-Identifier: MIT
|
|||
{{#> systems/ds4/templates/sheets/actor/components/actor-header.hbs}}
|
||||
{{/systems/ds4/templates/sheets/actor/components/actor-header.hbs}}
|
||||
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
{{#if (eq data.type 'character')}}
|
||||
|
|
|
@ -4,14 +4,12 @@ SPDX-FileCopyrightText: 2021 Johannes Loher
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab biography" data-group="primary" data-tab="biography">
|
||||
<div class="ds4-biography-tab-content">
|
||||
<!-- beautify ignore:start -->
|
||||
<!-- prettier-ignore-start -->
|
||||
{{!-- remove indentation to avoid annoying Handlebars auto-indent --}}
|
||||
<div class="ds4-biography-tab-content">
|
||||
<!-- beautify ignore:start -->
|
||||
<!-- prettier-ignore-start -->
|
||||
{{!-- remove indentation to avoid annoying Handlebars auto-indent --}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/profile.hbs}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/biography.hbs}}
|
||||
<!-- beautify ignore:end -->
|
||||
<!-- prettier-ignore-end -->
|
||||
</div>
|
||||
<!-- beautify ignore:end -->
|
||||
<!-- prettier-ignore-end -->
|
||||
</div>
|
||||
|
|
|
@ -5,14 +5,14 @@ SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab abilities" data-group="primary" data-tab="abilities">
|
||||
|
||||
{{!-- TALENT --}}
|
||||
<h4 class="ds4-embedded-document-list-title">{{localize 'DS4.ItemTypeTalentPlural'}}</h4>
|
||||
{{#unless (isEmpty itemsByType.talent)}}
|
||||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--talent item-list">
|
||||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs type='talent'}}
|
||||
{{!-- rank --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.rank.total"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.rank.total"
|
||||
title="{{localize 'DS4.SortByTalentRank'}}">{{localize 'DS4.TalentRank'}}</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-header.hbs}}
|
||||
{{#each itemsByType.talent as |item id|}}
|
||||
|
@ -64,4 +64,3 @@ SPDX-License-Identifier: MIT
|
|||
{{/unless}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/add-button.hbs title='DS4.UserInteractionAddItemTitle'
|
||||
documentType='item' type='alphabet'}}
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,5 @@ SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab inventory" data-group="primary" data-tab="inventory">
|
||||
{{> systems/ds4/templates/sheets/actor/components/currency.hbs}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/items-overview.hbs}}
|
||||
</div>
|
||||
{{> systems/ds4/templates/sheets/actor/components/currency.hbs}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/items-overview.hbs}}
|
||||
|
|
|
@ -5,15 +5,13 @@ SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab abilities" data-group="primary" data-tab="abilities">
|
||||
{{#unless (isEmpty itemsByType.specialCreatureAbility)}}
|
||||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--special-creature-ability item-list">
|
||||
{{> systems/ds4/templates/sheets/actor/components/item-list-header.hbs type='specialCreatureAbility'}}
|
||||
{{#each itemsByType.specialCreatureAbility as |item id|}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs item=item}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{/unless}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/add-button.hbs title='DS4.UserInteractionAddItemTitle'
|
||||
documentType='item' type='specialCreatureAbility'}}
|
||||
</div>
|
||||
{{#unless (isEmpty itemsByType.specialCreatureAbility)}}
|
||||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--special-creature-ability item-list">
|
||||
{{> systems/ds4/templates/sheets/actor/components/item-list-header.hbs type='specialCreatureAbility'}}
|
||||
{{#each itemsByType.specialCreatureAbility as |item id|}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs item=item}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{/unless}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/add-button.hbs title='DS4.UserInteractionAddItemTitle'
|
||||
documentType='item' type='specialCreatureAbility'}}
|
||||
|
|
|
@ -5,6 +5,4 @@ SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab inventory" data-group="primary" data-tab="inventory">
|
||||
{{> systems/ds4/templates/sheets/actor/components/items-overview.hbs}}
|
||||
</div>
|
||||
{{> systems/ds4/templates/sheets/actor/components/items-overview.hbs}}
|
||||
|
|
|
@ -4,6 +4,4 @@ SPDX-FileCopyrightText: 2021 Johannes Loher
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab description" data-group="primary" data-tab="description">
|
||||
{{> systems/ds4/templates/sheets/actor/components/description.hbs}}
|
||||
</div>
|
||||
{{> systems/ds4/templates/sheets/actor/components/description.hbs}}
|
||||
|
|
|
@ -5,15 +5,13 @@ SPDX-FileCopyrightText: 2021 Gesina Schwalbe
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab effects" data-group="primary" data-tab="effects">
|
||||
{{#unless (isEmpty enrichedEffects)}}
|
||||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--effect effect-list">
|
||||
{{> systems/ds4/templates/sheets/actor/components/effect-list-header.hbs}}
|
||||
{{#each enrichedEffects as |effectData id| }}
|
||||
{{> systems/ds4/templates/sheets/actor/components/effect-list-entry.hbs effectData=effectData}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{/unless}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/add-button.hbs title='DS4.UserInteractionAddEffectTitle'
|
||||
documentType='effect'}}
|
||||
</div>
|
||||
{{#unless (isEmpty enrichedEffects)}}
|
||||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--effect effect-list">
|
||||
{{> systems/ds4/templates/sheets/actor/components/effect-list-header.hbs}}
|
||||
{{#each enrichedEffects as |effectData id| }}
|
||||
{{> systems/ds4/templates/sheets/actor/components/effect-list-entry.hbs effectData=effectData}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{/unless}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/add-button.hbs title='DS4.UserInteractionAddEffectTitle'
|
||||
documentType='effect'}}
|
||||
|
|
|
@ -40,21 +40,19 @@ titleKey=titleKey}}
|
|||
titleKey=titleKey}}
|
||||
{{/inline}}
|
||||
|
||||
|
||||
{{!-- ======================================================================== --}}
|
||||
|
||||
|
||||
<div class="ds4-sheet-tab tab spells" data-group="primary" data-tab="spells">
|
||||
{{#unless (isEmpty itemsByType.spell)}}
|
||||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--spell item-list">
|
||||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hideDescription=true
|
||||
type='spell'}}
|
||||
{{!-- spell type --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.spellType"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.spellType"
|
||||
title="{{localize 'DS4.SortBySpellType'}}">{{localize 'DS4.SpellTypeAbbr'}}</div>
|
||||
|
||||
{{!-- spell modifier --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.spellModifier.complex"
|
||||
<div class="ds4-embedded-document-list__clickable" data-action="sortItems" data-data-path="system.spellModifier.complex"
|
||||
data-data-path2="system.spellModifier.numerical" title="{{localize 'DS4.SortBySpellModifier'}}">{{localize
|
||||
'DS4.SpellModifierAbbr'}}</div>
|
||||
|
||||
|
@ -81,6 +79,7 @@ titleKey=titleKey}}
|
|||
'')}}{{item.system.spellModifier.numerical}}{{else}}{{item.system.spellModifier.complex}}{{/if}}
|
||||
</div>
|
||||
|
||||
|
||||
{{!-- max. distance --}}
|
||||
{{> distanceUnit titleKey='DS4.SpellDistance' unitDatum=item.system.maxDistance
|
||||
config=@root/config}}
|
||||
|
@ -98,4 +97,3 @@ titleKey=titleKey}}
|
|||
{{/unless}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/add-button.hbs title='DS4.UserInteractionAddItemTitle'
|
||||
documentType='item' type='spell'}}
|
||||
</div>
|
||||
|
|
|
@ -4,8 +4,6 @@ SPDX-FileCopyrightText: 2021 Johannes Loher
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab values" data-group="primary" data-tab="values">
|
||||
{{> systems/ds4/templates/sheets/actor/components/core-values.hbs}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/combat-values.hbs}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/checks.hbs}}
|
||||
</div>
|
||||
{{> systems/ds4/templates/sheets/actor/components/core-values.hbs}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/combat-values.hbs}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/checks.hbs}}
|
||||
|
|
|
@ -9,17 +9,25 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{tabs.description.cssClass}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{tabs.effects.cssClass}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -9,28 +9,35 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="properties">{{localize 'DS4.HeadingProperties'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Properties Tab --}}
|
||||
{{#> systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/armor.hbs}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/protective.hbs}}
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
{{/systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
<div class="tab {{#if tabs.properties}}{{tabs.properties.cssClass}}{{/if}}" data-tab="properties" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/armor.hbs}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/protective.hbs}}
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -5,7 +5,7 @@ SPDX-License-Identifier: MIT
|
|||
--}}
|
||||
|
||||
<header class="ds4-item-header">
|
||||
<img class="ds4-item-header__img" src="{{data.img}}" data-edit="img" alt="{{localize 'DS4.ItemImageAltText'}}"
|
||||
<img class="ds4-item-header__img" src="{{data.img}}" data-action="editImage" alt="{{localize 'DS4.ItemImageAltText'}}"
|
||||
title="{{data.name}}" />
|
||||
<div class="ds4-item-header__data">
|
||||
<h2 class="ds4-item-header__type">{{lookup config.i18n.itemTypes item.type}}</h2>
|
||||
|
|
|
@ -88,10 +88,8 @@ SPDX-License-Identifier: MIT
|
|||
<div class="form-group">
|
||||
<label for="system.allowsDefense-{{data._id}}" title="{{localize 'DS4.SpellAllowsDefenseDescription'}}">{{localize
|
||||
"DS4.SpellAllowsDefense"}}</label>
|
||||
<div class="form-fields">
|
||||
<input id="system.allowsDefense-{{data._id}}" data-dtype="Boolean" type="checkbox" name="system.allowsDefense"
|
||||
{{checked data.system.allowsDefense}} />
|
||||
</div>
|
||||
<input id="system.allowsDefense-{{data._id}}" data-dtype="Boolean" type="checkbox" name="system.allowsDefense"
|
||||
{{checked data.system.allowsDefense}} />
|
||||
</div>
|
||||
<div class="form-group slim">
|
||||
<label title="{{localize 'DS4.SpellMinimumLevelDescription'}}">{{localize "DS4.SpellMinimumLevel"}}</label>
|
||||
|
|
|
@ -9,26 +9,33 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="properties">{{localize 'DS4.HeadingProperties'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Properties Tab --}}
|
||||
{{#> systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
{{/systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
<div class="tab {{#if tabs.properties}}{{tabs.properties.cssClass}}{{/if}}" data-tab="properties" data-group="primary">
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -9,17 +9,25 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -9,23 +9,30 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="properties">{{localize 'DS4.HeadingProperties'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Properties Tab --}}
|
||||
{{#> systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
{{/systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
<div class="tab {{#if tabs.properties}}{{tabs.properties.cssClass}}{{/if}}" data-tab="properties" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -9,17 +9,25 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -9,27 +9,34 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="properties">{{localize 'DS4.HeadingProperties'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Properties Tab --}}
|
||||
{{#> systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/protective.hbs}}
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
{{/systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
<div class="tab {{#if tabs.properties}}{{tabs.properties.cssClass}}{{/if}}" data-tab="properties" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/protective.hbs}}
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -9,23 +9,30 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="properties">{{localize 'DS4.HeadingProperties'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Properties Tab --}}
|
||||
{{#> systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/special-creature-ability.hbs}}
|
||||
{{/systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
<div class="tab {{#if tabs.properties}}{{tabs.properties.cssClass}}{{/if}}" data-tab="properties" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/special-creature-ability.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -9,26 +9,33 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="properties">{{localize 'DS4.HeadingProperties'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{tabs.description.cssClass}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Properties Tab --}}
|
||||
{{#> systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/spell.hbs}}
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
{{/systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
<div class="tab {{tabs.properties.cssClass}}" data-tab="properties" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/spell.hbs}}
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{tabs.effects.cssClass}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -4,7 +4,15 @@ SPDX-FileCopyrightText: 2021 Johannes Loher
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab description" data-group="primary" data-tab="description">
|
||||
{{editor data.system.description target="system.description" button=true owner=owner
|
||||
editable=editable engine="prosemirror"}}
|
||||
</div>
|
||||
{{#if editable}}
|
||||
<prose-mirror
|
||||
name="system.description"
|
||||
button="true"
|
||||
editable="{{editable}}"
|
||||
toggled="false"
|
||||
value="{{data.system.description}}">
|
||||
{{{enrichedDescription}}}
|
||||
</prose-mirror>
|
||||
{{else}}
|
||||
{{{enrichedDescription}}}
|
||||
{{/if}}
|
||||
|
|
|
@ -4,15 +4,13 @@ SPDX-FileCopyrightText: 2021 Johannes Loher
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab effects" data-group="primary" data-tab="effects">
|
||||
{{#unless (isEmpty data.effects)}}
|
||||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--item-effect effect-list">
|
||||
{{> systems/ds4/templates/sheets/item/components/effect-list-header.hbs}}
|
||||
{{#each data.effects as |effectData id| }}
|
||||
{{> systems/ds4/templates/sheets/item/components/effect-list-entry.hbs effectData=effectData}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{/unless}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/add-button.hbs title='DS4.UserInteractionAddEffectTitle'
|
||||
documentType='effect'}}
|
||||
</div>
|
||||
{{#unless (isEmpty enrichedEffects)}}
|
||||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--item-effect effect-list">
|
||||
{{> systems/ds4/templates/sheets/item/components/effect-list-header.hbs}}
|
||||
{{#each enrichedEffects as |effectData id| }}
|
||||
{{> systems/ds4/templates/sheets/item/components/effect-list-entry.hbs effectData=effectData}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{/unless}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/add-button.hbs title='DS4.UserInteractionAddEffectTitle'
|
||||
documentType='effect'}}
|
||||
|
|
|
@ -4,6 +4,4 @@ SPDX-FileCopyrightText: 2021 Johannes Loher
|
|||
SPDX-License-Identifier: MIT
|
||||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab properties" data-group="primary" data-tab="properties">
|
||||
{{> @partial-block}}
|
||||
</div>
|
||||
{{> @partial-block}}
|
||||
|
|
|
@ -9,23 +9,30 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="properties">{{localize 'DS4.HeadingProperties'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Properties Tab --}}
|
||||
{{#> systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/talent.hbs}}
|
||||
{{/systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
<div class="tab {{#if tabs.properties}}{{tabs.properties.cssClass}}{{/if}}" data-tab="properties" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/talent.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -9,27 +9,34 @@ SPDX-License-Identifier: MIT
|
|||
{{> systems/ds4/templates/sheets/item/components/item-header.hbs}}
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
<nav class="ds4-sheet-tab-nav tabs" data-group="primary">
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="description">{{localize 'DS4.HeadingDescription'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="properties">{{localize 'DS4.HeadingProperties'}}</a>
|
||||
<a class="ds4-sheet-tab-nav__item" data-tab="effects">{{localize 'DS4.HeadingEffects'}}</a>
|
||||
<nav class="tabs" data-group="primary">
|
||||
{{#each tabs}}
|
||||
<a class="item {{cssClass}}" data-tab="{{id}}" data-group="{{group}}">
|
||||
{{#if icon}}<i class="{{icon}}"></i>{{/if}}
|
||||
{{label}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
|
||||
{{!-- Sheet Body --}}
|
||||
<section class="ds4-sheet-body">
|
||||
<section class="sheet-body">
|
||||
{{!-- Description Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
<div class="tab {{#if tabs.description}}{{tabs.description.cssClass}}{{/if}}" data-tab="description" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/description.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Properties Tab --}}
|
||||
{{#> systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/weapon.hbs}}
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
{{/systems/ds4/templates/sheets/item/tabs/properties.hbs}}
|
||||
<div class="tab {{#if tabs.properties}}{{tabs.properties.cssClass}}{{/if}}" data-tab="properties" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/weapon.hbs}}
|
||||
{{#if isOwned}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/equipable.hbs}}
|
||||
{{/if}}
|
||||
{{> systems/ds4/templates/sheets/item/components/properties/physical.hbs}}
|
||||
</div>
|
||||
|
||||
{{!-- Effects Tab --}}
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
<div class="tab {{#if tabs.effects}}{{tabs.effects.cssClass}}{{/if}}" data-tab="effects" data-group="primary">
|
||||
{{> systems/ds4/templates/sheets/item/tabs/effects.hbs}}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
|
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: MIT
|
|||
}}
|
||||
{{#if @root/editable}}
|
||||
<div class="ds4-add-button">
|
||||
<a class="control-{{documentType}}" title="{{localize title}}" data-action="create" {{#if type}}data-type="{{type}}"
|
||||
<a class="ds4-add-button__link" title="{{localize title}}" data-action="{{concat 'create' (capitalize documentType)}}" {{#if type}}data-type="{{type}}"
|
||||
{{/if}}>
|
||||
<i class="fas fa-plus"></i>
|
||||
{{localize "DS4.UserInteractionAdd"}}
|
||||
|
|
|
@ -14,9 +14,9 @@ SPDX-License-Identifier: MIT
|
|||
--}}
|
||||
<div class="ds4-control-button-group">
|
||||
{{#if @root/editable}}
|
||||
<a class="ds4-control-button-group__button control-{{documentType}}" data-action="edit"
|
||||
<a class="ds4-control-button-group__button" data-action="{{concat 'edit' (capitalize documentType)}}" data-document-type="{{documentType}}"
|
||||
title="{{localize editTitle}}"><i class="fas fa-edit"></i></a>
|
||||
<a class="ds4-control-button-group__button control-{{documentType}}" data-action="delete"
|
||||
<a class="ds4-control-button-group__button" data-action="{{concat 'delete' (capitalize documentType)}}" data-document-type="{{documentType}}"
|
||||
title="{{localize deleteTitle}}"><i class="fas fa-trash"></i></a>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -7,13 +7,14 @@ SPDX-License-Identifier: MIT
|
|||
{{!--
|
||||
!-- Render an image that has a dice overlay image.
|
||||
!-- @param rollable: A flag indicating whether or not the image is actually rollable.
|
||||
!-- @param rollableClass: The CSS class(es) to add if the image is rollable.
|
||||
!-- @param rollableAction: The action to trigger when the image is clicked (e.g. "rollItem").
|
||||
!-- @param title: The title for the rollable image if it is not actually rollable.
|
||||
!-- @param rollableTitle: The title for the rollable image if it is rollable.
|
||||
!-- @param src: The path to the image.
|
||||
!-- @param alt: An alternate text for the image.
|
||||
--}}
|
||||
<div class="ds4-rollable-image{{#if rollable}} ds4-rollable-image--rollable {{rollableClass}}{{/if}}"
|
||||
<div class="ds4-rollable-image{{#if rollable}} ds4-rollable-image--rollable{{/if}}"
|
||||
{{#if rollable}}data-action="{{rollableAction}}"{{/if}}
|
||||
title="{{#if rollable}}{{rollableTitle}}{{else}}{{title}}{{/if}}">
|
||||
{{#if src}}
|
||||
<img class="ds4-rollable-image__image" alt="{{alt}}" src="{{src}}" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue