mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Merge branch 'main' of https://github.com/Foundryborne/daggerheart into chat-levelup-summary
This commit is contained in:
commit
0bdcb07690
40 changed files with 387 additions and 232 deletions
|
|
@ -2376,7 +2376,6 @@
|
|||
"maxDomains": { "label": "Max Class Domains", "hint": "Max domains you can set on a class" }
|
||||
},
|
||||
"currency": {
|
||||
"enabled": "Enable Overrides",
|
||||
"title": "Currency Overrides",
|
||||
"currencyName": "Currency Name",
|
||||
"coinName": "Coin Name",
|
||||
|
|
@ -2580,6 +2579,7 @@
|
|||
"evasionMin": "Evasion (Min)",
|
||||
"evasionMax": "Evasion (Max)",
|
||||
"subtype": "Subtype",
|
||||
"missing": "<i>Missing</i>",
|
||||
"folders": {
|
||||
"characters": "Characters",
|
||||
"adversaries": "Adversaries",
|
||||
|
|
@ -2633,7 +2633,7 @@
|
|||
"cardTooHighLevel": "The card is too high level!",
|
||||
"duplicateCard": "You cannot select the same card more than once.",
|
||||
"duplicateCharacter": "This actor is already registered in the party members list.",
|
||||
"onlyCharactersInPartySheet": "You can drag only characters to a party sheet.",
|
||||
"onlyCharactersInPartySheet": "You can only drag characters, companions and adverasries to the party sheet.",
|
||||
"notPrimary": "The weapon is not a primary weapon!",
|
||||
"notSecondary": "The weapon is not a secondary weapon!",
|
||||
"itemTooHighTier": "The item must be from Tier1",
|
||||
|
|
@ -2670,7 +2670,8 @@
|
|||
"subclassAlreadyLinked": "{name} is already a subclass in the class {class}. Remove it from there if you want it to be a subclass to this class.",
|
||||
"gmRequired": "This action requires an online GM",
|
||||
"gmOnly": "This can only be accessed by the GM",
|
||||
"noActorOwnership": "You do not have permissions for this character"
|
||||
"noActorOwnership": "You do not have permissions for this character",
|
||||
"documentIsMissing": "The {documentType} is missing from the world."
|
||||
},
|
||||
"Sidebar": {
|
||||
"daggerheartMenu": {
|
||||
|
|
|
|||
|
|
@ -178,10 +178,17 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
|||
}
|
||||
|
||||
static async takeDowntime() {
|
||||
const moves = Object.values(this.moveData).flatMap(category => {
|
||||
return Object.values(category.moves)
|
||||
.filter(x => x.selected)
|
||||
.flatMap(move => [...Array(move.selected).keys()].map(_ => move));
|
||||
const moves = Object.keys(this.moveData).flatMap(categoryKey => {
|
||||
const category = this.moveData[categoryKey];
|
||||
return Object.keys(category.moves)
|
||||
.filter(x => category.moves[x].selected)
|
||||
.flatMap(key => {
|
||||
const move = category.moves[key];
|
||||
return [...Array(move.selected).keys()].map(_ => ({
|
||||
...move,
|
||||
movePath: `${categoryKey}.moves.${key}`
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
CONFIG.DH.SETTINGS.gameSettings.appearance
|
||||
).showGenericStatusEffects;
|
||||
if (!useGeneric) {
|
||||
partContext.statuses = Object.values(CONFIG.DH.GENERAL.conditions).map(status => ({
|
||||
partContext.statuses = Object.values(CONFIG.DH.GENERAL.conditions()).map(status => ({
|
||||
value: status.id,
|
||||
label: game.i18n.localize(status.name)
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -210,26 +210,33 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
context.resources.stress.emptyPips =
|
||||
context.resources.stress.max < maxResource ? maxResource - context.resources.stress.max : 0;
|
||||
|
||||
context.inventory = {
|
||||
currency: {
|
||||
title: game.i18n.localize('DAGGERHEART.CONFIG.Gold.title'),
|
||||
coins: game.i18n.localize('DAGGERHEART.CONFIG.Gold.coins'),
|
||||
handfuls: game.i18n.localize('DAGGERHEART.CONFIG.Gold.handfuls'),
|
||||
bags: game.i18n.localize('DAGGERHEART.CONFIG.Gold.bags'),
|
||||
chests: game.i18n.localize('DAGGERHEART.CONFIG.Gold.chests')
|
||||
}
|
||||
};
|
||||
context.inventory = { currencies: {} };
|
||||
const { title, ...currencies } = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Homebrew
|
||||
).currency;
|
||||
for (let key in currencies) {
|
||||
context.inventory.currencies[key] = {
|
||||
...currencies[key],
|
||||
field: context.systemFields.gold.fields[key],
|
||||
value: context.source.system.gold[key]
|
||||
};
|
||||
}
|
||||
// context.inventory = {
|
||||
// currency: {
|
||||
// title: game.i18n.localize('DAGGERHEART.CONFIG.Gold.title'),
|
||||
// coins: game.i18n.localize('DAGGERHEART.CONFIG.Gold.coins'),
|
||||
// handfuls: game.i18n.localize('DAGGERHEART.CONFIG.Gold.handfuls'),
|
||||
// bags: game.i18n.localize('DAGGERHEART.CONFIG.Gold.bags'),
|
||||
// chests: game.i18n.localize('DAGGERHEART.CONFIG.Gold.chests')
|
||||
// }
|
||||
// };
|
||||
|
||||
context.beastformActive = this.document.effects.find(x => x.type === 'beastform');
|
||||
|
||||
const homebrewCurrency = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).currency;
|
||||
if (homebrewCurrency.enabled) {
|
||||
context.inventory.currency = homebrewCurrency;
|
||||
}
|
||||
|
||||
if (context.inventory.length === 0) {
|
||||
context.inventory = Array(1).fill(Array(5).fill([]));
|
||||
}
|
||||
// if (context.inventory.length === 0) {
|
||||
// context.inventory = Array(1).fill(Array(5).fill([]));
|
||||
// }
|
||||
|
||||
return context;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { socketEvent } from '../../../systemRegistration/socket.mjs';
|
|||
import GroupRollDialog from '../../dialogs/group-roll-dialog.mjs';
|
||||
import DhpActor from '../../../documents/actor.mjs';
|
||||
import DHItem from '../../../documents/item.mjs';
|
||||
import DhParty from '../../../data/actor/party.mjs';
|
||||
|
||||
export default class Party extends DHBaseActorSheet {
|
||||
constructor(options) {
|
||||
|
|
@ -19,7 +20,8 @@ export default class Party extends DHBaseActorSheet {
|
|||
static DEFAULT_OPTIONS = {
|
||||
classes: ['party'],
|
||||
position: {
|
||||
width: 550
|
||||
width: 550,
|
||||
height: 900,
|
||||
},
|
||||
window: {
|
||||
resizable: true
|
||||
|
|
@ -79,6 +81,9 @@ export default class Party extends DHBaseActorSheet {
|
|||
}
|
||||
};
|
||||
|
||||
static ALLOWED_ACTOR_TYPES = ['character', 'companion', 'adversary'];
|
||||
static DICE_ROLL_ACTOR_TYPES = ['character'];
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
this._createFilterMenus();
|
||||
|
|
@ -92,23 +97,17 @@ export default class Party extends DHBaseActorSheet {
|
|||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
|
||||
context.inventory = {
|
||||
currency: {
|
||||
title: game.i18n.localize('DAGGERHEART.CONFIG.Gold.title'),
|
||||
coins: game.i18n.localize('DAGGERHEART.CONFIG.Gold.coins'),
|
||||
handfuls: game.i18n.localize('DAGGERHEART.CONFIG.Gold.handfuls'),
|
||||
bags: game.i18n.localize('DAGGERHEART.CONFIG.Gold.bags'),
|
||||
chests: game.i18n.localize('DAGGERHEART.CONFIG.Gold.chests')
|
||||
}
|
||||
};
|
||||
|
||||
const homebrewCurrency = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).currency;
|
||||
if (homebrewCurrency.enabled) {
|
||||
context.inventory.currency = homebrewCurrency;
|
||||
}
|
||||
|
||||
if (context.inventory.length === 0) {
|
||||
context.inventory = Array(1).fill(Array(5).fill([]));
|
||||
context.inventory = { currencies: {} };
|
||||
const { title, ...currencies } = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Homebrew
|
||||
).currency;
|
||||
for (let key in currencies) {
|
||||
context.inventory.currencies[key] = {
|
||||
...currencies[key],
|
||||
field: context.systemFields.gold.fields[key],
|
||||
value: context.source.system.gold[key]
|
||||
};
|
||||
}
|
||||
|
||||
return context;
|
||||
|
|
@ -277,13 +276,17 @@ export default class Party extends DHBaseActorSheet {
|
|||
}
|
||||
|
||||
static async #tagTeamRoll() {
|
||||
new game.system.api.applications.dialogs.TagTeamDialog(this.document.system.partyMembers).render({
|
||||
new game.system.api.applications.dialogs.TagTeamDialog(
|
||||
this.document.system.partyMembers.filter(x => Party.DICE_ROLL_ACTOR_TYPES.includes(x.type))
|
||||
).render({
|
||||
force: true
|
||||
});
|
||||
}
|
||||
|
||||
static async #groupRoll(params) {
|
||||
new GroupRollDialog(this.document.system.partyMembers).render({ force: true });
|
||||
static async #groupRoll(_params) {
|
||||
new GroupRollDialog(
|
||||
this.document.system.partyMembers.filter(x => Party.DICE_ROLL_ACTOR_TYPES.includes(x.type))
|
||||
).render({ force: true });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -453,17 +456,17 @@ export default class Party extends DHBaseActorSheet {
|
|||
event.stopPropagation();
|
||||
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
const item = await foundry.utils.fromUuid(data.uuid);
|
||||
const document = await foundry.utils.fromUuid(data.uuid);
|
||||
|
||||
if (item instanceof DhpActor) {
|
||||
if (document instanceof DhpActor && Party.ALLOWED_ACTOR_TYPES.includes(document.type)) {
|
||||
const currentMembers = this.document.system.partyMembers.map(x => x.uuid);
|
||||
if (currentMembers.includes(data.uuid)) {
|
||||
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.duplicateCharacter'));
|
||||
}
|
||||
|
||||
await this.document.update({ 'system.partyMembers': [...currentMembers, item.uuid] });
|
||||
} else if (item instanceof DHItem) {
|
||||
this.document.createEmbeddedDocuments('Item', [item.toObject()]);
|
||||
await this.document.update({ 'system.partyMembers': [...currentMembers, document.uuid] });
|
||||
} else if (document instanceof DHItem) {
|
||||
this.document.createEmbeddedDocuments('Item', [document.toObject()]);
|
||||
} else {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.onlyCharactersInPartySheet'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,12 +132,21 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
}
|
||||
|
||||
async actionUseButton(event, message) {
|
||||
const { moveIndex, actionIndex } = event.currentTarget.dataset;
|
||||
const { moveIndex, actionIndex, movePath } = event.currentTarget.dataset;
|
||||
const parent = await foundry.utils.fromUuid(message.system.actor);
|
||||
const actionType = message.system.moves[moveIndex].actions[actionIndex];
|
||||
const cls = game.system.api.models.actions.actionsTypes[actionType.type];
|
||||
const action = new cls(
|
||||
{ ...actionType, _id: foundry.utils.randomID(), name: game.i18n.localize(actionType.name) },
|
||||
{
|
||||
...actionType,
|
||||
_id: foundry.utils.randomID(),
|
||||
name: game.i18n.localize(actionType.name),
|
||||
originItem: {
|
||||
type: CONFIG.DH.ITEM.originItemType.restMove,
|
||||
itemPath: movePath,
|
||||
actionIndex: actionIndex
|
||||
}
|
||||
},
|
||||
{ parent: parent.system }
|
||||
);
|
||||
|
||||
|
|
@ -192,9 +201,18 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
|
||||
async groupRollButton(event, message) {
|
||||
const path = event.currentTarget.dataset.path;
|
||||
const isLeader = path === 'leader';
|
||||
const { actor: actorData, trait } = foundry.utils.getProperty(message.system, path);
|
||||
const actor = game.actors.get(actorData._id);
|
||||
|
||||
if (!actor) {
|
||||
return ui.notifications.error(
|
||||
game.i18n.format('DAGGERHEART.UI.Notifications.documentIsMissing', {
|
||||
documentType: game.i18n.localize('TYPES.Actor.character')
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (!actor.testUserPermission(game.user, 'OWNER')) {
|
||||
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.noActorOwnership'));
|
||||
}
|
||||
|
|
@ -214,7 +232,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
hasRoll: true,
|
||||
skips: {
|
||||
createMessage: true,
|
||||
resources: true
|
||||
resources: !isLeader
|
||||
}
|
||||
};
|
||||
const result = await actor.diceRoll({
|
||||
|
|
@ -225,6 +243,9 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
})
|
||||
});
|
||||
|
||||
if (!result) return;
|
||||
await game.system.api.fields.ActionFields.CostField.execute.call({ actor }, result);
|
||||
|
||||
const newMessageData = foundry.utils.deepClone(message.system);
|
||||
foundry.utils.setProperty(newMessageData, `${path}.result`, result.roll);
|
||||
const renderData = { system: new game.system.api.models.chatMessages.config.groupRoll(newMessageData) };
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
const property = foundry.utils.getProperty(item, field.key);
|
||||
if (Array.isArray(property)) property.join(', ');
|
||||
if (typeof field.format !== 'function') return property ?? '-';
|
||||
return field.format(property);
|
||||
return game.i18n.localize(field.format(property));
|
||||
}
|
||||
|
||||
formatChoices(data) {
|
||||
|
|
@ -430,7 +430,7 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
if (matchesMenu) this.#filteredItems.browser.input.add(item.id);
|
||||
|
||||
const { search } = this.#filteredItems.browser;
|
||||
li.hidden = !(search.has(item.id) && matchesMenu);
|
||||
li.hidden = !((this.#search.browser.query.length === 0 || search.has(item.id)) && matchesMenu);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -469,6 +469,7 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
|
||||
static resetFilters() {
|
||||
this.render({ force: true });
|
||||
this.loadItems();
|
||||
}
|
||||
|
||||
static getFolderConfig(folder, property = 'columns') {
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ export const typeConfig = {
|
|||
{
|
||||
key: 'system.linkedClass',
|
||||
label: 'Class',
|
||||
format: linkedClass => linkedClass.name
|
||||
format: linkedClass => linkedClass?.name ?? 'DAGGERHEART.UI.ItemBrowser.missing'
|
||||
},
|
||||
{
|
||||
key: 'system.spellcastingTrait',
|
||||
|
|
@ -375,10 +375,12 @@ export const typeConfig = {
|
|||
key: 'system.linkedClass.uuid',
|
||||
label: 'Class',
|
||||
choices: items => {
|
||||
const list = items.map(item => ({
|
||||
value: item.system.linkedClass.uuid,
|
||||
label: item.system.linkedClass.name
|
||||
}));
|
||||
const list = items
|
||||
.filter(item => item.system.linkedClass)
|
||||
.map(item => ({
|
||||
value: item.system.linkedClass.uuid,
|
||||
label: item.system.linkedClass.name
|
||||
}));
|
||||
return list.reduce((a, c) => {
|
||||
if (!a.find(i => i.value === c.value)) a.push(c);
|
||||
return a;
|
||||
|
|
|
|||
|
|
@ -1547,3 +1547,8 @@ export const beastformTypes = {
|
|||
label: 'DAGGERHEART.CONFIG.BeastformType.hybrid'
|
||||
}
|
||||
};
|
||||
|
||||
export const originItemType = {
|
||||
itemCollection: 'itemCollection',
|
||||
restMove: 'restMove'
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import DhpActor from '../../documents/actor.mjs';
|
||||
import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs';
|
||||
import { ActionMixin } from '../fields/actionField.mjs';
|
||||
import { originItemField } from '../chat-message/actorRoll.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
|
|
@ -25,6 +26,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
description: new fields.HTMLField(),
|
||||
img: new fields.FilePathField({ initial: undefined, categories: ['IMAGE'], base64: false }),
|
||||
chatDisplay: new fields.BooleanField({ initial: true, label: 'DAGGERHEART.ACTIONS.Config.displayInChat' }),
|
||||
originItem: originItemField(),
|
||||
actionType: new fields.StringField({
|
||||
choices: CONFIG.DH.ITEM.actionTypes,
|
||||
initial: 'action',
|
||||
|
|
@ -215,6 +217,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
title: `${this.item instanceof CONFIG.Actor.documentClass ? '' : `${this.item.name}: `}${game.i18n.localize(this.name)}`,
|
||||
source: {
|
||||
item: this.item._id,
|
||||
originItem: this.originItem,
|
||||
action: this._id,
|
||||
actor: this.actor.uuid
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ export default class BeastformEffect extends BaseEffect {
|
|||
const fields = foundry.data.fields;
|
||||
return {
|
||||
characterTokenData: new fields.SchemaField({
|
||||
usesDynamicToken: new fields.BooleanField({ initial: false }),
|
||||
tokenImg: new fields.FilePathField({
|
||||
categories: ['IMAGE'],
|
||||
base64: false,
|
||||
nullable: true
|
||||
nullable: true,
|
||||
wildcard: true
|
||||
}),
|
||||
tokenRingImg: new fields.FilePathField({
|
||||
initial: 'icons/svg/mystery-man.svg',
|
||||
|
|
@ -38,20 +40,38 @@ export default class BeastformEffect extends BaseEffect {
|
|||
|
||||
async _preDelete() {
|
||||
if (this.parent.parent.type === 'character') {
|
||||
const update = {
|
||||
const baseUpdate = {
|
||||
height: this.characterTokenData.tokenSize.height,
|
||||
width: this.characterTokenData.tokenSize.width,
|
||||
width: this.characterTokenData.tokenSize.width
|
||||
};
|
||||
const update = {
|
||||
...baseUpdate,
|
||||
texture: {
|
||||
src: this.characterTokenData.tokenImg
|
||||
},
|
||||
ring: {
|
||||
enabled: this.characterTokenData.usesDynamicToken,
|
||||
subject: {
|
||||
texture: this.characterTokenData.tokenRingImg
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await updateActorTokens(this.parent.parent, update);
|
||||
const updateToken = token => ({
|
||||
...baseUpdate,
|
||||
'texture': {
|
||||
enabled: this.characterTokenData.usesDynamicToken,
|
||||
src: token.flags.daggerheart.beastformTokenImg
|
||||
},
|
||||
'ring': {
|
||||
subject: {
|
||||
texture: token.flags.daggerheart.beastformSubjectTexture
|
||||
}
|
||||
},
|
||||
'flags.daggerheart': { '-=beastformTokenImg': null, '-=beastformSubjectTexture': null }
|
||||
});
|
||||
|
||||
await updateActorTokens(this.parent.parent, update, updateToken);
|
||||
|
||||
await this.parent.parent.deleteEmbeddedDocuments('Item', this.featureIds);
|
||||
await this.parent.parent.deleteEmbeddedDocuments('ActiveEffect', this.effectIds);
|
||||
|
|
|
|||
|
|
@ -675,6 +675,8 @@ export default class DhCharacter extends BaseDataActor {
|
|||
}
|
||||
|
||||
_getTags() {
|
||||
return [this.class.value?.name, this.class.subclass?.name, this.community?.name, this.ancestry?.name].filter((t) => !!t);
|
||||
return [this.class.value?.name, this.class.subclass?.name, this.community?.name, this.ancestry?.name].filter(
|
||||
t => !!t
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export default class DhParty extends BaseDataActor {
|
|||
|
||||
// Clear this party from all members that aren't deleted
|
||||
for (const member of this.partyMembers) {
|
||||
member.parties?.delete(this.parent);
|
||||
member?.parties?.delete(this.parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,16 @@ const targetsField = () =>
|
|||
})
|
||||
);
|
||||
|
||||
export const originItemField = () =>
|
||||
new fields.SchemaField({
|
||||
type: new fields.StringField({
|
||||
choices: CONFIG.DH.ITEM.originItemType,
|
||||
initial: CONFIG.DH.ITEM.originItemType.itemCollection
|
||||
}),
|
||||
itemPath: new fields.StringField(),
|
||||
actionIndex: new fields.StringField()
|
||||
});
|
||||
|
||||
export default class DHActorRoll extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
return {
|
||||
|
|
@ -35,6 +45,7 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
|
|||
source: new fields.SchemaField({
|
||||
actor: new fields.StringField(),
|
||||
item: new fields.StringField(),
|
||||
originItem: originItemField(),
|
||||
action: new fields.StringField()
|
||||
}),
|
||||
damage: new fields.ObjectField(),
|
||||
|
|
@ -51,14 +62,23 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
|
|||
get actionItem() {
|
||||
const actionActor = this.actionActor;
|
||||
if (!actionActor || !this.source.item) return null;
|
||||
return actionActor.items.get(this.source.item);
|
||||
|
||||
switch (this.source.originItem.type) {
|
||||
case CONFIG.DH.ITEM.originItemType.restMove:
|
||||
const restMoves = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves;
|
||||
return Array.from(foundry.utils.getProperty(restMoves, `${this.source.originItem.itemPath}`).actions)[
|
||||
this.source.originItem.actionIndex
|
||||
];
|
||||
default:
|
||||
const item = actionActor.items.get(this.source.item);
|
||||
return item ? item.system.actionsList?.find(a => a.id === this.source.action) : null;
|
||||
}
|
||||
}
|
||||
|
||||
get action() {
|
||||
const actionActor = this.actionActor,
|
||||
actionItem = this.actionItem;
|
||||
const { actionActor, actionItem: itemAction } = this;
|
||||
if (!this.source.action) return null;
|
||||
if (actionItem) return actionItem.system.actionsList?.find(a => a.id === this.source.action);
|
||||
if (itemAction) return itemAction;
|
||||
else if (actionActor?.system.attack?._id === this.source.action) return actionActor.system.attack;
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,9 @@ export default class DamageField extends fields.SchemaField {
|
|||
});
|
||||
}
|
||||
|
||||
const token = game.scenes.find(x => x.active).tokens.find(x => x.id === target.id);
|
||||
const token = target.id
|
||||
? game.scenes.find(x => x.active).tokens.find(x => x.id === target.id)
|
||||
: actor.prototypeToken;
|
||||
if (config.hasHealing)
|
||||
damagePromises.push(
|
||||
actor.takeHealing(config.damage).then(updates => targetDamage.push({ token, updates }))
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export default class TargetField extends fields.SchemaField {
|
|||
if (!this.target?.type) return (config.targets = []);
|
||||
config.hasTarget = true;
|
||||
let targets;
|
||||
// If the Action is configured as self-targeted, set targets as the owner.
|
||||
// If the Action is configured as self-targeted, set targets as the owner. Probably better way than to fallback to getDependentTokens
|
||||
if (this.target?.type === CONFIG.DH.GENERAL.targetTypes.self.id)
|
||||
targets = [this.actor.token ?? this.actor.prototypeToken];
|
||||
else {
|
||||
|
|
@ -72,17 +72,17 @@ export default class TargetField extends fields.SchemaField {
|
|||
|
||||
/**
|
||||
* Format actor to useful datas for Action roll workflow.
|
||||
* @param {*} actor Actor object to format.
|
||||
* @param {*} token Token object to format.
|
||||
* @returns {*} Formatted Actor.
|
||||
*/
|
||||
static formatTarget(actor) {
|
||||
static formatTarget(token) {
|
||||
return {
|
||||
id: actor.id,
|
||||
actorId: actor.actor.uuid,
|
||||
name: actor.actor.name,
|
||||
img: actor.actor.img,
|
||||
difficulty: actor.actor.system.difficulty,
|
||||
evasion: actor.actor.system.evasion,
|
||||
id: token.id,
|
||||
actorId: token.actor.uuid,
|
||||
name: token.actor.name,
|
||||
img: token.actor.img,
|
||||
difficulty: token.actor.system.difficulty,
|
||||
evasion: token.actor.system.evasion,
|
||||
saved: {
|
||||
value: null,
|
||||
success: null
|
||||
|
|
|
|||
|
|
@ -160,7 +160,6 @@ export default class DHBeastform extends BaseDataItem {
|
|||
this.parent.effects.filter(x => x.type !== 'beastform').map(x => x.toObject())
|
||||
);
|
||||
|
||||
const tokenImages = await this.parent.parent.getTokenImages();
|
||||
const beastformEffect = this.parent.effects.find(x => x.type === 'beastform');
|
||||
await beastformEffect.updateSource({
|
||||
changes: [
|
||||
|
|
@ -175,7 +174,8 @@ export default class DHBeastform extends BaseDataItem {
|
|||
],
|
||||
system: {
|
||||
characterTokenData: {
|
||||
tokenImg: tokenImages[0],
|
||||
usesDynamicToken: this.parent.parent.prototypeToken.ring.enabled,
|
||||
tokenImg: this.parent.parent.prototypeToken.texture.src,
|
||||
tokenRingImg: this.parent.parent.prototypeToken.ring.subject.texture,
|
||||
tokenSize: {
|
||||
height: this.parent.parent.prototypeToken.height,
|
||||
|
|
@ -190,7 +190,7 @@ export default class DHBeastform extends BaseDataItem {
|
|||
|
||||
await this.parent.parent.createEmbeddedDocuments('ActiveEffect', [beastformEffect.toObject()]);
|
||||
|
||||
await updateActorTokens(this.parent.parent, {
|
||||
const prototypeTokenUpdate = {
|
||||
height: this.tokenSize.height,
|
||||
width: this.tokenSize.width,
|
||||
texture: {
|
||||
|
|
@ -201,22 +201,20 @@ export default class DHBeastform extends BaseDataItem {
|
|||
texture: this.tokenRingImg
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const tokenUpdate = token => ({
|
||||
...prototypeTokenUpdate,
|
||||
flags: {
|
||||
daggerheart: {
|
||||
beastformTokenImg: token.texture.src,
|
||||
beastformSubjectTexture: token.ring.subject.texture
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await updateActorTokens(this.parent.parent, prototypeTokenUpdate, tokenUpdate);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_onCreate(_data, _options, userId) {
|
||||
if (userId !== game.user.id) return;
|
||||
|
||||
if (!this.parent.effects.find(x => x.type === 'beastform')) {
|
||||
this.parent.createEmbeddedDocuments('ActiveEffect', [
|
||||
{
|
||||
type: 'beastform',
|
||||
name: game.i18n.localize('DAGGERHEART.ITEMS.Beastform.beastformEffect'),
|
||||
img: 'icons/creatures/abilities/paw-print-pair-purple.webp'
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,16 @@
|
|||
import { defaultRestOptions } from '../../config/generalConfig.mjs';
|
||||
import { ActionsField } from '../fields/actionField.mjs';
|
||||
|
||||
const currencyField = (initial, label) =>
|
||||
new foundry.data.fields.SchemaField({
|
||||
enabled: new foundry.data.fields.BooleanField({ required: true, initial: true }),
|
||||
label: new foundry.data.fields.StringField({
|
||||
required: true,
|
||||
initial,
|
||||
label
|
||||
})
|
||||
});
|
||||
|
||||
export default class DhHomebrew extends foundry.abstract.DataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
|
@ -30,36 +40,15 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
|
|||
initial: () => [2, 1, 1, 0, 0, -1]
|
||||
}),
|
||||
currency: new fields.SchemaField({
|
||||
enabled: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.enabled'
|
||||
}),
|
||||
title: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Gold',
|
||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.currencyName'
|
||||
}),
|
||||
coins: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Coins',
|
||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.coinName'
|
||||
}),
|
||||
handfuls: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Handfuls',
|
||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.handfulName'
|
||||
}),
|
||||
bags: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Bags',
|
||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.bagName'
|
||||
}),
|
||||
chests: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Chests',
|
||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.chestName'
|
||||
})
|
||||
coins: currencyField('Coins', 'DAGGERHEART.SETTINGS.Homebrew.currency.coinName'),
|
||||
handfuls: currencyField('Handfuls', 'DAGGERHEART.SETTINGS.Homebrew.currency.handfulName'),
|
||||
bags: currencyField('Bags', 'DAGGERHEART.SETTINGS.Homebrew.currency.bagName'),
|
||||
chests: currencyField('Chests', 'DAGGERHEART.SETTINGS.Homebrew.currency.chestName')
|
||||
}),
|
||||
restMoves: new fields.SchemaField({
|
||||
longRest: new fields.SchemaField({
|
||||
|
|
@ -146,4 +135,26 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
|
|||
})
|
||||
};
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
_initializeSource(source, options = {}) {
|
||||
source = super._initializeSource(source, options);
|
||||
source.currency.coins = {
|
||||
enabled: source.currency.coins.enabled ?? true,
|
||||
label: source.currency.coins.label || source.currency.coins
|
||||
};
|
||||
source.currency.handfuls = {
|
||||
enabled: source.currency.handfuls.enabled ?? true,
|
||||
label: source.currency.handfuls.label || source.currency.handfuls
|
||||
};
|
||||
source.currency.bags = {
|
||||
enabled: source.currency.bags.enabled ?? true,
|
||||
label: source.currency.bags.label || source.currency.bags
|
||||
};
|
||||
source.currency.chests = {
|
||||
enabled: source.currency.chests.enabled ?? true,
|
||||
label: source.currency.chests.label || source.currency.chests
|
||||
};
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,9 +145,11 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
|||
});
|
||||
|
||||
html.querySelectorAll('.token-target-container').forEach(element => {
|
||||
element.addEventListener('pointerover', this.hoverTarget);
|
||||
element.addEventListener('pointerout', this.unhoverTarget);
|
||||
element.addEventListener('click', this.clickTarget);
|
||||
if (element.dataset.token) {
|
||||
element.addEventListener('pointerover', this.hoverTarget);
|
||||
element.addEventListener('pointerout', this.unhoverTarget);
|
||||
element.addEventListener('click', this.clickTarget);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -251,7 +251,13 @@ export const adjustRange = (rangeVal, decrease) => {
|
|||
return range[rangeKeys[newIndex]];
|
||||
};
|
||||
|
||||
export const updateActorTokens = async (actor, update) => {
|
||||
/**
|
||||
*
|
||||
* @param {DhActor} actor - The actor for which all tokens will run a data update.
|
||||
* @param {string} update - The data update to be applied to all tokens.
|
||||
* @param {func} updateToken - Optional, specific data update for the non-prototype tokens as a function using the token data. Useful to handle wildcard images where each token has a different image but the prototype has a wildcard path.
|
||||
*/
|
||||
export const updateActorTokens = async (actor, update, updateToken) => {
|
||||
await actor.prototypeToken.update({ ...update });
|
||||
|
||||
/* Update the tokens in all scenes belonging to Actor */
|
||||
|
|
@ -259,7 +265,7 @@ export const updateActorTokens = async (actor, update) => {
|
|||
const tokenActor = token.baseActor ?? token.actor;
|
||||
if (token.id && tokenActor?.id === actor.id) {
|
||||
await token.update({
|
||||
...update,
|
||||
...(updateToken ? updateToken(token) : update),
|
||||
_id: token.id
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ export async function runMigrations() {
|
|||
let lastMigrationVersion = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion);
|
||||
if (!lastMigrationVersion) lastMigrationVersion = game.system.version;
|
||||
|
||||
//#region old migrations
|
||||
if (foundry.utils.isNewerVersion('1.1.0', lastMigrationVersion)) {
|
||||
const lockedPacks = [];
|
||||
const compendiumActors = [];
|
||||
|
|
@ -190,6 +191,7 @@ export async function runMigrations() {
|
|||
|
||||
lastMigrationVersion = '1.2.0';
|
||||
}
|
||||
//#endregion
|
||||
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,11 +57,12 @@
|
|||
}
|
||||
|
||||
.currency-section {
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
gap: 10px;
|
||||
padding: 10px 10px 0;
|
||||
|
||||
input {
|
||||
.input {
|
||||
color: light-dark(@dark, @beige);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,11 +61,12 @@
|
|||
}
|
||||
|
||||
.currency-section {
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
gap: 10px;
|
||||
padding: 10px 10px 0;
|
||||
|
||||
input {
|
||||
.input {
|
||||
color: light-dark(@dark, @beige);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ body.game:is(.performance-low, .noblur) {
|
|||
background: light-dark(@dark-blue-40, @dark-golden-40);
|
||||
border-radius: 6px;
|
||||
border: 1px solid light-dark(@dark-blue, @golden);
|
||||
max-width: 230px;
|
||||
width: 230px;
|
||||
height: -webkit-fill-available;
|
||||
|
||||
.actor-name {
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@
|
|||
|
||||
.application.sheet.daggerheart.actor.dh-style.party {
|
||||
.tab {
|
||||
height: -webkit-fill-available;
|
||||
max-height: 514px;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
|
||||
scrollbar-gutter: stable;
|
||||
|
||||
&.active {
|
||||
overflow: auto;
|
||||
|
|
|
|||
|
|
@ -28,12 +28,15 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 6px;
|
||||
|
||||
&:hover {
|
||||
background: @golden-10;
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: @golden-10;
|
||||
}
|
||||
}
|
||||
|
||||
header {
|
||||
|
|
|
|||
|
|
@ -90,11 +90,14 @@
|
|||
background: transparent;
|
||||
transition: all 0.3s ease;
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: @golden-10;
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: @golden-10;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
|
|
|
|||
|
|
@ -21,11 +21,6 @@
|
|||
padding: 8px;
|
||||
--button-size: 0;
|
||||
|
||||
&.used {
|
||||
opacity: 0.5;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&.inactive {
|
||||
background: var(--color-warm-2);
|
||||
color: var(--color-light-1);
|
||||
|
|
@ -35,6 +30,11 @@
|
|||
filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.used {
|
||||
opacity: 0.5;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,21 @@
|
|||
}
|
||||
}
|
||||
|
||||
.toggleable-row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
&.spaced {
|
||||
padding-right: 28.5px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.setting-group-field {
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
"id": "daggerheart",
|
||||
"title": "Daggerheart",
|
||||
"description": "An unofficial implementation of the Daggerheart system",
|
||||
"version": "1.2.1",
|
||||
"version": "1.2.2",
|
||||
"compatibility": {
|
||||
"minimum": "13",
|
||||
"verified": "13.350",
|
||||
"verified": "13.351",
|
||||
"maximum": "13"
|
||||
},
|
||||
"authors": [
|
||||
|
|
|
|||
|
|
@ -29,13 +29,25 @@
|
|||
<legend>
|
||||
{{localize "DAGGERHEART.SETTINGS.Homebrew.currency.title"}}
|
||||
</legend>
|
||||
{{formGroup settingFields.schema.fields.currency.fields.enabled value=settingFields._source.currency.enabled localize=true}}
|
||||
{{formGroup settingFields.schema.fields.currency.fields.title value=settingFields._source.currency.title localize=true}}
|
||||
{{formGroup settingFields.schema.fields.currency.fields.coins value=settingFields._source.currency.coins localize=true}}
|
||||
{{formGroup settingFields.schema.fields.currency.fields.handfuls value=settingFields._source.currency.handfuls localize=true}}
|
||||
{{formGroup settingFields.schema.fields.currency.fields.bags value=settingFields._source.currency.bags localize=true}}
|
||||
{{formGroup settingFields.schema.fields.currency.fields.chests value=settingFields._source.currency.chests localize=true}}
|
||||
|
||||
<div class="toggleable-row spaced">
|
||||
{{formGroup settingFields.schema.fields.currency.fields.title value=settingFields._source.currency.title localize=true}}
|
||||
</div>
|
||||
<div class="toggleable-row">
|
||||
{{formGroup settingFields.schema.fields.currency.fields.coins.fields.label value=settingFields._source.currency.coins.label localize=true}}
|
||||
<input type="checkbox" {{checked settingFields._source.currency.coins.enabled}} disabled />
|
||||
</div>
|
||||
<div class="toggleable-row">
|
||||
{{formGroup settingFields.schema.fields.currency.fields.handfuls.fields.label value=settingFields._source.currency.handfuls.label localize=true}}
|
||||
<input type="checkbox" name="currency.handfuls.enabled" {{checked settingFields._source.currency.handfuls.enabled}} />
|
||||
</div>
|
||||
<div class="toggleable-row">
|
||||
{{formGroup settingFields.schema.fields.currency.fields.bags.fields.label value=settingFields._source.currency.bags.label localize=true}}
|
||||
<input type="checkbox" name="currency.bags.enabled" {{checked settingFields._source.currency.bags.enabled}} />
|
||||
</div>
|
||||
<div class="toggleable-row">
|
||||
{{formGroup settingFields.schema.fields.currency.fields.chests.fields.label value=settingFields._source.currency.chests.label localize=true}}
|
||||
<input type="checkbox" name="currency.chests.enabled" {{checked settingFields._source.currency.chests.enabled}} />
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -13,27 +13,14 @@
|
|||
</div>
|
||||
|
||||
<div class="currency-section">
|
||||
<div class="input">
|
||||
<span>{{localize this.inventory.currency.coins}}</span>
|
||||
{{formInput systemFields.gold.fields.coins value=source.system.gold.coins enriched=source.system.gold.coins
|
||||
localize=true toggled=true}}
|
||||
</div>
|
||||
<div class="input">
|
||||
<span>{{localize this.inventory.currency.handfuls}}</span>
|
||||
{{formInput systemFields.gold.fields.handfuls value=source.system.gold.handfuls
|
||||
enriched=source.system.gold.handfuls localize=true toggled=true}}
|
||||
</div>
|
||||
<div class="input">
|
||||
<span>{{localize this.inventory.currency.bags}}</span>
|
||||
{{formInput systemFields.gold.fields.bags value=source.system.gold.bags enriched=source.system.gold.bags
|
||||
localize=true toggled=true}}
|
||||
</div>
|
||||
<div class="input">
|
||||
<span>{{localize this.inventory.currency.chests}}</span>
|
||||
{{formInput systemFields.gold.fields.chests value=source.system.gold.chests
|
||||
enriched=source.system.gold.chests localize=true toggled=true}}
|
||||
</div>
|
||||
|
||||
{{#each this.inventory.currencies as | currency |}}
|
||||
{{#if currency.enabled}}
|
||||
<div class="input">
|
||||
<span>{{localize currency.label}}</span>
|
||||
{{formInput currency.field value=currency.value enriched=currency.value toggled=true}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<div class="items-section">
|
||||
|
|
|
|||
|
|
@ -16,7 +16,15 @@
|
|||
</div>
|
||||
|
||||
<div class="currency-section">
|
||||
<div class="input">
|
||||
{{#each this.inventory.currencies as | currency |}}
|
||||
{{#if currency.enabled}}
|
||||
<div class="input">
|
||||
<span>{{localize currency.label}}</span>
|
||||
{{formInput currency.field value=currency.value enriched=currency.value toggled=true}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{!-- <div class="input">
|
||||
<span>{{localize this.inventory.currency.coins}}</span>
|
||||
{{formInput systemFields.gold.fields.coins value=source.system.gold.coins enriched=source.system.gold.coins
|
||||
localize=true toggled=true}}
|
||||
|
|
@ -35,7 +43,7 @@
|
|||
<span>{{localize this.inventory.currency.chests}}</span>
|
||||
{{formInput systemFields.gold.fields.chests value=source.system.gold.chests
|
||||
enriched=source.system.gold.chests localize=true toggled=true}}
|
||||
</div>
|
||||
</div> --}}
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
item=actor
|
||||
type='character'
|
||||
isActor=true
|
||||
hideContextMenu=true
|
||||
}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -22,19 +22,21 @@
|
|||
<h2 class="actor-name">{{actor.name}}</h2>
|
||||
<img class="actor-img" src="{{actor.img}}">
|
||||
<div class="resources">
|
||||
<div class="slot-section">
|
||||
<div class="slot-bar">
|
||||
{{#times actor.system.resources.hitPoints.max}}
|
||||
<span class='slot {{#if (gte actor.system.resources.hitPoints.value (add this 1))}}filled{{/if}}'
|
||||
data-action='toggleHitPoints' data-actor-id="{{actor.uuid}}" data-value="{{add this 1}}">
|
||||
</span>
|
||||
{{/times}}
|
||||
{{#unless (eq actor.type 'companion') }}
|
||||
<div class="slot-section">
|
||||
<div class="slot-bar">
|
||||
{{#times actor.system.resources.hitPoints.max}}
|
||||
<span class='slot {{#if (gte actor.system.resources.hitPoints.value (add this 1))}}filled{{/if}}'
|
||||
data-action='toggleHitPoints' data-actor-id="{{actor.uuid}}" data-value="{{add this 1}}">
|
||||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
<div class="slot-label">
|
||||
<span class="label">{{localize "DAGGERHEART.GENERAL.HitPoints.short"}}</span>
|
||||
<span class="value">{{actor.system.resources.hitPoints.value}} / {{actor.system.resources.hitPoints.max}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slot-label">
|
||||
<span class="label">{{localize "DAGGERHEART.GENERAL.HitPoints.short"}}</span>
|
||||
<span class="value">{{actor.system.resources.hitPoints.value}} / {{actor.system.resources.hitPoints.max}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
<div class="slot-section">
|
||||
<div class="slot-bar">
|
||||
|
|
@ -71,26 +73,30 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#unless (or (eq actor.type 'companion') (eq actor.type 'adversary')) }}
|
||||
<div class="hope-section">
|
||||
<h4>{{localize "DAGGERHEART.GENERAL.hope"}}</h4>
|
||||
{{#times actor.system.resources.hope.max}}
|
||||
<span class='hope-value' data-action='toggleHope' data-actor-id="{{actor.uuid}}" data-value="{{add this 1}}">
|
||||
{{#if (gte actor.system.resources.hope.value (add this 1))}}
|
||||
<i class='fa-solid fa-diamond'></i>
|
||||
{{else}}
|
||||
<i class='fa-regular fa-circle'></i>
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
<div class="hope-section">
|
||||
<h4>{{localize "DAGGERHEART.GENERAL.hope"}}</h4>
|
||||
{{#times actor.system.resources.hope.max}}
|
||||
<span class='hope-value' data-action='toggleHope' data-actor-id="{{actor.uuid}}" data-value="{{add this 1}}">
|
||||
{{#if (gte actor.system.resources.hope.value (add this 1))}}
|
||||
<i class='fa-solid fa-diamond'></i>
|
||||
{{else}}
|
||||
<i class='fa-regular fa-circle'></i>
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
<div class="threshold-section">
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.minor"}}</h4>
|
||||
<h4 class="threshold-value">{{actor.system.damageThresholds.major}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.major"}}</h4>
|
||||
<h4 class="threshold-value">{{actor.system.damageThresholds.severe}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.severe"}}</h4>
|
||||
</div>
|
||||
{{#unless (eq actor.type 'companion')}}
|
||||
<div class="threshold-section">
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.minor"}}</h4>
|
||||
<h4 class="threshold-value">{{actor.system.damageThresholds.major}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.major"}}</h4>
|
||||
<h4 class="threshold-value">{{actor.system.damageThresholds.severe}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.severe"}}</h4>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ Parameters:
|
|||
- isGlassy {boolean} : If true, applies the 'glassy' class to the fieldset.
|
||||
- cardView {boolean} : If true and type is 'domainCard', renders using domain card layout.
|
||||
- isActor {boolean} : Passed through to inventory-item partials.
|
||||
- isItem {boolean} : Passed through to inventory-item partials
|
||||
- actorType {boolean} : The actor type of the parent actor
|
||||
- canCreate {boolean} : If true, show createDoc anchor on legend
|
||||
- inVault {boolean} : If true, the domainCard is created with inVault=true
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
Parameters:
|
||||
- type {string} : The type of items in the list
|
||||
- isActor {boolean} : Passed through to inventory-item partials.
|
||||
- isItem {boolean} : Passed through to inventory-item partials
|
||||
- actorType {boolean} : The actor type of the parent actor
|
||||
- categoryAdversary {string} : Category adversary id.
|
||||
- noExtensible {boolean} : If true, the inventory-item-content would be collapsable/extendible else it always be showed
|
||||
|
|
@ -18,7 +19,7 @@ Parameters:
|
|||
|
||||
<li class="inventory-item" data-item-id="{{item.id}}" {{#if (or (eq type 'action' ) (eq type 'attack' ))}}
|
||||
data-action-id="{{item.id}}" {{/if}} data-item-uuid="{{item.uuid}}" data-type="{{type}}" data-no-compendium-edit="{{noCompendiumEdit}}" draggable="true">
|
||||
<div class="inventory-item-header {{#if (eq actorType 'party')}}padded{{/if}}" {{#unless noExtensible}}data-action="toggleExtended" {{/unless}}>
|
||||
<div class="inventory-item-header {{#if hideContextMenu}}padded{{/if}}" {{#unless noExtensible}}data-action="toggleExtended" {{/unless}}>
|
||||
{{!-- Image --}}
|
||||
<div class="img-portait" data-action='{{ifThen (or (hasProperty item "use") (eq type "attack")) "useItem" (ifThen
|
||||
(hasProperty item "toChat" ) "toChat" "editDoc" ) }}' {{#unless hideTooltip}} {{#if (eq type 'attack' )}}
|
||||
|
|
@ -67,7 +68,7 @@ Parameters:
|
|||
{{!-- Controls --}}
|
||||
{{#unless hideControls}}
|
||||
<div class="controls">
|
||||
{{#if isActor}}
|
||||
{{#if isActor}}
|
||||
<a data-action="editDoc" data-tooltip="DAGGERHEART.UI.Tooltip.openActorWorld">
|
||||
<i class="fa-solid fa-globe"></i>
|
||||
</a>
|
||||
|
|
@ -81,7 +82,7 @@ Parameters:
|
|||
<i class='fas fa-trash'></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{else}}
|
||||
{{#unless (eq actorType 'party')}}
|
||||
{{#if (eq type 'weapon')}}
|
||||
<a class="{{#unless item.system.equipped}}unequipped{{/unless}}" data-action="toggleEquipItem"
|
||||
|
|
@ -94,27 +95,30 @@ Parameters:
|
|||
<i class="fa-solid fa-shield"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if (eq type 'domainCard')}}
|
||||
<a data-action="toggleVault"
|
||||
data-tooltip="DAGGERHEART.UI.Tooltip.{{ifThen item.system.inVault 'sendToLoadout' 'sendToVault' }}">
|
||||
<i class="fa-solid {{ifThen item.system.inVault 'fa-arrow-up' 'fa-arrow-down'}}"></i>
|
||||
</a>
|
||||
{{else if (eq type 'effect')}}
|
||||
<a data-action="toggleEffect"
|
||||
data-tooltip="DAGGERHEART.UI.Tooltip.{{ifThen item.disabled 'enableEffect' 'disableEffect' }}">
|
||||
<i class="{{ifThen item.disabled 'fa-solid fa-toggle-off' 'fa-solid fa-toggle-on'}}"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if (hasProperty item "toChat")}}
|
||||
<a data-action="toChat" data-tooltip="DAGGERHEART.UI.Tooltip.sendToChat">
|
||||
<i class="fa-regular fa-message"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<a data-action="editDoc" data-tooltip="DAGGERHEART.UI.Tooltip.openActorWorld">
|
||||
<i class="fa-solid fa-globe"></i>
|
||||
</a>
|
||||
<a data-action="deleteItem" data-tooltip="DAGGERHEART.UI.Tooltip.deleteItem">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</a>
|
||||
{{/unless}}
|
||||
{{#if (eq type 'domainCard')}}
|
||||
<a data-action="toggleVault"
|
||||
data-tooltip="DAGGERHEART.UI.Tooltip.{{ifThen item.system.inVault 'sendToLoadout' 'sendToVault' }}">
|
||||
<i class="fa-solid {{ifThen item.system.inVault 'fa-arrow-up' 'fa-arrow-down'}}"></i>
|
||||
</a>
|
||||
{{else if (eq type 'effect')}}
|
||||
<a data-action="toggleEffect"
|
||||
data-tooltip="DAGGERHEART.UI.Tooltip.{{ifThen item.disabled 'enableEffect' 'disableEffect' }}">
|
||||
<i class="{{ifThen item.disabled 'fa-solid fa-toggle-off' 'fa-solid fa-toggle-on'}}"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if (and (hasProperty item "toChat") (not (eq actorType 'party')))}}
|
||||
<a data-action="toChat" data-tooltip="DAGGERHEART.UI.Tooltip.sendToChat">
|
||||
<i class="fa-regular fa-message"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#unless hideContextMenu}}
|
||||
<a data-action="triggerContextMenu" data-tooltip="DAGGERHEART.UI.Tooltip.moreOptions">
|
||||
<i class="fa-solid fa-ellipsis-vertical"></i>
|
||||
|
|
@ -122,7 +126,7 @@ Parameters:
|
|||
{{/unless}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
<div class="inventory-item-content{{#unless noExtensible}} extensible{{/unless}}">
|
||||
{{!-- Description --}}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<ul class="daggerheart chat damage-summary">
|
||||
{{#each targets}}
|
||||
<li class="token-target-container" data-token="{{this.token.id}}">
|
||||
<li class="token-target-container {{#if this.token.id}}clickable{{/if}}" data-token="{{this.token.id}}">
|
||||
<header>
|
||||
<img src="{{this.token.texture.src}}" />
|
||||
<h2 class="actor-name">{{this.token.name}}</h2>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
</div>
|
||||
</details>
|
||||
{{#each move.actions as | action index |}}
|
||||
<button class="action-use-button" data-move-index="{{@../key}}" data-action-index="{{index}}">
|
||||
<button class="action-use-button" data-move-index="{{@../key}}" data-action-index="{{index}}" data-move-path="{{../movePath}}" >
|
||||
<span>{{localize action.name}}</span>
|
||||
</button>
|
||||
{{/each}}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
</div>
|
||||
<div class="targets-container">
|
||||
{{#each targets}}
|
||||
<div class="token-target-container" data-token="{{this.id}}">
|
||||
<div class="token-target-container {{#if this.id}}clickable{{/if}}" data-token="{{this.id}}">
|
||||
<img src="{{this.texture.src}}" />
|
||||
<h2 class="title">{{this.name}}</h2>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue