mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
[Fix] Downtime Rework (#367)
* Fixed so that the dropdown for activeEffectAutocomplete never ends up behind dialog * Downtime can now display both ShortRest and LongRest options depending on character rules * Initial downtime layout rework * Fixed styling for downtime tooltip * Added icon to homebrew menu for DowntimeActions * Fixed columns if both types of moves are not available * Changed the lightmode to darkmode * Added downtime buttons * . * Moved extra rest options from rules to bonuses * Improved dialog width
This commit is contained in:
parent
0cc1597dfe
commit
6e87e4dad0
25 changed files with 390 additions and 152 deletions
32
lang/en.json
32
lang/en.json
|
|
@ -249,8 +249,9 @@
|
||||||
"title": "{actor} - Death Move"
|
"title": "{actor} - Death Move"
|
||||||
},
|
},
|
||||||
"Downtime": {
|
"Downtime": {
|
||||||
"downtimeHeader": "Downtime Moves ({current}/{max})",
|
|
||||||
"longRest": {
|
"longRest": {
|
||||||
|
"title": "Long Rest",
|
||||||
|
"moves": "Long Rest Moves ({current}/{max})",
|
||||||
"clearStress": {
|
"clearStress": {
|
||||||
"description": "Describe how you blow off steam or pull yourself together, and clear all marked Stress.",
|
"description": "Describe how you blow off steam or pull yourself together, and clear all marked Stress.",
|
||||||
"name": "Clear Stress"
|
"name": "Clear Stress"
|
||||||
|
|
@ -267,7 +268,6 @@
|
||||||
"description": "Describe how you patch yourself up and remove all marked Hit Points. You may also do this on an ally instead.",
|
"description": "Describe how you patch yourself up and remove all marked Hit Points. You may also do this on an ally instead.",
|
||||||
"name": "Tend to Wounds"
|
"name": "Tend to Wounds"
|
||||||
},
|
},
|
||||||
"title": "Long Rest",
|
|
||||||
"workOnAProject": {
|
"workOnAProject": {
|
||||||
"description": "Establish or continue work on a project.",
|
"description": "Establish or continue work on a project.",
|
||||||
"name": "Work on a Project"
|
"name": "Work on a Project"
|
||||||
|
|
@ -275,6 +275,7 @@
|
||||||
},
|
},
|
||||||
"shortRest": {
|
"shortRest": {
|
||||||
"title": "Short Rest",
|
"title": "Short Rest",
|
||||||
|
"moves": "Short Rest Moves ({current}/{max})",
|
||||||
"tendToWounds": {
|
"tendToWounds": {
|
||||||
"name": "Tend to Wounds",
|
"name": "Tend to Wounds",
|
||||||
"description": "Describe how you hastily patch yourself up, then clear a number of Hit Points equal to 1d4 + your tier. You can do this to an ally instead."
|
"description": "Describe how you hastily patch yourself up, then clear a number of Hit Points equal to 1d4 + your tier. You can do this to an ally instead."
|
||||||
|
|
@ -291,7 +292,8 @@
|
||||||
"name": "Prepare",
|
"name": "Prepare",
|
||||||
"description": "Describe how you prepare yourself for the path ahead, then gain a Hope. If you choose to Prepare with one or more members of your party, you each gain 2 Hope."
|
"description": "Describe how you prepare yourself for the path ahead, then gain a Hope. If you choose to Prepare with one or more members of your party, you each gain 2 Hope."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"takeDowntime": "Take Downtime"
|
||||||
},
|
},
|
||||||
"HUD": {
|
"HUD": {
|
||||||
"tokenHUD": {
|
"tokenHUD": {
|
||||||
|
|
@ -1012,6 +1014,30 @@
|
||||||
"singular": "Adversary",
|
"singular": "Adversary",
|
||||||
"plural": "Adversaries"
|
"plural": "Adversaries"
|
||||||
},
|
},
|
||||||
|
"Bonuses": {
|
||||||
|
"rest": {
|
||||||
|
"shortRest": {
|
||||||
|
"shortRestMoves": {
|
||||||
|
"label": "Short Rest: Bonus Short Rest Moves",
|
||||||
|
"hint": "The number of extra Short Rest Moves the character can take during a Short Rest."
|
||||||
|
},
|
||||||
|
"longRestMoves": {
|
||||||
|
"label": "Short Rest: Bonus Long Rest Moves",
|
||||||
|
"hint": "The number of extra Long Rest Moves the character can take during a Short Rest."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"longRest": {
|
||||||
|
"shortRestMoves": {
|
||||||
|
"label": "Long Rest: Bonus Short Rest Moves",
|
||||||
|
"hint": "The number of extra Short Rest Moves the character can take during a Long Rest."
|
||||||
|
},
|
||||||
|
"longRestMoves": {
|
||||||
|
"label": "Long Rest: Bonus Long Rest Moves",
|
||||||
|
"hint": "The number of extra Long Rest Moves the character can take during a Long Rest."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Character": {
|
"Character": {
|
||||||
"singular": "Character",
|
"singular": "Character",
|
||||||
"plural": "Characters"
|
"plural": "Characters"
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,22 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.shortrest = shortrest;
|
this.shortrest = shortrest;
|
||||||
|
|
||||||
const options = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves;
|
this.moveData = foundry.utils.deepClone(
|
||||||
this.moveData = shortrest ? options.shortRest : options.longRest;
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves
|
||||||
|
);
|
||||||
|
this.nrChoices = {
|
||||||
|
shortRest: {
|
||||||
|
max:
|
||||||
|
(shortrest ? this.moveData.shortRest.nrChoices : 0) +
|
||||||
|
actor.system.bonuses.rest[`${shortrest ? 'short' : 'long'}Rest`].shortMoves
|
||||||
|
},
|
||||||
|
longRest: {
|
||||||
|
max:
|
||||||
|
(!shortrest ? this.moveData.longRest.nrChoices : 0) +
|
||||||
|
actor.system.bonuses.rest[`${shortrest ? 'short' : 'long'}Rest`].longMoves
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.nrChoices.total = { max: this.nrChoices.shortRest.max + this.nrChoices.longRest.max };
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
|
|
@ -17,8 +31,8 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
classes: ['daggerheart', 'views', 'downtime'],
|
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'downtime'],
|
||||||
position: { width: 680, height: 'auto' },
|
position: { width: 'auto', height: 'auto' },
|
||||||
actions: {
|
actions: {
|
||||||
selectMove: this.selectMove,
|
selectMove: this.selectMove,
|
||||||
takeDowntime: this.takeDowntime
|
takeDowntime: this.takeDowntime
|
||||||
|
|
@ -29,7 +43,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
application: {
|
application: {
|
||||||
id: 'downtime',
|
id: 'downtime',
|
||||||
template: 'systems/daggerheart/templates/dialogs/downtime.hbs'
|
template: 'systems/daggerheart/templates/dialogs/downtime/downtime.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -37,46 +51,83 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
super._attachPartListeners(partId, htmlElement, options);
|
super._attachPartListeners(partId, htmlElement, options);
|
||||||
|
|
||||||
htmlElement
|
htmlElement
|
||||||
.querySelectorAll('.activity-image')
|
.querySelectorAll('.activity-container')
|
||||||
.forEach(element => element.addEventListener('contextmenu', this.deselectMove.bind(this)));
|
.forEach(element => element.addEventListener('contextmenu', this.deselectMove.bind(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
|
context.title = game.i18n.localize(
|
||||||
|
`DAGGERHEART.APPLICATIONS.Downtime.${this.shortrest ? 'shortRest' : 'longRest'}.title`
|
||||||
|
);
|
||||||
context.selectedActivity = this.selectedActivity;
|
context.selectedActivity = this.selectedActivity;
|
||||||
context.moveData = this.moveData;
|
context.moveData = this.moveData;
|
||||||
context.nrCurrentChoices = Object.values(this.moveData.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0);
|
context.nrCurrentChoices = Object.values(this.moveData).reduce((acc, category) => {
|
||||||
context.disabledDowntime = context.nrCurrentChoices < context.moveData.nrChoices;
|
acc += Object.values(category.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0);
|
||||||
|
return acc;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
context.nrChoices = {
|
||||||
|
...this.nrChoices,
|
||||||
|
shortRest: {
|
||||||
|
...this.nrChoices.shortRest,
|
||||||
|
current: Object.values(this.moveData.shortRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0)
|
||||||
|
},
|
||||||
|
longRest: {
|
||||||
|
...this.nrChoices.longRest,
|
||||||
|
current: Object.values(this.moveData.longRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
context.nrChoices.total = {
|
||||||
|
...this.nrChoices.total,
|
||||||
|
current: context.nrChoices.shortRest.current + context.nrChoices.longRest.current
|
||||||
|
};
|
||||||
|
|
||||||
|
context.shortRestMoves = this.nrChoices.shortRest.max > 0 ? this.moveData.shortRest : null;
|
||||||
|
context.longRestMoves = this.nrChoices.longRest.max > 0 ? this.moveData.longRest : null;
|
||||||
|
|
||||||
|
context.disabledDowntime = context.nrChoices.total.current < context.nrChoices.total.max;
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static selectMove(_, button) {
|
static selectMove(_, target) {
|
||||||
const nrSelected = Object.values(this.moveData.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0);
|
const nrSelected = Object.values(this.moveData[target.dataset.category].moves).reduce(
|
||||||
if (nrSelected === this.moveData.nrChoices) {
|
(acc, x) => acc + (x.selected ?? 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nrSelected === this.nrChoices[target.dataset.category].max) {
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noMoreMoves'));
|
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noMoreMoves'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const move = button.dataset.move;
|
const move = target.dataset.move;
|
||||||
this.moveData.moves[move].selected = this.moveData.moves[move].selected
|
this.moveData[target.dataset.category].moves[move].selected = this.moveData[target.dataset.category].moves[move]
|
||||||
? this.moveData.moves[move].selected + 1
|
.selected
|
||||||
|
? this.moveData[target.dataset.category].moves[move].selected + 1
|
||||||
: 1;
|
: 1;
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectMove(event) {
|
deselectMove(event) {
|
||||||
const move = event.currentTarget.dataset.move;
|
const button = event.target.closest('.activity-container');
|
||||||
this.moveData.moves[move].selected = this.moveData.moves[move].selected
|
const move = button.dataset.move;
|
||||||
? this.moveData.moves[move].selected - 1
|
this.moveData[button.dataset.category].moves[move].selected = this.moveData[button.dataset.category].moves[move]
|
||||||
|
.selected
|
||||||
|
? this.moveData[button.dataset.category].moves[move].selected - 1
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
static async takeDowntime() {
|
static async takeDowntime() {
|
||||||
const moves = Object.values(this.moveData.moves).filter(x => x.selected);
|
const moves = Object.values(this.moveData).flatMap(category => {
|
||||||
|
return Object.values(category.moves)
|
||||||
|
.filter(x => x.selected)
|
||||||
|
.flatMap(move => [...Array(move.selected).keys()].map(_ => move));
|
||||||
|
});
|
||||||
|
|
||||||
const cls = getDocumentClass('ChatMessage');
|
const cls = getDocumentClass('ChatMessage');
|
||||||
const msg = new cls({
|
const msg = new cls({
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@ import DHActionConfig from '../../sheets-configs/action-config.mjs';
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
export default class DhSettingsActionView extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class DhSettingsActionView extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
constructor(resolve, reject, title, name, img, description, actions) {
|
constructor(resolve, reject, title, name, icon, img, description, actions) {
|
||||||
super({});
|
super({});
|
||||||
|
|
||||||
this.resolve = resolve;
|
this.resolve = resolve;
|
||||||
this.reject = reject;
|
this.reject = reject;
|
||||||
this.viewTitle = title;
|
this.viewTitle = title;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.icon = icon;
|
||||||
this.img = img;
|
this.img = img;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.actions = actions;
|
this.actions = actions;
|
||||||
|
|
@ -23,7 +24,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
classes: ['daggerheart', 'setting', 'dh-style'],
|
classes: ['daggerheart', 'setting', 'dh-style'],
|
||||||
position: { width: '400', height: 'auto' },
|
position: { width: 440, height: 'auto' },
|
||||||
actions: {
|
actions: {
|
||||||
editImage: this.onEditImage,
|
editImage: this.onEditImage,
|
||||||
addItem: this.addItem,
|
addItem: this.addItem,
|
||||||
|
|
@ -46,6 +47,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.name = this.name;
|
context.name = this.name;
|
||||||
|
context.icon = this.icon;
|
||||||
context.img = this.img;
|
context.img = this.img;
|
||||||
context.description = this.description;
|
context.description = this.description;
|
||||||
context.enrichedDescription = await foundry.applications.ux.TextEditor.enrichHTML(context.description);
|
context.enrichedDescription = await foundry.applications.ux.TextEditor.enrichHTML(context.description);
|
||||||
|
|
@ -55,8 +57,9 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App
|
||||||
}
|
}
|
||||||
|
|
||||||
static async updateData(event, element, formData) {
|
static async updateData(event, element, formData) {
|
||||||
const { name, img, description } = foundry.utils.expandObject(formData.object);
|
const { name, icon, description } = foundry.utils.expandObject(formData.object);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.icon = icon;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
|
|
@ -65,6 +68,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App
|
||||||
static async saveForm(event) {
|
static async saveForm(event) {
|
||||||
this.resolve({
|
this.resolve({
|
||||||
name: this.name,
|
name: this.name,
|
||||||
|
icon: this.icon,
|
||||||
img: this.img,
|
img: this.img,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
actions: this.actions
|
actions: this.actions
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
reject,
|
reject,
|
||||||
game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.downtimeMoves'),
|
game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.downtimeMoves'),
|
||||||
move.name,
|
move.name,
|
||||||
|
move.icon,
|
||||||
move.img,
|
move.img,
|
||||||
move.description,
|
move.description,
|
||||||
move.actions
|
move.actions
|
||||||
|
|
@ -87,6 +88,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
await this.settings.updateSource({
|
await this.settings.updateSource({
|
||||||
[`restMoves.${type}.moves.${id}`]: {
|
[`restMoves.${type}.moves.${id}`]: {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
|
icon: data.icon,
|
||||||
img: data.img,
|
img: data.img,
|
||||||
description: data.description
|
description: data.description
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,9 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
||||||
element.value = `system.${item.value}`;
|
element.value = `system.${item.value}`;
|
||||||
},
|
},
|
||||||
click: e => e.fetch(),
|
click: e => e.fetch(),
|
||||||
|
customize: function (_input, _inputRect, container) {
|
||||||
|
container.style.zIndex = foundry.applications.api.ApplicationV2._maxZ;
|
||||||
|
},
|
||||||
minLength: 0
|
minLength: 0
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
useAction: this.useAction,
|
useAction: this.useAction,
|
||||||
toggleResourceDice: this.toggleResourceDice,
|
toggleResourceDice: this.toggleResourceDice,
|
||||||
handleResourceDice: this.handleResourceDice,
|
handleResourceDice: this.handleResourceDice,
|
||||||
toChat: this.toChat
|
toChat: this.toChat,
|
||||||
|
useDowntime: this.useDowntime
|
||||||
},
|
},
|
||||||
window: {
|
window: {
|
||||||
resizable: true
|
resizable: true
|
||||||
|
|
@ -752,6 +753,12 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static useDowntime(_, button) {
|
||||||
|
new game.system.api.applications.dialogs.Downtime(this.document, button.dataset.type === 'shortRest').render(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async _onDragStart(event) {
|
async _onDragStart(event) {
|
||||||
const item = this.getItem(event);
|
const item = this.getItem(event);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ export const defaultRestOptions = {
|
||||||
tendToWounds: {
|
tendToWounds: {
|
||||||
id: 'tendToWounds',
|
id: 'tendToWounds',
|
||||||
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.name'),
|
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.name'),
|
||||||
|
icon: 'fa-solid fa-bandage',
|
||||||
img: 'icons/magic/life/cross-worn-green.webp',
|
img: 'icons/magic/life/cross-worn-green.webp',
|
||||||
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.description'),
|
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.description'),
|
||||||
actions: [
|
actions: [
|
||||||
|
|
@ -153,6 +154,7 @@ export const defaultRestOptions = {
|
||||||
clearStress: {
|
clearStress: {
|
||||||
id: 'clearStress',
|
id: 'clearStress',
|
||||||
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.name'),
|
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.name'),
|
||||||
|
icon: 'fa-regular fa-face-surprise',
|
||||||
img: 'icons/magic/perception/eye-ringed-green.webp',
|
img: 'icons/magic/perception/eye-ringed-green.webp',
|
||||||
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.description'),
|
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.description'),
|
||||||
actions: [
|
actions: [
|
||||||
|
|
@ -176,6 +178,7 @@ export const defaultRestOptions = {
|
||||||
repairArmor: {
|
repairArmor: {
|
||||||
id: 'repairArmor',
|
id: 'repairArmor',
|
||||||
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.name'),
|
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.name'),
|
||||||
|
icon: 'fa-solid fa-hammer',
|
||||||
img: 'icons/skills/trades/smithing-anvil-silver-red.webp',
|
img: 'icons/skills/trades/smithing-anvil-silver-red.webp',
|
||||||
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.description'),
|
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.description'),
|
||||||
actions: []
|
actions: []
|
||||||
|
|
@ -183,6 +186,7 @@ export const defaultRestOptions = {
|
||||||
prepare: {
|
prepare: {
|
||||||
id: 'prepare',
|
id: 'prepare',
|
||||||
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.name'),
|
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.name'),
|
||||||
|
icon: 'fa-solid fa-dumbbell',
|
||||||
img: 'icons/skills/trades/academics-merchant-scribe.webp',
|
img: 'icons/skills/trades/academics-merchant-scribe.webp',
|
||||||
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.description'),
|
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.description'),
|
||||||
actions: []
|
actions: []
|
||||||
|
|
@ -192,6 +196,7 @@ export const defaultRestOptions = {
|
||||||
tendToWounds: {
|
tendToWounds: {
|
||||||
id: 'tendToWounds',
|
id: 'tendToWounds',
|
||||||
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.name'),
|
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.name'),
|
||||||
|
icon: 'fa-solid fa-bandage',
|
||||||
img: 'icons/magic/life/cross-worn-green.webp',
|
img: 'icons/magic/life/cross-worn-green.webp',
|
||||||
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.description'),
|
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.description'),
|
||||||
actions: []
|
actions: []
|
||||||
|
|
@ -199,6 +204,7 @@ export const defaultRestOptions = {
|
||||||
clearStress: {
|
clearStress: {
|
||||||
id: 'clearStress',
|
id: 'clearStress',
|
||||||
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.name'),
|
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.name'),
|
||||||
|
icon: 'fa-regular fa-face-surprise',
|
||||||
img: 'icons/magic/perception/eye-ringed-green.webp',
|
img: 'icons/magic/perception/eye-ringed-green.webp',
|
||||||
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.description'),
|
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.description'),
|
||||||
actions: []
|
actions: []
|
||||||
|
|
@ -206,6 +212,7 @@ export const defaultRestOptions = {
|
||||||
repairArmor: {
|
repairArmor: {
|
||||||
id: 'repairArmor',
|
id: 'repairArmor',
|
||||||
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.name'),
|
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.name'),
|
||||||
|
icon: 'fa-solid fa-hammer',
|
||||||
img: 'icons/skills/trades/smithing-anvil-silver-red.webp',
|
img: 'icons/skills/trades/smithing-anvil-silver-red.webp',
|
||||||
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.description'),
|
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.description'),
|
||||||
actions: []
|
actions: []
|
||||||
|
|
@ -213,6 +220,7 @@ export const defaultRestOptions = {
|
||||||
prepare: {
|
prepare: {
|
||||||
id: 'prepare',
|
id: 'prepare',
|
||||||
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.name'),
|
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.name'),
|
||||||
|
icon: 'fa-solid fa-dumbbell',
|
||||||
img: 'icons/skills/trades/academics-merchant-scribe.webp',
|
img: 'icons/skills/trades/academics-merchant-scribe.webp',
|
||||||
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.description'),
|
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.description'),
|
||||||
actions: []
|
actions: []
|
||||||
|
|
@ -220,19 +228,12 @@ export const defaultRestOptions = {
|
||||||
workOnAProject: {
|
workOnAProject: {
|
||||||
id: 'workOnAProject',
|
id: 'workOnAProject',
|
||||||
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.name'),
|
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.name'),
|
||||||
|
icon: 'fa-solid fa-diagram-project',
|
||||||
img: 'icons/skills/social/thumbsup-approval-like.webp',
|
img: 'icons/skills/social/thumbsup-approval-like.webp',
|
||||||
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.description'),
|
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.description'),
|
||||||
actions: []
|
actions: []
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
custom: {
|
|
||||||
id: 'customActivity',
|
|
||||||
name: '',
|
|
||||||
img: 'icons/skills/trades/academics-investigation-puzzles.webp',
|
|
||||||
description: '',
|
|
||||||
namePlaceholder: 'DAGGERHEART.APPLICATIONS.Downtime.custom.namePlaceholder',
|
|
||||||
placeholder: 'DAGGERHEART.APPLICATIONS.Downtime.custom.placeholder'
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deathMoves = {
|
export const deathMoves = {
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,44 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
}),
|
}),
|
||||||
rally: new fields.ArrayField(new fields.StringField(), {
|
rally: new fields.ArrayField(new fields.StringField(), {
|
||||||
label: 'DAGGERHEART.CLASS.Feature.rallyDice'
|
label: 'DAGGERHEART.CLASS.Feature.rallyDice'
|
||||||
|
}),
|
||||||
|
rest: new fields.SchemaField({
|
||||||
|
shortRest: new fields.SchemaField({
|
||||||
|
shortMoves: new fields.NumberField({
|
||||||
|
required: true,
|
||||||
|
integer: true,
|
||||||
|
min: 0,
|
||||||
|
initial: 0,
|
||||||
|
label: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.shortRestMoves.label',
|
||||||
|
hint: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.shortRestMoves.hint'
|
||||||
|
}),
|
||||||
|
longMoves: new fields.NumberField({
|
||||||
|
required: true,
|
||||||
|
integer: true,
|
||||||
|
min: 0,
|
||||||
|
initial: 0,
|
||||||
|
label: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.longRestMoves.label',
|
||||||
|
hint: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.longRestMoves.hint'
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
longRest: new fields.SchemaField({
|
||||||
|
shortMoves: new fields.NumberField({
|
||||||
|
required: true,
|
||||||
|
integer: true,
|
||||||
|
min: 0,
|
||||||
|
initial: 0,
|
||||||
|
label: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.shortRestMoves.label',
|
||||||
|
hint: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.shortRestMoves.hint'
|
||||||
|
}),
|
||||||
|
longMoves: new fields.NumberField({
|
||||||
|
required: true,
|
||||||
|
integer: true,
|
||||||
|
min: 0,
|
||||||
|
initial: 0,
|
||||||
|
label: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.longRestMoves.label',
|
||||||
|
hint: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.longRestMoves.hint'
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }),
|
companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }),
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
|
||||||
moves: new fields.TypedObjectField(
|
moves: new fields.TypedObjectField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
name: new fields.StringField({ required: true }),
|
name: new fields.StringField({ required: true }),
|
||||||
|
icon: new fields.StringField({ required: true }),
|
||||||
img: new fields.FilePathField({
|
img: new fields.FilePathField({
|
||||||
initial: 'icons/magic/life/cross-worn-green.webp',
|
initial: 'icons/magic/life/cross-worn-green.webp',
|
||||||
categories: ['IMAGE'],
|
categories: ['IMAGE'],
|
||||||
|
|
@ -70,6 +71,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
|
||||||
moves: new fields.TypedObjectField(
|
moves: new fields.TypedObjectField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
name: new fields.StringField({ required: true }),
|
name: new fields.StringField({ required: true }),
|
||||||
|
icon: new fields.StringField({ required: true }),
|
||||||
img: new fields.FilePathField({
|
img: new fields.FilePathField({
|
||||||
initial: 'icons/magic/life/cross-worn-green.webp',
|
initial: 'icons/magic/life/cross-worn-green.webp',
|
||||||
categories: ['IMAGE'],
|
categories: ['IMAGE'],
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export default class DHToken extends TokenDocument {
|
||||||
});
|
});
|
||||||
bars.sort((a, b) => a.label.compare(b.label));
|
bars.sort((a, b) => a.label.compare(b.label));
|
||||||
|
|
||||||
const invalidAttributes = ['gold', 'levelData', 'rules.damageReduction.maxArmorMarked.value'];
|
const invalidAttributes = ['gold', 'levelData', 'actions', 'rules.damageReduction.maxArmorMarked.value'];
|
||||||
const values = attributes.value.reduce((acc, v) => {
|
const values = attributes.value.reduce((acc, v) => {
|
||||||
const a = v.join('.');
|
const a = v.join('.');
|
||||||
if (invalidAttributes.some(x => a.startsWith(x))) return acc;
|
if (invalidAttributes.some(x => a.startsWith(x))) return acc;
|
||||||
|
|
@ -32,19 +32,19 @@ export default class DHToken extends TokenDocument {
|
||||||
|
|
||||||
return bars.concat(values);
|
return bars.concat(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _getTrackedAttributesFromSchema(schema, _path=[]) {
|
static _getTrackedAttributesFromSchema(schema, _path = []) {
|
||||||
const attributes = {bar: [], value: []};
|
const attributes = { bar: [], value: [] };
|
||||||
for ( const [name, field] of Object.entries(schema.fields) ) {
|
for (const [name, field] of Object.entries(schema.fields)) {
|
||||||
const p = _path.concat([name]);
|
const p = _path.concat([name]);
|
||||||
if ( field instanceof foundry.data.fields.NumberField ) attributes.value.push(p);
|
if (field instanceof foundry.data.fields.NumberField) attributes.value.push(p);
|
||||||
if ( field instanceof foundry.data.fields.ArrayField ) attributes.value.push(p);
|
if (field instanceof foundry.data.fields.ArrayField) attributes.value.push(p);
|
||||||
const isSchema = field instanceof foundry.data.fields.SchemaField;
|
const isSchema = field instanceof foundry.data.fields.SchemaField;
|
||||||
const isModel = field instanceof foundry.data.fields.EmbeddedDataField;
|
const isModel = field instanceof foundry.data.fields.EmbeddedDataField;
|
||||||
if ( isSchema || isModel ) {
|
if (isSchema || isModel) {
|
||||||
const schema = isModel ? field.model.schema : field;
|
const schema = isModel ? field.model.schema : field;
|
||||||
const isBar = schema.has && schema.has("value") && schema.has("max");
|
const isBar = schema.has && schema.has('value') && schema.has('max');
|
||||||
if ( isBar ) attributes.bar.push(p);
|
if (isBar) attributes.bar.push(p);
|
||||||
else {
|
else {
|
||||||
const inner = this.getTrackedAttributes(schema, p);
|
const inner = this.getTrackedAttributes(schema, p);
|
||||||
attributes.bar.push(...inner.bar);
|
attributes.bar.push(...inner.bar);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,28 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
||||||
options.direction = this._determineItemTooltipDirection(element);
|
options.direction = this._determineItemTooltipDirection(element);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
const shortRest = element.dataset.tooltip?.startsWith('#shortRest#');
|
||||||
|
const longRest = element.dataset.tooltip?.startsWith('#longRest#');
|
||||||
|
if (shortRest || longRest) {
|
||||||
|
const key = element.dataset.tooltip.slice(shortRest ? 11 : 10);
|
||||||
|
const downtimeOptions = shortRest
|
||||||
|
? CONFIG.DH.GENERAL.defaultRestOptions.shortRest()
|
||||||
|
: CONFIG.DH.GENERAL.defaultRestOptions.longRest();
|
||||||
|
const move = downtimeOptions[key];
|
||||||
|
html = await foundry.applications.handlebars.renderTemplate(
|
||||||
|
`systems/daggerheart/templates/ui/tooltip/downtime.hbs`,
|
||||||
|
{
|
||||||
|
move: move
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.tooltip.innerHTML = html;
|
||||||
|
options.direction = this._determineItemTooltipDirection(
|
||||||
|
element,
|
||||||
|
this.constructor.TOOLTIP_DIRECTIONS.UP
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const isAdvantage = element.dataset.tooltip?.startsWith('#advantage#');
|
const isAdvantage = element.dataset.tooltip?.startsWith('#advantage#');
|
||||||
const isDisadvantage = element.dataset.tooltip?.startsWith('#disadvantage#');
|
const isDisadvantage = element.dataset.tooltip?.startsWith('#disadvantage#');
|
||||||
if (isAdvantage || isDisadvantage) {
|
if (isAdvantage || isDisadvantage) {
|
||||||
|
|
@ -44,9 +66,34 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
||||||
super.activate(element, { ...options, html: html });
|
super.activate(element, { ...options, html: html });
|
||||||
}
|
}
|
||||||
|
|
||||||
_determineItemTooltipDirection(element) {
|
_determineItemTooltipDirection(element, prefered = this.constructor.TOOLTIP_DIRECTIONS.LEFT) {
|
||||||
const pos = element.getBoundingClientRect();
|
const pos = element.getBoundingClientRect();
|
||||||
const dirs = this.constructor.TOOLTIP_DIRECTIONS;
|
const dirs = this.constructor.TOOLTIP_DIRECTIONS;
|
||||||
return dirs[pos.x - this.tooltip.offsetWidth < 0 ? 'DOWN' : 'LEFT'];
|
switch (prefered) {
|
||||||
|
case this.constructor.TOOLTIP_DIRECTIONS.LEFT:
|
||||||
|
return dirs[
|
||||||
|
pos.x - this.tooltip.offsetWidth < 0
|
||||||
|
? this.constructor.TOOLTIP_DIRECTIONS.DOWN
|
||||||
|
: this.constructor.TOOLTIP_DIRECTIONS.LEFT
|
||||||
|
];
|
||||||
|
case this.constructor.TOOLTIP_DIRECTIONS.UP:
|
||||||
|
return dirs[
|
||||||
|
pos.y - this.tooltip.offsetHeight < 0
|
||||||
|
? this.constructor.TOOLTIP_DIRECTIONS.RIGHT
|
||||||
|
: this.constructor.TOOLTIP_DIRECTIONS.UP
|
||||||
|
];
|
||||||
|
case this.constructor.TOOLTIP_DIRECTIONS.RIGHT:
|
||||||
|
return dirs[
|
||||||
|
pos.x + this.tooltip.offsetWidth > document.body.clientWidth
|
||||||
|
? this.constructor.TOOLTIP_DIRECTIONS.DOWN
|
||||||
|
: this.constructor.TOOLTIP_DIRECTIONS.RIGHT
|
||||||
|
];
|
||||||
|
case this.constructor.TOOLTIP_DIRECTIONS.DOWN:
|
||||||
|
return dirs[
|
||||||
|
pos.y + this.tooltip.offsetHeight > document.body.clientHeight
|
||||||
|
? this.constructor.TOOLTIP_DIRECTIONS.LEFT
|
||||||
|
: this.constructor.TOOLTIP_DIRECTIONS.DOWN
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ export const preloadHandlebarsTemplates = async function () {
|
||||||
'systems/daggerheart/templates/settings/components/settings-item-line.hbs',
|
'systems/daggerheart/templates/settings/components/settings-item-line.hbs',
|
||||||
'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs',
|
'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs',
|
||||||
'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs',
|
'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs',
|
||||||
'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs'
|
'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs',
|
||||||
|
'systems/daggerheart/templates/dialogs/downtime/activities.hbs'
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,81 +1,75 @@
|
||||||
@import '../../utils/spacing.less';
|
@import '../../utils/spacing.less';
|
||||||
@import '../../utils/colors.less';
|
@import '../../utils/colors.less';
|
||||||
|
|
||||||
.daggerheart.views {
|
.theme-light .daggerheart.dh-style.views.downtime {
|
||||||
|
.downtime-container .activity-container .activity-selected-marker {
|
||||||
|
background-image: url(../assets/parchments/dh-parchment-light.png);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.daggerheart.dh-style.views.downtime {
|
||||||
|
font-family: @font-body;
|
||||||
|
|
||||||
.downtime-container {
|
.downtime-container {
|
||||||
.downtime-header {
|
.activities-grouping {
|
||||||
margin: 0;
|
width: 280px;
|
||||||
color: light-dark(@dark-blue, @golden);
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-container {
|
.activities-container {
|
||||||
display: flex;
|
width: 100%;
|
||||||
align-items: center;
|
|
||||||
padding: 8px;
|
|
||||||
|
|
||||||
.activity-title {
|
.activity-container {
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
.activity-title-text {
|
.activity-inner-container {
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-image {
|
|
||||||
width: 80px;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
align-items: center;
|
||||||
margin-right: 8px;
|
gap: 4px;
|
||||||
border: 2px solid black;
|
|
||||||
border-radius: 50%;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.activity-select-label {
|
.activity-marker {
|
||||||
position: absolute;
|
font-size: 8px;
|
||||||
top: -9px;
|
flex: none;
|
||||||
font-size: 14px;
|
color: light-dark(#18162e, #f3c267);
|
||||||
border: 1px solid light-dark(@dark-blue, @golden);
|
margin-right: 4px;
|
||||||
border-radius: 6px;
|
|
||||||
color: light-dark(@beige, @dark);
|
|
||||||
background-image: url(../assets/parchments/dh-parchment-light.png);
|
|
||||||
padding: 0 8px;
|
|
||||||
line-height: 1;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
.activity-select-section {
|
||||||
border-radius: 50%;
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
&:hover,
|
.activity-icon {
|
||||||
&.selected {
|
min-width: 24px;
|
||||||
filter: drop-shadow(0 0 6px gold);
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-name-input {
|
.activity-selected-marker {
|
||||||
font-size: 24px;
|
font-size: 14px;
|
||||||
|
border: 1px solid light-dark(@dark-blue, @golden);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: light-dark(@dark, @beige);
|
||||||
|
background-image: url(../assets/parchments/dh-parchment-dark.png);
|
||||||
|
padding: 0 8px;
|
||||||
|
line-height: 1;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 0;
|
|
||||||
background: transparent;
|
|
||||||
color: rgb(239, 230, 216);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-body {
|
|
||||||
flex: 1;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.downtime {
|
footer {
|
||||||
.activity-text-area {
|
margin-top: 8px;
|
||||||
resize: none;
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
flex: 1;
|
||||||
|
font-family: 'Montserrat', sans-serif;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,22 @@
|
||||||
height: 40px;
|
height: 40px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.feature-tab {
|
.navigation-container {
|
||||||
border: none;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
a {
|
.navigation-inner-container {
|
||||||
color: light-dark(@dark-blue, @golden);
|
flex: 1;
|
||||||
font-family: @font-body;
|
|
||||||
|
.feature-tab {
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: light-dark(@dark-blue, @golden);
|
||||||
|
font-family: @font-body;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -193,5 +193,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.character-downtime-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 2px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
border-color: light-dark(@dark, @beige);
|
border-color: light-dark(@dark, @beige);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background-image: url('../assets/parchments/dh-parchment-dark.png');
|
background-image: url('../assets/parchments/dh-parchment-dark.png');
|
||||||
z-index: 200;
|
|
||||||
max-height: 400px !important;
|
max-height: 400px !important;
|
||||||
width: fit-content !important;
|
width: fit-content !important;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,20 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
|
||||||
|
.tooltip-title-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
|
.tooltip-image {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid @golden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tooltip-title {
|
.tooltip-title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
<div>
|
|
||||||
<div class="downtime-container">
|
|
||||||
<h2 class="downtime-header">{{localize "DAGGERHEART.APPLICATIONS.Downtime.downtimeHeader" current=nrCurrentChoices max=moveData.nrChoices}}</h2>
|
|
||||||
{{#each moveData.moves as |move key|}}
|
|
||||||
<div class="activity-container">
|
|
||||||
<div class="activity-title">
|
|
||||||
<div class="activity-image {{#if this.selected}}selected{{/if}}" data-action="selectMove" data-move="{{key}}">
|
|
||||||
{{#if this.selected}}<div class="activity-select-label">{{move.selected}}</div>{{/if}}
|
|
||||||
<img src="{{move.img}}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<span class="activity-title-text">{{localize this.name}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="activity-body">
|
|
||||||
{{localize this.description}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
<footer class="flexrow">
|
|
||||||
<button type="button" data-action="close">{{localize "DAGGERHEART.Application.Cancel"}}</button>
|
|
||||||
<button type="button" data-action="takeDowntime" {{#if this.disabledDowntime}}disabled{{/if}}>{{localize "DAGGERHEART.Application.Downtime.TakeDowntime"}}</button>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
18
templates/dialogs/downtime/activities.hbs
Normal file
18
templates/dialogs/downtime/activities.hbs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<fieldset class="one-column activities-grouping">
|
||||||
|
<legend>{{localize (concat "DAGGERHEART.APPLICATIONS.Downtime." category ".moves") max=nrChoices.max current=nrChoices.current}}</legend>
|
||||||
|
|
||||||
|
<div class="activities-container">
|
||||||
|
{{#each moves as |move key|}}
|
||||||
|
<a class="activity-container" data-action="selectMove" data-category="{{../category}}" data-move="{{key}}" data-tooltip="{{concat "#" ../category "#" key}}">
|
||||||
|
<div class="activity-inner-container">
|
||||||
|
<i class="{{#if move.selected}}fa-solid{{else}}fa-regular{{/if}} fa-circle activity-marker"></i>
|
||||||
|
<div class="activity-select-section">
|
||||||
|
<i class="{{move.icon}} activity-icon"></i>
|
||||||
|
<div>{{move.name}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{#if move.selected}}<div class="activity-selected-marker">{{move.selected}}</div>{{/if}}
|
||||||
|
</a>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
14
templates/dialogs/downtime/downtime.hbs
Normal file
14
templates/dialogs/downtime/downtime.hbs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<div>
|
||||||
|
<header class="dialog-header">
|
||||||
|
<h1>{{title}}</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="downtime-container {{#if (and shortRestMoves.moves longRestMoves.moves)}}two-columns even{{else}}one-column{{/if}}">
|
||||||
|
{{#if shortRestMoves.moves}}{{> "systems/daggerheart/templates/dialogs/downtime/activities.hbs" moves=shortRestMoves.moves category='shortRest' nrChoices=nrChoices.shortRest}}{{/if}}
|
||||||
|
{{#if longRestMoves.moves}}{{> "systems/daggerheart/templates/dialogs/downtime/activities.hbs" moves=longRestMoves.moves category='longRest' nrChoices=nrChoices.longRest}}{{/if}}
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<button type="button" data-action="close">{{localize "Cancel"}}</button>
|
||||||
|
<button type="button" data-action="takeDowntime" {{#if disabledDowntime}}disabled{{/if}}>{{localize "DAGGERHEART.APPLICATIONS.Downtime.takeDowntime"}}</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{formGroup settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints localize=true}}
|
{{formGroup settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints localize=true}}
|
||||||
s {{formGroup settingFields.schema.fields.hordeDamage value=settingFields._source.hordeDamage localize=true}}
|
{{formGroup settingFields.schema.fields.hordeDamage value=settingFields._source.hordeDamage localize=true}}
|
||||||
|
|
||||||
<footer class="form-footer">
|
<footer class="form-footer">
|
||||||
<button data-action="reset">
|
<button data-action="reset">
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
<div>
|
<div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{localize "Icon"}}</label>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<input type="text" name="icon" value="{{icon}}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize "Description"}}</legend>
|
<legend>{{localize "Description"}}</legend>
|
||||||
|
|
||||||
<prose-mirror name="description" value="{{description}}" toggled=true>
|
<prose-mirror name="description" value="{{description}}">
|
||||||
{{{ enrichedDescription }}}
|
{{{ enrichedDescription }}}
|
||||||
</prose-mirror>
|
</prose-mirror>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{{!-- <fieldset>
|
|
||||||
<legend>{{localize "Actions"}} <a data-action="addItem"><i class="fa-solid fa-plus"></i></a></legend>
|
|
||||||
|
|
||||||
<div class="settings-items">
|
|
||||||
{{#each this.actions as |action index|}}
|
|
||||||
{{> "systems/daggerheart/templates/settings/components/settings-item-line.hbs" action type="actions" id=index }}
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
</fieldset> --}}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -116,5 +116,14 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
|
{{#> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
|
||||||
|
<div class="character-downtime-container">
|
||||||
|
<button data-action="useDowntime" data-type="shortRest" data-tooltip="{{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}}">
|
||||||
|
<i class="fa-solid fa-chair"></i>
|
||||||
|
</button>
|
||||||
|
<button data-action="useDowntime" data-type="longRest" data-tooltip="{{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}}">
|
||||||
|
<i class="fa-solid fa-bed"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{{/'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
<section class='tab-navigation'>
|
<section class='tab-navigation'>
|
||||||
<line-div></line-div>
|
<div class='navigation-container'>
|
||||||
<nav class='feature-tab sheet-tabs tabs' data-group='primary'>
|
<div class="navigation-inner-container">
|
||||||
{{#each tabs as |tab|}}
|
<line-div></line-div>
|
||||||
<a class='{{tab.id}} {{tab.cssClass}}' data-action='tab' data-group='{{tab.group}}' data-tab='{{tab.id}}'>
|
<nav class='feature-tab sheet-tabs tabs' data-group='primary'>
|
||||||
{{localize tab.label}}
|
{{#each tabs as |tab|}}
|
||||||
</a>
|
<a class='{{tab.id}} {{tab.cssClass}}' data-action='tab' data-group='{{tab.group}}' data-tab='{{tab.id}}'>
|
||||||
{{/each}}
|
{{localize tab.label}}
|
||||||
</nav>
|
</a>
|
||||||
<line-div></line-div>
|
{{/each}}
|
||||||
|
</nav>
|
||||||
|
<line-div></line-div>
|
||||||
|
</div>
|
||||||
|
{{#if @partial-block}}
|
||||||
|
{{> @partial-block }}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
7
templates/ui/tooltip/downtime.hbs
Normal file
7
templates/ui/tooltip/downtime.hbs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<div class="daggerheart dh-style tooltip">
|
||||||
|
<div class="tooltip-title-container">
|
||||||
|
<img class="tooltip-image" src="{{move.img}}" />
|
||||||
|
<h2 class="tooltip-title">{{move.name}}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="tooltip-description">{{{move.description}}}</div>
|
||||||
|
</div>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue