mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-17 15:39:02 +01:00
Fixed hybrid
This commit is contained in:
parent
011f5d2b14
commit
796cec01ee
13 changed files with 464 additions and 110 deletions
23
lang/en.json
23
lang/en.json
|
|
@ -106,6 +106,10 @@
|
||||||
"horderHp": "Horde/HP"
|
"horderHp": "Horde/HP"
|
||||||
},
|
},
|
||||||
"Character": {
|
"Character": {
|
||||||
|
"advantageSources": {
|
||||||
|
"label": "Advantage Sources",
|
||||||
|
"hint": "Add single words or short text as reminders and hints of what a character has advantage on."
|
||||||
|
},
|
||||||
"age": "Age",
|
"age": "Age",
|
||||||
"companionFeatures": "Companion Features",
|
"companionFeatures": "Companion Features",
|
||||||
"contextMenu": {
|
"contextMenu": {
|
||||||
|
|
@ -117,6 +121,10 @@
|
||||||
"unequip": "Unequip",
|
"unequip": "Unequip",
|
||||||
"useItem": "Use Item"
|
"useItem": "Use Item"
|
||||||
},
|
},
|
||||||
|
"disadvantageSources": {
|
||||||
|
"label": "Disadvantage Sources",
|
||||||
|
"hint": "Add single words or short text as reminders and hints of what a character has disadvantage on."
|
||||||
|
},
|
||||||
"faith": "Faith",
|
"faith": "Faith",
|
||||||
"levelUp": "You can level up",
|
"levelUp": "You can level up",
|
||||||
"pronouns": "Pronouns",
|
"pronouns": "Pronouns",
|
||||||
|
|
@ -1014,6 +1022,7 @@
|
||||||
},
|
},
|
||||||
"Advantage": {
|
"Advantage": {
|
||||||
"full": "Advantage",
|
"full": "Advantage",
|
||||||
|
"plural": "Advantages",
|
||||||
"short": "Adv"
|
"short": "Adv"
|
||||||
},
|
},
|
||||||
"Adversary": {
|
"Adversary": {
|
||||||
|
|
@ -1169,6 +1178,11 @@
|
||||||
"hint": "The cost in stress you can pay to reduce minor damage to none."
|
"hint": "The cost in stress you can pay to reduce minor damage to none."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"attack": {
|
||||||
|
"damage": {
|
||||||
|
"value": { "label": "Base Attack: Damage" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Tabs": {
|
"Tabs": {
|
||||||
|
|
@ -1266,6 +1280,7 @@
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
"true": "True",
|
"true": "True",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
|
"unarmedStrike": "Unarmed Strike",
|
||||||
"unarmored": "Unarmored",
|
"unarmored": "Unarmored",
|
||||||
"use": "Use",
|
"use": "Use",
|
||||||
"used": "Used",
|
"used": "Used",
|
||||||
|
|
@ -1327,8 +1342,10 @@
|
||||||
"beastformEffect": "Beastform Transformation",
|
"beastformEffect": "Beastform Transformation",
|
||||||
"evolve": "Evolve",
|
"evolve": "Evolve",
|
||||||
"evolvedFeatureTitle": "Evolved",
|
"evolvedFeatureTitle": "Evolved",
|
||||||
|
"evolvedDrag": "Drag a form here to evolve it.",
|
||||||
"hybridize": "Hybridize",
|
"hybridize": "Hybridize",
|
||||||
"hybridFeatureTitle": "Hybrid Features"
|
"hybridizeFeatureTitle": "Hybrid Features",
|
||||||
|
"hybridizeDrag": "Drag a form here to hybridize it."
|
||||||
},
|
},
|
||||||
"Class": {
|
"Class": {
|
||||||
"hopeFeatures": "Hope Features",
|
"hopeFeatures": "Hope Features",
|
||||||
|
|
@ -1573,7 +1590,9 @@
|
||||||
"featureNotFoundation": "This feature is used as something else than a Foundation 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.",
|
"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.",
|
"featureNotMastery": "This feature is used as something else than a Mastery feature and cannot be used here.",
|
||||||
"beastformMissingEffect": "The Beastform is missing a Beastform Effect. Cannot be used."
|
"beastformMissingEffect": "The Beastform is missing a Beastform Effect. Cannot be used.",
|
||||||
|
"beastformToManyAdvantages": "You cannot select any more advantages.",
|
||||||
|
"beastformToManyFeatures": "You cannot select any more features."
|
||||||
},
|
},
|
||||||
"Tooltip": {
|
"Tooltip": {
|
||||||
"openItemWorld": "Open Item World",
|
"openItemWorld": "Open Item World",
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
this.configData = configData;
|
this.configData = configData;
|
||||||
this.selected = null;
|
this.selected = null;
|
||||||
this.evolved = { form: null };
|
this.evolved = { form: null };
|
||||||
this.hybrid = null;
|
this.hybrid = { forms: {}, advantages: {}, features: {} };
|
||||||
|
|
||||||
this._dragDrop = this._createDragDropHandlers();
|
this._dragDrop = this._createDragDropHandlers();
|
||||||
}
|
}
|
||||||
|
|
@ -21,6 +21,8 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
selectBeastform: this.selectBeastform,
|
selectBeastform: this.selectBeastform,
|
||||||
|
toggleHybridFeature: this.toggleHybridFeature,
|
||||||
|
toggleHybridAdvantage: this.toggleHybridAdvantage,
|
||||||
submitBeastform: this.submitBeastform
|
submitBeastform: this.submitBeastform
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
|
|
@ -38,7 +40,7 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
/** @override */
|
/** @override */
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
beastform: {
|
beastform: {
|
||||||
template: 'systems/daggerheart/templates/dialogs/beastformDialog.hbs'
|
template: 'systems/daggerheart/templates/dialogs/beastform/beastformDialog.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -65,7 +67,33 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
context.selectedBeastformEffect = this.selected?.effects?.find?.(x => x.type === 'beastform');
|
context.selectedBeastformEffect = this.selected?.effects?.find?.(x => x.type === 'beastform');
|
||||||
|
|
||||||
context.evolved = this.evolved;
|
context.evolved = this.evolved;
|
||||||
context.hybrid = this.hybrid;
|
|
||||||
|
context.hybridForms = Object.keys(this.hybrid.forms).reduce((acc, formKey) => {
|
||||||
|
if (!this.hybrid.forms[formKey]) {
|
||||||
|
acc[formKey] = null;
|
||||||
|
} else {
|
||||||
|
const data = this.hybrid.forms[formKey].toObject();
|
||||||
|
acc[formKey] = {
|
||||||
|
...data,
|
||||||
|
system: {
|
||||||
|
...data.system,
|
||||||
|
features: this.hybrid.forms[formKey].system.features.map(feature => ({
|
||||||
|
...feature.toObject(),
|
||||||
|
uuid: feature.uuid,
|
||||||
|
selected: Boolean(this.hybrid.features?.[formKey]?.[feature.uuid])
|
||||||
|
})),
|
||||||
|
advantageOn: Object.keys(data.system.advantageOn).reduce((acc, key) => {
|
||||||
|
acc[key] = {
|
||||||
|
...data.system.advantageOn[key],
|
||||||
|
selected: Boolean(this.hybrid.advantages?.[formKey]?.[key])
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
const maximumDragTier = Math.max(
|
const maximumDragTier = Math.max(
|
||||||
this.selected?.system?.evolved?.maximumTier ?? 0,
|
this.selected?.system?.evolved?.maximumTier ?? 0,
|
||||||
|
|
@ -83,13 +111,16 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
acc[tier.id].values[x.uuid] = {
|
acc[tier.id].values[x.uuid] = {
|
||||||
selected: this.selected?.uuid == x.uuid,
|
selected: this.selected?.uuid == x.uuid,
|
||||||
value: x,
|
value: x,
|
||||||
draggable: maximumDragTier ? x.system.tier <= maximumDragTier : false
|
draggable:
|
||||||
|
!['evolved', 'hybrid'].includes(x.system.beastformType) && maximumDragTier
|
||||||
|
? x.system.tier <= maximumDragTier
|
||||||
|
: false
|
||||||
};
|
};
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
); // Also get from compendium when added
|
);
|
||||||
|
|
||||||
context.canSubmit = this.canSubmit();
|
context.canSubmit = this.canSubmit();
|
||||||
|
|
||||||
|
|
@ -103,6 +134,19 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
return true;
|
return true;
|
||||||
case 'evolved':
|
case 'evolved':
|
||||||
return this.evolved.form;
|
return this.evolved.form;
|
||||||
|
case 'hybrid':
|
||||||
|
const selectedAdvantages = Object.values(this.hybrid.advantages).reduce(
|
||||||
|
(acc, form) => acc + Object.values(form).length,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
const selectedFeatures = Object.values(this.hybrid.features).reduce(
|
||||||
|
(acc, form) => acc + Object.values(form).length,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
const advantagesSelected = selectedAdvantages === this.selected.system.hybrid.advantages;
|
||||||
|
const featuresSelected = selectedFeatures === this.selected.system.hybrid.features;
|
||||||
|
return advantagesSelected && featuresSelected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,7 +179,62 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
|
|
||||||
if (this.selected) {
|
if (this.selected) {
|
||||||
if (this.selected.system.beastformType !== 'evolved') this.evolved.form = null;
|
if (this.selected.system.beastformType !== 'evolved') this.evolved.form = null;
|
||||||
if (this.selected.system.beastformType !== 'hybrid') this.hybrid = null;
|
if (this.selected.system.beastformType !== 'hybrid') {
|
||||||
|
this.hybrid.forms = {};
|
||||||
|
this.hybrid.advantages = {};
|
||||||
|
this.hybrid.features = {};
|
||||||
|
} else {
|
||||||
|
this.hybrid.forms = [...Array(this.selected.system.hybrid.beastformOptions).keys()].reduce((acc, _) => {
|
||||||
|
acc[foundry.utils.randomID()] = null;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
static toggleHybridFeature(_, button) {
|
||||||
|
const current = this.hybrid.features[button.dataset.form];
|
||||||
|
if (!current) this.hybrid.features[button.dataset.form] = {};
|
||||||
|
|
||||||
|
if (this.hybrid.features[button.dataset.form][button.id])
|
||||||
|
delete this.hybrid.features[button.dataset.form][button.id];
|
||||||
|
else {
|
||||||
|
const currentFeatures = Object.values(this.hybrid.features).reduce(
|
||||||
|
(acc, form) => acc + Object.values(form).length,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (currentFeatures === this.selected.system.hybrid.features) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.beastformToManyFeatures'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const feature = this.hybrid.forms[button.dataset.form].system.features.find(x => x.uuid === button.id);
|
||||||
|
this.hybrid.features[button.dataset.form][button.id] = feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
static toggleHybridAdvantage(_, button) {
|
||||||
|
const current = this.hybrid.advantages[button.dataset.form];
|
||||||
|
if (!current) this.hybrid.advantages[button.dataset.form] = {};
|
||||||
|
|
||||||
|
if (this.hybrid.advantages[button.dataset.form][button.id])
|
||||||
|
delete this.hybrid.advantages[button.dataset.form][button.id];
|
||||||
|
else {
|
||||||
|
const currentAdvantages = Object.values(this.hybrid.advantages).reduce(
|
||||||
|
(acc, form) => acc + Object.values(form).length,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (currentAdvantages === this.selected.system.hybrid.advantages) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.beastformToManyAdvantages'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const advantage = this.hybrid.forms[button.dataset.form].system.advantageOn[button.id];
|
||||||
|
this.hybrid.advantages[button.dataset.form][button.id] = advantage;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
|
|
@ -164,23 +263,17 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
|
|
||||||
async _onDragStart(event) {
|
async _onDragStart(event) {
|
||||||
const target = event.currentTarget;
|
const target = event.currentTarget;
|
||||||
if (!this.selected) {
|
const abort = () => event.preventDefault();
|
||||||
event.preventDefault();
|
if (!this.selected) abort();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const draggedForm = await foundry.utils.fromUuid(target.dataset.uuid);
|
const draggedForm = await foundry.utils.fromUuid(target.dataset.uuid);
|
||||||
|
if (['evolved', 'hybrid'].includes(draggedForm.system.beastformType)) abort();
|
||||||
|
|
||||||
if (this.selected.system.beastformType === 'evolved') {
|
if (this.selected.system.beastformType === 'evolved') {
|
||||||
if (draggedForm.system.tier > this.selected.system.evolved.maximumTier) {
|
if (draggedForm.system.tier > this.selected.system.evolved.maximumTier) abort();
|
||||||
event.preventDefault();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (this.selected.system.beastformType === 'hybrid') {
|
if (this.selected.system.beastformType === 'hybrid') {
|
||||||
if (draggedForm.system.tier > this.selected.system.hybrid.maximumTier) {
|
if (draggedForm.system.tier > this.selected.system.hybrid.maximumTier) abort();
|
||||||
event.preventDefault();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event.dataTransfer.setData('text/plain', JSON.stringify(target.dataset));
|
event.dataTransfer.setData('text/plain', JSON.stringify(target.dataset));
|
||||||
|
|
@ -191,9 +284,20 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const data = foundry.applications.ux.TextEditor.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.getDragEventData(event);
|
||||||
const item = await fromUuid(data.uuid);
|
const item = await fromUuid(data.uuid);
|
||||||
|
if (!item) return;
|
||||||
|
|
||||||
if (event.target.closest('.advanced-form-container.evolved')) {
|
if (event.target.closest('.advanced-form-container.evolved')) {
|
||||||
this.evolved.form = item;
|
this.evolved.form = item;
|
||||||
|
} else {
|
||||||
|
const hybridContainer = event.target.closest('.advanced-form-container.hybridized');
|
||||||
|
if (hybridContainer) {
|
||||||
|
const existingId = Object.keys(this.hybrid.forms).find(
|
||||||
|
key => this.hybrid.forms[key]?.uuid === item.uuid
|
||||||
|
);
|
||||||
|
if (existingId) this.hybrid.forms[existingId] = null;
|
||||||
|
|
||||||
|
this.hybrid.forms[hybridContainer.id] = item;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,25 @@ export default class BeastformSheet extends DHBaseItemSheet {
|
||||||
|
|
||||||
const advantageOnInput = htmlElement.querySelector('.advantageon-input');
|
const advantageOnInput = htmlElement.querySelector('.advantageon-input');
|
||||||
if (advantageOnInput) {
|
if (advantageOnInput) {
|
||||||
const tagifyElement = new Tagify(advantageOnInput);
|
const tagifyElement = new Tagify(advantageOnInput, {
|
||||||
|
tagTextProp: 'name',
|
||||||
|
templates: {
|
||||||
|
tag(tagData) {
|
||||||
|
return `<tag
|
||||||
|
contenteditable='false'
|
||||||
|
spellcheck='false'
|
||||||
|
tabIndex="${this.settings.a11y.focusableTags ? 0 : -1}"
|
||||||
|
class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ''}"
|
||||||
|
${this.getAttributes(tagData)}>
|
||||||
|
<x class="${this.settings.classNames.tagX}" role='button' aria-label='remove tag'></x>
|
||||||
|
<div>
|
||||||
|
<span class="${this.settings.classNames.tagText}">${tagData[this.settings.tagTextProp] || tagData.value}</span>
|
||||||
|
${tagData.src ? `<img src="${tagData.src}"></i>` : ''}
|
||||||
|
</div>
|
||||||
|
</tag>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
tagifyElement.on('add', this.advantageOnAdd.bind(this));
|
tagifyElement.on('add', this.advantageOnAdd.bind(this));
|
||||||
tagifyElement.on('remove', this.advantageOnRemove.bind(this));
|
tagifyElement.on('remove', this.advantageOnRemove.bind(this));
|
||||||
}
|
}
|
||||||
|
|
@ -61,19 +79,25 @@ export default class BeastformSheet extends DHBaseItemSheet {
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
|
context.advantageOn = JSON.stringify(
|
||||||
|
Object.keys(context.document.system.advantageOn).map(key => ({
|
||||||
|
value: key,
|
||||||
|
name: context.document.system.advantageOn[key].value
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
async advantageOnAdd(event) {
|
async advantageOnAdd(event) {
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.advantageOn': [...this.document.system.advantageOn, event.detail.data.value]
|
[`system.advantageOn.${foundry.utils.randomID()}`]: { value: event.detail.data.value }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async advantageOnRemove(event) {
|
async advantageOnRemove(event) {
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.advantageOn': this.document.system.advantageOn.filter(x => x !== event.detail.data.value)
|
[`system.advantageOn.-=${event.detail.data.value}`]: null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,19 +48,29 @@ export default class DhBeastformAction extends DHBaseAction {
|
||||||
formData.system.features = [...formData.system.features, ...selectedForm.system.features.map(x => x.uuid)];
|
formData.system.features = [...formData.system.features, ...selectedForm.system.features.map(x => x.uuid)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectedForm.system.beastformType === CONFIG.DH.ITEM.beastformTypes.hybrid.id) {
|
||||||
|
formData.system.advantageOn = Object.values(hybridData.advantages).reduce((advantages, formCategory) => {
|
||||||
|
Object.keys(formCategory).forEach(advantageKey => {
|
||||||
|
advantages[advantageKey] = formCategory[advantageKey];
|
||||||
|
});
|
||||||
|
return advantages;
|
||||||
|
}, {});
|
||||||
|
formData.system.features = [
|
||||||
|
...formData.system.features,
|
||||||
|
...Object.values(hybridData.features).flatMap(x => Object.keys(x))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
this.actor.createEmbeddedDocuments('Item', [formData]);
|
this.actor.createEmbeddedDocuments('Item', [formData]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleActiveTransformations() {
|
async handleActiveTransformations() {
|
||||||
const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform');
|
const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform');
|
||||||
if (beastformEffects.length > 0) {
|
const existingEffects = beastformEffects.length > 0;
|
||||||
for (let effect of beastformEffects) {
|
await this.actor.deleteEmbeddedDocuments(
|
||||||
await effect.delete();
|
'ActiveEffect',
|
||||||
}
|
beastformEffects.map(x => x.id)
|
||||||
|
);
|
||||||
return true;
|
return existingEffects;
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export default class DHDamageAction extends DHBaseAction {
|
||||||
if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(systemData));
|
if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(systemData));
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: this.name }),
|
title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: game.i18n.localize(this.name) }),
|
||||||
roll: { formula },
|
roll: { formula },
|
||||||
targets: systemData.targets.filter(t => t.hit) ?? data.targets,
|
targets: systemData.targets.filter(t => t.hit) ?? data.targets,
|
||||||
hasSave: this.hasSave,
|
hasSave: this.hasSave,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||||
import DhLevelData from '../levelData.mjs';
|
import DhLevelData from '../levelData.mjs';
|
||||||
import BaseDataActor from './base.mjs';
|
import BaseDataActor from './base.mjs';
|
||||||
import { attributeField, resourceField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs';
|
import { attributeField, resourceField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs';
|
||||||
|
import ActionField from '../fields/actionField.mjs';
|
||||||
|
|
||||||
export default class DhCharacter extends BaseDataActor {
|
export default class DhCharacter extends BaseDataActor {
|
||||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Character'];
|
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Character'];
|
||||||
|
|
@ -87,8 +88,45 @@ 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()),
|
attack: new ActionField({
|
||||||
disadvantageSources: new fields.ArrayField(new fields.StringField()),
|
initial: {
|
||||||
|
name: 'DAGGERHEART.GENERAL.unarmedStrike',
|
||||||
|
img: 'icons/skills/melee/unarmed-punch-fist-yellow-red.webp',
|
||||||
|
_id: foundry.utils.randomID(),
|
||||||
|
systemPath: 'attack',
|
||||||
|
type: 'attack',
|
||||||
|
range: 'melee',
|
||||||
|
target: {
|
||||||
|
type: 'any',
|
||||||
|
amount: 1
|
||||||
|
},
|
||||||
|
roll: {
|
||||||
|
type: 'attack',
|
||||||
|
trait: 'strength'
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
type: ['physical'],
|
||||||
|
value: {
|
||||||
|
custom: {
|
||||||
|
enabled: true,
|
||||||
|
formula: '@system.rules.attack.damage.value'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
advantageSources: new fields.ArrayField(new fields.StringField(), {
|
||||||
|
label: 'DAGGERHEART.ACTORS.Character.advantageSources.label',
|
||||||
|
hint: 'DAGGERHEART.ACTORS.Character.advantageSources.hint'
|
||||||
|
}),
|
||||||
|
disadvantageSources: new fields.ArrayField(new fields.StringField(), {
|
||||||
|
label: 'DAGGERHEART.ACTORS.Character.disadvantageSources.label',
|
||||||
|
hint: 'DAGGERHEART.ACTORS.Character.disadvantageSources.hint'
|
||||||
|
}),
|
||||||
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({
|
||||||
|
|
@ -161,6 +199,15 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
magical: new fields.BooleanField({ initial: false }),
|
magical: new fields.BooleanField({ initial: false }),
|
||||||
physical: new fields.BooleanField({ initial: false })
|
physical: new fields.BooleanField({ initial: false })
|
||||||
}),
|
}),
|
||||||
|
attack: new fields.SchemaField({
|
||||||
|
damage: new fields.SchemaField({
|
||||||
|
value: new fields.StringField({
|
||||||
|
required: true,
|
||||||
|
initial: '@profd4',
|
||||||
|
label: 'DAGGERHEART.GENERAL.Rules.attack.damage.value.label'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}),
|
||||||
weapon: new fields.SchemaField({
|
weapon: new fields.SchemaField({
|
||||||
/* Unimplemented
|
/* Unimplemented
|
||||||
-> Should remove the lowest damage dice from weapon damage
|
-> Should remove the lowest damage dice from weapon damage
|
||||||
|
|
@ -420,11 +467,14 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
const data = super.getRollData();
|
const data = super.getRollData();
|
||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
|
system: {
|
||||||
...this.resources.tokens,
|
...this.resources.tokens,
|
||||||
...this.resources.dice,
|
...this.resources.dice,
|
||||||
...this.bonuses,
|
...this.bonuses,
|
||||||
|
...this.rules,
|
||||||
tier: this.tier,
|
tier: this.tier,
|
||||||
level: this.levelData.level.current
|
level: this.levelData.level.current
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,11 @@ export default class DHBeastform extends BaseDataItem {
|
||||||
initial: CONFIG.DH.ACTOR.abilities.agility.id
|
initial: CONFIG.DH.ACTOR.abilities.agility.id
|
||||||
}),
|
}),
|
||||||
examples: new fields.StringField(),
|
examples: new fields.StringField(),
|
||||||
advantageOn: new fields.ArrayField(new fields.StringField()),
|
advantageOn: new fields.TypedObjectField(
|
||||||
|
new fields.SchemaField({
|
||||||
|
value: new fields.StringField()
|
||||||
|
})
|
||||||
|
),
|
||||||
features: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
features: new ForeignDocumentUUIDArrayField({ type: 'Item' }),
|
||||||
evolved: new fields.SchemaField({
|
evolved: new fields.SchemaField({
|
||||||
maximumTier: new fields.NumberField({
|
maximumTier: new fields.NumberField({
|
||||||
|
|
@ -104,7 +108,13 @@ export default class DHBeastform extends BaseDataItem {
|
||||||
await beastformEffect.updateSource({
|
await beastformEffect.updateSource({
|
||||||
changes: [
|
changes: [
|
||||||
...beastformEffect.changes,
|
...beastformEffect.changes,
|
||||||
{ key: 'system.advantageSources', mode: 2, value: this.advantageOn.join(', ') }
|
{
|
||||||
|
key: 'system.advantageSources',
|
||||||
|
mode: 2,
|
||||||
|
value: Object.values(this.advantageOn)
|
||||||
|
.map(x => x.value)
|
||||||
|
.join(', ')
|
||||||
|
}
|
||||||
],
|
],
|
||||||
system: {
|
system: {
|
||||||
characterTokenData: {
|
characterTokenData: {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -38,12 +38,14 @@ export default class DHToken extends TokenDocument {
|
||||||
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.StringField) 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);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,26 @@
|
||||||
@import '../../utils/colors.less';
|
@import '../../utils/colors.less';
|
||||||
@import '../../utils/mixin.less';
|
@import '../../utils/mixin.less';
|
||||||
|
|
||||||
.appTheme({
|
.theme-light .application.daggerheart.dh-style.views.beastform-selection .beastforms-outer-container {
|
||||||
&.beastform-selection {
|
.beastform-title {
|
||||||
.beastforms-outer-container .beastform-title {
|
background-image: url('../assets/parchments/dh-parchment-light.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
.advanced-container {
|
||||||
|
.advanced-forms-container {
|
||||||
|
.advanced-form-container {
|
||||||
|
background-image: url('../assets/parchments/dh-parchment-light.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
.hybrid-data-wrapper .hybrid-data-container .hybrid-data-inner-container .hybrid-data {
|
||||||
background-image: url('../assets/parchments/dh-parchment-light.png');
|
background-image: url('../assets/parchments/dh-parchment-light.png');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {});
|
.form-features .form-feature {
|
||||||
|
background-image: url('../assets/parchments/dh-parchment-light.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.application.daggerheart.dh-style.views.beastform-selection {
|
.application.daggerheart.dh-style.views.beastform-selection {
|
||||||
.beastforms-outer-container {
|
.beastforms-outer-container {
|
||||||
|
|
@ -80,6 +93,17 @@
|
||||||
width: 300px;
|
width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advanced-forms-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.advanced-form-container {
|
.advanced-form-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -91,11 +115,72 @@
|
||||||
height: 120px;
|
height: 120px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
color: light-dark(@dark, @beige);
|
||||||
|
background-image: url('../assets/parchments/dh-parchment-dark.png');
|
||||||
|
|
||||||
|
&.hybridized {
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: start;
|
||||||
|
padding-top: 4px;
|
||||||
|
height: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.empty {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.beastform-title {
|
||||||
|
position: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.empty-form {
|
.empty-form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.beastform-title-wrapper {
|
||||||
|
height: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hybrid-data-wrapper {
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.hybrid-data-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
padding: 0 4px;
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hybrid-data-inner-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
.hybrid-data {
|
||||||
|
padding: 0 2px;
|
||||||
|
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');
|
||||||
|
opacity: 0.4;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,13 +189,13 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
margin-top: 8px;
|
margin: 8px 0;
|
||||||
|
|
||||||
.form-feature {
|
.form-feature {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
padding: 0 2px;
|
padding: 0 4px;
|
||||||
border: 1px solid light-dark(@dark-blue, @golden);
|
border: 1px solid light-dark(@dark-blue, @golden);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: light-dark(@dark, @beige);
|
color: light-dark(@dark, @beige);
|
||||||
|
|
|
||||||
94
templates/dialogs/beastform/beastformDialog.hbs
Normal file
94
templates/dialogs/beastform/beastformDialog.hbs
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
<div>
|
||||||
|
<div class="beastforms-outer-container">
|
||||||
|
<div class="beastforms-container">
|
||||||
|
{{#each beastformTiers as |tier tierKey|}}
|
||||||
|
<fieldset class="beastforms-tier">
|
||||||
|
<legend>{{tier.label}}</legend>
|
||||||
|
{{#each tier.values as |form uuid|}}
|
||||||
|
<div data-action="selectBeastform" data-uuid="{{uuid}}" data-tooltip="{{concat "#item#" uuid}}" class="beastform-container {{#unless form.selected}}inactive{{/unless}} {{#if form.draggable}}draggable{{/if}}">
|
||||||
|
<img src="{{form.value.img}}" />
|
||||||
|
<div class="beastform-title">{{form.value.name}}</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</fieldset>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
<div class="advanced-container {{#if (or (eq selected.system.beastformType 'evolved') (eq selected.system.beastformType 'hybrid'))}}expanded{{/if}}">
|
||||||
|
{{#if (eq selected.system.beastformType 'evolved')}}
|
||||||
|
<h2>{{localize "DAGGERHEART.ITEMS.Beastform.evolve"}}</h2>
|
||||||
|
|
||||||
|
<div class="form-features">
|
||||||
|
{{#if selectedBeastformEffect}}
|
||||||
|
<div class="form-feature" data-tooltip="{{concat "#item#" selectedBeastformEffect.uuid}}">
|
||||||
|
<h4>{{localize "DAGGERHEART.ITEMS.Beastform.evolvedFeatureTitle"}}</h4>
|
||||||
|
<div>{{{selectedBeastformEffect.description}}}</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="advanced-form-container evolved">
|
||||||
|
{{#if evolved.form}}
|
||||||
|
<div class="beastform-title">{{concat (localize "DAGGERHEART.CONFIG.BeastformType.evolved") " " evolved.form.name}}</div>
|
||||||
|
<img src="{{evolved.form.img}}" />
|
||||||
|
{{else}}
|
||||||
|
<div class="empty-form">
|
||||||
|
<i class="fa-solid fa-plus"></i>
|
||||||
|
<label>{{localize "DAGGERHEART.ITEMS.Beastform.evolvedDrag"}}</label>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if (eq selected.system.beastformType 'hybrid')}}
|
||||||
|
<h2>{{localize "DAGGERHEART.ITEMS.Beastform.hybridize"}}</h2>
|
||||||
|
|
||||||
|
<div class="form-features">
|
||||||
|
{{#if selectedBeastformEffect}}
|
||||||
|
<div class="form-feature" data-tooltip="{{concat "#item#" selectedBeastformEffect.uuid}}">
|
||||||
|
<h4>{{localize "DAGGERHEART.ITEMS.Beastform.hybridizeFeatureTitle"}}</h4>
|
||||||
|
<div>{{{selectedBeastformEffect.description}}}</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="advanced-forms-container">
|
||||||
|
{{#each hybridForms as | form key |}}
|
||||||
|
<div class="advanced-form-container hybridized {{#unless form}}empty{{/unless}}" id="{{key}}">
|
||||||
|
{{#if form}}
|
||||||
|
<div class="beastform-title-wrapper">
|
||||||
|
<div class="beastform-title">{{form.name}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="hybrid-data-wrapper">
|
||||||
|
<div class="hybrid-data-container">
|
||||||
|
<label>{{localize "DAGGERHEART.GENERAL.features"}}</label>
|
||||||
|
<div class="hybrid-data-inner-container">
|
||||||
|
{{#each form.system.features as | feature |}}
|
||||||
|
<a data-action="toggleHybridFeature" id="{{feature.uuid}}" data-form="{{@../key}}"><div class="hybrid-data {{#if feature.selected}}active{{/if}}" data-tooltip="{{concat "#item#" feature.uuid}}">{{feature.name}}</div></a>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hybrid-data-container">
|
||||||
|
<label>{{localize "DAGGERHEART.GENERAL.Advantage.plural"}}</label>
|
||||||
|
<div class="hybrid-data-inner-container">
|
||||||
|
{{#each form.system.advantageOn as | advantage id |}}
|
||||||
|
<a data-action="toggleHybridAdvantage" id="{{id}}" data-form="{{@../key}}"><div class="hybrid-data {{#if advantage.selected}}active{{/if}}">{{advantage.value}}</div></a>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="empty-form">
|
||||||
|
<i class="fa-solid fa-plus"></i>
|
||||||
|
<label>{{localize "DAGGERHEART.ITEMS.Beastform.hybridizeDrag"}}</label>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<button type="button" data-action="submitBeastform" {{#if (not canSubmit)}}disabled{{/if}}>{{localize "DAGGERHEART.ITEMS.Beastform.transform"}}</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
<div>
|
|
||||||
<div class="beastforms-outer-container">
|
|
||||||
<div class="beastforms-container">
|
|
||||||
{{#each beastformTiers as |tier tierKey|}}
|
|
||||||
<fieldset class="beastforms-tier">
|
|
||||||
<legend>{{tier.label}}</legend>
|
|
||||||
{{#each tier.values as |form uuid|}}
|
|
||||||
<div data-action="selectBeastform" data-uuid="{{uuid}}" data-tooltip="{{concat "#item#" uuid}}" class="beastform-container {{#unless form.selected}}inactive{{/unless}} {{#if form.draggable}}draggable{{/if}}">
|
|
||||||
<img src="{{form.value.img}}" />
|
|
||||||
<div class="beastform-title">{{form.value.name}}</div>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</fieldset>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
<div class="advanced-container {{#if (or (eq selected.system.beastformType 'evolved') (eq selected.system.beastformType 'hybrid'))}}expanded{{/if}}">
|
|
||||||
{{#if (eq selected.system.beastformType 'evolved')}}
|
|
||||||
<h2>{{localize "DAGGERHEART.ITEMS.Beastform.evolve"}}</h2>
|
|
||||||
<div class="advanced-form-container evolved">
|
|
||||||
{{#if evolved.form}}
|
|
||||||
<div class="beastform-title">{{concat (localize "DAGGERHEART.CONFIG.BeastformType.evolved") " " evolved.form.name}}</div>
|
|
||||||
<img src="{{evolved.form.img}}" />
|
|
||||||
{{else}}
|
|
||||||
<div class="empty-form">
|
|
||||||
<i class="fa-solid fa-plus"></i>
|
|
||||||
<label>{{localize "Drag a form here to evolve it"}}</label>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
<div class="form-features">
|
|
||||||
{{#if selectedBeastformEffect}}
|
|
||||||
<div class="form-feature" data-tooltip="{{concat "#item#" selectedBeastformEffect.uuid}}">
|
|
||||||
<h4>{{localize "DAGGERHEART.ITEMS.Beastform.evolvedFeatureTitle"}}</h4>
|
|
||||||
<div>{{{selectedBeastformEffect.description}}}</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<button type="button" data-action="submitBeastform" {{#if (not canSubmit)}}disabled{{/if}}>{{localize "DAGGERHEART.ITEMS.Beastform.transform"}}</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">
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,13 @@
|
||||||
{{formGroup systemFields.mainTrait value=source.system.mainTrait blank=false localize=true}}
|
{{formGroup systemFields.mainTrait value=source.system.mainTrait blank=false localize=true}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{#unless (eq source.system.beastformType 'hybrid')}}
|
||||||
{{formGroup systemFields.examples value=source.system.examples localize=true}}
|
{{formGroup systemFields.examples value=source.system.examples localize=true}}
|
||||||
|
|
||||||
<div class="advantage-on-section">
|
<div class="advantage-on-section">
|
||||||
<label>{{localize "DAGGERHEART.ITEMS.Beastform.FIELDS.advantageOn.label"}}</label>
|
<label>{{localize "DAGGERHEART.ITEMS.Beastform.FIELDS.advantageOn.label"}}</label>
|
||||||
<input class="advantageon-input" value="{{source.system.advantageOn}}" />
|
<input class="advantageon-input" value="{{advantageOn}}" />
|
||||||
</div>
|
</div>
|
||||||
|
{{/unless}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<fieldset class="two-columns even">
|
<fieldset class="two-columns even">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue