mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-17 07:36:26 +01:00
Merge branch 'main' into feature/beastform-types
This commit is contained in:
commit
9f22545f7d
29 changed files with 391 additions and 115 deletions
|
|
@ -140,6 +140,7 @@ Hooks.once('init', () => {
|
||||||
CONFIG.Combat.documentClass = documents.DhpCombat;
|
CONFIG.Combat.documentClass = documents.DhpCombat;
|
||||||
CONFIG.ui.combat = applications.ui.DhCombatTracker;
|
CONFIG.ui.combat = applications.ui.DhCombatTracker;
|
||||||
CONFIG.ui.chat = applications.ui.DhChatLog;
|
CONFIG.ui.chat = applications.ui.DhChatLog;
|
||||||
|
CONFIG.ui.hotbar = applications.ui.DhHotbar;
|
||||||
CONFIG.Token.rulerClass = placeables.DhTokenRuler;
|
CONFIG.Token.rulerClass = placeables.DhTokenRuler;
|
||||||
|
|
||||||
CONFIG.ui.resources = applications.ui.DhFearTracker;
|
CONFIG.ui.resources = applications.ui.DhFearTracker;
|
||||||
|
|
|
||||||
15
lang/en.json
15
lang/en.json
|
|
@ -1340,8 +1340,8 @@
|
||||||
},
|
},
|
||||||
"DomainCard": {
|
"DomainCard": {
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
"foundation": "Foundation",
|
|
||||||
"recallCost": "Recall Cost",
|
"recallCost": "Recall Cost",
|
||||||
|
"foundationTitle": "Foundation",
|
||||||
"specializationTitle": "Specialization",
|
"specializationTitle": "Specialization",
|
||||||
"masteryTitle": "Mastery"
|
"masteryTitle": "Mastery"
|
||||||
},
|
},
|
||||||
|
|
@ -1552,7 +1552,18 @@
|
||||||
"noAvailableArmorMarks": "You have no more available armor marks",
|
"noAvailableArmorMarks": "You have no more available armor marks",
|
||||||
"notEnoughStress": "You don't have enough stress",
|
"notEnoughStress": "You don't have enough stress",
|
||||||
"damageIgnore": "{character} did not take damage",
|
"damageIgnore": "{character} did not take damage",
|
||||||
"featureIsMissing": "Feature is missing"
|
"featureIsMissing": "Feature is missing",
|
||||||
|
"actionIsMissing": "Action is missing",
|
||||||
|
"attackIsMissing": "Attack is missing",
|
||||||
|
"unownedActionMacro": "Cannot make a Use macro for an Action not on your character",
|
||||||
|
"unownedAttackMacro": "Cannot make a Use macro for an Attack that doesn't belong to one of your characters",
|
||||||
|
"featureNotHope": "This feature is used as something else than a Hope feature and cannot be used here.",
|
||||||
|
"featureNotClass": "This feature is used as something else than a Class feature and cannot be used here.",
|
||||||
|
"featureNotPrimary": "This feature is used as something else than a Primary feature and cannot be used here.",
|
||||||
|
"featureNotSecondary": "This feature is used as something else than a Secondary feature and cannot be used here.",
|
||||||
|
"featureNotFoundation": "This feature is used as something else than a Foundation feature and cannot be used here.",
|
||||||
|
"featureNotSpecialization": "This feature is used as something else than a Specialization feature and cannot be used here.",
|
||||||
|
"featureNotMastery": "This feature is used as something else than a Mastery feature and cannot be used here."
|
||||||
},
|
},
|
||||||
"Tooltip": {
|
"Tooltip": {
|
||||||
"openItemWorld": "Open Item World",
|
"openItemWorld": "Open Item World",
|
||||||
|
|
|
||||||
|
|
@ -506,9 +506,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
||||||
name: this.setup.ancestryName ?? this.setup.primaryAncestry.name,
|
name: this.setup.ancestryName ?? this.setup.primaryAncestry.name,
|
||||||
system: {
|
system: {
|
||||||
...this.setup.primaryAncestry.system,
|
...this.setup.primaryAncestry.system,
|
||||||
features: [primaryAncestryFeature.uuid, secondaryAncestryFeature.uuid],
|
features: [primaryAncestryFeature.uuid, secondaryAncestryFeature.uuid]
|
||||||
primaryFeature: primaryAncestryFeature.uuid,
|
|
||||||
secondaryFeature: secondaryAncestryFeature.uuid
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ export default class ResourceDiceDialog extends HandlebarsApplicationMixin(Appli
|
||||||
|
|
||||||
static async rerollDice() {
|
static async rerollDice() {
|
||||||
const max = itemAbleRollParse(this.item.system.resource.max, this.actor, this.item);
|
const max = itemAbleRollParse(this.item.system.resource.max, this.actor, this.item);
|
||||||
const diceFormula = `${max}d${this.item.system.resource.dieFaces}`;
|
const diceFormula = `${max}${this.item.system.resource.dieFaces}`;
|
||||||
const roll = await new Roll(diceFormula).evaluate();
|
const roll = await new Roll(diceFormula).evaluate();
|
||||||
if (game.modules.get('dice-so-nice')?.active) await game.dice3d.showForRoll(roll, game.user, true);
|
if (game.modules.get('dice-so-nice')?.active) await game.dice3d.showForRoll(roll, game.user, true);
|
||||||
this.rollValues = roll.terms[0].results.map(x => ({ value: x.result, used: false }));
|
this.rollValues = roll.terms[0].results.map(x => ({ value: x.result, used: false }));
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
||||||
actions: {
|
actions: {
|
||||||
openSettings: DHBaseActorSheet.#openSettings
|
openSettings: DHBaseActorSheet.#openSettings
|
||||||
},
|
},
|
||||||
dragDrop: []
|
dragDrop: [{ dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null }]
|
||||||
};
|
};
|
||||||
|
|
||||||
/**@type {typeof DHBaseActorSettings}*/
|
/**@type {typeof DHBaseActorSettings}*/
|
||||||
|
|
@ -49,4 +49,27 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
||||||
static async #openSettings() {
|
static async #openSettings() {
|
||||||
await this.settingSheet.render({ force: true });
|
await this.settingSheet.render({ force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/* Application Drag/Drop */
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On dragStart on the item.
|
||||||
|
* @param {DragEvent} event - The drag event
|
||||||
|
*/
|
||||||
|
async _onDragStart(event) {
|
||||||
|
const attackItem = event.currentTarget.closest('.inventory-item[data-type="attack"]');
|
||||||
|
|
||||||
|
if (attackItem) {
|
||||||
|
const attackData = {
|
||||||
|
type: 'Attack',
|
||||||
|
actorUuid: this.document.uuid,
|
||||||
|
img: this.document.system.attack.img,
|
||||||
|
fromInternal: true
|
||||||
|
};
|
||||||
|
event.dataTransfer.setData('text/plain', JSON.stringify(attackData));
|
||||||
|
event.dataTransfer.setDragImage(attackItem.querySelector('img'), 60, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
},
|
},
|
||||||
dragDrop: [
|
dragDrop: [
|
||||||
{ dragSelector: null, dropSelector: '.tab.features .drop-section' },
|
{ dragSelector: null, dropSelector: '.tab.features .drop-section' },
|
||||||
{ dragSelector: '.feature-item', dropSelector: null }
|
{ dragSelector: '.feature-item', dropSelector: null },
|
||||||
|
{ dragSelector: '.action-item', dropSelector: null }
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -258,6 +259,23 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true };
|
const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true };
|
||||||
event.dataTransfer.setData('text/plain', JSON.stringify(featureData));
|
event.dataTransfer.setData('text/plain', JSON.stringify(featureData));
|
||||||
event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0);
|
event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0);
|
||||||
|
} else {
|
||||||
|
const actionItem = event.currentTarget.closest('.action-item');
|
||||||
|
if (actionItem) {
|
||||||
|
const action = this.document.system.actions[actionItem.dataset.index];
|
||||||
|
if (!action) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.actionIsMissing'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const actionData = {
|
||||||
|
type: 'Action',
|
||||||
|
data: { ...action.toObject(), id: action.id, itemUuid: this.document.uuid },
|
||||||
|
fromInternal: true
|
||||||
|
};
|
||||||
|
event.dataTransfer.setData('text/plain', JSON.stringify(actionData));
|
||||||
|
event.dataTransfer.setDragImage(actionItem.querySelector('img'), 60, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,22 +63,8 @@ export default class AncestrySheet extends DHHeritageSheet {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const target = button.closest('.feature-item');
|
const target = button.closest('.feature-item');
|
||||||
const feature = this.document.system[`${target.dataset.type}Feature`];
|
const feature = this.document.system[`${target.dataset.type}Feature`];
|
||||||
const featureExists = feature && Object.keys(feature).length > 0;
|
|
||||||
|
|
||||||
if (featureExists) {
|
if (feature) await feature.update({ 'system.subType': null });
|
||||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
|
||||||
window: {
|
|
||||||
title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', {
|
|
||||||
type: game.i18n.localize(`TYPES.Item.feature`),
|
|
||||||
name: feature.name
|
|
||||||
})
|
|
||||||
},
|
|
||||||
content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: feature.name })
|
|
||||||
});
|
|
||||||
if (!confirmed) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (featureExists && target.dataset.type === 'primary') await feature.update({ 'system.primary': null });
|
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.features': this.document.system.features.filter(x => x && x.uuid !== feature.uuid).map(x => x.uuid)
|
'system.features': this.document.system.features.filter(x => x && x.uuid !== feature.uuid).map(x => x.uuid)
|
||||||
});
|
});
|
||||||
|
|
@ -94,15 +80,18 @@ export default class AncestrySheet extends DHHeritageSheet {
|
||||||
*/
|
*/
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
|
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
if (item?.type === 'feature') {
|
if (item?.type === 'feature') {
|
||||||
const subType = event.target.closest('.primary-feature') ? 'primary' : 'secondary';
|
const subType = event.target.closest('.primary-feature') ? 'primary' : 'secondary';
|
||||||
await item.update({ 'system.subType': subType });
|
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes[subType]) {
|
||||||
|
const error = subType === 'primary' ? 'featureNotPrimary' : 'featureNotSecondary';
|
||||||
|
ui.notifications.warn(game.i18n.localize(`DAGGERHEART.UI.Notifications.${error}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await item.update({ 'system.subType': subType });
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ export default class ClassSheet extends DHBaseItemSheet {
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
|
event.stopPropagation();
|
||||||
const data = TextEditor.getDragEventData(event);
|
const data = TextEditor.getDragEventData(event);
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
const target = event.target.closest('fieldset.drop-section');
|
const target = event.target.closest('fieldset.drop-section');
|
||||||
|
|
@ -87,12 +88,24 @@ export default class ClassSheet extends DHBaseItemSheet {
|
||||||
});
|
});
|
||||||
} else if (item.type === 'feature') {
|
} else if (item.type === 'feature') {
|
||||||
if (target.classList.contains('hope-feature')) {
|
if (target.classList.contains('hope-feature')) {
|
||||||
|
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.hope) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotHope'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.hope });
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.hopeFeatures': [...this.document.system.hopeFeatures.map(x => x.uuid), item.uuid]
|
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||||
});
|
});
|
||||||
} else if (target.classList.contains('class-feature')) {
|
} else if (target.classList.contains('class-feature')) {
|
||||||
|
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.class) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotClass'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.class });
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.classFeatures': [...this.document.system.classFeatures.map(x => x.uuid), item.uuid]
|
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (item.type === 'weapon') {
|
} else if (item.type === 'weapon') {
|
||||||
|
|
@ -177,28 +190,25 @@ export default class ClassSheet extends DHBaseItemSheet {
|
||||||
doc.sheet.render({ force: true });
|
doc.sheet.render({ force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
getActionPath(type) {
|
|
||||||
return type === 'hope' ? 'hopeFeatures' : 'classFeatures';
|
|
||||||
}
|
|
||||||
|
|
||||||
static async addFeature(_, target) {
|
static async addFeature(_, target) {
|
||||||
const actionPath = this.getActionPath(target.dataset.type);
|
|
||||||
const feature = await game.items.documentClass.create({
|
const feature = await game.items.documentClass.create({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') })
|
name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }),
|
||||||
|
system: {
|
||||||
|
subType:
|
||||||
|
target.dataset.type === 'hope'
|
||||||
|
? CONFIG.DH.ITEM.featureSubTypes.hope
|
||||||
|
: CONFIG.DH.ITEM.featureSubTypes.class
|
||||||
|
}
|
||||||
});
|
});
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
[`system.${actionPath}`]: [
|
[`system.features`]: [...this.document.system.features.filter(x => x).map(x => x.uuid), feature.uuid]
|
||||||
...this.document.system[actionPath].filter(x => x).map(x => x.uuid),
|
|
||||||
feature.uuid
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async editFeature(_, button) {
|
static async editFeature(_, button) {
|
||||||
const target = button.closest('.feature-item');
|
const target = button.closest('.feature-item');
|
||||||
const actionPath = this.getActionPath(button.dataset.type);
|
const feature = this.document.system.features.find(x => x?.id === target.dataset.featureId);
|
||||||
const feature = this.document.system[actionPath].find(x => x?.id === target.dataset.featureId);
|
|
||||||
if (!feature) {
|
if (!feature) {
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
||||||
return;
|
return;
|
||||||
|
|
@ -210,10 +220,16 @@ export default class ClassSheet extends DHBaseItemSheet {
|
||||||
static async deleteFeature(event, button) {
|
static async deleteFeature(event, button) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const target = button.closest('.feature-item');
|
const target = button.closest('.feature-item');
|
||||||
const actionPath = this.getActionPath(button.dataset.type);
|
|
||||||
|
const feature = this.document.system.features.find(
|
||||||
|
feature => feature && feature.id === target.dataset.featureId
|
||||||
|
);
|
||||||
|
if (feature) {
|
||||||
|
await feature.update({ 'system.subType': null });
|
||||||
|
}
|
||||||
|
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
[`system.${actionPath}`]: this.document.system[actionPath]
|
[`system.features`]: this.document.system.features
|
||||||
.filter(feature => feature && feature.id !== target.dataset.featureId)
|
.filter(feature => feature && feature.id !== target.dataset.featureId)
|
||||||
.map(x => x.uuid)
|
.map(x => x.uuid)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -40,28 +40,46 @@ export default class SubclassSheet extends DHBaseItemSheet {
|
||||||
static async addFeature(_, target) {
|
static async addFeature(_, target) {
|
||||||
const feature = await game.items.documentClass.create({
|
const feature = await game.items.documentClass.create({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') })
|
name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }),
|
||||||
|
system: {
|
||||||
|
subType:
|
||||||
|
target.dataset.type === 'foundation'
|
||||||
|
? CONFIG.DH.ITEM.featureSubTypes.foundation
|
||||||
|
: target.dataset.type === 'specialization'
|
||||||
|
? CONFIG.DH.ITEM.featureSubTypes.specialization
|
||||||
|
: CONFIG.DH.ITEM.featureSubTypes.mastery
|
||||||
|
}
|
||||||
});
|
});
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
[`system.${target.dataset.type}`]: feature.uuid
|
[`system.features`]: [...this.document.system.features.map(x => x.uuid), feature.uuid]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async editFeature(_, button) {
|
static async editFeature(_, button) {
|
||||||
const feature = this.document.system[button.dataset.type];
|
const feature = this.document.system.features.find(x => x.id === button.dataset.feature);
|
||||||
if (!feature) {
|
if (!feature) {
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (feature) {
|
||||||
|
await feature.update({ 'system.subType': null });
|
||||||
|
}
|
||||||
|
|
||||||
feature.sheet.render(true);
|
feature.sheet.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async deleteFeature(event, button) {
|
static async deleteFeature(event, target) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
const feature = this.document.system.features.find(feature => feature.id === target.dataset.feature);
|
||||||
|
if (feature) {
|
||||||
|
await feature.update({ 'system.subType': null });
|
||||||
|
}
|
||||||
|
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
[`system.${button.dataset.type}`]: null
|
[`system.features`]: this.document.system.features
|
||||||
|
.filter(feature => feature && feature.id !== target.dataset.feature)
|
||||||
|
.map(x => x.uuid)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,18 +100,45 @@ export default class SubclassSheet extends DHBaseItemSheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
if (data.fromInternal) return;
|
if (data.fromInternal) return;
|
||||||
|
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
if (item?.type === 'feature') {
|
const target = event.target.closest('fieldset.drop-section');
|
||||||
const dropSection = event.target.closest('.drop-section');
|
if (item.type === 'feature') {
|
||||||
if (this.document.system[dropSection.dataset.type]) {
|
if (target.dataset.type === 'foundation') {
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsFull'));
|
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.foundation) {
|
||||||
return;
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotFoundation'));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await this.document.update({ [`system.${dropSection.dataset.type}`]: item.uuid });
|
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.foundation });
|
||||||
|
await this.document.update({
|
||||||
|
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||||
|
});
|
||||||
|
} else if (target.dataset.type === 'specialization') {
|
||||||
|
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.specialization) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotSpecialization'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.specialization });
|
||||||
|
await this.document.update({
|
||||||
|
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||||
|
});
|
||||||
|
} else if (target.dataset.type === 'mastery') {
|
||||||
|
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.mastery) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotMastery'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.mastery });
|
||||||
|
await this.document.update({
|
||||||
|
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@ export { default as DhChatLog } from './chatLog.mjs';
|
||||||
export { default as DhCombatTracker } from './combatTracker.mjs';
|
export { default as DhCombatTracker } from './combatTracker.mjs';
|
||||||
export * as DhCountdowns from './countdowns.mjs';
|
export * as DhCountdowns from './countdowns.mjs';
|
||||||
export { default as DhFearTracker } from './fearTracker.mjs';
|
export { default as DhFearTracker } from './fearTracker.mjs';
|
||||||
|
export { default as DhHotbar } from './hotbar.mjs';
|
||||||
|
|
|
||||||
129
module/applications/ui/hotbar.mjs
Normal file
129
module/applications/ui/hotbar.mjs
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
export default class DhHotbar extends foundry.applications.ui.Hotbar {
|
||||||
|
constructor(options) {
|
||||||
|
super(options);
|
||||||
|
|
||||||
|
this.setupHooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async useItem(uuid) {
|
||||||
|
const item = await fromUuid(uuid);
|
||||||
|
if (!item) {
|
||||||
|
return ui.notifications.warn('WARNING.ObjectDoesNotExist', {
|
||||||
|
format: {
|
||||||
|
name: game.i18n.localize('Document'),
|
||||||
|
identifier: uuid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await item.use({});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async useAction(itemUuid, actionId) {
|
||||||
|
const item = await foundry.utils.fromUuid(itemUuid);
|
||||||
|
if (!item) {
|
||||||
|
return ui.notifications.warn('WARNING.ObjectDoesNotExist', {
|
||||||
|
format: {
|
||||||
|
name: game.i18n.localize('Document'),
|
||||||
|
identifier: itemUuid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = item.system.actions.find(x => x.id === actionId);
|
||||||
|
if (!action) {
|
||||||
|
return ui.notifications.warn('DAGGERHEART.UI.Notifications.actionIsMissing');
|
||||||
|
}
|
||||||
|
|
||||||
|
await action.use({});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async useAttack(actorUuid) {
|
||||||
|
const actor = await foundry.utils.fromUuid(actorUuid);
|
||||||
|
if (!actor) {
|
||||||
|
return ui.notifications.warn('WARNING.ObjectDoesNotExist', {
|
||||||
|
format: {
|
||||||
|
name: game.i18n.localize('Document'),
|
||||||
|
identifier: actorUuid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const attack = actor.system.attack;
|
||||||
|
if (!attack) {
|
||||||
|
return ui.notifications.warn('DAGGERHEART.UI.Notifications.attackIsMissing');
|
||||||
|
}
|
||||||
|
|
||||||
|
await attack.use({});
|
||||||
|
}
|
||||||
|
|
||||||
|
setupHooks() {
|
||||||
|
Hooks.on('hotbarDrop', (bar, data, slot) => {
|
||||||
|
if (data.type === 'Item') {
|
||||||
|
const item = foundry.utils.fromUuidSync(data.uuid);
|
||||||
|
if (item.uuid.startsWith('Compendium') || !item.isOwned || !item.isOwner) return true;
|
||||||
|
|
||||||
|
switch (item.type) {
|
||||||
|
case 'ancestry':
|
||||||
|
case 'community':
|
||||||
|
case 'class':
|
||||||
|
case 'subclass':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
this.createItemMacro(item, slot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (data.type === 'Action') {
|
||||||
|
const item = foundry.utils.fromUuidSync(data.data.itemUuid);
|
||||||
|
if (item.uuid.startsWith('Compendium')) return true;
|
||||||
|
if (!item.isOwned || !item.isOwner) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.unownedActionMacro'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.createActionMacro(data, slot);
|
||||||
|
return false;
|
||||||
|
} else if (data.type === 'Attack') {
|
||||||
|
const actor = foundry.utils.fromUuidSync(data.actorUuid);
|
||||||
|
if (actor.uuid.startsWith('Compendium')) return true;
|
||||||
|
if (!actor.isOwner) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.unownedAttackMacro'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.createAttackMacro(data, slot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async createItemMacro(data, slot) {
|
||||||
|
const macro = await Macro.implementation.create({
|
||||||
|
name: `${game.i18n.localize('Display')} ${name}`,
|
||||||
|
type: CONST.MACRO_TYPES.SCRIPT,
|
||||||
|
img: data.img,
|
||||||
|
command: `await game.system.api.applications.ui.DhHotbar.useItem("${data.uuid}");`
|
||||||
|
});
|
||||||
|
await game.user.assignHotbarMacro(macro, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
async createActionMacro(data, slot) {
|
||||||
|
const macro = await Macro.implementation.create({
|
||||||
|
name: `${game.i18n.localize('Display')} ${name}`,
|
||||||
|
type: CONST.MACRO_TYPES.SCRIPT,
|
||||||
|
img: data.data.img,
|
||||||
|
command: `await game.system.api.applications.ui.DhHotbar.useAction("${data.data.itemUuid}", "${data.data.id}");`
|
||||||
|
});
|
||||||
|
await game.user.assignHotbarMacro(macro, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
async createAttackMacro(data, slot) {
|
||||||
|
const macro = await Macro.implementation.create({
|
||||||
|
name: `${game.i18n.localize('Display')} ${name}`,
|
||||||
|
type: CONST.MACRO_TYPES.SCRIPT,
|
||||||
|
img: data.img,
|
||||||
|
command: `await game.system.api.applications.ui.DhHotbar.useAttack("${data.actorUuid}");`
|
||||||
|
});
|
||||||
|
await game.user.assignHotbarMacro(macro, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -411,7 +411,7 @@ export const levelupData = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const subclassFeatureLabels = {
|
export const subclassFeatureLabels = {
|
||||||
1: 'DAGGERHEART.ITEMS.DomainCard.foundation',
|
1: 'DAGGERHEART.ITEMS.DomainCard.foundationTitle',
|
||||||
2: 'DAGGERHEART.ITEMS.DomainCard.specializationTitle',
|
2: 'DAGGERHEART.ITEMS.DomainCard.specializationTitle',
|
||||||
3: 'DAGGERHEART.ITEMS.DomainCard.masteryTitle'
|
3: 'DAGGERHEART.ITEMS.DomainCard.masteryTitle'
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1322,7 +1322,12 @@ export const featureTypes = {
|
||||||
|
|
||||||
export const featureSubTypes = {
|
export const featureSubTypes = {
|
||||||
primary: 'primary',
|
primary: 'primary',
|
||||||
secondary: 'secondary'
|
secondary: 'secondary',
|
||||||
|
hope: 'hope',
|
||||||
|
class: 'class',
|
||||||
|
foundation: 'foundation',
|
||||||
|
specialization: 'specialization',
|
||||||
|
mastery: 'mastery'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const actionTypes = {
|
export const actionTypes = {
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,8 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
value: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }),
|
value: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }),
|
||||||
subclass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true })
|
subclass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true })
|
||||||
}),
|
}),
|
||||||
|
advantageSources: new fields.ArrayField(new fields.StringField()),
|
||||||
|
disadvantageSources: new fields.ArrayField(new fields.StringField()),
|
||||||
levelData: new fields.EmbeddedDataField(DhLevelData),
|
levelData: new fields.EmbeddedDataField(DhLevelData),
|
||||||
bonuses: new fields.SchemaField({
|
bonuses: new fields.SchemaField({
|
||||||
roll: new fields.SchemaField({
|
roll: new fields.SchemaField({
|
||||||
|
|
@ -122,12 +124,9 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
label: 'DAGGERHEART.GENERAL.Range.other'
|
label: 'DAGGERHEART.GENERAL.Range.other'
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
rally: new fields.ArrayField(
|
rally: new fields.ArrayField(new fields.StringField(), {
|
||||||
new fields.StringField(),
|
label: 'DAGGERHEART.CLASS.Feature.rallyDice'
|
||||||
{
|
})
|
||||||
label: 'DAGGERHEART.CLASS.Feature.rallyDice'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }),
|
companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }),
|
||||||
rules: new fields.SchemaField({
|
rules: new fields.SchemaField({
|
||||||
|
|
@ -250,23 +249,23 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
features = [];
|
features = [];
|
||||||
|
|
||||||
for (let item of this.parent.items) {
|
for (let item of this.parent.items) {
|
||||||
if (item.system.type === CONFIG.DH.ITEM.featureTypes.ancestry.id) {
|
if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.ancestry.id) {
|
||||||
ancestryFeatures.push(item);
|
ancestryFeatures.push(item);
|
||||||
} else if (item.system.type === CONFIG.DH.ITEM.featureTypes.community.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.community.id) {
|
||||||
communityFeatures.push(item);
|
communityFeatures.push(item);
|
||||||
} else if (item.system.type === CONFIG.DH.ITEM.featureTypes.class.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.class.id) {
|
||||||
classFeatures.push(item);
|
classFeatures.push(item);
|
||||||
} else if (item.system.type === CONFIG.DH.ITEM.featureTypes.subclass.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) {
|
||||||
const subclassState = this.class.subclass.system.featureState;
|
const subclassState = this.class.subclass.system.featureState;
|
||||||
const identifier = item.system.identifier;
|
const subType = item.system.subType;
|
||||||
if (
|
if (
|
||||||
identifier === 'foundationFeature' ||
|
subType === CONFIG.DH.ITEM.featureSubTypes.foundation ||
|
||||||
(identifier === 'specializationFeature' && subclassState >= 2) ||
|
(subType === CONFIG.DH.ITEM.featureSubTypes.specialization && subclassState >= 2) ||
|
||||||
(identifier === 'masterFeature' && subclassState >= 3)
|
(subType === CONFIG.DH.ITEM.featureSubTypes.mastery && subclassState >= 3)
|
||||||
) {
|
) {
|
||||||
subclassFeatures.push(item);
|
subclassFeatures.push(item);
|
||||||
}
|
}
|
||||||
} else if (item.system.type === CONFIG.DH.ITEM.featureTypes.companion.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.companion.id) {
|
||||||
companionFeatures.push(item);
|
companionFeatures.push(item);
|
||||||
} else if (item.type === 'feature' && !item.system.type) {
|
} else if (item.type === 'feature' && !item.system.type) {
|
||||||
features.push(item);
|
features.push(item);
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,8 @@ export const registerCountdownHooks = () => {
|
||||||
if (application) {
|
if (application) {
|
||||||
foundry.applications.instances.get(application)?.render();
|
foundry.applications.instances.get(application)?.render();
|
||||||
} else {
|
} else {
|
||||||
foundry.applications.instances.get('narrative-countdowns').render();
|
foundry.applications.instances.get('narrative-countdowns')?.render();
|
||||||
foundry.applications.instances.get('encounter-countdowns').render();
|
foundry.applications.instances.get('encounter-countdowns')?.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -53,11 +53,14 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
||||||
}),
|
}),
|
||||||
diceStates: new fields.TypedObjectField(
|
diceStates: new fields.TypedObjectField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
value: new fields.NumberField({ integer: true, nullable: true, initial: null }),
|
value: new fields.NumberField({ integer: true, initial: 1, min: 1 }),
|
||||||
used: new fields.BooleanField({ initial: false })
|
used: new fields.BooleanField({ initial: false })
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
dieFaces: new fields.StringField({ initial: '4' })
|
dieFaces: new fields.StringField({
|
||||||
|
choices: CONFIG.DH.GENERAL.diceTypes,
|
||||||
|
initial: CONFIG.DH.GENERAL.diceTypes.d4
|
||||||
|
})
|
||||||
},
|
},
|
||||||
{ nullable: true, initial: null }
|
{ nullable: true, initial: null }
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ export default class DHBeastform extends BaseDataItem {
|
||||||
|
|
||||||
const beastformEffect = this.parent.effects.find(x => x.type === 'beastform');
|
const beastformEffect = this.parent.effects.find(x => x.type === 'beastform');
|
||||||
await beastformEffect.updateSource({
|
await beastformEffect.updateSource({
|
||||||
|
changes: [...beastformEffect.changes, { key: 'system.advantageSources', mode: 2, value: this.advantageOn }],
|
||||||
system: {
|
system: {
|
||||||
characterTokenData: {
|
characterTokenData: {
|
||||||
tokenImg: this.parent.parent.prototypeToken.texture.src,
|
tokenImg: this.parent.parent.prototypeToken.texture.src,
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,7 @@ export default class DHClass extends BaseDataItem {
|
||||||
label: 'DAGGERHEART.GENERAL.hitPoints.plural'
|
label: 'DAGGERHEART.GENERAL.hitPoints.plural'
|
||||||
}),
|
}),
|
||||||
evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.evasion' }),
|
evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.evasion' }),
|
||||||
hopeFeatures: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
features: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
||||||
classFeatures: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
|
||||||
subclasses: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }),
|
subclasses: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }),
|
||||||
inventory: new fields.SchemaField({
|
inventory: new fields.SchemaField({
|
||||||
take: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }),
|
take: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }),
|
||||||
|
|
@ -52,12 +51,18 @@ export default class DHClass extends BaseDataItem {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get hopeFeature() {
|
get hopeFeatures() {
|
||||||
return this.hopeFeatures.length > 0 ? this.hopeFeatures[0] : null;
|
return (
|
||||||
|
this.features.filter(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.hope) ??
|
||||||
|
(this.features.filter(x => !x).length > 0 ? {} : null)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get features() {
|
get classFeatures() {
|
||||||
return [...this.hopeFeatures.filter(x => x), ...this.classFeatures.filter(x => x)];
|
return (
|
||||||
|
this.features.filter(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.class) ??
|
||||||
|
(this.features.filter(x => !x).length > 0 ? {} : null)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _preCreate(data, options, user) {
|
async _preCreate(data, options, user) {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ export default class DHDomainCard extends BaseDataItem {
|
||||||
required: true,
|
required: true,
|
||||||
initial: CONFIG.DH.DOMAIN.cardTypes.ability.id
|
initial: CONFIG.DH.DOMAIN.cardTypes.ability.id
|
||||||
}),
|
}),
|
||||||
foundation: new fields.BooleanField({ initial: false }),
|
|
||||||
inVault: new fields.BooleanField({ initial: false }),
|
inVault: new fields.BooleanField({ initial: false }),
|
||||||
actions: new fields.ArrayField(new ActionField())
|
actions: new fields.ArrayField(new ActionField())
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||||
import BaseDataItem from './base.mjs';
|
import BaseDataItem from './base.mjs';
|
||||||
|
|
||||||
export default class DHSubclass extends BaseDataItem {
|
export default class DHSubclass extends BaseDataItem {
|
||||||
|
|
@ -22,20 +22,22 @@ export default class DHSubclass extends BaseDataItem {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
initial: null
|
initial: null
|
||||||
}),
|
}),
|
||||||
foundationFeature: new ForeignDocumentUUIDField({ type: 'Item' }),
|
features: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
||||||
specializationFeature: new ForeignDocumentUUIDField({ type: 'Item' }),
|
|
||||||
masteryFeature: new ForeignDocumentUUIDField({ type: 'Item' }),
|
|
||||||
featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }),
|
featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }),
|
||||||
isMulticlass: new fields.BooleanField({ initial: false })
|
isMulticlass: new fields.BooleanField({ initial: false })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get features() {
|
get foundationFeatures() {
|
||||||
return [
|
return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.foundation);
|
||||||
{ ...this.foundationFeature?.toObject(), identifier: 'foundationFeature' },
|
}
|
||||||
{ ...this.specializationFeature?.toObject(), identifier: 'specializationFeature' },
|
|
||||||
{ ...this.masteryFeature?.toObject(), identifier: 'masteryFeature' }
|
get specializationFeatures() {
|
||||||
];
|
return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.specialization);
|
||||||
|
}
|
||||||
|
|
||||||
|
get masteryFeatures() {
|
||||||
|
return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.mastery);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _preCreate(data, options, user) {
|
async _preCreate(data, options, user) {
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,24 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
||||||
this.tooltip.innerHTML = html;
|
this.tooltip.innerHTML = html;
|
||||||
options.direction = this._determineItemTooltipDirection(element);
|
options.direction = this._determineItemTooltipDirection(element);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const isAdvantage = element.dataset.tooltip?.startsWith('#advantage#');
|
||||||
|
const isDisadvantage = element.dataset.tooltip?.startsWith('#disadvantage#');
|
||||||
|
if (isAdvantage || isDisadvantage) {
|
||||||
|
const actorUuid = element.dataset.tooltip.slice(isAdvantage ? 11 : 14);
|
||||||
|
const actor = await foundry.utils.fromUuid(actorUuid);
|
||||||
|
|
||||||
|
if (actor) {
|
||||||
|
html = await foundry.applications.handlebars.renderTemplate(
|
||||||
|
`systems/daggerheart/templates/ui/tooltip/advantage.hbs`,
|
||||||
|
{
|
||||||
|
sources: isAdvantage ? actor.system.advantageSources : actor.system.disadvantageSources
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.tooltip.innerHTML = html;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.activate(element, { ...options, html: html });
|
super.activate(element, { ...options, html: html });
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,10 @@
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 17px;
|
line-height: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.advantage-chip-tooltip {
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.advantage-chip {
|
.advantage-chip {
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,14 @@
|
||||||
{{#times (rollParsed item.system.resource.max actor item numerical=true)}}
|
{{#times (rollParsed item.system.resource.max actor item numerical=true)}}
|
||||||
{{#with (ifThen (lookup ../diceStates this) (lookup ../diceStates this) this) as | state |}}
|
{{#with (ifThen (lookup ../diceStates this) (lookup ../diceStates this) this) as | state |}}
|
||||||
<div class="resource-item" data-dice="{{#if ../../this}}{{../this}}{{else}}{{state}}{{/if}}">
|
<div class="resource-item" data-dice="{{#if ../../this}}{{../this}}{{else}}{{state}}{{/if}}">
|
||||||
<input type="number" data-dtype="Number" name={{concat "diceStates." (ifThen ../../this ../this state) ".value" }} value="{{state.value}}" />
|
<input type="number" data-dtype="Number" name={{concat "diceStates." (ifThen ../../this ../this state) ".value" }} value="{{state.value}}" min="1" />
|
||||||
<img src="{{concat "systems/daggerheart/assets/icons/dice/hope/d" (ifThen ../../item.system.resource.dieFaces ../../item.system.resource.dieFaces ../item.system.resource.dieFaces) ".svg"}}" />
|
<img src="{{concat "systems/daggerheart/assets/icons/dice/hope/" (ifThen ../../item.system.resource.dieFaces ../../item.system.resource.dieFaces ../item.system.resource.dieFaces) ".svg"}}" />
|
||||||
</div>
|
</div>
|
||||||
{{/with}}
|
{{/with}}
|
||||||
{{/times}}
|
{{/times}}
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<button data-action="save">{{localize 'Save'}}</button>
|
<button type="button" data-action="save">{{localize 'Save'}}</button>
|
||||||
<button data-action="rerollDice">{{localize "DAGGERHEART.APPLICATIONS.ResourceDice.rerollDice"}}</button>
|
<button type="button" data-action="rerollDice">{{localize "DAGGERHEART.APPLICATIONS.ResourceDice.rerollDice"}}</button>
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -98,6 +98,9 @@
|
||||||
<span><i class="fa-regular fa-circle"></i></span>
|
<span><i class="fa-regular fa-circle"></i></span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<span class="label">{{localize "DAGGERHEART.GENERAL.Advantage.full"}}</span>
|
<span class="label">{{localize "DAGGERHEART.GENERAL.Advantage.full"}}</span>
|
||||||
|
{{#if @root.rollConfig.data.advantageSources.length}}
|
||||||
|
<span class="advantage-chip-tooltip" data-tooltip="{{concat "#advantage#" @root.rollConfig.source.actor}}"><i class="fa-solid fa-circle-info"></i></span>
|
||||||
|
{{/if}}
|
||||||
</button>
|
</button>
|
||||||
<button class="disadvantage-chip flex1 {{#if (eq advantage -1)}}selected{{/if}}" data-action="updateIsAdvantage" data-advantage="-1">
|
<button class="disadvantage-chip flex1 {{#if (eq advantage -1)}}selected{{/if}}" data-action="updateIsAdvantage" data-advantage="-1">
|
||||||
{{#if (eq advantage -1)}}
|
{{#if (eq advantage -1)}}
|
||||||
|
|
@ -106,6 +109,9 @@
|
||||||
<span><i class="fa-regular fa-circle"></i></span>
|
<span><i class="fa-regular fa-circle"></i></span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<span class="label">{{localize "DAGGERHEART.GENERAL.Disadvantage.full"}}</span>
|
<span class="label">{{localize "DAGGERHEART.GENERAL.Disadvantage.full"}}</span>
|
||||||
|
{{#if @root.rollConfig.data.disadvantageSources.length}}
|
||||||
|
<span class="advantage-chip-tooltip" data-tooltip="{{concat "#disadvantage#" @root.rollConfig.source.actor}}"><i class="fa-solid fa-circle-info"></i></span>
|
||||||
|
{{/if}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{{#unless (eq @root.rollType 'D20Roll')}}
|
{{#unless (eq @root.rollType 'D20Roll')}}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
<a class="item-resource" data-action="toggleResourceDice" data-dice="{{#if ../../this}}{{../this}}{{else}}{{state}}{{/if}}">
|
<a class="item-resource" data-action="toggleResourceDice" data-dice="{{#if ../../this}}{{../this}}{{else}}{{state}}{{/if}}">
|
||||||
<div class="item-dice-resource">
|
<div class="item-dice-resource">
|
||||||
<label>{{ifThen state.value state.value '?'}}</label>
|
<label>{{ifThen state.value state.value '?'}}</label>
|
||||||
<img src="{{concat "systems/daggerheart/assets/icons/dice/hope/d" (ifThen ../../item.system.resource.dieFaces ../../item.system.resource.dieFaces ../item.system.resource.dieFaces) ".svg"}}" />
|
<img src="{{concat "systems/daggerheart/assets/icons/dice/hope/" (ifThen ../../item.system.resource.dieFaces ../../item.system.resource.dieFaces ../item.system.resource.dieFaces) ".svg"}}" />
|
||||||
{{#if state.used}}<i class="fa-solid fa-x"></i>{{/if}}
|
{{#if state.used}}<i class="fa-solid fa-x"></i>{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
{{formGroup systemFields.resource.fields.value value=source.system.resource.value localize=true}}
|
{{formGroup systemFields.resource.fields.value value=source.system.resource.value localize=true}}
|
||||||
{{formGroup systemFields.resource.fields.max value=source.system.resource.max localize=true}}
|
{{formGroup systemFields.resource.fields.max value=source.system.resource.max localize=true}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{formGroup systemFields.resource.fields.dieFaces value=source.system.resource.dieFaces localize=true}}
|
{{formGroup systemFields.resource.fields.dieFaces value=source.system.resource.dieFaces localize=true blank=false}}
|
||||||
{{formGroup systemFields.resource.fields.max value=source.system.resource.max label="DAGGERHEART.ITEMS.FIELDS.resource.amount.label" localize=true}}
|
{{formGroup systemFields.resource.fields.max value=source.system.resource.max label="DAGGERHEART.ITEMS.FIELDS.resource.amount.label" localize=true}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.type"}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.type"}}</span>
|
||||||
{{formField systemFields.type value=source.system.type localize=true}}
|
{{formField systemFields.type value=source.system.type localize=true}}
|
||||||
<span>{{localize "DAGGERHEART.ITEMS.DomainCard.foundation"}}</span>
|
|
||||||
{{formField systemFields.foundation value=source.system.foundation }}
|
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.Domain.single"}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.Domain.single"}}</span>
|
||||||
{{formField systemFields.domain value=source.system.domain localize=true}}
|
{{formField systemFields.domain value=source.system.domain localize=true}}
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.level"}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.level"}}</span>
|
||||||
|
|
|
||||||
|
|
@ -3,42 +3,42 @@
|
||||||
data-tab='{{tabs.features.id}}'
|
data-tab='{{tabs.features.id}}'
|
||||||
data-group='{{tabs.features.group}}'
|
data-group='{{tabs.features.group}}'
|
||||||
>
|
>
|
||||||
<fieldset class="drop-section" data-type="foundationFeature">
|
<fieldset class="drop-section" data-type="foundation">
|
||||||
<legend>
|
<legend>
|
||||||
{{localize "DAGGERHEART.GENERAL.Tabs.foundation"}}
|
{{localize "DAGGERHEART.GENERAL.Tabs.foundation"}}
|
||||||
<a {{#if source.system.foundationFeature}}disabled{{/if}}><i data-action="addFeature" data-type="foundationFeature" class="fa-solid fa-plus icon-button {{#if source.system.foundationFeature}}disabled{{/if}}"></i></a>
|
<a><i data-action="addFeature" data-type="foundation" class="fa-solid fa-plus icon-button"></i></a>
|
||||||
</legend>
|
</legend>
|
||||||
|
|
||||||
<div class="feature-list">
|
<div class="feature-list">
|
||||||
{{#if source.system.foundationFeature}}
|
{{#each source.system.foundationFeatures as | feature | }}
|
||||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='foundationFeature' feature=source.system.foundationFeature}}
|
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='foundation' feature=feature}}
|
||||||
{{/if}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset class="drop-section" data-type="specializationFeature">
|
<fieldset class="drop-section" data-type="specialization">
|
||||||
<legend>
|
<legend>
|
||||||
{{localize "DAGGERHEART.GENERAL.Tabs.specialization"}}
|
{{localize "DAGGERHEART.GENERAL.Tabs.specialization"}}
|
||||||
<a {{#if source.system.specializationFeature}}disabled{{/if}}><i data-action="addFeature" data-type="specializationFeature" class="fa-solid fa-plus icon-button {{#if source.system.specializationFeature}}disabled{{/if}}"></i></a>
|
<a><i data-action="addFeature" data-type="specialization" class="fa-solid fa-plus icon-button"></i></a>
|
||||||
</legend>
|
</legend>
|
||||||
|
|
||||||
<div class="feature-list">
|
<div class="feature-list">
|
||||||
{{#if source.system.specializationFeature}}
|
{{#each source.system.specializationFeatures as | feature |}}
|
||||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='specializationFeature' feature=source.system.specializationFeature}}
|
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='specialization' feature=feature}}
|
||||||
{{/if}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset class="drop-section" data-type="masteryFeature">
|
<fieldset class="drop-section" data-type="mastery">
|
||||||
<legend>
|
<legend>
|
||||||
{{localize "DAGGERHEART.GENERAL.Tabs.mastery"}}
|
{{localize "DAGGERHEART.GENERAL.Tabs.mastery"}}
|
||||||
<a {{#if source.system.masteryFeature}}disabled{{/if}}><i data-action="addFeature" data-type="masteryFeature" class="fa-solid fa-plus icon-button {{#if source.system.masteryFeature}}disabled{{/if}}"></i></a>
|
<a><i data-action="addFeature" data-type="mastery" class="fa-solid fa-plus icon-button"></i></a>
|
||||||
</legend>
|
</legend>
|
||||||
|
|
||||||
<div class="feature-list">
|
<div class="feature-list">
|
||||||
{{#if source.system.masteryFeature}}
|
{{#each source.system.masteryFeatures as | feature |}}
|
||||||
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='masteryFeature' feature=source.system.masteryFeature}}
|
{{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='mastery' feature=feature}}
|
||||||
{{/if}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</section>
|
</section>
|
||||||
5
templates/ui/tooltip/advantage.hbs
Normal file
5
templates/ui/tooltip/advantage.hbs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div class="daggerheart dh-style tooltip">
|
||||||
|
{{#each sources as | source |}}
|
||||||
|
<div>{{{source}}}</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue