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
562c404534
53 changed files with 581 additions and 162 deletions
13
lang/en.json
13
lang/en.json
|
|
@ -1801,6 +1801,7 @@
|
||||||
"plural": "Costs"
|
"plural": "Costs"
|
||||||
},
|
},
|
||||||
"Damage": {
|
"Damage": {
|
||||||
|
"massive": "Massive",
|
||||||
"severe": "Severe",
|
"severe": "Severe",
|
||||||
"major": "Major",
|
"major": "Major",
|
||||||
"minor": "Minor",
|
"minor": "Minor",
|
||||||
|
|
@ -2442,9 +2443,12 @@
|
||||||
},
|
},
|
||||||
"currency": {
|
"currency": {
|
||||||
"title": "Currency Overrides",
|
"title": "Currency Overrides",
|
||||||
|
"changeIcon": "Change Currency Icon",
|
||||||
"currencyName": "Currency Name",
|
"currencyName": "Currency Name",
|
||||||
"coinName": "Coin Name",
|
"coinName": "Coin Name",
|
||||||
"handfulName": "Handful Name",
|
"handfulName": "Handful Name",
|
||||||
|
"iconName": "Icon Name",
|
||||||
|
"iconNameHint": "Icons are from fontawesome",
|
||||||
"bagName": "Bag Name",
|
"bagName": "Bag Name",
|
||||||
"chestName": "Chest Name"
|
"chestName": "Chest Name"
|
||||||
},
|
},
|
||||||
|
|
@ -2506,6 +2510,11 @@
|
||||||
"hint": "Apply variant rules from the Daggerheart system",
|
"hint": "Apply variant rules from the Daggerheart system",
|
||||||
"name": "Variant Rules",
|
"name": "Variant Rules",
|
||||||
"actionTokens": "Action Tokens"
|
"actionTokens": "Action Tokens"
|
||||||
|
},
|
||||||
|
"SpotlightRequestQueue": {
|
||||||
|
"name": "Spotlight Request Queue",
|
||||||
|
"label": "Spotlight Request Queue",
|
||||||
|
"hint": "Adds more structure to spotlight requests by ordering them from oldest to newest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Resources": {
|
"Resources": {
|
||||||
|
|
@ -2519,6 +2528,10 @@
|
||||||
"actionTokens": {
|
"actionTokens": {
|
||||||
"enabled": { "label": "Enabled" },
|
"enabled": { "label": "Enabled" },
|
||||||
"tokens": { "label": "Tokens" }
|
"tokens": { "label": "Tokens" }
|
||||||
|
},
|
||||||
|
"massiveDamage":{
|
||||||
|
"title":"Massive Damage",
|
||||||
|
"enabled": { "label": "Enabled" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
icon: 'fa-solid fa-gears'
|
icon: 'fa-solid fa-gears'
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
editCurrencyIcon: this.changeCurrencyIcon,
|
||||||
addItem: this.addItem,
|
addItem: this.addItem,
|
||||||
editItem: this.editItem,
|
editItem: this.editItem,
|
||||||
removeItem: this.removeItem,
|
removeItem: this.removeItem,
|
||||||
|
|
@ -115,6 +116,45 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async changeCurrencyIcon(_, target) {
|
||||||
|
const type = target.dataset.currency;
|
||||||
|
const currentIcon = this.settings.currency[type].icon;
|
||||||
|
const icon = await foundry.applications.api.DialogV2.input({
|
||||||
|
classes: ['daggerheart', 'dh-style', 'change-currency-icon'],
|
||||||
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
|
'systems/daggerheart/templates/settings/homebrew-settings/change-currency-icon.hbs',
|
||||||
|
{ currentIcon }
|
||||||
|
),
|
||||||
|
window: {
|
||||||
|
title: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.currency.changeIcon'),
|
||||||
|
icon: 'fa-solid fa-coins'
|
||||||
|
},
|
||||||
|
render: (_, dialog) => {
|
||||||
|
const icon = dialog.element.querySelector('.displayed-icon i');
|
||||||
|
const input = dialog.element.querySelector('input');
|
||||||
|
const reset = dialog.element.querySelector('button[data-action=reset]');
|
||||||
|
input.addEventListener('input', () => {
|
||||||
|
icon.classList.value = input.value;
|
||||||
|
});
|
||||||
|
reset.addEventListener('click', () => {
|
||||||
|
const currencyField = DhHomebrew.schema.fields.currency.fields[type];
|
||||||
|
const initial = currencyField.fields.icon.getInitialValue();
|
||||||
|
input.value = icon.classList.value = initial;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
ok: {
|
||||||
|
callback: (_, button) => button.form.elements.icon.value
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (icon !== null) {
|
||||||
|
await this.settings.updateSource({
|
||||||
|
[`currency.${type}.icon`]: icon
|
||||||
|
});
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static async addItem(_, target) {
|
static async addItem(_, target) {
|
||||||
const { type } = target.dataset;
|
const { type } = target.dataset;
|
||||||
if (['shortRest', 'longRest'].includes(type)) {
|
if (['shortRest', 'longRest'].includes(type)) {
|
||||||
|
|
|
||||||
|
|
@ -685,8 +685,6 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
ability: abilityLabel
|
ability: abilityLabel
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) game.system.api.fields.ActionFields.CostField.execute.call(this, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: redo toggleEquipItem method
|
//TODO: redo toggleEquipItem method
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,80 @@ export default function DHApplicationMixin(Base) {
|
||||||
_attachPartListeners(partId, htmlElement, options) {
|
_attachPartListeners(partId, htmlElement, options) {
|
||||||
super._attachPartListeners(partId, htmlElement, options);
|
super._attachPartListeners(partId, htmlElement, options);
|
||||||
this._dragDrop.forEach(d => d.bind(htmlElement));
|
this._dragDrop.forEach(d => d.bind(htmlElement));
|
||||||
|
|
||||||
|
// Handle delta inputs
|
||||||
|
for (const deltaInput of htmlElement.querySelectorAll('input[data-allow-delta]')) {
|
||||||
|
deltaInput.dataset.numValue = deltaInput.value;
|
||||||
|
deltaInput.inputMode = 'numeric';
|
||||||
|
deltaInput.pattern = '^[+=\\-]?\d*';
|
||||||
|
|
||||||
|
const handleUpdate = (delta = 0) => {
|
||||||
|
const min = Number(deltaInput.min) || 0;
|
||||||
|
const max = Number(deltaInput.max) || Infinity;
|
||||||
|
const current = Number(deltaInput.dataset.numValue);
|
||||||
|
const rawNumber = Number(deltaInput.value);
|
||||||
|
if (Number.isNaN(rawNumber)) {
|
||||||
|
deltaInput.value = delta ? Math.clamp(current + delta, min, max) : current;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newValue =
|
||||||
|
deltaInput.value.startsWith('+') || deltaInput.value.startsWith('-')
|
||||||
|
? Math.clamp(current + rawNumber + delta, min, max)
|
||||||
|
: Math.clamp(rawNumber + delta, min, max);
|
||||||
|
deltaInput.value = deltaInput.dataset.numValue = newValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Force valid characters while inputting
|
||||||
|
deltaInput.addEventListener('input', () => {
|
||||||
|
deltaInput.value = /[+=\-]?\d*/.exec(deltaInput.value)?.at(0) ?? deltaInput.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Recreate Keyup/Keydown support
|
||||||
|
deltaInput.addEventListener('keydown', event => {
|
||||||
|
const step = event.key === 'ArrowUp' ? 1 : event.key === 'ArrowDown' ? -1 : 0;
|
||||||
|
if (step !== 0) {
|
||||||
|
handleUpdate(step);
|
||||||
|
deltaInput.dispatchEvent(new Event("change", { bubbles: true }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Mousewheel while focused support
|
||||||
|
deltaInput.addEventListener(
|
||||||
|
'wheel',
|
||||||
|
event => {
|
||||||
|
if (deltaInput === document.activeElement) {
|
||||||
|
event.preventDefault();
|
||||||
|
handleUpdate(Math.sign(-1 * event.deltaY));
|
||||||
|
deltaInput.dispatchEvent(new Event("change", { bubbles: true }));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ passive: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
deltaInput.addEventListener('change', () => {
|
||||||
|
handleUpdate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle contenteditable
|
||||||
|
for (const input of htmlElement.querySelectorAll('[contenteditable][data-property]')) {
|
||||||
|
const property = input.dataset.property;
|
||||||
|
input.addEventListener("blur", () => {
|
||||||
|
const selection = document.getSelection();
|
||||||
|
if (input.contains(selection.anchorNode)) {
|
||||||
|
selection.empty();
|
||||||
|
}
|
||||||
|
this.document.update({ [property]: input.textContent });
|
||||||
|
});
|
||||||
|
|
||||||
|
input.addEventListener("keydown", event => {
|
||||||
|
if (event.key === "Enter") input.blur();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Chrome sometimes add <br>, which aren't a problem for the value but are for the placeholder
|
||||||
|
input.addEventListener("input", () => input.querySelectorAll("br").forEach((i) => i.remove()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,6 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result) return;
|
if (!result) return;
|
||||||
await game.system.api.fields.ActionFields.CostField.execute.call({ actor }, result);
|
|
||||||
|
|
||||||
const newMessageData = foundry.utils.deepClone(message.system);
|
const newMessageData = foundry.utils.deepClone(message.system);
|
||||||
foundry.utils.setProperty(newMessageData, `${path}.result`, result.roll);
|
foundry.utils.setProperty(newMessageData, `${path}.result`, result.roll);
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
||||||
actions: {
|
actions: {
|
||||||
requestSpotlight: this.requestSpotlight,
|
requestSpotlight: this.requestSpotlight,
|
||||||
toggleSpotlight: this.toggleSpotlight,
|
toggleSpotlight: this.toggleSpotlight,
|
||||||
setActionTokens: this.setActionTokens,
|
setActionTokens: this.setActionTokens
|
||||||
openCountdowns: this.openCountdowns
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -57,21 +56,26 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
||||||
|
|
||||||
const adversaries = context.turns?.filter(x => x.isNPC) ?? [];
|
const adversaries = context.turns?.filter(x => x.isNPC) ?? [];
|
||||||
const characters = context.turns?.filter(x => !x.isNPC) ?? [];
|
const characters = context.turns?.filter(x => !x.isNPC) ?? [];
|
||||||
|
const spotlightQueueEnabled = game.settings.get(
|
||||||
|
CONFIG.DH.id,
|
||||||
|
CONFIG.DH.SETTINGS.gameSettings.SpotlightRequestQueue
|
||||||
|
);
|
||||||
|
|
||||||
const spotlightRequests = characters
|
const spotlightRequests = characters
|
||||||
?.filter(x => !x.isNPC)
|
?.filter(x => !x.isNPC && spotlightQueueEnabled)
|
||||||
.filter(x => x.system.spotlight.requestOrderIndex > 0)
|
.filter(x => x.system.spotlight.requestOrderIndex > 0)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const valueA = a.system.spotlight.requestOrderIndex;
|
const valueA = a.system.spotlight.requestOrderIndex;
|
||||||
const valueB = b.system.spotlight.requestOrderIndex;
|
const valueB = b.system.spotlight.requestOrderIndex;
|
||||||
|
|
||||||
return valueA - valueB;
|
return valueA - valueB;
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.assign(context, {
|
Object.assign(context, {
|
||||||
actionTokens: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).actionTokens,
|
actionTokens: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).actionTokens,
|
||||||
adversaries,
|
adversaries,
|
||||||
characters: characters?.filter(x => !x.isNPC).filter(x => x.system.spotlight.requestOrderIndex == 0),
|
characters: characters
|
||||||
|
?.filter(x => !x.isNPC)
|
||||||
|
.filter(x => !spotlightQueueEnabled || x.system.spotlight.requestOrderIndex == 0),
|
||||||
spotlightRequests
|
spotlightRequests
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -161,9 +165,13 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
||||||
|
|
||||||
if (this.viewed.turn !== toggleTurn) {
|
if (this.viewed.turn !== toggleTurn) {
|
||||||
const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns;
|
const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns;
|
||||||
await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.spotlight.id);
|
|
||||||
if (combatant.actor.type === 'character') {
|
if (combatant.actor.type === 'character') {
|
||||||
await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.characterSpotlight.id);
|
await updateCountdowns(
|
||||||
|
CONFIG.DH.GENERAL.countdownProgressionTypes.spotlight.id,
|
||||||
|
CONFIG.DH.GENERAL.countdownProgressionTypes.characterSpotlight.id
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.spotlight.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const autoPoints = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).actionPoints;
|
const autoPoints = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).actionPoints;
|
||||||
|
|
|
||||||
|
|
@ -245,14 +245,20 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
||||||
return super.close(options);
|
return super.close(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async updateCountdowns(progressType) {
|
/**
|
||||||
|
* Sends updates of the countdowns to the GM player. Since this is asynchronous, be sure to
|
||||||
|
* update all the countdowns at the same time.
|
||||||
|
*
|
||||||
|
* @param {...any} progressTypes Countdowns to be updated
|
||||||
|
*/
|
||||||
|
static async updateCountdowns(...progressTypes) {
|
||||||
const { countdownAutomation } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
const { countdownAutomation } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
||||||
if (!countdownAutomation) return;
|
if (!countdownAutomation) return;
|
||||||
|
|
||||||
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||||
const updatedCountdowns = Object.keys(countdownSetting.countdowns).reduce((acc, key) => {
|
const updatedCountdowns = Object.keys(countdownSetting.countdowns).reduce((acc, key) => {
|
||||||
const countdown = countdownSetting.countdowns[key];
|
const countdown = countdownSetting.countdowns[key];
|
||||||
if (countdown.progress.type === progressType && countdown.progress.current > 0) {
|
if (progressTypes.indexOf(countdown.progress.type) !== -1 && countdown.progress.current > 0) {
|
||||||
acc.push(key);
|
acc.push(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -260,7 +266,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const countdownData = countdownSetting.toObject();
|
const countdownData = countdownSetting.toObject();
|
||||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, {
|
const settings = {
|
||||||
...countdownData,
|
...countdownData,
|
||||||
countdowns: Object.keys(countdownData.countdowns).reduce((acc, key) => {
|
countdowns: Object.keys(countdownData.countdowns).reduce((acc, key) => {
|
||||||
const countdown = foundry.utils.deepClone(countdownData.countdowns[key]);
|
const countdown = foundry.utils.deepClone(countdownData.countdowns[key]);
|
||||||
|
|
@ -271,14 +277,12 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
||||||
acc[key] = countdown;
|
acc[key] = countdown;
|
||||||
return acc;
|
return acc;
|
||||||
}, {})
|
}, {})
|
||||||
|
};
|
||||||
|
await emitAsGM(GMUpdateEvent.UpdateCountdowns,
|
||||||
|
DhCountdowns.gmSetSetting.bind(settings),
|
||||||
|
settings, null, {
|
||||||
|
refreshType: RefreshType.Countdown
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = { refreshType: RefreshType.Countdown };
|
|
||||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
|
||||||
action: socketEvent.Refresh,
|
|
||||||
data
|
|
||||||
});
|
|
||||||
Hooks.callAll(socketEvent.Refresh, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onRender(context, options) {
|
async _onRender(context, options) {
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ export default class DhEffectsDisplay extends HandlebarsApplicationMixin(Applica
|
||||||
async removeEffect(event) {
|
async removeEffect(event) {
|
||||||
const element = event.target.closest('.effect-container');
|
const element = event.target.closest('.effect-container');
|
||||||
const effects = DhEffectsDisplay.getTokenEffects();
|
const effects = DhEffectsDisplay.getTokenEffects();
|
||||||
const effect = effects.find(x => x.id === element.id);
|
const effect = effects.find(x => x.id === element.dataset.effectId);
|
||||||
await effect.delete();
|
await effect.delete();
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ export const BPModifiers = {
|
||||||
increaseDamage: {
|
increaseDamage: {
|
||||||
sort: 2,
|
sort: 2,
|
||||||
description: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage.description',
|
description: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage.description',
|
||||||
|
effectTargetTypes: ['adversary'],
|
||||||
effects: [
|
effects: [
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage.effect.name',
|
name: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage.effect.name',
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ export const gameSettings = {
|
||||||
LevelTiers: 'LevelTiers',
|
LevelTiers: 'LevelTiers',
|
||||||
Countdowns: 'Countdowns',
|
Countdowns: 'Countdowns',
|
||||||
LastMigrationVersion: 'LastMigrationVersion',
|
LastMigrationVersion: 'LastMigrationVersion',
|
||||||
TagTeamRoll: 'TagTeamRoll'
|
TagTeamRoll: 'TagTeamRoll',
|
||||||
|
SpotlightRequestQueue: 'SpotlightRequestQueue',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const actionAutomationChoices = {
|
export const actionAutomationChoices = {
|
||||||
|
|
|
||||||
|
|
@ -193,8 +193,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
async use(event) {
|
async use(event) {
|
||||||
if (!this.actor) throw new Error("An Action can't be used outside of an Actor context.");
|
if (!this.actor) throw new Error("An Action can't be used outside of an Actor context.");
|
||||||
|
|
||||||
if (this.chatDisplay) await this.toChat();
|
|
||||||
|
|
||||||
let config = this.prepareConfig(event);
|
let config = this.prepareConfig(event);
|
||||||
if (!config) return;
|
if (!config) return;
|
||||||
|
|
||||||
|
|
@ -211,6 +209,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
|
|
||||||
if (Hooks.call(`${CONFIG.DH.id}.postUseAction`, this, config) === false) return;
|
if (Hooks.call(`${CONFIG.DH.id}.postUseAction`, this, config) === false) return;
|
||||||
|
|
||||||
|
if (this.chatDisplay) await this.toChat();
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
import { defaultRestOptions } from '../../config/generalConfig.mjs';
|
import { defaultRestOptions } from '../../config/generalConfig.mjs';
|
||||||
import { ActionsField } from '../fields/actionField.mjs';
|
import { ActionsField } from '../fields/actionField.mjs';
|
||||||
|
|
||||||
const currencyField = (initial, label) =>
|
const currencyField = (initial, label, icon) =>
|
||||||
new foundry.data.fields.SchemaField({
|
new foundry.data.fields.SchemaField({
|
||||||
enabled: new foundry.data.fields.BooleanField({ required: true, initial: true }),
|
enabled: new foundry.data.fields.BooleanField({ required: true, initial: true }),
|
||||||
label: new foundry.data.fields.StringField({
|
label: new foundry.data.fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
initial,
|
initial,
|
||||||
label
|
label
|
||||||
})
|
}),
|
||||||
|
icon: new foundry.data.fields.StringField({ required: true, nullable: false, blank: true, initial: icon })
|
||||||
});
|
});
|
||||||
|
|
||||||
export default class DhHomebrew extends foundry.abstract.DataModel {
|
export default class DhHomebrew extends foundry.abstract.DataModel {
|
||||||
|
|
@ -45,10 +46,22 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
|
||||||
initial: 'Gold',
|
initial: 'Gold',
|
||||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.currencyName'
|
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.currencyName'
|
||||||
}),
|
}),
|
||||||
coins: currencyField('Coins', 'DAGGERHEART.SETTINGS.Homebrew.currency.coinName'),
|
coins: currencyField(
|
||||||
handfuls: currencyField('Handfuls', 'DAGGERHEART.SETTINGS.Homebrew.currency.handfulName'),
|
'Coins',
|
||||||
bags: currencyField('Bags', 'DAGGERHEART.SETTINGS.Homebrew.currency.bagName'),
|
'DAGGERHEART.SETTINGS.Homebrew.currency.coinName',
|
||||||
chests: currencyField('Chests', 'DAGGERHEART.SETTINGS.Homebrew.currency.chestName')
|
'fa-solid fa-coin-front'
|
||||||
|
),
|
||||||
|
handfuls: currencyField(
|
||||||
|
'Handfuls',
|
||||||
|
'DAGGERHEART.SETTINGS.Homebrew.currency.handfulName',
|
||||||
|
'fa-solid fa-coins'
|
||||||
|
),
|
||||||
|
bags: currencyField('Bags', 'DAGGERHEART.SETTINGS.Homebrew.currency.bagName', 'fa-solid fa-sack'),
|
||||||
|
chests: currencyField(
|
||||||
|
'Chests',
|
||||||
|
'DAGGERHEART.SETTINGS.Homebrew.currency.chestName',
|
||||||
|
'fa-solid fa-treasure-chest'
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
restMoves: new fields.SchemaField({
|
restMoves: new fields.SchemaField({
|
||||||
longRest: new fields.SchemaField({
|
longRest: new fields.SchemaField({
|
||||||
|
|
@ -139,22 +152,10 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
_initializeSource(source, options = {}) {
|
_initializeSource(source, options = {}) {
|
||||||
source = super._initializeSource(source, options);
|
source = super._initializeSource(source, options);
|
||||||
source.currency.coins = {
|
for (const type of ['coins', 'handfuls', 'bags', 'chests']) {
|
||||||
enabled: source.currency.coins.enabled ?? true,
|
const initial = this.schema.fields.currency.fields[type].getInitialValue();
|
||||||
label: source.currency.coins.label || source.currency.coins
|
source.currency[type] = foundry.utils.mergeObject(initial, source.currency[type], { inplace: false });
|
||||||
};
|
}
|
||||||
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;
|
return source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,13 @@ export default class DhVariantRules extends foundry.abstract.DataModel {
|
||||||
label: 'DAGGERHEART.CONFIG.Range.close.name'
|
label: 'DAGGERHEART.CONFIG.Range.close.name'
|
||||||
}),
|
}),
|
||||||
far: new fields.NumberField({ required: true, initial: 60, label: 'DAGGERHEART.CONFIG.Range.far.name' })
|
far: new fields.NumberField({ required: true, initial: 60, label: 'DAGGERHEART.CONFIG.Range.far.name' })
|
||||||
|
}),
|
||||||
|
massiveDamage: new fields.SchemaField({
|
||||||
|
enabled: new fields.BooleanField({
|
||||||
|
required: true,
|
||||||
|
initial: false,
|
||||||
|
label: 'DAGGERHEART.SETTINGS.VariantRules.FIELDS.massiveDamage.enabled.label'
|
||||||
|
})
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,51 @@ export default class DHRoll extends Roll {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function automateHopeFear(config) {
|
||||||
|
const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
||||||
|
const hopeFearAutomation = automationSettings.hopeFear;
|
||||||
|
if (!config.source?.actor ||
|
||||||
|
(game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) ||
|
||||||
|
config.actionType === 'reaction' ||
|
||||||
|
config.tagTeamSelected ||
|
||||||
|
config.skips?.resources)
|
||||||
|
return;
|
||||||
|
const actor = await fromUuid(config.source.actor);
|
||||||
|
let updates = [];
|
||||||
|
if (!actor) return;
|
||||||
|
|
||||||
|
if (config.rerolledRoll) {
|
||||||
|
if (config.roll.result.duality != config.rerolledRoll.result.duality) {
|
||||||
|
const hope = (config.roll.isCritical || config.roll.result.duality === 1 ? 1 : 0)
|
||||||
|
- (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1 ? 1 : 0);
|
||||||
|
const stress = (config.roll.isCritical ? 1 : 0) - (config.rerolledRoll.isCritical ? 1 : 0);
|
||||||
|
const fear = (config.roll.result.duality === -1 ? 1 : 0)
|
||||||
|
- (config.rerolledRoll.result.duality === -1 ? 1 : 0)
|
||||||
|
|
||||||
|
if (hope !== 0)
|
||||||
|
updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true });
|
||||||
|
if (stress !== 0)
|
||||||
|
updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true });
|
||||||
|
if (fear !== 0)
|
||||||
|
updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (config.roll.isCritical || config.roll.result.duality === 1)
|
||||||
|
updates.push({ key: 'hope', value: 1, total: -1, enabled: true });
|
||||||
|
if (config.roll.isCritical)
|
||||||
|
updates.push({ key: 'stress', value: -1, total: 1, enabled: true });
|
||||||
|
if (config.roll.result.duality === -1)
|
||||||
|
updates.push({ key: 'fear', value: 1, total: -1, enabled: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updates.length) {
|
||||||
|
const target = actor.system.partner ?? actor;
|
||||||
|
if (!['dead', 'defeated', 'unconscious'].some(x => actor.statuses.has(x))) {
|
||||||
|
await target.modifyResource(updates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const registerRollDiceHooks = () => {
|
export const registerRollDiceHooks = () => {
|
||||||
Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async (config, message) => {
|
Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async (config, message) => {
|
||||||
const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
||||||
|
|
@ -247,45 +292,16 @@ export const registerRollDiceHooks = () => {
|
||||||
!config.skips?.updateCountdowns
|
!config.skips?.updateCountdowns
|
||||||
) {
|
) {
|
||||||
const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns;
|
const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns;
|
||||||
await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id);
|
|
||||||
|
|
||||||
if (config.roll.result.duality === -1) {
|
if (config.roll.result.duality === -1) {
|
||||||
await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id);
|
await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id,
|
||||||
|
CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id);
|
||||||
|
} else {
|
||||||
|
await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const hopeFearAutomation = automationSettings.hopeFear;
|
await automateHopeFear(config);
|
||||||
if (
|
|
||||||
!config.source?.actor ||
|
|
||||||
(game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) ||
|
|
||||||
config.actionType === 'reaction' ||
|
|
||||||
config.tagTeamSelected ||
|
|
||||||
config.skips?.resources
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
const actor = await fromUuid(config.source.actor);
|
|
||||||
let updates = [];
|
|
||||||
if (!actor) return;
|
|
||||||
if (config.roll.isCritical || config.roll.result.duality === 1)
|
|
||||||
updates.push({ key: 'hope', value: 1, total: -1, enabled: true });
|
|
||||||
if (config.roll.isCritical) updates.push({ key: 'stress', value: 1, total: -1, enabled: true });
|
|
||||||
if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1, total: -1, enabled: true });
|
|
||||||
|
|
||||||
if (config.rerolledRoll) {
|
|
||||||
if (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1)
|
|
||||||
updates.push({ key: 'hope', value: -1, total: 1, enabled: true });
|
|
||||||
if (config.rerolledRoll.isCritical) updates.push({ key: 'stress', value: -1, total: 1, enabled: true });
|
|
||||||
if (config.rerolledRoll.result.duality === -1)
|
|
||||||
updates.push({ key: 'fear', value: -1, total: 1, enabled: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updates.length) {
|
|
||||||
const target = actor.system.partner ?? actor;
|
|
||||||
if (!['dead', 'defeated', 'unconscious'].some(x => actor.statuses.has(x))) {
|
|
||||||
if (config.rerolledRoll) target.modifyResource(updates);
|
|
||||||
else config.costs = [...(config.costs ?? []), ...updates];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.roll.hasOwnProperty('success') && !config.targets?.length) return;
|
if (!config.roll.hasOwnProperty('success') && !config.targets?.length) return;
|
||||||
|
|
||||||
|
|
@ -296,7 +312,5 @@ export const registerRollDiceHooks = () => {
|
||||||
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 == actor.id) ui.combat.setCombatantSpotlight(currentCombatant.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -262,8 +262,7 @@ export default class DualityRoll extends D20Roll {
|
||||||
targets: message.system.targets,
|
targets: message.system.targets,
|
||||||
tagTeamSelected: Object.values(tagTeamSettings.members).some(x => x.messageId === message._id),
|
tagTeamSelected: Object.values(tagTeamSettings.members).some(x => x.messageId === message._id),
|
||||||
roll: newRoll,
|
roll: newRoll,
|
||||||
rerolledRoll:
|
rerolledRoll: message.system.roll
|
||||||
newRoll.result.duality !== message.system.roll.result.duality ? message.system.roll : undefined
|
|
||||||
});
|
});
|
||||||
return { newRoll, parsedRoll };
|
return { newRoll, parsedRoll };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -526,7 +526,7 @@ export default class DhpActor extends Actor {
|
||||||
|
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
getRollData() {
|
getRollData() {
|
||||||
const rollData = super.getRollData();
|
const rollData = super.getRollData().clone();
|
||||||
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;
|
||||||
|
|
@ -679,6 +679,10 @@ export default class DhpActor extends Actor {
|
||||||
return updates;
|
return updates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resources are modified asynchronously, so be careful not to update the same resource in
|
||||||
|
* quick succession.
|
||||||
|
*/
|
||||||
async modifyResource(resources) {
|
async modifyResource(resources) {
|
||||||
if (!resources?.length) return;
|
if (!resources?.length) return;
|
||||||
|
|
||||||
|
|
@ -761,6 +765,10 @@ export default class DhpActor extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
convertDamageToThreshold(damage) {
|
convertDamageToThreshold(damage) {
|
||||||
|
const massiveDamageEnabled=game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).massiveDamage.enabled;
|
||||||
|
if (massiveDamageEnabled && damage >= (this.system.damageThresholds.severe * 2)) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
return damage >= this.system.damageThresholds.severe ? 3 : damage >= this.system.damageThresholds.major ? 2 : 1;
|
return damage >= this.system.damageThresholds.severe ? 3 : damage >= this.system.damageThresholds.major ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ export default class DhpCombat extends Combat {
|
||||||
...effect,
|
...effect,
|
||||||
name: game.i18n.localize(effect.name),
|
name: game.i18n.localize(effect.name),
|
||||||
description: game.i18n.localize(effect.description),
|
description: game.i18n.localize(effect.description),
|
||||||
|
effectTargetTypes: grouping.effectTargetTypes ?? [],
|
||||||
flags: {
|
flags: {
|
||||||
[`${CONFIG.DH.id}.${CONFIG.DH.FLAGS.combatToggle}`]: {
|
[`${CONFIG.DH.id}.${CONFIG.DH.FLAGS.combatToggle}`]: {
|
||||||
category: toggle.category,
|
category: toggle.category,
|
||||||
|
|
@ -45,11 +46,7 @@ export default class DhpCombat extends Combat {
|
||||||
for (let actor of actors) {
|
for (let actor of actors) {
|
||||||
await actor.createEmbeddedDocuments(
|
await actor.createEmbeddedDocuments(
|
||||||
'ActiveEffect',
|
'ActiveEffect',
|
||||||
effects.map(effect => ({
|
effects.filter(x => x.effectTargetTypes.includes(actor.type))
|
||||||
...effect,
|
|
||||||
name: game.i18n.localize(effect.name),
|
|
||||||
description: game.i18n.localize(effect.description)
|
|
||||||
}))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,8 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
||||||
{
|
{
|
||||||
item: item,
|
item: item,
|
||||||
description: item.system?.enrichedDescription ?? item.enrichedDescription,
|
description: item.system?.enrichedDescription ?? item.enrichedDescription,
|
||||||
config: CONFIG.DH
|
config: CONFIG.DH,
|
||||||
|
allDomains: CONFIG.DH.DOMAIN.allDomains()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ foundry.dice.terms.Die.prototype.selfCorrecting = function (modifier) {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDamageKey = damage => {
|
export const getDamageKey = damage => {
|
||||||
return ['none', 'minor', 'major', 'severe', 'any'][damage];
|
return ['none', 'minor', 'major', 'severe', 'massive','any'][damage];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDamageLabel = damage => {
|
export const getDamageLabel = damage => {
|
||||||
|
|
@ -225,7 +225,8 @@ export const damageKeyToNumber = key => {
|
||||||
minor: 1,
|
minor: 1,
|
||||||
major: 2,
|
major: 2,
|
||||||
severe: 3,
|
severe: 3,
|
||||||
any: 4
|
massive: 4,
|
||||||
|
any: 5
|
||||||
}[key];
|
}[key];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,16 @@ export const registerDHSettings = () => {
|
||||||
registerMenuSettings();
|
registerMenuSettings();
|
||||||
registerMenus();
|
registerMenus();
|
||||||
registerNonConfigSettings();
|
registerNonConfigSettings();
|
||||||
|
|
||||||
|
game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.SpotlightRequestQueue, {
|
||||||
|
name: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.SpotlightRequestQueue.name'),
|
||||||
|
label: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.SpotlightRequestQueue.label'),
|
||||||
|
hint: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.SpotlightRequestQueue.hint'),
|
||||||
|
scope: 'world',
|
||||||
|
config: true,
|
||||||
|
type: Boolean,
|
||||||
|
onChange: () => ui.combat.render(),
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
const registerMenuSettings = () => {
|
const registerMenuSettings = () => {
|
||||||
|
|
|
||||||
|
|
@ -427,7 +427,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
|
||||||
|
|
@ -307,7 +307,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
@ -319,7 +320,7 @@
|
||||||
"trait": null,
|
"trait": null,
|
||||||
"difficulty": null,
|
"difficulty": null,
|
||||||
"bonus": null,
|
"bonus": null,
|
||||||
"advState": "neutral",
|
"advState": "advantage",
|
||||||
"diceRolling": {
|
"diceRolling": {
|
||||||
"multiplier": "prof",
|
"multiplier": "prof",
|
||||||
"flatMultiplier": 1,
|
"flatMultiplier": 1,
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@
|
||||||
"experiences": {
|
"experiences": {
|
||||||
"7GpgCWSe6hNwnOO7": {
|
"7GpgCWSe6hNwnOO7": {
|
||||||
"name": "Throw",
|
"name": "Throw",
|
||||||
"value": 2
|
"value": 2,
|
||||||
|
"description": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bonuses": {
|
"bonuses": {
|
||||||
|
|
@ -105,7 +106,8 @@
|
||||||
},
|
},
|
||||||
"base": false
|
"base": false
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"name": "Club",
|
"name": "Club",
|
||||||
"img": "icons/weapons/clubs/club-banded-barbed-black.webp",
|
"img": "icons/weapons/clubs/club-banded-barbed-black.webp",
|
||||||
|
|
@ -337,10 +339,11 @@
|
||||||
{
|
{
|
||||||
"value": {
|
"value": {
|
||||||
"custom": {
|
"custom": {
|
||||||
"enabled": false
|
"enabled": false,
|
||||||
|
"formula": ""
|
||||||
},
|
},
|
||||||
"flatMultiplier": 1,
|
"flatMultiplier": 1,
|
||||||
"dice": "d12",
|
"dice": "d10",
|
||||||
"bonus": 2,
|
"bonus": 2,
|
||||||
"multiplier": "flat"
|
"multiplier": "flat"
|
||||||
},
|
},
|
||||||
|
|
@ -356,12 +359,14 @@
|
||||||
"dice": "d6",
|
"dice": "d6",
|
||||||
"bonus": null,
|
"bonus": null,
|
||||||
"custom": {
|
"custom": {
|
||||||
"enabled": false
|
"enabled": false,
|
||||||
|
"formula": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
@ -528,7 +533,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,8 @@
|
||||||
},
|
},
|
||||||
"base": false
|
"base": false
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"img": "icons/magic/symbols/rune-sigil-rough-white-teal.webp",
|
"img": "icons/magic/symbols/rune-sigil-rough-white-teal.webp",
|
||||||
"type": "attack",
|
"type": "attack",
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,8 @@
|
||||||
},
|
},
|
||||||
"base": false
|
"base": false
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"type": "attack",
|
"type": "attack",
|
||||||
"chatDisplay": false
|
"chatDisplay": false
|
||||||
|
|
@ -358,7 +359,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,89 @@
|
||||||
"system": {
|
"system": {
|
||||||
"description": "<p> The Assassin deals direct damage while they’re <em>Hidden</em>.</p>",
|
"description": "<p> The Assassin deals direct damage while they’re <em>Hidden</em>.</p>",
|
||||||
"resource": null,
|
"resource": null,
|
||||||
"actions": {},
|
"actions": {
|
||||||
|
"xFBE0jLf96fbCY7K": {
|
||||||
|
"type": "attack",
|
||||||
|
"_id": "xFBE0jLf96fbCY7K",
|
||||||
|
"systemPath": "actions",
|
||||||
|
"baseAction": false,
|
||||||
|
"description": "<p>The Assassin deals direct damage while they’re <em>Hidden</em>.</p>",
|
||||||
|
"chatDisplay": true,
|
||||||
|
"originItem": {
|
||||||
|
"type": "itemCollection"
|
||||||
|
},
|
||||||
|
"actionType": "action",
|
||||||
|
"cost": [],
|
||||||
|
"uses": {
|
||||||
|
"value": null,
|
||||||
|
"max": "",
|
||||||
|
"recovery": null,
|
||||||
|
"consumeOnSuccess": false
|
||||||
|
},
|
||||||
|
"damage": {
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"value": {
|
||||||
|
"custom": {
|
||||||
|
"enabled": false,
|
||||||
|
"formula": ""
|
||||||
|
},
|
||||||
|
"flatMultiplier": 2,
|
||||||
|
"dice": "d10",
|
||||||
|
"bonus": 2,
|
||||||
|
"multiplier": "flat"
|
||||||
|
},
|
||||||
|
"applyTo": "hitPoints",
|
||||||
|
"type": [
|
||||||
|
"physical"
|
||||||
|
],
|
||||||
|
"base": false,
|
||||||
|
"resultBased": false,
|
||||||
|
"valueAlt": {
|
||||||
|
"multiplier": "prof",
|
||||||
|
"flatMultiplier": 1,
|
||||||
|
"dice": "d6",
|
||||||
|
"bonus": null,
|
||||||
|
"custom": {
|
||||||
|
"enabled": false,
|
||||||
|
"formula": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"type": "any",
|
||||||
|
"amount": null
|
||||||
|
},
|
||||||
|
"effects": [],
|
||||||
|
"roll": {
|
||||||
|
"type": "attack",
|
||||||
|
"trait": null,
|
||||||
|
"difficulty": null,
|
||||||
|
"bonus": null,
|
||||||
|
"advState": "neutral",
|
||||||
|
"diceRolling": {
|
||||||
|
"multiplier": "prof",
|
||||||
|
"flatMultiplier": 1,
|
||||||
|
"dice": "d6",
|
||||||
|
"compare": null,
|
||||||
|
"treshold": null
|
||||||
|
},
|
||||||
|
"useDefault": false
|
||||||
|
},
|
||||||
|
"save": {
|
||||||
|
"trait": null,
|
||||||
|
"difficulty": null,
|
||||||
|
"damageMod": "none"
|
||||||
|
},
|
||||||
|
"name": "Hidden attack",
|
||||||
|
"img": "icons/magic/perception/silhouette-stealth-shadow.webp",
|
||||||
|
"range": "close"
|
||||||
|
}
|
||||||
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -478,7 +478,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,87 @@
|
||||||
"name": "Curse",
|
"name": "Curse",
|
||||||
"img": "icons/magic/unholy/hand-marked-pink.webp",
|
"img": "icons/magic/unholy/hand-marked-pink.webp",
|
||||||
"range": "veryClose"
|
"range": "veryClose"
|
||||||
|
},
|
||||||
|
"zLKfwa8a2YBRLKAF": {
|
||||||
|
"type": "attack",
|
||||||
|
"_id": "zLKfwa8a2YBRLKAF",
|
||||||
|
"systemPath": "actions",
|
||||||
|
"baseAction": false,
|
||||||
|
"description": "<p> Attacks made by the Hunter against a Deathlocked target deal direct damage.</p>",
|
||||||
|
"chatDisplay": true,
|
||||||
|
"originItem": {
|
||||||
|
"type": "itemCollection"
|
||||||
|
},
|
||||||
|
"actionType": "action",
|
||||||
|
"cost": [],
|
||||||
|
"uses": {
|
||||||
|
"value": null,
|
||||||
|
"max": "",
|
||||||
|
"recovery": null,
|
||||||
|
"consumeOnSuccess": false
|
||||||
|
},
|
||||||
|
"damage": {
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"value": {
|
||||||
|
"custom": {
|
||||||
|
"enabled": false,
|
||||||
|
"formula": ""
|
||||||
|
},
|
||||||
|
"flatMultiplier": 2,
|
||||||
|
"dice": "d12",
|
||||||
|
"bonus": 1,
|
||||||
|
"multiplier": "flat"
|
||||||
|
},
|
||||||
|
"applyTo": "hitPoints",
|
||||||
|
"type": [
|
||||||
|
"physical"
|
||||||
|
],
|
||||||
|
"base": false,
|
||||||
|
"resultBased": false,
|
||||||
|
"valueAlt": {
|
||||||
|
"multiplier": "prof",
|
||||||
|
"flatMultiplier": 1,
|
||||||
|
"dice": "d6",
|
||||||
|
"bonus": null,
|
||||||
|
"custom": {
|
||||||
|
"enabled": false,
|
||||||
|
"formula": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"type": "any",
|
||||||
|
"amount": null
|
||||||
|
},
|
||||||
|
"effects": [],
|
||||||
|
"roll": {
|
||||||
|
"type": "attack",
|
||||||
|
"trait": null,
|
||||||
|
"difficulty": null,
|
||||||
|
"bonus": null,
|
||||||
|
"advState": "neutral",
|
||||||
|
"diceRolling": {
|
||||||
|
"multiplier": "prof",
|
||||||
|
"flatMultiplier": 1,
|
||||||
|
"dice": "d6",
|
||||||
|
"compare": null,
|
||||||
|
"treshold": null
|
||||||
|
},
|
||||||
|
"useDefault": false
|
||||||
|
},
|
||||||
|
"save": {
|
||||||
|
"trait": null,
|
||||||
|
"difficulty": null,
|
||||||
|
"damageMod": "none"
|
||||||
|
},
|
||||||
|
"name": "Deathlocked attack",
|
||||||
|
"img": "icons/magic/unholy/hand-marked-pink.webp",
|
||||||
|
"range": "veryClose"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
|
|
|
||||||
|
|
@ -312,9 +312,10 @@
|
||||||
{
|
{
|
||||||
"value": {
|
"value": {
|
||||||
"custom": {
|
"custom": {
|
||||||
"enabled": false
|
"enabled": false,
|
||||||
|
"formula": ""
|
||||||
},
|
},
|
||||||
"flatMultiplier": 1,
|
"flatMultiplier": 2,
|
||||||
"dice": "d6",
|
"dice": "d6",
|
||||||
"bonus": 8,
|
"bonus": 8,
|
||||||
"multiplier": "flat"
|
"multiplier": "flat"
|
||||||
|
|
@ -331,12 +332,14 @@
|
||||||
"dice": "d6",
|
"dice": "d6",
|
||||||
"bonus": null,
|
"bonus": null,
|
||||||
"custom": {
|
"custom": {
|
||||||
"enabled": false
|
"enabled": false,
|
||||||
|
"formula": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
|
||||||
|
|
@ -804,7 +804,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
|
||||||
|
|
@ -208,13 +208,13 @@
|
||||||
},
|
},
|
||||||
"changes": [
|
"changes": [
|
||||||
{
|
{
|
||||||
"key": "system.resistance.magical.reduction",
|
"key": "system.rules.damageReduction.reduceSeverity.magical",
|
||||||
"mode": 2,
|
"mode": 2,
|
||||||
"value": "1",
|
"value": "1",
|
||||||
"priority": null
|
"priority": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "system.resistance.magical.reduction",
|
"key": "system.rules.damageReduction.reduceSeverity.physical",
|
||||||
"mode": 2,
|
"mode": 2,
|
||||||
"value": "1",
|
"value": "1",
|
||||||
"priority": null
|
"priority": null
|
||||||
|
|
|
||||||
|
|
@ -457,7 +457,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"includeBase": false
|
"includeBase": false,
|
||||||
|
"direct": true
|
||||||
},
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "any",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"folder": "hLn0v6ov6KuFgptu",
|
"folder": "hLn0v6ov6KuFgptu",
|
||||||
"name": "Elundrian Chain Mail",
|
"name": "Elundrian Chain Armor",
|
||||||
"type": "armor",
|
"type": "armor",
|
||||||
"_id": "Q6LxmtFetDDkoZVZ",
|
"_id": "Q6LxmtFetDDkoZVZ",
|
||||||
"img": "icons/equipment/chest/breastplate-sculpted-green.webp",
|
"img": "icons/equipment/chest/breastplate-sculpted-green.webp",
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
"changes": [
|
"changes": [
|
||||||
{
|
{
|
||||||
"key": "system.rules.damageReduction.maxArmorMarked.stressExtra",
|
"key": "system.rules.damageReduction.maxArmorMarked.value",
|
||||||
"mode": 2,
|
"mode": 2,
|
||||||
"value": "1",
|
"value": "1",
|
||||||
"priority": null
|
"priority": null
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,16 @@
|
||||||
"description": "<p>Mark a Stress to pick up and carry another willing creature approximately your size or smaller.</p>",
|
"description": "<p>Mark a Stress to pick up and carry another willing creature approximately your size or smaller.</p>",
|
||||||
"chatDisplay": true,
|
"chatDisplay": true,
|
||||||
"actionType": "action",
|
"actionType": "action",
|
||||||
"cost": [],
|
"cost": [
|
||||||
|
{
|
||||||
|
"scalable": false,
|
||||||
|
"key": "stress",
|
||||||
|
"value": 1,
|
||||||
|
"itemId": null,
|
||||||
|
"step": null,
|
||||||
|
"consumeOnSuccess": false
|
||||||
|
}
|
||||||
|
],
|
||||||
"uses": {
|
"uses": {
|
||||||
"value": null,
|
"value": null,
|
||||||
"max": "",
|
"max": "",
|
||||||
|
|
@ -60,12 +69,12 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"target": {
|
"target": {
|
||||||
"type": "any",
|
"type": "self",
|
||||||
"amount": null
|
"amount": null
|
||||||
},
|
},
|
||||||
"name": "Spend Hope",
|
"name": "Spend Hope",
|
||||||
"img": "icons/magic/light/projectile-beam-yellow.webp",
|
"img": "icons/magic/light/projectile-beam-yellow.webp",
|
||||||
"range": ""
|
"range": "self"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
|
|
|
||||||
|
|
@ -37,3 +37,5 @@
|
||||||
@import './image-select/sheet.less';
|
@import './image-select/sheet.less';
|
||||||
|
|
||||||
@import './item-transfer/sheet.less';
|
@import './item-transfer/sheet.less';
|
||||||
|
|
||||||
|
@import './settings/change-currency-icon.less';
|
||||||
13
styles/less/dialog/settings/change-currency-icon.less
Normal file
13
styles/less/dialog/settings/change-currency-icon.less
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
.application.daggerheart.dialog.dh-style.change-currency-icon {
|
||||||
|
.displayed-icon {
|
||||||
|
height: 2.5rem;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
.input-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
input[type='text'],
|
input[type='text'],
|
||||||
input[type='number'],
|
input[type='number'],
|
||||||
textarea {
|
textarea,
|
||||||
|
.input[contenteditable] {
|
||||||
background: light-dark(transparent, transparent);
|
background: light-dark(transparent, transparent);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
box-shadow: 0 4px 30px @soft-shadow;
|
box-shadow: 0 4px 30px @soft-shadow;
|
||||||
|
|
@ -43,6 +44,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input[contenteditable] {
|
||||||
|
cursor: var(--cursor-text);
|
||||||
|
&:empty:before {
|
||||||
|
color: light-dark(@dark-40, @beige-50);
|
||||||
|
content: attr(placeholder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
input[type='checkbox'],
|
input[type='checkbox'],
|
||||||
input[type='radio'] {
|
input[type='radio'] {
|
||||||
&:checked::after {
|
&:checked::after {
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
.effect-locked {
|
.effect-locked {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 2px;
|
bottom: 2px;
|
||||||
right: 2px;
|
left: 11.5px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: @golden;
|
color: @golden;
|
||||||
filter: drop-shadow(0 0 3px black);
|
filter: drop-shadow(0 0 3px black);
|
||||||
|
|
|
||||||
|
|
@ -12,18 +12,19 @@
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0;
|
padding: 8px 0;
|
||||||
padding-top: 5px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
input[type='text'] {
|
h1 {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
padding: 6px 0 0 0;
|
||||||
font-size: var(--font-size-32);
|
font-size: var(--font-size-32);
|
||||||
height: 42px;
|
|
||||||
text-align: start;
|
text-align: start;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
outline: 2px solid transparent;
|
outline: 2px solid transparent;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
word-break: break-word;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
outline: 2px solid light-dark(@dark, @golden);
|
outline: 2px solid light-dark(@dark, @golden);
|
||||||
|
|
|
||||||
|
|
@ -34,19 +34,22 @@
|
||||||
.name-row {
|
.name-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
align-items: end;
|
align-items: start;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
input[type='text'] {
|
h1 {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
padding: 6px 0 0 0;
|
||||||
font-size: var(--font-size-32);
|
font-size: var(--font-size-32);
|
||||||
height: 42px;
|
|
||||||
text-align: start;
|
text-align: start;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
outline: 2px solid transparent;
|
outline: 2px solid transparent;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
word-break: break-word;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
outline: 2px solid light-dark(@dark, @golden);
|
outline: 2px solid light-dark(@dark, @golden);
|
||||||
|
|
@ -57,6 +60,8 @@
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
|
height: var(--font-size-32);
|
||||||
|
margin-top: 6px;
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
@import './mixin.less';
|
@import './mixin.less';
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--font-title: 'Cinzel Decorative';
|
--dh-font-title: 'Cinzel Decorative';
|
||||||
--font-subtitle: 'Cinzel';
|
--dh-font-subtitle: 'Cinzel';
|
||||||
--font-body: 'Montserrat';
|
--dh-font-body: 'Montserrat';
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-title: ~"var(--font-title, 'Cinzel Decorative'), serif";
|
@font-title: ~"var(--dh-font-title, 'Cinzel Decorative'), serif";
|
||||||
@font-subtitle: ~"var(--font-subtitle, 'Cinzel'), serif";
|
@font-subtitle: ~"var(--dh-font-subtitle, 'Cinzel'), serif";
|
||||||
@font-body: ~"var(--font-body, 'Montserrat'), sans-serif";
|
@font-body: ~"var(--dh-font-body, 'Montserrat'), sans-serif";
|
||||||
|
|
||||||
.dh-style {
|
.dh-style {
|
||||||
.dh-typography();
|
.dh-typography();
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,12 @@
|
||||||
</button>
|
</button>
|
||||||
<div class="palette status-effects" data-palette="effects">
|
<div class="palette status-effects" data-palette="effects">
|
||||||
{{#each systemStatusEffects as |status|}}
|
{{#each systemStatusEffects as |status|}}
|
||||||
<div class="effect-control-container" {{#if status.disabled}}data-tooltip="{{localize "DAGGERHEART.UI.Tooltip.immune"}}"{{else if status.title}}data-tooltip-text="{{status.title}}"{{/if}}>
|
<div
|
||||||
<img class="effect-control {{status.cssClass}} {{#if (or status.disabled status.locked)}}disabled{{/if}}" src="{{status.src}}" data-action="effect" data-status-id="{{status.id}}">
|
class="effect-control effect-control-container {{status.cssClass}} {{#if (or status.disabled status.locked)}}disabled{{/if}}"
|
||||||
|
{{#if status.disabled}}data-tooltip="{{localize "DAGGERHEART.UI.Tooltip.immune"}}"{{else if status.title}}data-tooltip-text="{{status.title}}"{{/if}}
|
||||||
|
data-action="effect" data-status-id="{{status.id}}"
|
||||||
|
>
|
||||||
|
<img src="{{status.src}}" />
|
||||||
{{#if status.disabled}}
|
{{#if status.disabled}}
|
||||||
<span class="effect-control-disabled-marker">/</span>
|
<span class="effect-control-disabled-marker">/</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
@ -57,8 +61,12 @@
|
||||||
{{#if genericStatusEffects}}
|
{{#if genericStatusEffects}}
|
||||||
<label class="palette-category-title">{{localize "DAGGERHEART.APPLICATIONS.HUD.tokenHUD.genericEffects"}}</label>
|
<label class="palette-category-title">{{localize "DAGGERHEART.APPLICATIONS.HUD.tokenHUD.genericEffects"}}</label>
|
||||||
{{#each genericStatusEffects as |status|}}
|
{{#each genericStatusEffects as |status|}}
|
||||||
<div class="effect-control-container" {{#if status.title}}data-tooltip-text="{{status.title}}"{{/if}}>
|
<div
|
||||||
<img class="effect-control {{status.cssClass}} {{#if (or status.disabled status.locked)}}disabled{{/if}}" src="{{status.src}}" data-action="effect" data-status-id="{{status.id}}" >
|
class="effect-control effect-control-container {{status.cssClass}} {{#if (or status.disabled status.locked)}}disabled{{/if}}"
|
||||||
|
{{#if status.title}}data-tooltip-text="{{status.title}}"{{/if}}
|
||||||
|
data-action="effect" data-status-id="{{status.id}}"
|
||||||
|
>
|
||||||
|
<img src="{{status.src}}" />
|
||||||
{{#if status.locked}}<i class="effect-locked fa-solid fa-lock"></i>{{/if}}
|
{{#if status.locked}}<i class="effect-locked fa-solid fa-lock"></i>{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<div>
|
||||||
|
<div class="displayed-icon">
|
||||||
|
<i class="{{currentIcon}}" inert></i>
|
||||||
|
</div>
|
||||||
|
<span>{{localize "DAGGERHEART.SETTINGS.Homebrew.currency.iconName"}} (<em>{{localize "DAGGERHEART.SETTINGS.Homebrew.currency.iconNameHint"}}</em>)</span>
|
||||||
|
<div class="input-row">
|
||||||
|
<input type="text" name="icon" value="{{currentIcon}}" />
|
||||||
|
<button type="button" data-action="reset" class="plain icon fa-solid fa-redo"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -33,18 +33,22 @@
|
||||||
{{formGroup settingFields.schema.fields.currency.fields.title value=settingFields._source.currency.title localize=true}}
|
{{formGroup settingFields.schema.fields.currency.fields.title value=settingFields._source.currency.title localize=true}}
|
||||||
</div>
|
</div>
|
||||||
<div class="toggleable-row">
|
<div class="toggleable-row">
|
||||||
|
<button class="icon {{settingFields._source.currency.coins.icon}}" data-action="editCurrencyIcon" data-currency="coins" data-tooltip="DAGGERHEART.SETTINGS.Homebrew.currency.changeIcon"></button>
|
||||||
{{formGroup settingFields.schema.fields.currency.fields.coins.fields.label value=settingFields._source.currency.coins.label localize=true}}
|
{{formGroup settingFields.schema.fields.currency.fields.coins.fields.label value=settingFields._source.currency.coins.label localize=true}}
|
||||||
<input type="checkbox" name="currency.coins.enabled" {{checked settingFields._source.currency.coins.enabled}} />
|
<input type="checkbox" name="currency.coins.enabled" {{checked settingFields._source.currency.coins.enabled}} />
|
||||||
</div>
|
</div>
|
||||||
<div class="toggleable-row">
|
<div class="toggleable-row">
|
||||||
|
<button class="icon {{settingFields._source.currency.handfuls.icon}}" data-action="editCurrencyIcon" data-currency="handfuls" data-tooltip="DAGGERHEART.SETTINGS.Homebrew.currency.changeIcon"></button>
|
||||||
{{formGroup settingFields.schema.fields.currency.fields.handfuls.fields.label value=settingFields._source.currency.handfuls.label localize=true}}
|
{{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}} />
|
<input type="checkbox" name="currency.handfuls.enabled" {{checked settingFields._source.currency.handfuls.enabled}} />
|
||||||
</div>
|
</div>
|
||||||
<div class="toggleable-row">
|
<div class="toggleable-row">
|
||||||
|
<button class="icon {{settingFields._source.currency.bags.icon}}" data-action="editCurrencyIcon" data-currency="bags" data-tooltip="DAGGERHEART.SETTINGS.Homebrew.currency.changeIcon"></button>
|
||||||
{{formGroup settingFields.schema.fields.currency.fields.bags.fields.label value=settingFields._source.currency.bags.label localize=true}}
|
{{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}} />
|
<input type="checkbox" name="currency.bags.enabled" {{checked settingFields._source.currency.bags.enabled}} />
|
||||||
</div>
|
</div>
|
||||||
<div class="toggleable-row">
|
<div class="toggleable-row">
|
||||||
|
<button class="icon {{settingFields._source.currency.chests.icon}}" data-action="editCurrencyIcon" data-currency="chests" data-tooltip="DAGGERHEART.SETTINGS.Homebrew.currency.changeIcon"></button>
|
||||||
{{formGroup settingFields.schema.fields.currency.fields.chests.fields.label value=settingFields._source.currency.chests.label localize=true}}
|
{{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}} />
|
<input type="checkbox" name="currency.chests.enabled" {{checked settingFields._source.currency.chests.enabled}} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{localize "DAGGERHEART.SETTINGS.VariantRules.FIELDS.massiveDamage.title"}}</label>
|
||||||
|
<div class="form-fields">
|
||||||
|
{{formGroup settingFields.schema.fields.massiveDamage.fields.enabled value=settingFields._source.massiveDamage.enabled localize=true}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<footer class="form-footer">
|
<footer class="form-footer">
|
||||||
<button data-action="reset">
|
<button data-action="reset">
|
||||||
<i class="fa-solid fa-arrow-rotate-left"></i>
|
<i class="fa-solid fa-arrow-rotate-left"></i>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
<header class='adversary-header-sheet'>
|
<header class='adversary-header-sheet'>
|
||||||
<line-div></line-div>
|
<line-div></line-div>
|
||||||
<div class="name-row">
|
<div class="name-row">
|
||||||
<h1 class='actor-name'>
|
<h1 class='input actor-name' contenteditable="plaintext-only" data-property="name" placeholder="{{localize "DAGGERHEART.GENERAL.actorName"}}">{{source.name}}</h1>
|
||||||
<input type='text' name='name' value='{{source.name}}' placeholder="{{localize "DAGGERHEART.GENERAL.actorName"}}"
|
|
||||||
/>
|
|
||||||
</h1>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<div class="tag">
|
<div class="tag">
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,7 @@
|
||||||
<header class="character-header-sheet">
|
<header class="character-header-sheet">
|
||||||
<line-div></line-div>
|
<line-div></line-div>
|
||||||
<div class="name-row">
|
<div class="name-row">
|
||||||
<h1 class='actor-name'>
|
<h1 class="actor-name input" contenteditable="plaintext-only" data-property="name" placeholder="{{localize "DAGGERHEART.GENERAL.actorName"}}">{{source.name}}</h1>
|
||||||
<input
|
|
||||||
type='text'
|
|
||||||
name='name'
|
|
||||||
value='{{document.name}}'
|
|
||||||
placeholder='{{localize "DAGGERHEART.GENERAL.actorName"}}'
|
|
||||||
/>
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<div class='level-div'>
|
<div class='level-div'>
|
||||||
<h3 class='label'>
|
<h3 class='label'>
|
||||||
{{#if (or document.system.needsCharacterSetup document.system.levelData.canLevelUp)}}
|
{{#if (or document.system.needsCharacterSetup document.system.levelData.canLevelUp)}}
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,10 @@
|
||||||
{{#each this.inventory.currencies as | currency |}}
|
{{#each this.inventory.currencies as | currency |}}
|
||||||
{{#if currency.enabled}}
|
{{#if currency.enabled}}
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<span>{{localize currency.label}}</span>
|
<span>
|
||||||
{{formInput currency.field value=currency.value enriched=currency.value toggled=true}}
|
<i class="{{currency.icon}}" inert></i> {{localize currency.label}}
|
||||||
|
</span>
|
||||||
|
<input type="text" name="{{currency.field.fieldPath}}" data-allow-delta value="{{currency.value}}" data-dtype="Number" min="0" step="1" />
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,10 @@
|
||||||
{{#each this.inventory.currencies as | currency |}}
|
{{#each this.inventory.currencies as | currency |}}
|
||||||
{{#if currency.enabled}}
|
{{#if currency.enabled}}
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<span>{{localize currency.label}}</span>
|
<span>
|
||||||
{{formInput currency.field value=currency.value enriched=currency.value toggled=true}}
|
<i class="{{currency.icon}}" inert></i> {{localize currency.label}}
|
||||||
|
</span>
|
||||||
|
<input type="text" name="{{currency.field.fieldPath}}" data-allow-delta value="{{currency.value}}" data-dtype="Number" min="0" step="1" />
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="effects-display-container">
|
<div class="effects-display-container">
|
||||||
{{#each effects as | effect |}}
|
{{#each effects as | effect |}}
|
||||||
<span class="effect-container {{#if effect.condition}}disabled{{/if}}" data-tooltip="#effect-display#" id="{{effect.id}}"
|
<span class="effect-container {{#if effect.condition}}disabled{{/if}}" data-tooltip="#effect-display#" data-effect-id="{{effect.id}}"
|
||||||
data-applied-by="{{effect.appliedBy}}" {{#if effect.condition}}data-condition="{{effect.condition}}"{{else}}data-uuid="{{effect.uuid}}"{{/if}}
|
{{#if effect.appliedBy}}data-applied-by="{{effect.appliedBy}}"{{/if}}
|
||||||
|
{{#if effect.condition}}data-condition="{{effect.condition}}"{{else}}data-uuid="{{effect.uuid}}"{{/if}}
|
||||||
>
|
>
|
||||||
<a {{#if effect.condition}}disabled{{/if}}>
|
<a {{#if effect.condition}}disabled{{/if}}>
|
||||||
<img src="{{effect.img}}" />
|
<img src="{{effect.img}}" />
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="tooltip-information-section">
|
<div class="tooltip-information-section">
|
||||||
<div class="tooltip-information">
|
<div class="tooltip-information">
|
||||||
<label>{{localize "DAGGERHEART.GENERAL.Domain.single"}}</label>
|
<label>{{localize "DAGGERHEART.GENERAL.Domain.single"}}</label>
|
||||||
{{#with (lookup config.DOMAIN.domains item.system.domain) as | domain |}}
|
{{#with (lookup allDomains item.system.domain) as | domain |}}
|
||||||
<div>{{localize domain.label}}</div>
|
<div>{{localize domain.label}}</div>
|
||||||
{{/with}}
|
{{/with}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue