Fix conflict

This commit is contained in:
Dapoolp 2025-07-12 18:15:43 +02:00
commit d9ef062ce2
60 changed files with 879 additions and 133 deletions

View file

@ -41,10 +41,14 @@ Hooks.once('init', () => {
]
);
CONFIG.statusEffects = Object.values(SYSTEM.GENERAL.conditions).map(x => ({
...x,
name: game.i18n.localize(x.name)
}));
CONFIG.statusEffects = [
...CONFIG.statusEffects,
...Object.values(SYSTEM.GENERAL.conditions).map(x => ({
...x,
name: game.i18n.localize(x.name),
systemEffect: true
}))
];
CONFIG.Dice.daggerheart = {
DualityDie: DualityDie,
@ -108,6 +112,8 @@ Hooks.once('init', () => {
}
);
CONFIG.Token.hudClass = applications.hud.DHTokenHUD;
CONFIG.Combat.dataModels = {
base: models.DhCombat
};

View file

@ -279,6 +279,11 @@
}
}
},
"HUD": {
"tokenHUD": {
"genericEffects": "Foundry Effects"
}
},
"Levelup": {
"actions": {
"creatureComfort": {
@ -672,6 +677,10 @@
"name": "Dice Set"
}
},
"SelectAction": {
"selectType": "Select Action Type",
"selectAction": "Select Action"
},
"Traits": {
"agility": {
"name": "Agility",
@ -968,6 +977,10 @@
"singular": "Character",
"plural": "Characters"
},
"Cost": {
"single": "Cost",
"plural": "Costs"
},
"Damage": {
"severe": "Severe",
"major": "Major",
@ -1078,6 +1091,7 @@
"specialization": "Specialization",
"mastery": "Mastery",
"optional": "Optional",
"recovery": "Recovery",
"setup": "Setup",
"equipment": "Equipment"
},
@ -1099,6 +1113,8 @@
"burden": "Burden",
"check": "{check} Check",
"criticalSuccess": "Critical Success",
"damage": "Damage",
"damageType": "Damage Type",
"description": "Description",
"duality": "Duality",
"dualityRoll": "Duality Roll",
@ -1111,17 +1127,25 @@
"inactiveEffects": "Inactive Effects",
"inventory": "Inventory",
"level": "Level",
"max": "Max",
"modifier": "Modifier",
"multiclass": "Multiclass",
"none": "None",
"quantity": "Quantity",
"range": "Range",
"recovery": "Recovery",
"scalable": "Scalable",
"stress": "Stress",
"take": "Take",
"target": "Target",
"title": "Title",
"true": "True",
"type": "Type",
"unarmored": "Unarmored",
"use": "Use"
"use": "Use",
"used": "Used",
"uses": "Uses",
"value": "Value"
},
"ITEMS": {
"Armor": {
@ -1178,6 +1202,7 @@
"spellcastingTrait": "Spellcasting Trait"
},
"Weapon": {
"weaponType": "Weapon Type",
"primaryWeapon": "Primary Weapon",
"secondaryWeapon": "Secondary Weapon"
}
@ -1185,7 +1210,8 @@
"SETTINGS": {
"Appearance": {
"FIELDS": {
"displayFear": { "label": "Fear Display" }
"displayFear": { "label": "Fear Display" },
"showGenericStatusEffects": { "label": "Show Foundry Status Effects" }
},
"fearDisplay": {
"token": "Tokens",
@ -1385,7 +1411,8 @@
"unequip": "Unequip",
"sendToVault": "Send to Vault",
"sendToLoadout": "Send to Loadout",
"makeDeathMove": "Make a Death Move"
"makeDeathMove": "Make a Death Move",
"rangeAndTarget": "Range & Target"
}
}
}

View file

@ -1,5 +1,6 @@
export * as characterCreation from './characterCreation/_module.mjs';
export * as dialogs from './dialogs/_module.mjs';
export * as hud from './hud/_module.mjs';
export * as levelup from './levelup/_module.mjs';
export * as settings from './settings/_module.mjs';
export * as sheets from './sheets/_module.mjs';

View file

@ -11,7 +11,7 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl
static DEFAULT_OPTIONS = {
tag: 'form',
classes: ['daggerheart', 'views', 'damage-selection'],
classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'],
position: {
width: 400,
height: 'auto'

View file

@ -11,11 +11,14 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application
static DEFAULT_OPTIONS = {
tag: 'form',
id: 'roll-selection',
classes: ['daggerheart', 'views', 'damage-selection'],
classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'],
position: {
width: 400,
height: 'auto'
},
window: {
icon: 'fa-solid fa-dice'
},
actions: {
submitRoll: this.submitRoll
},
@ -34,9 +37,15 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application
}
};
get title() {
return game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name');
}
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
context.title = this.config.title;
context.title = this.config.title
? this.config.title
: game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name');
context.extraFormula = this.config.extraFormula;
context.formula = this.roll.constructFormula(this.config);
return context;

View file

@ -23,7 +23,7 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
static DEFAULT_OPTIONS = {
tag: 'form',
classes: ['daggerheart', 'views', 'damage-selection'],
classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'],
position: {
width: 400,
height: 'auto'

View file

@ -0,0 +1 @@
export { default as DHTokenHUD } from './tokenHud.mjs';

View file

@ -0,0 +1,84 @@
export default class DHTokenHUD extends TokenHUD {
static DEFAULT_OPTIONS = {
classes: ['daggerheart']
};
/** @override */
static PARTS = {
hud: {
root: true,
template: 'systems/daggerheart/templates/hud/tokenHUD.hbs'
}
};
async _prepareContext(options) {
const context = await super._prepareContext(options);
context.systemStatusEffects = Object.keys(context.statusEffects).reduce((acc, key) => {
const effect = context.statusEffects[key];
if (effect.systemEffect) acc[key] = effect;
return acc;
}, {});
const useGeneric = game.settings.get(
CONFIG.DH.id,
CONFIG.DH.SETTINGS.gameSettings.appearance
).showGenericStatusEffects;
context.genericStatusEffects = useGeneric
? Object.keys(context.statusEffects).reduce((acc, key) => {
const effect = context.statusEffects[key];
if (!effect.systemEffect) acc[key] = effect;
return acc;
}, {})
: null;
return context;
}
_getStatusEffectChoices() {
// Include all HUD-enabled status effects
const choices = {};
for (const status of CONFIG.statusEffects) {
if (
status.hud === false ||
(foundry.utils.getType(status.hud) === 'Object' &&
status.hud.actorTypes?.includes(this.document.actor.type) === false)
) {
continue;
}
choices[status.id] = {
_id: status._id,
id: status.id,
systemEffect: status.systemEffect,
title: game.i18n.localize(status.name ?? /** @deprecated since v12 */ status.label),
src: status.img ?? /** @deprecated since v12 */ status.icon,
isActive: false,
isOverlay: false
};
}
// Update the status of effects which are active for the token actor
const activeEffects = this.actor?.effects || [];
for (const effect of activeEffects) {
for (const statusId of effect.statuses) {
const status = choices[statusId];
if (!status) continue;
if (status._id) {
if (status._id !== effect.id) continue;
} else {
if (effect.statuses.size !== 1) continue;
}
status.isActive = true;
if (effect.getFlag('core', 'overlay')) status.isOverlay = true;
break;
}
}
// Flag status CSS class
for (const status of Object.values(choices)) {
status.cssClass = [status.isActive ? 'active' : null, status.isOverlay ? 'overlay' : null].filterJoin(' ');
}
return choices;
}
}

View file

@ -10,6 +10,7 @@ export default class AdversarySheet extends DHBaseActorSheet {
actions: {
reactionRoll: AdversarySheet.#reactionRoll,
useItem: this.useItem,
useAction: this.useItem,
toChat: this.toChat
},
window: {

View file

@ -24,6 +24,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
levelManagement: CharacterSheet.#levelManagement,
toggleEquipItem: CharacterSheet.#toggleEquipItem,
useItem: this.useItem, //TODO Fix this
useAction: this.useAction,
toChat: this.toChat
},
window: {
@ -620,6 +621,20 @@ export default class CharacterSheet extends DHBaseActorSheet {
}
}
/**
* Use an action
* @type {ApplicationClickAction}
*/
static async useAction(event, button) {
const item = this.getItem(button);
if (!item) return;
const action = item.system.actions.find(x => x.id === button.dataset.actionId);
if (!action) return;
action.use(event);
}
/**
* Send item to Chat
* @type {ApplicationClickAction}

View file

@ -11,6 +11,7 @@ export default class DhpEnvironment extends DHBaseActorSheet {
},
actions: {
useItem: this.useItem,
useAction: this.useItem,
toChat: this.toChat
},
dragDrop: [{ dragSelector: '.action-section .inventory-item', dropSelector: null }]

View file

@ -61,12 +61,17 @@ export default class FeatureSheet extends DHBaseItemSheet {
static async selectActionType() {
const content = await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/actionTypes/actionType.hbs',
{ types: CONFIG.DH.ACTIONS.actionTypes }
{
types: CONFIG.DH.ACTIONS.actionTypes,
itemName: game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectType')
}
),
title = 'Select Action Type';
title = game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectType');
console.log(this.document);
return foundry.applications.api.DialogV2.prompt({
window: { title },
classes: ['daggerheart', 'dh-style'],
content,
ok: {
label: title,

View file

@ -113,7 +113,7 @@ export const adversaryTypes = {
},
social: {
id: 'social',
label: 'DAGGERHEART.CONFIG.AdversaryTypee.social.label',
label: 'DAGGERHEART.CONFIG.AdversaryType.social.label',
description: 'DAGGERHEART.ACTORS.Adversary.social.description'
},
solo: {

View file

@ -70,7 +70,7 @@ export default class DhCompanion extends BaseDataActor {
type: ['physical'],
value: {
dice: 'd6',
multiplier: 'flat'
multiplier: 'prof'
}
}
]
@ -88,6 +88,12 @@ export default class DhCompanion extends BaseDataActor {
};
}
get proficiency() {
return {
total: this.partner?.system?.proficiency?.total ?? 1
};
}
prepareBaseData() {
const partnerSpellcastingModifier = this.partner?.system?.spellcastingModifiers?.main;
const spellcastingModifier = this.partner?.system?.traits?.[partnerSpellcastingModifier]?.total;

View file

@ -44,6 +44,12 @@ export default class DHArmor extends BaseDataItem {
};
}
get customActions() {
return this.actions.filter(
action => !this.armorFeatures.some(feature => feature.actionIds.includes(action.id))
);
}
async _preUpdate(changes, options, user) {
const allowed = await super._preUpdate(changes, options, user);
if (allowed === false) return false;

View file

@ -74,6 +74,12 @@ export default class DHWeapon extends BaseDataItem {
return [this.attack, ...this.actions];
}
get customActions() {
return this.actions.filter(
action => !this.weaponFeatures.some(feature => feature.actionIds.includes(action.id))
);
}
async _preUpdate(changes, options, user) {
const allowed = await super._preUpdate(changes, options, user);
if (allowed === false) return false;

View file

@ -40,6 +40,10 @@ export default class DhAppearance extends foundry.abstract.DataModel {
outline: new fields.ColorField({ required: true, initial: '#ffffff' }),
edge: new fields.ColorField({ required: true, initial: '#000000' })
})
}),
showGenericStatusEffects: new fields.BooleanField({
initial: true,
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.showGenericStatusEffects.label'
})
};
}

View file

@ -2,7 +2,7 @@ export default class DhRangeMeasurement extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
enabled: new fields.BooleanField({ required: true, initial: false, label: 'DAGGERHEART.GENERAL.enabled' }),
enabled: new fields.BooleanField({ required: true, initial: true, label: 'DAGGERHEART.GENERAL.enabled' }),
melee: new fields.NumberField({ required: true, initial: 5, label: 'DAGGERHEART.CONFIG.Range.melee.name' }),
veryClose: new fields.NumberField({
required: true,

View file

@ -80,12 +80,16 @@ export default class DHItem extends foundry.documents.Item {
async selectActionDialog(prevEvent) {
const content = await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/dialogs/actionSelect.hbs',
{ actions: this.system.actionsList }
{
actions: this.system.actionsList,
itemName: this.name
}
),
title = 'Select Action';
title = game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectAction');
return foundry.applications.api.DialogV2.prompt({
window: { title },
classes: ['daggerheart', 'dh-style'],
content,
ok: {
label: title,

View file

@ -2,15 +2,33 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
async activate(element, options = {}) {
let html = options.html;
if (element.dataset.tooltip?.startsWith('#item#')) {
const item = await foundry.utils.fromUuid(element.dataset.tooltip.slice(6));
const splitValues = element.dataset.tooltip.slice(6).split('#action#');
const itemUuid = splitValues[0];
const actionId = splitValues.length > 1 ? splitValues[1] : null;
const baseItem = await foundry.utils.fromUuid(itemUuid);
const item = actionId ? baseItem.system.actions.find(x => x.id === actionId) : baseItem;
if (item) {
const type = actionId ? 'action' : item.type;
html = await foundry.applications.handlebars.renderTemplate(
`systems/daggerheart/templates/ui/tooltip/${item.type}.hbs`,
item
`systems/daggerheart/templates/ui/tooltip/${type}.hbs`,
{
item: item,
config: CONFIG.DH
}
);
this.tooltip.innerHTML = html;
options.direction = this._determineItemTooltipDirection(element);
}
}
super.activate(element, { ...options, html: html });
}
_determineItemTooltipDirection(element) {
const pos = element.getBoundingClientRect();
const dirs = this.constructor.TOOLTIP_DIRECTIONS;
return dirs[pos.x - this.tooltip.offsetWidth < 0 ? 'DOWN' : 'LEFT'];
}
}

View file

@ -1,47 +1,49 @@
import { getWidthOfText } from './utils.mjs';
export default class RegisterHandlebarsHelpers {
static registerHelpers() {
Handlebars.registerHelper({
times: this.times,
join: this.join,
add: this.add,
subtract: this.subtract,
includes: this.includes,
case: this.case
times: this.times,
damageFormula: this.damageFormula,
damageSymbols: this.damageSymbols,
tertiary: this.tertiary,
signedNumber: this.signedNumber
});
}
static times(nr, block) {
var accum = '';
for (var i = 0; i < nr; ++i) accum += block.fn(i);
return accum;
}
static join(...options) {
return options.slice(0, options.length - 1);
}
static add(a, b) {
const aNum = Number.parseInt(a);
const bNum = Number.parseInt(b);
return (Number.isNaN(aNum) ? 0 : aNum) + (Number.isNaN(bNum) ? 0 : bNum);
}
static subtract(a, b) {
const aNum = Number.parseInt(a);
const bNum = Number.parseInt(b);
return (Number.isNaN(aNum) ? 0 : aNum) - (Number.isNaN(bNum) ? 0 : bNum);
}
static includes(list, item) {
return list.includes(item);
}
static case(value, options) {
if (value == this.switch_value) {
this.switch_break = true;
return options.fn(this);
}
static times(nr, block) {
var accum = '';
for (var i = 0; i < nr; ++i) accum += block.fn(i);
return accum;
}
static damageFormula(attack, actor) {
const traitTotal = actor.system.traits?.[attack.roll.trait]?.total;
const instances = [
attack.damage.parts.map(x => Roll.replaceFormulaData(x.value.getFormula(), actor)).join(' + '),
traitTotal
].filter(x => x);
return instances.join(traitTotal > 0 ? ' + ' : ' - ');
}
static damageSymbols(damageParts) {
const symbols = new Set();
damageParts.forEach(part => symbols.add(...CONFIG.DH.GENERAL.damageTypes[part.type].icon));
return new Handlebars.SafeString(Array.from(symbols).map(symbol => `<i class="fa-solid ${symbol}"></i>`));
}
static tertiary(a, b) {
return a ?? b;
}
}

View file

@ -22,6 +22,7 @@ export const preloadHandlebarsTemplates = async function () {
'systems/daggerheart/templates/actionTypes/beastform.hbs',
'systems/daggerheart/templates/settings/components/settings-item-line.hbs',
'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs',
'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs'
'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs',
'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs'
]);
};

View file

@ -60,7 +60,7 @@ const registerMenuSettings = () => {
});
game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement, {
scope: 'client',
scope: 'world',
config: false,
type: DhRangeMeasurement
});

View file

@ -3,6 +3,8 @@
@import './less/dialog/index.less';
@import './less//hud/index.less';
@import './less/utils/colors.less';
@import './less/utils/fonts.less';
@ -10,4 +12,6 @@
@import './less/ui/index.less';
@import './less/ux/index.less';
@import '../node_modules/@yaireo/tagify/dist/tagify.css';

View file

@ -0,0 +1,19 @@
@import '../../utils/fonts.less';
.application.daggerheart.dh-style {
.actions-list {
display: flex;
flex-direction: column;
gap: 10px;
.action-item {
display: flex;
align-items: center;
gap: 5px;
.label {
font-family: @font-body;
}
}
}
}

View file

@ -0,0 +1,20 @@
@import '../../utils/colors.less';
.daggerheart.dialog.dh-style.views.damage-selection {
.damage-section-container {
display: flex;
flex-direction: column;
gap: 12px;
input[type='text'],
input[type='number'] {
color: light-dark(@dark, @beige);
outline: 2px solid transparent;
transition: all 0.3s ease;
&:hover {
outline: 2px solid light-dark(@dark, @beige);
}
}
}
}

View file

@ -114,15 +114,5 @@
}
}
}
.formula-label {
font-family: @font-body;
font-style: normal;
font-weight: 500;
font-size: 14px;
line-height: 17px;
color: light-dark(@dark, @beige);
}
}
}

View file

@ -4,6 +4,10 @@
@import './level-up/summary-container.less';
@import './level-up/tiers-container.less';
@import './actions/action-list.less';
@import './damage-selection/sheet.less';
@import './downtime/downtime-container.less';
@import './beastform/beastform-container.less';

View file

@ -1,5 +1,6 @@
@import '../utils/colors.less';
@import '../utils/fonts.less';
@import '../utils/mixin.less';
.appTheme({
&.dialog {
@ -40,4 +41,19 @@
}
}
}
.submit-btn {
width: 100%;
height: 38px;
}
.formula-label {
font-family: @font-body;
font-style: normal;
font-weight: 500;
font-size: 14px;
line-height: 17px;
color: light-dark(@dark, @beige);
}
}

View file

@ -35,15 +35,16 @@
}
}
input[type='checkbox'] {
input[type='checkbox'],
input[type='radio'] {
&:checked::after {
color: light-dark(@dark, @golden);
color: light-dark(@dark-40, @golden);
}
&:checked::before {
color: light-dark(transparent, @dark-blue);
color: light-dark(@dark-40, @golden-40);
}
&::before {
color: light-dark(@dark, @beige);
color: light-dark(@dark-40, @golden-40);
}
}
@ -353,6 +354,17 @@
transform: translateY(-20px);
transform-origin: top;
}
.item-buttons {
grid-column: span 3;
display: flex;
gap: 8px;
flex-wrap: wrap;
button {
white-space: nowrap;
}
}
}
.application.setting.dh-style {

View file

@ -4,8 +4,8 @@
// Theme handling
.appTheme({
background: @semi-transparent-dark-blue;
backdrop-filter: blur(9px);
background: @dark-blue-60;
backdrop-filter: blur(10px);
}, {
background: url('../assets/parchments/dh-parchment-light.png') no-repeat center;
});
@ -44,6 +44,8 @@
top: -36px;
min-height: -webkit-fill-available;
transition: opacity 0.3s ease;
padding-bottom: 20px;
margin-bottom: -36px;
.tab {
padding: 0 10px;

View file

@ -0,0 +1 @@
@import './token-hud/token-hud.less';

View file

@ -0,0 +1,10 @@
.daggerheart.placeable-hud {
.col.right {
.palette {
.palette-category-title {
grid-column: span var(--effect-columns);
font-weight: bold;
}
}
}
}

View file

@ -5,6 +5,7 @@
.tab.experiences {
.add-experience-btn {
width: 100%;
height: 38px;
margin-bottom: 12px;
}

View file

@ -10,6 +10,7 @@
.add-feature-btn {
width: 100%;
height: 38px;
margin-bottom: 12px;
}

View file

@ -10,6 +10,7 @@
.add-action-btn {
width: 100%;
height: 38px;
margin-bottom: 12px;
}

View file

@ -10,6 +10,7 @@
.add-feature-btn {
width: 100%;
height: 38px;
margin-bottom: 12px;
}

View file

@ -25,10 +25,12 @@
@dark-blue-10: #18162e10;
@dark-blue-40: #18162e40;
@dark-blue-50: #18162e50;
@dark-blue-60: #18162e60;
@semi-transparent-dark-blue: rgba(24, 22, 46, 0.33);
@dark: #222;
@dark-15: #22222215;
@dark-40: #22222240;
@deep-black: #0e0d15;

View file

@ -0,0 +1 @@
@import './tooltip/tooltip.less';

View file

@ -0,0 +1,106 @@
.daggerheart.dh-style.tooltip {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
.tooltip-title {
margin: 0;
text-align: center;
}
.tooltip-image {
height: 180px;
width: 180px;
}
.tooltip-description {
font-style: italic;
}
.tooltip-sub-title {
margin: 0;
color: light-dark(@dark-blue, @beige);
}
.tooltip-information-section {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4px;
&.triple {
grid-template-columns: 1fr 1fr 1fr;
}
&.border {
border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px;
padding: 2px;
}
.tooltip-information {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
&.full-width {
grid-column: span 2;
}
label {
font-weight: bold;
}
label,
div {
white-space: nowrap;
}
}
}
.tooltip-tags {
width: 100%;
display: flex;
flex-direction: column;
gap: 4px;
.tooltip-tag {
width: 100%;
display: grid;
grid-template-columns: 80px 1fr;
align-items: start;
gap: 8px;
padding: 4px;
border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px;
.tooltip-tag-label-container {
display: flex;
align-items: center;
flex-direction: column;
gap: 2px;
.tooltip-tag-image {
width: 40px;
height: 40px;
}
}
.tooltip-tag-label {
font-weight: bold;
text-align: center;
}
.tooltip-tag-description {
display: flex;
flex-wrap: wrap;
}
}
}
.spaced {
margin-bottom: 4px;
}
}

View file

@ -1,13 +1,12 @@
<form id="action-type-select">
<ul class="unlist list-select">
<header class="dialog-header">
<h1>{{itemName}}</h1>
</header>
<ul class="actions-list">
{{#each types}}
<li>
<label>
{{! TODO: remove dh-icon}}
<dh-icon class="dh-icon fas {{icon}}"></dh-icon>
<span>{{localize name}}</span>
<input type="radio" name="type" value="{{id}}" {{#if (eq @index 0)}}checked{{/if}}>
</label>
<li class="action-item">
<input type="radio" name="type" value="{{id}}" {{#if (eq @index 0)}}checked{{/if}}>
<span class="label">{{localize name}}</span>
</li>
{{/each}}
</ul>

View file

@ -1,12 +1,12 @@
<form id="item-action-select">
<ul class="unlist list-select">
<header class="dialog-header">
<h1>{{itemName}}</h1>
</header>
<ul class="actions-list">
{{#each actions}}
<li>
<label>
<dh-icon><img src="{{ img }}"></dh-icon>
<span>{{ name }}</span>
<input type="radio" name="actionId" value="{{_id}}" {{#if (eq @index 0)}}checked{{/if}}>
</label>
<li class="action-item">
<input type="radio" name="actionId" value="{{_id}}" {{#if (eq @index 0)}}checked{{/if}}>
<span class="label">{{ name }}</span>
</li>
{{/each}}
</ul>

View file

@ -1,33 +1,13 @@
<div>
<section class="damage-section-container">
<header class="dialog-header">
<h1>{{title}}</h1>
</header>
<span class="formula-label"><b>Formula:</b> {{@root.formula}}</span>
<div class="form-group">
<label><strong>{{title}}</strong></label>
<div class="form-fields">
{{!-- <input type="text" value="{{formula}}" disabled /> --}}
<div>{{@root.formula}}</div>
</div>
<div>
<input type="text" value="{{extraFormula}}" name="extraFormula" placeholder="Situational Bonus">
</div>
<input type="text" value="{{extraFormula}}" name="extraFormula" placeholder="Situational Bonus">
</div>
{{!-- {{#each bonusDamage as |damage index|}}
<div class="form-group">
<label><strong>{{damage.description}}</strong></label>
<div class="form-fields">
<label>Enabled</label>
<input style="align-self: baseline;" type="checkbox" name="bonusDamage.{{index}}.initiallySelected" {{checked damage.initiallySelected}} />
{{#if (and damage.initiallySelected damage.hopeIncrease)}}
<label>Hope</label>
<div class="hope-container">
<i data-action="decreaseHopeUse" data-index="{{index}}" class="fa-solid fa-caret-left icon-button {{#if (eq damage.hopeUses 0)}}disabled{{/if}}"></i>
<div>{{damage.hopeUses}}</div>
<i data-action="increaseHopeUse" data-index="{{index}}" class="fa-solid fa-caret-right icon-button {{#if (eq ../hopeUsed ../hope)}}disabled{{/if}}"></i>
</div>
{{/if}}
</div>
</div>
{{/each}} --}}
<footer>
<button data-action="submitRoll">Roll</button>
</footer>
</div>
<button class="submit-btn" data-action="submitRoll">
<i class="fa-solid fa-dice"></i>
<span class="label">Roll</span>
</button>
</section>

View file

@ -0,0 +1,78 @@
<div class="col left">
<div class="attribute elevation" data-tooltip="HUD.Elevation">
<i class="fas fa-angle-up"></i>
<input type="text" name="elevation" value="{{elevation}}" {{disabled (or locked (and isGamePaused (not isGM)))}}>
</div>
<button type="button" class="control-icon" data-action="sort" data-direction="up" data-tooltip="HUD.ToFront">
<img src="{{icons.up}}">
</button>
<button type="button" class="control-icon" data-action="sort" data-direction="down" data-tooltip="HUD.ToBack">
<img src="{{icons.down}}">
</button>
{{#if canConfigure}}
<button type="button" class="control-icon" data-action="config" data-tooltip="HUD.OpenConfig">
<i class="fa-solid fa-gear" inert></i>
</button>
{{/if}}
</div>
<div class="col middle">
<div class="attribute bar2">
{{#if displayBar2}}
<input type="text" name="bar2" value="{{bar2Data.value}}" {{#unless bar2Data.editable}}disabled{{/unless}}>
{{/if}}
</div>
<div class="attribute bar1">
{{#if displayBar1}}
<input type="text" name="bar1" value="{{bar1Data.value}}" {{#unless bar1Data.editable}}disabled{{/unless}}>
{{/if}}
</div>
</div>
<div class="col right">
{{#if isGM}}
<button type="button" class="control-icon {{visibilityClass}}" data-action="visibility" data-tooltip="HUD.ToggleVis">
<img src="{{icons.visibility}}">
</button>
{{/if}}
<button type="button" class="control-icon" data-action="togglePalette" data-palette="effects" data-tooltip="HUD.AssignStatusEffects">
<img src="{{icons.effects}}">
</button>
<div class="palette status-effects" data-palette="effects">
{{#each systemStatusEffects as |status|}}
<img class="effect-control {{status.cssClass}}" src="{{status.src}}" data-action="effect" data-status-id="{{status.id}}" {{#if status.title}}data-tooltip-text="{{status.title}}"{{/if}}>
{{/each}}
{{#if genericStatusEffects}}
<label class="palette-category-title">{{localize "DAGGERHEART.APPLICATIONS.HUD.tokenHUD.genericEffects"}}</label>
{{#each genericStatusEffects as |status|}}
<img class="effect-control {{status.cssClass}}" src="{{status.src}}" data-action="effect" data-status-id="{{status.id}}" {{#if status.title}}data-tooltip-text="{{status.title}}"{{/if}}>
{{/each}}
{{/if}}
</div>
<button type="button" class="control-icon" data-action="togglePalette" data-palette="movementActions" data-tooltip="HUD.SelectMovementAction">
<i class="{{movementActionsIcon}}" inert></i>
</button>
<div class="palette movement-actions" data-palette="movementActions">
{{#each movementActions as |action|}}
<a class="movement-action-control {{action.cssClass}}" data-action="movementAction" data-movement-action="{{action.id}}">
<span>{{#if action.icon}}<i class="{{action.icon}} fa-fw" inert></i>{{/if}} {{action.label}}</span>
</a>
{{/each}}
</div>
<button type="button" class="control-icon {{targetClass}}" data-action="target" data-tooltip="HUD.ToggleTargetState">
<i class="fa-solid fa-bullseye" inert></i>
</button>
{{#if canToggleCombat}}
<button type="button" class="control-icon {{combatClass}}" data-action="combat" data-tooltip="HUD.ToggleCombatState">
<img src="{{icons.combat}}">
</button>
{{/if}}
</div>

View file

@ -1,5 +1,6 @@
<div>
{{formGroup settingFields.schema.fields.displayFear value=settingFields._source.displayFear localize=true}}
{{formGroup settingFields.schema.fields.showGenericStatusEffects value=settingFields._source.showGenericStatusEffects localize=true}}
<fieldset>
<legend>{{localize "DAGGERHEART.SETTINGS.Menu.appearance.duality"}}</legend>

View file

@ -17,7 +17,7 @@
{{/each}}
{{else}}
{{#each values}}
{{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=this type=../type hideControls=../hideControls }}
{{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=this type=../type hideControls=../hideControls featureType=true }}
{{/each}}
{{#each adversaries as |adversary|}}

View file

@ -175,4 +175,12 @@
<span></span>
{{/unless}}
<div class="item-description">{{#unless isSidebar}}{{{item.system.description}}}{{/unless}}</div>
{{#if featureType}}
<div class="item-buttons">
{{#each item.system.actions as | action |}}
<button type="button" data-action="useAction" data-action-id="{{action.id}}">{{action.name}}</button>
{{/each}}
</div>
{{/if}}
</li>

View file

@ -10,6 +10,7 @@
<div class="action-item"
data-action="editAction"
data-index="{{index}}"
data-tooltip="{{concat "#item#" @root.document.uuid "#action#" action.id}}"
>
<img class="image" src="{{action.img}}" />
<span>{{action.name}}</span>

View file

@ -11,7 +11,7 @@
data-action="editFeature"
id="{{feature.id}}"
>
<img class="image" src="{{feature.img}}" />
<img class="image" src="{{feature.img}}" data-tooltip="{{concat "#item#" feature.uuid}}" />
<span>{{feature.name}}</span>
<div class="controls">
<a data-action="removeFeature" id="{{feature.id}}"><i class="fa-solid fa-trash"></i></a>

View file

@ -4,7 +4,7 @@
<line-div></line-div>
<h1 class='item-name'><input type='text' name='name' value='{{source.name}}' /></h1>
<div class='item-description'>
<h3>{{localize (concat 'TYPES.Item.feature' source.system.type)}}</h3>
<h3>{{localize 'TYPES.Item.feature'}}</h3>
</div>
</div>
</header>

View file

@ -0,0 +1,83 @@
<div class="daggerheart dh-style tooltip">
<h2 class="tooltip-title">{{item.name}}</h2>
<img class="tooltip-image" src="{{item.img}}" />
<div class="tooltip-description">{{{item.description}}}</div>
{{#if item.uses.max}}
<h4 class="tooltip-sub-title">{{localize "DAGGERHEART.GENERAL.uses"}}</h4>
<div class="tooltip-information-section triple spaced">
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.used"}}</label>
<div>{{item.uses.value}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.max"}}</label>
<div>{{item.uses.max}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.recovery"}}</label>
{{#with (lookup config.GENERAL.refreshTypes item.uses.recovery) as | type |}}
<div>{{localize type.label}}</div>
{{/with}}
</div>
</div>
{{/if}}
{{#if (gt item.cost.length 0)}}
<h4 class="tooltip-sub-title">{{localize "DAGGERHEART.GENERAL.Cost.plural"}}</h4>
{{#each item.cost as | cost |}}
<div class="tooltip-information-section border spaced">
<div class="tooltip-information">
<label>{{localize "Type"}}</label>
{{#with (lookup @root.config.GENERAL.abilityCosts cost.type) as | type |}}
<div>{{localize type.label}}</div>
{{/with}}
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.value"}}</label>
<div>{{cost.value}}</div>
</div>
{{#if cost.scalable}}
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.scalable"}}</label>
<div>{{localize "DAGGERHEART.GENERAL.true"}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.value"}}</label>
<div>{{cost.step}}</div>
</div>
{{/if}}
</div>
{{/each}}
{{/if}}
{{#if (or item.range item.target)}}
<h4 class="tooltip-sub-title">{{localize "DAGGERHEART.UI.Tooltip.rangeAndTarget"}}</h4>
<div class="tooltip-information-section border spaced">
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.range"}}</label>
<div>
{{#if item.range}}
{{#with (lookup @root.config.GENERAL.range item.range) as | range |}}
<div>{{localize range.label}}</div>
{{/with}}
{{else}}
<div>{{localize "DAGGERHEART.GENERAL.none"}}</div>
{{/if}}
</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.target"}}</label>
<div>
{{#if item.target.type}}
{{#with (lookup @root.config.ACTIONS.targetTypes item.target.type) as | target |}}
<div>{{@root.item.target.amount}} {{localize target.label}}</div>
{{/with}}
{{else}}
<div>{{localize "DAGGERHEART.GENERAL.none"}}</div>
{{/if}}
</div>
</div>
</div>
{{/if}}
</div>

View file

@ -0,0 +1,64 @@
<div class="daggerheart dh-style tooltip">
<h2 class="tooltip-title">{{item.name}}</h2>
<img class="tooltip-image" src="{{item.img}}" />
<div class="tooltip-description">{{{item.system.description}}}</div>
<div class="tooltip-information-section triple spaced">
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.Tiers.singular"}}</label>
{{#with (lookup config.GENERAL.tiers item.system.tier) as | tier |}}
<div>{{localize tier.label}}</div>
{{/with}}
</div>
<div class="tooltip-information">
<label>{{localize "Type"}}</label>
{{#with (lookup config.ACTOR.adversaryTypes item.system.type) as | type |}}
<div>{{localize type.label}}</div>
{{/with}}
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.ACTORS.Adversary.FIELDS.difficulty.label"}}</label>
<div>{{item.system.difficulty}}</div>
</div>
</div>
<div class="tooltip-information-section spaced">
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.hitPoints"}}</label>
<div>{{item.system.resources.hitPoints.max}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.stress"}}</label>
<div>{{item.system.resources.stress.max}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.major"}}</label>
<div>{{item.system.damageThresholds.major}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.severe"}}</label>
<div>{{item.system.damageThresholds.severe}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.attack"}}</label>
<div>{{numberFormat item.system.attack.roll.bonus sign=true}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.damage"}}</label>
<div>{{damageFormula item.system.attack item}}</div>
</div>
</div>
<strong>{{localize "DAGGERHEART.GENERAL.Experience.plural"}}</strong>
{{#each item.system.experiences as | experience |}}
<div>{{experience.name}} {{numberFormat experience.total sign=true}}</div>
{{/each}}
<div class="tooltip-information-section">
<div class="tooltip-information full-width">
<label>{{localize "DAGGERHEART.ACTORS.Adversary.FIELDS.motivesAndTactics.label"}}</label>
<div>{{item.system.motivesAndTactics}}</div>
</div>
</div>
{{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.features }}
</div>

View file

@ -1,5 +1,37 @@
<div>
<div>{{name}}</div>
<img src="{{img}}" />
<div>{{{system.description}}}</div>
<div class="daggerheart dh-style tooltip">
<h2 class="tooltip-title">{{item.name}}</h2>
<img class="tooltip-image" src="{{item.img}}" />
<div class="tooltip-description">{{{item.system.description}}}</div>
<div class="tooltip-information-section">
<div class="tooltip-information full-width">
<label>{{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}</label>
<div>{{item.system.baseScore}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.major"}}</label>
<div>{{item.system.baseThresholds.major}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.severe"}}</label>
<div>{{item.system.baseThresholds.severe}}</div>
</div>
</div>
{{#if (gt item.system.armorFeatures.length 0)}}<h4 class="tooltip-sub-title">{{localize "DAGGERHEART.GENERAL.features"}}</h4>{{/if}}
<div class="tooltip-tags">
{{#each item.system.armorFeatures}}
{{#with (lookup ../config.ITEM.armorFeatures this.value) as | feature | }}
<div class="tooltip-tag">
<div class="tooltip-tag-label-container">
<div class="tooltip-tag-label">{{localize feature.label}}</div>
</div>
<div class="tooltip-tag-description">{{{localize feature.description}}}</div>
</div>
{{/with}}
{{/each}}
</div>
{{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.customActions label=(localize "DAGGERHEART.GENERAL.Action.plural")}}
</div>

View file

@ -1,6 +0,0 @@
<div>
<div>{{name}}</div>
<img src="{{system.tokenImg}}" />
<div>{{{system.examples}}}</div>
<div>{{system.advantageOn}}</div>
</div>

View file

@ -0,0 +1,14 @@
<div class="daggerheart dh-style tooltip">
<h2 class="tooltip-title">{{item.name}}</h2>
<img class="tooltip-image" src="{{item.img}}" />
<div class="tooltip-description">{{{item.system.description}}}</div>
<div class="tooltip-information-section">
<div class="tooltip-information full-width">
<label>{{localize "DAGGERHEART.GENERAL.quantity"}}</label>
<div>{{item.system.quantity}}</div>
</div>
</div>
{{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }}
</div>

View file

@ -1,5 +1,31 @@
<div>
<div>{{name}}</div>
<img src="{{img}}" />
<div>{{{system.description}}}</div>
<div class="daggerheart dh-style tooltip">
<h2 class="tooltip-title">{{item.name}}</h2>
<img class="tooltip-image" src="{{item.img}}" />
<div class="tooltip-description">{{{item.system.description}}}</div>
<div class="tooltip-information-section">
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.Domain.single"}}</label>
{{#with (lookup config.DOMAIN.domains item.system.domain) as | domain |}}
<div>{{localize domain.label}}</div>
{{/with}}
</div>
<div class="tooltip-information">
<label>{{localize "Type"}}</label>
{{#with (lookup config.DOMAIN.cardTypes item.system.type) as | type |}}
<div>{{localize type.label}}</div>
{{/with}}
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.level"}}</label>
<div>{{item.system.level}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}</label>
<div>{{item.system.recallCost}}</div>
</div>
</div>
{{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }}
</div>

View file

@ -0,0 +1,8 @@
<div class="daggerheart dh-style tooltip">
<h2 class="tooltip-title">{{item.name}}</h2>
<img class="tooltip-image" src="{{item.img}}" />
<div class="tooltip-description">{{{item.system.description}}}</div>
{{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }}
{{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.effects label=(localize "DAGGERHEART.GENERAL.Effect.plural") }}
</div>

View file

@ -0,0 +1,7 @@
<div class="daggerheart dh-style tooltip">
<h2 class="tooltip-title">{{item.name}}</h2>
<img class="tooltip-image" src="{{item.img}}" />
<div class="tooltip-description">{{{item.system.description}}}</div>
{{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }}
</div>

View file

@ -0,0 +1,12 @@
{{#if (gt features.length 0)}}<h4 class="tooltip-sub-title">{{label}}</h4>{{/if}}
<div class="tooltip-tags">
{{#each features as | feature |}}
<div class="tooltip-tag">
<div class="tooltip-tag-label-container">
<div class="tooltip-tag-label">{{localize feature.name}}</div>
{{#if feature.img}}<img class="tooltip-tag-image" src="{{feature.img}}" />{{/if}}
</div>
<div class="tooltip-tag-description">{{{localize (tertiary feature.description feature.system.description)}}}</div>
</div>
{{/each}}
</div>

View file

@ -1,5 +1,56 @@
<div>
<div>{{name}}</div>
<img src="{{img}}" />
<div>{{{system.description}}}</div>
<div class="daggerheart dh-style tooltip">
<h2 class="tooltip-title">{{item.name}}</h2>
<img class="tooltip-image" src="{{item.img}}" />
<div class="tooltip-description">{{{item.system.description}}}</div>
<div class="tooltip-information-section">
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.ITEMS.Weapon.weaponType"}}</label>
<div>{{#if item.system.secondaryWeapon}}{{localize "DAGGERHEART.ITEMS.Weapon.secondaryWeapon"}}{{else}}{{localize "DAGGERHEART.ITEMS.Weapon.primaryWeapon"}}{{/if}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.burden"}}</label>
{{#with (lookup config.GENERAL.burden item.system.burden) as | burden |}}
<div>{{localize burden.label}}</div>
{{/with}}
</div>
{{#if item.system.attack.roll.trait}}
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.Trait.single"}}</label>
{{#with (lookup config.ACTOR.abilities item.system.attack.roll.trait) as | trait |}}
<div>{{localize trait.label}}</div>
{{/with}}
</div>
{{/if}}
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.range"}}</label>
{{#with (lookup config.GENERAL.range item.system.attack.range) as | range |}}
<div>{{localize range.label}}</div>
{{/with}}
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.damage"}}</label>
<div>{{{damageFormula item.system.attack item.parent}}}</div>
</div>
<div class="tooltip-information">
<label>{{localize "DAGGERHEART.GENERAL.damageType"}}</label>
<div>{{{damageSymbols item.system.attack.damage.parts}}}</div>
</div>
</div>
{{#if (gt item.system.weaponFeatures.length 0)}}<h4 class="tooltip-sub-title">{{localize "DAGGERHEART.GENERAL.features"}}</h4>{{/if}}
<div class="tooltip-tags">
{{#each item.system.weaponFeatures}}
{{#with (lookup ../config.ITEM.weaponFeatures this.value) as | feature | }}
<div class="tooltip-tag">
<div class="tooltip-tag-label-container">
<div class="tooltip-tag-label">{{localize feature.label}}</div>
</div>
<div class="tooltip-tag-description">{{{localize feature.description}}}</div>
</div>
{{/with}}
{{/each}}
</div>
{{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.customActions label=(localize "DAGGERHEART.GENERAL.Action.plural") }}
</div>