mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Merge branch 'main' into feature/death-moves
This commit is contained in:
commit
702de3d42a
32 changed files with 310 additions and 116 deletions
|
|
@ -326,6 +326,7 @@
|
||||||
"equip": "Equip",
|
"equip": "Equip",
|
||||||
"sendToChat": "Send To Chat",
|
"sendToChat": "Send To Chat",
|
||||||
"toLoadout": "Send to Loadout",
|
"toLoadout": "Send to Loadout",
|
||||||
|
"recall": "Recall",
|
||||||
"toVault": "Send to Vault",
|
"toVault": "Send to Vault",
|
||||||
"unequip": "Unequip",
|
"unequip": "Unequip",
|
||||||
"useItem": "Use Item"
|
"useItem": "Use Item"
|
||||||
|
|
@ -1800,7 +1801,9 @@
|
||||||
"label": "Long Rest: Bonus Long Rest Moves",
|
"label": "Long Rest: Bonus Long Rest Moves",
|
||||||
"hint": "The number of extra Long Rest Moves the character can take during a Long Rest."
|
"hint": "The number of extra Long Rest Moves the character can take during a Long Rest."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"target": "Target",
|
||||||
|
"targetSelf": "Self"
|
||||||
},
|
},
|
||||||
"maxLoadout": {
|
"maxLoadout": {
|
||||||
"label": "Max Loadout Cards Bonus"
|
"label": "Max Loadout Cards Bonus"
|
||||||
|
|
|
||||||
|
|
@ -278,19 +278,26 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
'close',
|
'close',
|
||||||
async () => {
|
async () => {
|
||||||
const selected = app.selected.toObject();
|
const selected = app.selected.toObject();
|
||||||
|
const evolved = app.evolved.form ? app.evolved.form.toObject() : null;
|
||||||
const data = await game.system.api.data.items.DHBeastform.getWildcardImage(
|
const data = await game.system.api.data.items.DHBeastform.getWildcardImage(
|
||||||
app.configData.data.parent,
|
app.configData.data.parent,
|
||||||
app.selected
|
evolved ?? app.selected
|
||||||
);
|
);
|
||||||
if (data) {
|
if (data) {
|
||||||
if (!data.selectedImage) selected = null;
|
if (!data.selectedImage) selected = null;
|
||||||
else {
|
else {
|
||||||
if (data.usesDynamicToken) selected.system.tokenRingImg = data.selectedImage;
|
const imageSource = evolved ?? selected;
|
||||||
else selected.system.tokenImg = data.selectedImage;
|
if (imageSource.usesDynamicToken) imageSource.system.tokenRingImg = data.selectedImage;
|
||||||
|
else imageSource.system.tokenImg = data.selectedImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve({ selected: selected, evolved: app.evolved, hybrid: app.hybrid, item: featureItem });
|
resolve({
|
||||||
|
selected: selected,
|
||||||
|
evolved: { ...app.evolved, form: evolved },
|
||||||
|
hybrid: app.hybrid,
|
||||||
|
item: featureItem
|
||||||
|
});
|
||||||
},
|
},
|
||||||
{ once: true }
|
{ once: true }
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -181,12 +181,17 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
.filter(x => category.moves[x].selected)
|
.filter(x => category.moves[x].selected)
|
||||||
.flatMap(key => {
|
.flatMap(key => {
|
||||||
const move = category.moves[key];
|
const move = category.moves[key];
|
||||||
|
const needsTarget = move.actions.filter(x => x.target?.type && x.target.type !== 'self').length > 0;
|
||||||
return [...Array(move.selected).keys()].map(_ => ({
|
return [...Array(move.selected).keys()].map(_ => ({
|
||||||
...move,
|
...move,
|
||||||
movePath: `${categoryKey}.moves.${key}`
|
movePath: `${categoryKey}.moves.${key}`,
|
||||||
|
needsTarget: needsTarget
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
const characters = game.actors.filter(x => x.type === 'character')
|
||||||
|
.filter(x => x.testUserPermission(game.user, 'LIMITED'))
|
||||||
|
.filter(x => x.uuid !== this.actor.uuid);
|
||||||
|
|
||||||
const cls = getDocumentClass('ChatMessage');
|
const cls = getDocumentClass('ChatMessage');
|
||||||
const msg = {
|
const msg = {
|
||||||
|
|
@ -206,7 +211,9 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
`DAGGERHEART.APPLICATIONS.Downtime.${this.shortrest ? 'shortRest' : 'longRest'}.title`
|
`DAGGERHEART.APPLICATIONS.Downtime.${this.shortrest ? 'shortRest' : 'longRest'}.title`
|
||||||
),
|
),
|
||||||
actor: { name: this.actor.name, img: this.actor.img },
|
actor: { name: this.actor.name, img: this.actor.img },
|
||||||
moves: moves
|
moves: moves,
|
||||||
|
characters: characters,
|
||||||
|
selfId: this.actor.uuid
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
flags: {
|
flags: {
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,19 @@ export default class DHAdversarySettings extends DHBaseActorSettings {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async _prepareContext(options) {
|
||||||
|
const context = await super._prepareContext(options);
|
||||||
|
|
||||||
|
const featureForms = ['passive', 'action', 'reaction'];
|
||||||
|
context.features = context.document.system.features.sort((a, b) =>
|
||||||
|
a.system.featureForm !== b.system.featureForm
|
||||||
|
? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm)
|
||||||
|
: a.sort - b.sort
|
||||||
|
);
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,19 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async _prepareContext(options) {
|
||||||
|
const context = await super._prepareContext(options);
|
||||||
|
|
||||||
|
const featureForms = ['passive', 'action', 'reaction'];
|
||||||
|
context.features = context.document.system.features.sort((a, b) =>
|
||||||
|
a.system.featureForm !== b.system.featureForm
|
||||||
|
? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm)
|
||||||
|
: a.sort - b.sort
|
||||||
|
);
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new category entry to the actor.
|
* Adds a new category entry to the actor.
|
||||||
* @type {ApplicationClickAction}
|
* @type {ApplicationClickAction}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,12 @@ export default class AdversarySheet extends DHBaseActorSheet {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
dragDrop: [{ dragSelector: '[data-item-id]', dropSelector: null }]
|
dragDrop: [
|
||||||
|
{
|
||||||
|
dragSelector: '[data-item-id][draggable="true"], [data-item-id] [draggable="true"]',
|
||||||
|
dropSelector: null
|
||||||
|
}
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
|
|
@ -88,6 +93,13 @@ export default class AdversarySheet extends DHBaseActorSheet {
|
||||||
context.resources.stress.emptyPips =
|
context.resources.stress.emptyPips =
|
||||||
context.resources.stress.max < maxResource ? maxResource - context.resources.stress.max : 0;
|
context.resources.stress.max < maxResource ? maxResource - context.resources.stress.max : 0;
|
||||||
|
|
||||||
|
const featureForms = ['passive', 'action', 'reaction'];
|
||||||
|
context.features = this.document.system.features.sort((a, b) =>
|
||||||
|
a.system.featureForm !== b.system.featureForm
|
||||||
|
? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm)
|
||||||
|
: a.sort - b.sort
|
||||||
|
);
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,6 +176,16 @@ export default class AdversarySheet extends DHBaseActorSheet {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @inheritdoc */
|
||||||
|
async _onDragStart(event) {
|
||||||
|
const inventoryItem = event.currentTarget.closest('.inventory-item');
|
||||||
|
if (inventoryItem) {
|
||||||
|
event.dataTransfer.setDragImage(inventoryItem.querySelector('img'), 60, 0);
|
||||||
|
}
|
||||||
|
super._onDragStart(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* Application Clicks Actions */
|
/* Application Clicks Actions */
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
|
||||||
|
|
@ -318,6 +318,40 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.loadoutMaxReached'));
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.loadoutMaxReached'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'recall',
|
||||||
|
icon: 'fa-solid fa-bolt-lightning',
|
||||||
|
condition: target => {
|
||||||
|
const doc = getDocFromElementSync(target);
|
||||||
|
return doc && doc.system.inVault;
|
||||||
|
},
|
||||||
|
callback: async (target, event) => {
|
||||||
|
const doc = await getDocFromElement(target);
|
||||||
|
const actorLoadout = doc.actor.system.loadoutSlot;
|
||||||
|
if (!actorLoadout.available) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.loadoutMaxReached'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (doc.system.recallCost == 0) {
|
||||||
|
return doc.update({ 'system.inVault': false });
|
||||||
|
}
|
||||||
|
const type = 'effect';
|
||||||
|
const cls = game.system.api.models.actions.actionsTypes[type];
|
||||||
|
const action = new cls({
|
||||||
|
...cls.getSourceConfig(doc.system),
|
||||||
|
type: type,
|
||||||
|
chatDisplay: false,
|
||||||
|
cost: [{
|
||||||
|
key: 'stress',
|
||||||
|
value: doc.system.recallCost
|
||||||
|
}]
|
||||||
|
}, { parent: doc.system });
|
||||||
|
const config = await action.use(event);
|
||||||
|
if (config) {
|
||||||
|
return doc.update({ 'system.inVault': false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'toVault',
|
name: 'toVault',
|
||||||
icon: 'fa-solid fa-arrow-down',
|
icon: 'fa-solid fa-arrow-down',
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,12 @@ export default class DhpEnvironment extends DHBaseActorSheet {
|
||||||
toggleResourceDice: DhpEnvironment.#toggleResourceDice,
|
toggleResourceDice: DhpEnvironment.#toggleResourceDice,
|
||||||
handleResourceDice: DhpEnvironment.#handleResourceDice
|
handleResourceDice: DhpEnvironment.#handleResourceDice
|
||||||
},
|
},
|
||||||
dragDrop: [{ dragSelector: '.inventory-item', dropSelector: null }]
|
dragDrop: [
|
||||||
|
{
|
||||||
|
dragSelector: '[data-item-id][draggable="true"], [data-item-id] [draggable="true"]',
|
||||||
|
dropSelector: null
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
/**@override */
|
/**@override */
|
||||||
|
|
@ -74,6 +79,9 @@ export default class DhpEnvironment extends DHBaseActorSheet {
|
||||||
case 'header':
|
case 'header':
|
||||||
await this._prepareHeaderContext(context, options);
|
await this._prepareHeaderContext(context, options);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'features':
|
||||||
|
await this._prepareFeaturesContext(context, options);
|
||||||
break;
|
break;
|
||||||
case 'notes':
|
case 'notes':
|
||||||
await this._prepareNotesContext(context, options);
|
await this._prepareNotesContext(context, options);
|
||||||
|
|
@ -110,6 +118,22 @@ export default class DhpEnvironment extends DHBaseActorSheet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare render context for the features part.
|
||||||
|
* @param {ApplicationRenderContext} context
|
||||||
|
* @param {ApplicationRenderOptions} options
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
async _prepareFeaturesContext(context, _options) {
|
||||||
|
const featureForms = ['passive', 'action', 'reaction'];
|
||||||
|
context.features = this.document.system.features.sort((a, b) =>
|
||||||
|
a.system.featureForm !== b.system.featureForm
|
||||||
|
? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm)
|
||||||
|
: a.sort - b.sort
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare render context for the Header part.
|
* Prepare render context for the Header part.
|
||||||
* @param {ApplicationRenderContext} context
|
* @param {ApplicationRenderContext} context
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,9 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
|
|
||||||
async actionUseButton(event, message) {
|
async actionUseButton(event, message) {
|
||||||
const { moveIndex, actionIndex, movePath } = event.currentTarget.dataset;
|
const { moveIndex, actionIndex, movePath } = event.currentTarget.dataset;
|
||||||
const parent = await foundry.utils.fromUuid(message.system.actor);
|
const targetUuid = event.currentTarget.closest('.action-use-button-parent').querySelector('select')?.value;
|
||||||
|
const parent = await foundry.utils.fromUuid(targetUuid || message.system.actor)
|
||||||
|
|
||||||
const actionType = message.system.moves[moveIndex].actions[actionIndex];
|
const actionType = message.system.moves[moveIndex].actions[actionIndex];
|
||||||
const cls = game.system.api.models.actions.actionsTypes[actionType.type];
|
const cls = game.system.api.models.actions.actionsTypes[actionType.type];
|
||||||
const action = new cls(
|
const action = new cls(
|
||||||
|
|
@ -146,7 +148,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
type: CONFIG.DH.ITEM.originItemType.restMove,
|
type: CONFIG.DH.ITEM.originItemType.restMove,
|
||||||
itemPath: movePath,
|
itemPath: movePath,
|
||||||
actionIndex: actionIndex
|
actionIndex: actionIndex
|
||||||
}
|
},
|
||||||
|
targetUuid: targetUuid
|
||||||
},
|
},
|
||||||
{ parent: parent.system }
|
{ parent: parent.system }
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@ export const defaultRestOptions = {
|
||||||
actionType: 'action',
|
actionType: 'action',
|
||||||
chatDisplay: false,
|
chatDisplay: false,
|
||||||
target: {
|
target: {
|
||||||
type: 'self'
|
type: 'friendly'
|
||||||
},
|
},
|
||||||
damage: {
|
damage: {
|
||||||
parts: [
|
parts: [
|
||||||
|
|
@ -298,7 +298,7 @@ export const defaultRestOptions = {
|
||||||
actionType: 'action',
|
actionType: 'action',
|
||||||
chatDisplay: false,
|
chatDisplay: false,
|
||||||
target: {
|
target: {
|
||||||
type: 'self'
|
type: 'friendly'
|
||||||
},
|
},
|
||||||
damage: {
|
damage: {
|
||||||
parts: [
|
parts: [
|
||||||
|
|
@ -341,7 +341,7 @@ export const defaultRestOptions = {
|
||||||
actionType: 'action',
|
actionType: 'action',
|
||||||
chatDisplay: false,
|
chatDisplay: false,
|
||||||
target: {
|
target: {
|
||||||
type: 'self'
|
type: 'friendly'
|
||||||
},
|
},
|
||||||
damage: {
|
damage: {
|
||||||
parts: [
|
parts: [
|
||||||
|
|
@ -407,7 +407,7 @@ export const defaultRestOptions = {
|
||||||
actionType: 'action',
|
actionType: 'action',
|
||||||
chatDisplay: false,
|
chatDisplay: false,
|
||||||
target: {
|
target: {
|
||||||
type: 'self'
|
type: 'friendly'
|
||||||
},
|
},
|
||||||
damage: {
|
damage: {
|
||||||
parts: [
|
parts: [
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
initial: 'action',
|
initial: 'action',
|
||||||
nullable: false,
|
nullable: false,
|
||||||
required: true
|
required: true
|
||||||
})
|
}),
|
||||||
|
targetUuid: new fields.StringField({ initial: undefined })
|
||||||
};
|
};
|
||||||
|
|
||||||
this.extraSchemas.forEach(s => {
|
this.extraSchemas.forEach(s => {
|
||||||
|
|
@ -241,7 +242,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
selectedRollMode: game.settings.get('core', 'rollMode'),
|
selectedRollMode: game.settings.get('core', 'rollMode'),
|
||||||
data: this.getRollData(),
|
data: this.getRollData(),
|
||||||
evaluate: this.hasRoll,
|
evaluate: this.hasRoll,
|
||||||
resourceUpdates: new ResourceUpdateMap(this.actor)
|
resourceUpdates: new ResourceUpdateMap(this.actor),
|
||||||
|
targetUuid: this.targetUuid
|
||||||
};
|
};
|
||||||
|
|
||||||
DHBaseAction.applyKeybindings(config);
|
DHBaseAction.applyKeybindings(config);
|
||||||
|
|
|
||||||
|
|
@ -66,12 +66,20 @@ export default class BeastformEffect extends BaseEffect {
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateToken = token => {
|
const updateToken = token => {
|
||||||
const { x, y } = game.system.api.documents.DhToken.getSnappedPositionInSquareGrid(
|
let x = null,
|
||||||
|
y = null;
|
||||||
|
if (token.object?.scene?.grid) {
|
||||||
|
const positionData = game.system.api.documents.DhToken.getSnappedPositionInSquareGrid(
|
||||||
token.object.scene.grid,
|
token.object.scene.grid,
|
||||||
{ x: token.x, y: token.y, elevation: token.elevation },
|
{ x: token.x, y: token.y, elevation: token.elevation },
|
||||||
baseUpdate.width,
|
baseUpdate.width,
|
||||||
baseUpdate.height
|
baseUpdate.height
|
||||||
);
|
);
|
||||||
|
|
||||||
|
x = positionData.x;
|
||||||
|
y = positionData.y;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...baseUpdate,
|
...baseUpdate,
|
||||||
x,
|
x,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import DHAdversarySettings from '../../applications/sheets-configs/adversary-settings.mjs';
|
import DHAdversarySettings from '../../applications/sheets-configs/adversary-settings.mjs';
|
||||||
import { ActionField } from '../fields/actionField.mjs';
|
import { ActionField } from '../fields/actionField.mjs';
|
||||||
import BaseDataActor from './base.mjs';
|
import BaseDataActor, { commonActorRules } from './base.mjs';
|
||||||
import { resourceField, bonusField } from '../fields/actorField.mjs';
|
import { resourceField, bonusField } from '../fields/actorField.mjs';
|
||||||
|
|
||||||
export default class DhpAdversary extends BaseDataActor {
|
export default class DhpAdversary extends BaseDataActor {
|
||||||
|
|
@ -56,25 +56,11 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
resources: new fields.SchemaField({
|
resources: new fields.SchemaField({
|
||||||
hitPoints: resourceField(
|
hitPoints: resourceField(0, 0, 'DAGGERHEART.GENERAL.HitPoints.plural', true),
|
||||||
0,
|
stress: resourceField(0, 0, 'DAGGERHEART.GENERAL.stress', true)
|
||||||
0,
|
|
||||||
'DAGGERHEART.GENERAL.HitPoints.plural',
|
|
||||||
true
|
|
||||||
),
|
|
||||||
stress: resourceField(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
'DAGGERHEART.GENERAL.stress',
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
rules: new fields.SchemaField({
|
rules: new fields.SchemaField({
|
||||||
conditionImmunities: new fields.SchemaField({
|
...commonActorRules()
|
||||||
hidden: new fields.BooleanField({ initial: false }),
|
|
||||||
restrained: new fields.BooleanField({ initial: false }),
|
|
||||||
vulnerable: new fields.BooleanField({ initial: false })
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
attack: new ActionField({
|
attack: new ActionField({
|
||||||
initial: {
|
initial: {
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,23 @@ import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs
|
||||||
import DHItem from '../../documents/item.mjs';
|
import DHItem from '../../documents/item.mjs';
|
||||||
import { getScrollTextData } from '../../helpers/utils.mjs';
|
import { getScrollTextData } from '../../helpers/utils.mjs';
|
||||||
|
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
const resistanceField = (resistanceLabel, immunityLabel, reductionLabel) =>
|
const resistanceField = (resistanceLabel, immunityLabel, reductionLabel) =>
|
||||||
new foundry.data.fields.SchemaField({
|
new fields.SchemaField({
|
||||||
resistance: new foundry.data.fields.BooleanField({
|
resistance: new fields.BooleanField({
|
||||||
initial: false,
|
initial: false,
|
||||||
label: `${resistanceLabel}.label`,
|
label: `${resistanceLabel}.label`,
|
||||||
hint: `${resistanceLabel}.hint`,
|
hint: `${resistanceLabel}.hint`,
|
||||||
isAttributeChoice: true
|
isAttributeChoice: true
|
||||||
}),
|
}),
|
||||||
immunity: new foundry.data.fields.BooleanField({
|
immunity: new fields.BooleanField({
|
||||||
initial: false,
|
initial: false,
|
||||||
label: `${immunityLabel}.label`,
|
label: `${immunityLabel}.label`,
|
||||||
hint: `${immunityLabel}.hint`,
|
hint: `${immunityLabel}.hint`,
|
||||||
isAttributeChoice: true
|
isAttributeChoice: true
|
||||||
}),
|
}),
|
||||||
reduction: new foundry.data.fields.NumberField({
|
reduction: new fields.NumberField({
|
||||||
integer: true,
|
integer: true,
|
||||||
initial: 0,
|
initial: 0,
|
||||||
label: `${reductionLabel}.label`,
|
label: `${reductionLabel}.label`,
|
||||||
|
|
@ -24,6 +26,25 @@ const resistanceField = (resistanceLabel, immunityLabel, reductionLabel) =>
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Common rules applying to Characters and Adversaries */
|
||||||
|
export const commonActorRules = (extendedData = { damageReduction: {} }) => ({
|
||||||
|
conditionImmunities: new fields.SchemaField({
|
||||||
|
hidden: new fields.BooleanField({ initial: false }),
|
||||||
|
restrained: new fields.BooleanField({ initial: false }),
|
||||||
|
vulnerable: new fields.BooleanField({ initial: false })
|
||||||
|
}),
|
||||||
|
damageReduction: new fields.SchemaField({
|
||||||
|
thresholdImmunities: new fields.SchemaField({
|
||||||
|
minor: new fields.BooleanField({ initial: false })
|
||||||
|
}),
|
||||||
|
reduceSeverity: new fields.SchemaField({
|
||||||
|
magical: new fields.NumberField({ initial: 0, min: 0 }),
|
||||||
|
physical: new fields.NumberField({ initial: 0, min: 0 })
|
||||||
|
}),
|
||||||
|
...extendedData.damageReduction
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes metadata about the actor data model type
|
* Describes metadata about the actor data model type
|
||||||
* @typedef {Object} ActorDataModelMetadata
|
* @typedef {Object} ActorDataModelMetadata
|
||||||
|
|
@ -54,7 +75,6 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
|
||||||
|
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
|
||||||
const schema = {};
|
const schema = {};
|
||||||
|
|
||||||
if (this.metadata.hasAttribution) {
|
if (this.metadata.hasAttribution) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { burden } from '../../config/generalConfig.mjs';
|
import { burden } from '../../config/generalConfig.mjs';
|
||||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||||
import DhLevelData from '../levelData.mjs';
|
import DhLevelData from '../levelData.mjs';
|
||||||
import BaseDataActor from './base.mjs';
|
import BaseDataActor, { commonActorRules } from './base.mjs';
|
||||||
import { attributeField, resourceField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs';
|
import { attributeField, resourceField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs';
|
||||||
import { ActionField } from '../fields/actionField.mjs';
|
import { ActionField } from '../fields/actionField.mjs';
|
||||||
import DHCharacterSettings from '../../applications/sheets-configs/character-settings.mjs';
|
import DHCharacterSettings from '../../applications/sheets-configs/character-settings.mjs';
|
||||||
|
|
@ -212,7 +212,10 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
}),
|
}),
|
||||||
companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }),
|
companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }),
|
||||||
rules: new fields.SchemaField({
|
rules: new fields.SchemaField({
|
||||||
damageReduction: new fields.SchemaField({
|
...commonActorRules({
|
||||||
|
damageReduction: {
|
||||||
|
magical: new fields.BooleanField({ initial: false }),
|
||||||
|
physical: new fields.BooleanField({ initial: false }),
|
||||||
maxArmorMarked: new fields.SchemaField({
|
maxArmorMarked: new fields.SchemaField({
|
||||||
value: new fields.NumberField({
|
value: new fields.NumberField({
|
||||||
required: true,
|
required: true,
|
||||||
|
|
@ -229,7 +232,9 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
stressDamageReduction: new fields.SchemaField({
|
stressDamageReduction: new fields.SchemaField({
|
||||||
severe: stressDamageReductionRule('DAGGERHEART.GENERAL.Rules.damageReduction.stress.severe'),
|
severe: stressDamageReductionRule(
|
||||||
|
'DAGGERHEART.GENERAL.Rules.damageReduction.stress.severe'
|
||||||
|
),
|
||||||
major: stressDamageReductionRule('DAGGERHEART.GENERAL.Rules.damageReduction.stress.major'),
|
major: stressDamageReductionRule('DAGGERHEART.GENERAL.Rules.damageReduction.stress.major'),
|
||||||
minor: stressDamageReductionRule('DAGGERHEART.GENERAL.Rules.damageReduction.stress.minor'),
|
minor: stressDamageReductionRule('DAGGERHEART.GENERAL.Rules.damageReduction.stress.minor'),
|
||||||
any: stressDamageReductionRule('DAGGERHEART.GENERAL.Rules.damageReduction.stress.any')
|
any: stressDamageReductionRule('DAGGERHEART.GENERAL.Rules.damageReduction.stress.any')
|
||||||
|
|
@ -240,16 +245,8 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
label: 'DAGGERHEART.GENERAL.Rules.damageReduction.increasePerArmorMark.label',
|
label: 'DAGGERHEART.GENERAL.Rules.damageReduction.increasePerArmorMark.label',
|
||||||
hint: 'DAGGERHEART.GENERAL.Rules.damageReduction.increasePerArmorMark.hint'
|
hint: 'DAGGERHEART.GENERAL.Rules.damageReduction.increasePerArmorMark.hint'
|
||||||
}),
|
}),
|
||||||
magical: new fields.BooleanField({ initial: false }),
|
|
||||||
physical: new fields.BooleanField({ initial: false }),
|
|
||||||
thresholdImmunities: new fields.SchemaField({
|
|
||||||
minor: new fields.BooleanField({ initial: false })
|
|
||||||
}),
|
|
||||||
reduceSeverity: new fields.SchemaField({
|
|
||||||
magical: new fields.NumberField({ initial: 0, min: 0 }),
|
|
||||||
physical: new fields.NumberField({ initial: 0, min: 0 })
|
|
||||||
}),
|
|
||||||
disabledArmor: new fields.BooleanField({ intial: false })
|
disabledArmor: new fields.BooleanField({ intial: false })
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
attack: new fields.SchemaField({
|
attack: new fields.SchemaField({
|
||||||
damage: new fields.SchemaField({
|
damage: new fields.SchemaField({
|
||||||
|
|
@ -278,11 +275,6 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
conditionImmunities: new fields.SchemaField({
|
|
||||||
hidden: new fields.BooleanField({ initial: false }),
|
|
||||||
restrained: new fields.BooleanField({ initial: false }),
|
|
||||||
vulnerable: new fields.BooleanField({ initial: false })
|
|
||||||
}),
|
|
||||||
runeWard: new fields.BooleanField({ initial: false }),
|
runeWard: new fields.BooleanField({ initial: false }),
|
||||||
burden: new fields.SchemaField({
|
burden: new fields.SchemaField({
|
||||||
ignore: new fields.BooleanField()
|
ignore: new fields.BooleanField()
|
||||||
|
|
@ -451,8 +443,7 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.foundation ||
|
item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.foundation ||
|
||||||
(item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.specialization &&
|
(item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.specialization && subclassState >= 2) ||
|
||||||
subclassState >= 2) ||
|
|
||||||
(item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.mastery && subclassState >= 3)
|
(item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.mastery && subclassState >= 3)
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ export default class BeastformField extends fields.SchemaField {
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
static async transform(selectedForm, evolvedData, hybridData) {
|
static async transform(selectedForm, evolvedData, hybridData) {
|
||||||
const formData = evolvedData?.form ? evolvedData.form.toObject() : selectedForm;
|
const formData = evolvedData?.form ?? selectedForm;
|
||||||
const beastformEffect = formData.effects.find(x => x.type === 'beastform');
|
const beastformEffect = formData.effects.find(x => x.type === 'beastform');
|
||||||
if (!beastformEffect) {
|
if (!beastformEffect) {
|
||||||
ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect');
|
ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect');
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,12 @@ export default class TargetField extends fields.SchemaField {
|
||||||
config.hasTarget = true;
|
config.hasTarget = true;
|
||||||
let targets;
|
let targets;
|
||||||
// If the Action is configured as self-targeted, set targets as the owner. Probably better way than to fallback to getDependentTokens
|
// 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)
|
if (this.target?.type === CONFIG.DH.GENERAL.targetTypes.self.id) {
|
||||||
targets = [this.actor.token ?? this.actor.prototypeToken];
|
targets = [this.actor.token ?? this.actor.prototypeToken];
|
||||||
else {
|
} else if (config.targetUuid) {
|
||||||
|
const actor = fromUuidSync(config.targetUuid);
|
||||||
|
targets = [actor.token ?? actor.prototypeToken];
|
||||||
|
} else {
|
||||||
targets = Array.from(game.user.targets);
|
targets = Array.from(game.user.targets);
|
||||||
if (this.target.type !== CONFIG.DH.GENERAL.targetTypes.any.id) {
|
if (this.target.type !== CONFIG.DH.GENERAL.targetTypes.any.id) {
|
||||||
targets = targets.filter(target => TargetField.isTargetFriendly(this.actor, target, this.target.type));
|
targets = targets.filter(target => TargetField.isTargetFriendly(this.actor, target, this.target.type));
|
||||||
|
|
|
||||||
|
|
@ -218,12 +218,20 @@ export default class DHBeastform extends BaseDataItem {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const tokenUpdate = token => {
|
const tokenUpdate = token => {
|
||||||
const { x, y } = game.system.api.documents.DhToken.getSnappedPositionInSquareGrid(
|
let x = null,
|
||||||
|
y = null;
|
||||||
|
if (token.object?.scene?.grid) {
|
||||||
|
const positionData = game.system.api.documents.DhToken.getSnappedPositionInSquareGrid(
|
||||||
token.object.scene.grid,
|
token.object.scene.grid,
|
||||||
{ x: token.x, y: token.y, elevation: token.elevation },
|
{ x: token.x, y: token.y, elevation: token.elevation },
|
||||||
width ?? token.width,
|
width ?? token.width,
|
||||||
height ?? token.height
|
height ?? token.height
|
||||||
);
|
);
|
||||||
|
|
||||||
|
x = positionData.x;
|
||||||
|
y = positionData.y;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...prototypeTokenUpdate,
|
...prototypeTokenUpdate,
|
||||||
x,
|
x,
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ export default class DualityRoll extends D20Roll {
|
||||||
|
|
||||||
if (looseSpotlight && game.combat?.active) {
|
if (looseSpotlight && game.combat?.active) {
|
||||||
const currentCombatant = game.combat.combatants.get(game.combat.current?.combatantId);
|
const currentCombatant = game.combat.combatants.get(game.combat.current?.combatantId);
|
||||||
if (currentCombatant?.actorId == actor.id) ui.combat.setCombatantSpotlight(currentCombatant.id);
|
if (currentCombatant?.actorId == config.data.id) ui.combat.setCombatantSpotlight(currentCombatant.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
||||||
import { LevelOptionType } from '../data/levelTier.mjs';
|
import { LevelOptionType } from '../data/levelTier.mjs';
|
||||||
import DHFeature from '../data/item/feature.mjs';
|
import DHFeature from '../data/item/feature.mjs';
|
||||||
import { createScrollText, damageKeyToNumber } from '../helpers/utils.mjs';
|
import { createScrollText, damageKeyToNumber, getDamageKey } from '../helpers/utils.mjs';
|
||||||
import DhCompanionLevelUp from '../applications/levelup/companionLevelup.mjs';
|
import DhCompanionLevelUp from '../applications/levelup/companionLevelup.mjs';
|
||||||
import { ResourceUpdateMap } from '../data/action/baseAction.mjs';
|
import { ResourceUpdateMap } from '../data/action/baseAction.mjs';
|
||||||
|
|
||||||
|
|
@ -543,6 +543,7 @@ export default class DhpActor extends Actor {
|
||||||
/* system gets repeated infinately which causes issues when trying to use the data for document creation */
|
/* system gets repeated infinately which causes issues when trying to use the data for document creation */
|
||||||
delete rollData.system;
|
delete rollData.system;
|
||||||
|
|
||||||
|
rollData.id = this.id;
|
||||||
rollData.name = this.name;
|
rollData.name = this.name;
|
||||||
rollData.system = this.system.getRollData();
|
rollData.system = this.system.getRollData();
|
||||||
rollData.prof = this.system.proficiency ?? 1;
|
rollData.prof = this.system.proficiency ?? 1;
|
||||||
|
|
@ -630,6 +631,19 @@ export default class DhpActor extends Actor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.type === 'adversary') {
|
||||||
|
const reducedSeverity = hpDamage.damageTypes.reduce((value, curr) => {
|
||||||
|
return Math.max(this.system.rules.damageReduction.reduceSeverity[curr], value);
|
||||||
|
}, 0);
|
||||||
|
hpDamage.value = Math.max(hpDamage.value - reducedSeverity, 0);
|
||||||
|
|
||||||
|
if (
|
||||||
|
hpDamage.value &&
|
||||||
|
this.system.rules.damageReduction.thresholdImmunities[getDamageKey(hpDamage.value)]
|
||||||
|
) {
|
||||||
|
hpDamage.value -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updates.forEach(
|
updates.forEach(
|
||||||
|
|
|
||||||
|
|
@ -99,12 +99,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.action-use-button-parent {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.action-use-target {
|
||||||
|
display:flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 4px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 4px 8px 10px 40px;
|
||||||
|
font-size: var(--font-size-12);
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.action-use-button {
|
.action-use-button {
|
||||||
width: -webkit-fill-available;
|
width: -webkit-fill-available;
|
||||||
margin: 0 8px;
|
margin: 0 8px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "daggerheart",
|
"id": "daggerheart",
|
||||||
"title": "Daggerheart",
|
"title": "Daggerheart",
|
||||||
"description": "An unofficial implementation of the Daggerheart system",
|
"description": "An unofficial implementation of the Daggerheart system",
|
||||||
"version": "1.4.2",
|
"version": "1.4.4",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "13.346",
|
"minimum": "13.346",
|
||||||
"verified": "13.351",
|
"verified": "13.351",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<section
|
<section
|
||||||
class="tab {{tabs.domains.cssClass}} {{tabs.domains.id}}"
|
class="tab {{tabs.domains.cssClass}} {{tabs.domains.id}} scrollable"
|
||||||
data-tab="{{tabs.domains.id}}"
|
data-tab="{{tabs.domains.id}}"
|
||||||
data-group="{{tabs.domains.group}}"
|
data-group="{{tabs.domains.group}}"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<section
|
<section
|
||||||
class="tab {{tabs.downtime.cssClass}} {{tabs.downtime.id}}"
|
class="tab {{tabs.downtime.cssClass}} {{tabs.downtime.id}} scrollable"
|
||||||
data-tab="{{tabs.downtime.id}}"
|
data-tab="{{tabs.downtime.id}}"
|
||||||
data-group="{{tabs.downtime.group}}"
|
data-group="{{tabs.downtime.group}}"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<section
|
<section
|
||||||
class="tab {{tabs.itemFeatures.cssClass}} {{tabs.itemFeatures.id}}"
|
class="tab {{tabs.itemFeatures.cssClass}} {{tabs.itemFeatures.id}} scrollable"
|
||||||
data-tab="{{tabs.itemFeatures.id}}"
|
data-tab="{{tabs.itemFeatures.id}}"
|
||||||
data-group="{{tabs.itemFeatures.group}}"
|
data-group="{{tabs.itemFeatures.group}}"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<section
|
<section
|
||||||
class="tab {{tabs.settings.cssClass}} {{tabs.settings.id}}"
|
class="tab {{tabs.settings.cssClass}} {{tabs.settings.id}} scrollable"
|
||||||
data-tab="{{tabs.settings.id}}"
|
data-tab="{{tabs.settings.id}}"
|
||||||
data-group="{{tabs.settings.group}}"
|
data-group="{{tabs.settings.group}}"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<section
|
<section
|
||||||
class="tab {{tabs.types.cssClass}} {{tabs.types.id}}"
|
class="tab {{tabs.types.cssClass}} {{tabs.types.id}} scrollable"
|
||||||
data-tab="{{tabs.types.id}}"
|
data-tab="{{tabs.types.id}}"
|
||||||
data-group="{{tabs.types.group}}"
|
data-group="{{tabs.types.group}}"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize tabs.features.label}}</legend>
|
<legend>{{localize tabs.features.label}}</legend>
|
||||||
<ul class="feature-list">
|
<ul class="feature-list">
|
||||||
{{#each document.system.features as |feature|}}
|
{{#each @root.features as |feature|}}
|
||||||
<li class="feature-item" id="{{feature.id}}" draggable="true">
|
<li class="feature-item" id="{{feature.id}}" draggable="true">
|
||||||
<img src="{{feature.img}}" alt="">
|
<img src="{{feature.img}}" alt="">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize tabs.features.label}}</legend>
|
<legend>{{localize tabs.features.label}}</legend>
|
||||||
<ul class="feature-list">
|
<ul class="feature-list">
|
||||||
{{#each document.system.features as |feature|}}
|
{{#each @root.features as |feature|}}
|
||||||
<li class="feature-item" id="{{feature.id}}">
|
<li class="feature-item" id="{{feature.id}}">
|
||||||
<img src="{{feature.img}}" alt="">
|
<img src="{{feature.img}}" alt="">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
{{> 'daggerheart.inventory-items'
|
{{> 'daggerheart.inventory-items'
|
||||||
title=tabs.features.label
|
title=tabs.features.label
|
||||||
type='feature'
|
type='feature'
|
||||||
collection=document.system.features
|
collection=@root.features
|
||||||
hideContextMenu=true
|
hideContextMenu=true
|
||||||
canCreate=true
|
canCreate=true
|
||||||
showActions=true
|
showActions=true
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
{{> 'daggerheart.inventory-items'
|
{{> 'daggerheart.inventory-items'
|
||||||
title=tabs.features.label
|
title=tabs.features.label
|
||||||
type='feature'
|
type='feature'
|
||||||
collection=document.system.features
|
collection=@root.features
|
||||||
hideContextMenu=true
|
hideContextMenu=true
|
||||||
canCreate=true
|
canCreate=true
|
||||||
showActions=true
|
showActions=true
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,22 @@
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
{{#each move.actions as | action index |}}
|
{{#each move.actions as | action index |}}
|
||||||
|
<div class="action-use-button-parent">
|
||||||
<button class="action-use-button" data-move-index="{{@../key}}" data-action-index="{{index}}" data-move-path="{{../movePath}}" >
|
<button class="action-use-button" data-move-index="{{@../key}}" data-action-index="{{index}}" data-move-path="{{../movePath}}" >
|
||||||
<span>{{localize action.name}}</span>
|
<span>{{localize action.name}}</span>
|
||||||
</button>
|
</button>
|
||||||
|
{{#if move.needsTarget}}
|
||||||
|
<div class="action-use-target">
|
||||||
|
<label>{{localize "DAGGERHEART.GENERAL.Bonuses.rest.target"}}:</label>
|
||||||
|
<select>
|
||||||
|
<option value="{{../../selfId}}">{{localize "DAGGERHEART.GENERAL.Bonuses.rest.targetSelf"}}</option>
|
||||||
|
{{#each ../../characters as | character |}}
|
||||||
|
<option value="{{character.uuid}}">{{character.name}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue