mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
[Feature] Manual Character Editing (#490)
* Initial * Added Character-Settings * Finalized Character-Settings * Hide CharacterSetup if any part is done manually * Fixed class/subclass drag-drop * Fixed relinking of Features from items created on Character * Adding features on CharacterItems now adds them on the Character and relinks * Made suggested items inactive in the Class sheet if rendered from inside a Character * Added hope to CharacterSetting * add style to textarea element, add spellcasting and domain class into char sheet and move rest buttons to another place * Fixed characterCreation experience description --------- Co-authored-by: moliloo <dev.murilobrito@gmail.com>
This commit is contained in:
parent
263dfa69ae
commit
e1d8f8784a
49 changed files with 1205 additions and 386 deletions
35
lang/en.json
35
lang/en.json
|
|
@ -162,11 +162,25 @@
|
|||
},
|
||||
"faith": "Faith",
|
||||
"levelUp": "You can level up",
|
||||
"maxEvasionBonus": "Max Evasion Increase",
|
||||
"maxHPBonus": "Max HP Increase",
|
||||
"pronouns": "Pronouns",
|
||||
"story": {
|
||||
"backgroundTitle": "Background",
|
||||
"characteristics": "Characteristics",
|
||||
"connectionsTitle": "Connections"
|
||||
},
|
||||
"experienceDataRemoveConfirmation": {
|
||||
"title": "Remove Experience Data",
|
||||
"text": "The experience you are about to remove has levelup data linked to it (assumably because you did levelups with the 'levelupAuto' automation setting on). Removing it will remove this automation data aswell. Do you want to proceed?"
|
||||
},
|
||||
"manualMulticlass": {
|
||||
"title": "Multiclass",
|
||||
"text": "Do you want to add this class as your multiclass?"
|
||||
},
|
||||
"manualMulticlassSubclass": {
|
||||
"title": "Multiclass Subclass",
|
||||
"text": "Do you want to add this subclass as your multiclass subclass?"
|
||||
}
|
||||
},
|
||||
"Companion": {
|
||||
|
|
@ -460,6 +474,11 @@
|
|||
},
|
||||
"title": "{actor} Level Up"
|
||||
},
|
||||
"MulticlassChoice": {
|
||||
"title": "Multiclassing - {actor}",
|
||||
"explanation": "You are adding {class} as your multiclass",
|
||||
"selectDomainPrompt": "Select your new domain"
|
||||
},
|
||||
"OwnershipSelection": {
|
||||
"title": "Ownership Selection - {name}",
|
||||
"default": "Default Ownership"
|
||||
|
|
@ -1866,6 +1885,7 @@
|
|||
"levelUp": "Level Up",
|
||||
"loadout": "Loadout",
|
||||
"max": "Max",
|
||||
"maxWithThing": "Max {thing}",
|
||||
"multiclass": "Multiclass",
|
||||
"newCategory": "New Category",
|
||||
"none": "None",
|
||||
|
|
@ -2022,6 +2042,10 @@
|
|||
"gm": { "label": "GM" },
|
||||
"players": { "label": "Players" }
|
||||
},
|
||||
"levelupAuto": {
|
||||
"label": "Levelup Automation",
|
||||
"hint": "When you've made your choices and finish levelup, the numerical changes are automatically applied to your character."
|
||||
},
|
||||
"actionPoints": {
|
||||
"label": "Action Points",
|
||||
"hint": "Automatically give and take Action Points as combatants take their turns."
|
||||
|
|
@ -2205,7 +2229,9 @@
|
|||
"tooHighLevel": "You cannot raise the character level past the maximum",
|
||||
"tooLowLevel": "You cannot lower the character level below starting level",
|
||||
"subclassNotInClass": "This subclass does not belong to your selected class.",
|
||||
"subclassNotInMulticlass": "This subclass does not belong to your selected multiclass.",
|
||||
"missingClass": "You don't have a class selected yet.",
|
||||
"missingMulticlass": "Missing multiclass",
|
||||
"wrongDomain": "The card isn't from one of your class domains.",
|
||||
"cardTooHighLevel": "The card is too high level!",
|
||||
"duplicateCard": "You cannot select the same card more than once.",
|
||||
|
|
@ -2235,7 +2261,9 @@
|
|||
"beastformToManyFeatures": "You cannot select any more features.",
|
||||
"beastformEquipWeapon": "You cannot use weapons while in a Beastform.",
|
||||
"loadoutMaxReached": "You already have {max} cards in your loadout. Move atleast one to your vault before adding a new one.",
|
||||
"insufficientResources": "You have insufficient resources"
|
||||
"insufficientResources": "You have insufficient resources",
|
||||
"multiclassAlreadyPresent": "You already have a class and multiclass",
|
||||
"subclassesAlreadyPresent": "You already have a class and multiclass subclass"
|
||||
},
|
||||
"Tooltip": {
|
||||
"disableEffect": "Disable Effect",
|
||||
|
|
@ -2243,6 +2271,8 @@
|
|||
"openItemWorld": "Open Item World",
|
||||
"openActorWorld": "Open Actor World",
|
||||
"sendToChat": "Send to Chat",
|
||||
"maxEvasionClassBound": "Your Evasion base is set on your class. This is the increase ontop of that.",
|
||||
"maxHPClassBound": "Your max HP base is set on your class. This is the increase ontop of that.",
|
||||
"moreOptions": "More Options",
|
||||
"equip": "Equip",
|
||||
"unequip": "Unequip",
|
||||
|
|
@ -2252,7 +2282,8 @@
|
|||
"rangeAndTarget": "Range & Target",
|
||||
"dragApplyEffect": "Drag effect to apply it to an actor",
|
||||
"appliedEvenIfSuccessful": "Applied even if save succeeded",
|
||||
"diceIsRerolled": "The dice has been rerolled (x{times})"
|
||||
"diceIsRerolled": "The dice has been rerolled (x{times})",
|
||||
"openSheetSettings": "Open Settings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ export { default as DamageReductionDialog } from './damageReductionDialog.mjs';
|
|||
export { default as DamageSelectionDialog } from './damageSelectionDialog.mjs';
|
||||
export { default as DeathMove } from './deathMove.mjs';
|
||||
export { default as Downtime } from './downtime.mjs';
|
||||
export { default as MulticlassChoiceDialog } from './multiclassChoiceDialog.mjs';
|
||||
export { default as OwnershipSelection } from './ownershipSelection.mjs';
|
||||
export { default as ResourceDiceDialog } from './resourceDiceDialog.mjs';
|
||||
export { default as ActionSelectionDialog } from './actionSelectionDialog.mjs';
|
||||
|
|
|
|||
73
module/applications/dialogs/multiclassChoiceDialog.mjs
Normal file
73
module/applications/dialogs/multiclassChoiceDialog.mjs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class MulticlassChoiceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(actor, multiclass, options) {
|
||||
super(options);
|
||||
|
||||
this.actor = actor;
|
||||
this.multiclass = multiclass;
|
||||
this.selectedDomain = null;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return game.i18n.format('DAGGERHEART.APPLICATIONS.MulticlassChoice.title', { actor: this.actor.name });
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['daggerheart', 'dh-style', 'dialog', 'views', 'multiclass-choice'],
|
||||
position: { width: 'auto', height: 'auto' },
|
||||
window: { icon: 'fa-solid fa-person-rays' },
|
||||
actions: {
|
||||
save: MulticlassChoiceDialog.#save,
|
||||
selectDomain: MulticlassChoiceDialog.#selectDomain
|
||||
}
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
application: {
|
||||
id: 'multiclass-choice',
|
||||
template: 'systems/daggerheart/templates/dialogs/multiclassChoice.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.multiclass = this.multiclass;
|
||||
context.domainChoices = this.multiclass.domains.map(value => {
|
||||
const domain = CONFIG.DH.DOMAIN.domains[value];
|
||||
return {
|
||||
value: value,
|
||||
label: game.i18n.localize(domain.label),
|
||||
description: game.i18n.localize(domain.description),
|
||||
src: domain.src,
|
||||
selected: value === this.selectedDomain,
|
||||
disabled: this.actor.system.domains.includes(value)
|
||||
};
|
||||
});
|
||||
context.multiclassDisabled = !this.selectedDomain;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
_onClose(options = {}) {
|
||||
if (!options.submitted) this.move = null;
|
||||
}
|
||||
|
||||
static async configure(actor, multiclass, options = {}) {
|
||||
return new Promise(resolve => {
|
||||
const app = new this(actor, multiclass, options);
|
||||
app.addEventListener('close', () => resolve(app.selectedDomain), { once: true });
|
||||
app.render({ force: true });
|
||||
});
|
||||
}
|
||||
|
||||
static #save() {
|
||||
this.close({ submitted: true });
|
||||
}
|
||||
|
||||
static #selectDomain(_event, button) {
|
||||
this.selectedDomain = this.selectedDomain === button.dataset.domain ? null : button.dataset.domain;
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
|
@ -46,7 +46,8 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
tabs: { template: 'systems/daggerheart/templates/levelup/tabs/tab-navigation.hbs' },
|
||||
advancements: { template: 'systems/daggerheart/templates/levelup/tabs/advancements.hbs' },
|
||||
selections: { template: 'systems/daggerheart/templates/levelup/tabs/selections.hbs' },
|
||||
summary: { template: 'systems/daggerheart/templates/levelup/tabs/summary.hbs' }
|
||||
summary: { template: 'systems/daggerheart/templates/levelup/tabs/summary.hbs' },
|
||||
footer: { template: 'systems/daggerheart/templates/levelup/tabs/footer.hbs' }
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
|
|
@ -95,6 +96,7 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
const context = await super._prepareContext(_options);
|
||||
context.levelup = this.levelup;
|
||||
context.tabs = this._getTabs(this.constructor.TABS);
|
||||
context.levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
export { default as ActionConfig } from './action-config.mjs';
|
||||
export { default as CharacterSettings } from './character-settings.mjs';
|
||||
export { default as AdversarySettings } from './adversary-settings.mjs';
|
||||
export { default as CompanionSettings } from './companion-settings.mjs';
|
||||
export { default as DowntimeConfig } from './downtimeConfig.mjs';
|
||||
|
|
|
|||
143
module/applications/sheets-configs/character-settings.mjs
Normal file
143
module/applications/sheets-configs/character-settings.mjs
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
import DHBaseActorSettings from '../sheets/api/actor-setting.mjs';
|
||||
|
||||
/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
|
||||
|
||||
export default class DHCharacterSettings extends DHBaseActorSettings {
|
||||
/**@inheritdoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['character-settings'],
|
||||
position: { width: 455, height: 'auto' },
|
||||
actions: {
|
||||
addExperience: DHCharacterSettings.#addExperience,
|
||||
removeExperience: DHCharacterSettings.#removeExperience
|
||||
},
|
||||
dragDrop: [
|
||||
{ dragSelector: null, dropSelector: '.tab.features' },
|
||||
{ dragSelector: '.feature-item', dropSelector: null }
|
||||
]
|
||||
};
|
||||
|
||||
/**@override */
|
||||
static PARTS = {
|
||||
header: {
|
||||
id: 'header',
|
||||
template: 'systems/daggerheart/templates/sheets-settings/character-settings/header.hbs'
|
||||
},
|
||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||
details: {
|
||||
id: 'details',
|
||||
template: 'systems/daggerheart/templates/sheets-settings/character-settings/details.hbs'
|
||||
},
|
||||
experiences: {
|
||||
id: 'experiences',
|
||||
template: 'systems/daggerheart/templates/sheets-settings/character-settings/experiences.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
/** @override */
|
||||
static TABS = {
|
||||
primary: {
|
||||
tabs: [{ id: 'details' }, { id: 'experiences' }],
|
||||
initial: 'details',
|
||||
labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
|
||||
}
|
||||
};
|
||||
|
||||
/**@inheritdoc */
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
context.levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Adds a new experience entry to the actor.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #addExperience() {
|
||||
const newExperience = {
|
||||
name: 'Experience',
|
||||
modifier: 0
|
||||
};
|
||||
await this.actor.update({ [`system.experiences.${foundry.utils.randomID()}`]: newExperience });
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an experience entry from the actor.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #removeExperience(_, target) {
|
||||
const experience = this.actor.system.experiences[target.dataset.experience];
|
||||
const updates = {};
|
||||
|
||||
const relinkAchievementData = [];
|
||||
const relinkSelectionData = [];
|
||||
Object.keys(this.actor.system.levelData.levelups).forEach(key => {
|
||||
const level = this.actor.system.levelData.levelups[key];
|
||||
|
||||
const achievementIncludesExp = level.achievements.experiences[target.dataset.experience];
|
||||
if (achievementIncludesExp)
|
||||
relinkAchievementData.push({ levelKey: key, experience: target.dataset.experience });
|
||||
|
||||
const selectionIndex = level.selections.findIndex(
|
||||
x => x.optionKey === 'experience' && x.data[0] === target.dataset.experience
|
||||
);
|
||||
if (selectionIndex !== -1)
|
||||
relinkSelectionData.push({ levelKey: key, selectionIndex, experience: target.dataset.experience });
|
||||
});
|
||||
|
||||
if (relinkAchievementData.length > 0 || relinkSelectionData.length > 0) {
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: game.i18n.localize('DAGGERHEART.ACTORS.Character.experienceDataRemoveConfirmation.title')
|
||||
},
|
||||
content: game.i18n.localize('DAGGERHEART.ACTORS.Character.experienceDataRemoveConfirmation.text')
|
||||
});
|
||||
if (!confirmed) return;
|
||||
}
|
||||
|
||||
if (relinkAchievementData.length > 0) {
|
||||
relinkAchievementData.forEach(data => {
|
||||
updates[`system.levelData.levelups.${data.levelKey}.achievements.experiences.-=${data.experience}`] =
|
||||
null;
|
||||
});
|
||||
} else if (relinkSelectionData.length > 0) {
|
||||
relinkSelectionData.forEach(data => {
|
||||
updates[`system.levelData.levelups.${data.levelKey}.selections`] = this.actor.system.levelData.levelups[
|
||||
data.levelKey
|
||||
].selections.reduce((acc, selection, index) => {
|
||||
if (
|
||||
index === data.selectionIndex &&
|
||||
selection.optionKey === 'experience' &&
|
||||
selection.data.includes(data.experience)
|
||||
) {
|
||||
acc.push({ ...selection, data: selection.data.filter(x => x !== data.experience) });
|
||||
} else {
|
||||
acc.push(selection);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
});
|
||||
} else {
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', {
|
||||
type: game.i18n.localize(`DAGGERHEART.GENERAL.Experience.single`),
|
||||
name: experience.name
|
||||
})
|
||||
},
|
||||
content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: experience.name })
|
||||
});
|
||||
if (!confirmed) return;
|
||||
}
|
||||
|
||||
await this.actor.update({
|
||||
...updates,
|
||||
[`system.experiences.-=${target.dataset.experience}`]: null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,8 @@ export default class DHCompanionSettings extends DHBaseActorSettings {
|
|||
classes: ['companion-settings'],
|
||||
position: { width: 455, height: 'auto' },
|
||||
actions: {
|
||||
addExperience: DHCompanionSettings.#addExperience,
|
||||
removeExperience: DHCompanionSettings.#removeExperience,
|
||||
levelUp: DHCompanionSettings.#levelUp
|
||||
}
|
||||
};
|
||||
|
|
@ -88,6 +90,38 @@ export default class DHCompanionSettings extends DHBaseActorSettings {
|
|||
if (!value) await this.actor.updateLevel(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new experience entry to the actor.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #addExperience() {
|
||||
const newExperience = {
|
||||
name: 'Experience',
|
||||
modifier: 0
|
||||
};
|
||||
await this.actor.update({ [`system.experiences.${foundry.utils.randomID()}`]: newExperience });
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an experience entry from the actor.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #removeExperience(_, target) {
|
||||
const experience = this.actor.system.experiences[target.dataset.experience];
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', {
|
||||
type: game.i18n.localize(`DAGGERHEART.GENERAL.Experience.single`),
|
||||
name: experience.name
|
||||
})
|
||||
},
|
||||
content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: experience.name })
|
||||
});
|
||||
if (!confirmed) return;
|
||||
|
||||
await this.actor.update({ [`system.experiences.-=${target.dataset.experience}`]: null });
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the companion level-up dialog for the associated actor.
|
||||
* @type {ApplicationClickAction}
|
||||
|
|
|
|||
|
|
@ -716,10 +716,14 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the downtime application.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static useDowntime(_, button) {
|
||||
new game.system.api.applications.dialogs.Downtime(this.document, button.dataset.type === 'shortRest').render(
|
||||
true
|
||||
);
|
||||
new game.system.api.applications.dialogs.Downtime(this.document, button.dataset.type === 'shortRest').render({
|
||||
force: true
|
||||
});
|
||||
}
|
||||
|
||||
async _onDragStart(event) {
|
||||
|
|
|
|||
|
|
@ -417,17 +417,29 @@ export default function DHApplicationMixin(Base) {
|
|||
const { documentClass, type, inVault, disabled } = target.dataset;
|
||||
const parentIsItem = this.document.documentName === 'Item';
|
||||
const parent =
|
||||
parentIsItem && documentClass === 'Item'
|
||||
? type === 'action'
|
||||
? this.document.system
|
||||
: null
|
||||
: this.document;
|
||||
this.document.parent?.type === 'character'
|
||||
? this.document.parent
|
||||
: parentIsItem && documentClass === 'Item'
|
||||
? type === 'action'
|
||||
? this.document.system
|
||||
: null
|
||||
: this.document;
|
||||
|
||||
let systemData = {};
|
||||
if (parent?.type === 'character' && type === 'feature') {
|
||||
systemData = {
|
||||
originItemType: this.document.type,
|
||||
originId: this.document.id,
|
||||
identifier: this.document.system.isMulticlass ? 'multiclass' : null
|
||||
};
|
||||
}
|
||||
|
||||
const cls =
|
||||
type === 'action' ? game.system.api.models.actions.actionsTypes.base : getDocumentClass(documentClass);
|
||||
const data = {
|
||||
name: cls.defaultName({ type, parent }),
|
||||
type
|
||||
type,
|
||||
system: systemData
|
||||
};
|
||||
if (inVault) data['system.inVault'] = true;
|
||||
if (disabled) data.disabled = true;
|
||||
|
|
|
|||
|
|
@ -150,10 +150,24 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
static async #addFeature(_, target) {
|
||||
const { type } = target.dataset;
|
||||
const cls = foundry.documents.Item.implementation;
|
||||
const item = await cls.create({
|
||||
type: 'feature',
|
||||
name: cls.defaultName({ type: 'feature' })
|
||||
});
|
||||
|
||||
let systemData = {};
|
||||
if (this.document.parent?.type === 'character') {
|
||||
systemData = {
|
||||
originItemType: this.document.type,
|
||||
originId: this.document.id,
|
||||
identifier: this.document.system.isMulticlass ? 'multiclass' : null
|
||||
};
|
||||
}
|
||||
|
||||
const item = await cls.create(
|
||||
{
|
||||
type: 'feature',
|
||||
name: cls.defaultName({ type: 'feature' }),
|
||||
system: systemData
|
||||
},
|
||||
{ parent: this.document.parent?.type === 'character' ? this.document.parent : undefined }
|
||||
);
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features, { type, item }].map(x => ({
|
||||
...x,
|
||||
|
|
|
|||
|
|
@ -113,45 +113,47 @@ export default class ClassSheet extends DHBaseItemSheet {
|
|||
});
|
||||
} else if (item.type === 'feature') {
|
||||
super._onDrop(event);
|
||||
} else if (item.type === 'weapon') {
|
||||
if (target.classList.contains('primary-weapon-section')) {
|
||||
if (!item.system.secondary)
|
||||
} else if (this.document.parent?.type !== 'character') {
|
||||
if (item.type === 'weapon') {
|
||||
if (target.classList.contains('primary-weapon-section')) {
|
||||
if (!item.system.secondary)
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedPrimaryWeapon': item.uuid
|
||||
});
|
||||
} else if (target.classList.contains('secondary-weapon-section')) {
|
||||
if (item.system.secondary)
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedSecondaryWeapon': item.uuid
|
||||
});
|
||||
}
|
||||
} else if (item.type === 'armor') {
|
||||
if (target.classList.contains('armor-section')) {
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedPrimaryWeapon': item.uuid
|
||||
});
|
||||
} else if (target.classList.contains('secondary-weapon-section')) {
|
||||
if (item.system.secondary)
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedSecondaryWeapon': item.uuid
|
||||
});
|
||||
}
|
||||
} else if (item.type === 'armor') {
|
||||
if (target.classList.contains('armor-section')) {
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedArmor': item.uuid
|
||||
});
|
||||
}
|
||||
} else if (target.classList.contains('choice-a-section')) {
|
||||
if (item.type === 'loot' || item.type === 'consumable') {
|
||||
const filteredChoiceA = this.document.system.inventory.choiceA;
|
||||
if (filteredChoiceA.length < 2)
|
||||
await this.document.update({
|
||||
'system.inventory.choiceA': [...filteredChoiceA.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
} else if (item.type === 'loot') {
|
||||
if (target.classList.contains('take-section')) {
|
||||
const filteredTake = this.document.system.inventory.take.filter(x => x);
|
||||
if (filteredTake.length < 3)
|
||||
await this.document.update({
|
||||
'system.inventory.take': [...filteredTake.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (target.classList.contains('choice-b-section')) {
|
||||
const filteredChoiceB = this.document.system.inventory.choiceB.filter(x => x);
|
||||
if (filteredChoiceB.length < 2)
|
||||
await this.document.update({
|
||||
'system.inventory.choiceB': [...filteredChoiceB.map(x => x.uuid), item.uuid]
|
||||
'system.characterGuide.suggestedArmor': item.uuid
|
||||
});
|
||||
}
|
||||
} else if (target.classList.contains('choice-a-section')) {
|
||||
if (item.type === 'loot' || item.type === 'consumable') {
|
||||
const filteredChoiceA = this.document.system.inventory.choiceA;
|
||||
if (filteredChoiceA.length < 2)
|
||||
await this.document.update({
|
||||
'system.inventory.choiceA': [...filteredChoiceA.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
} else if (item.type === 'loot') {
|
||||
if (target.classList.contains('take-section')) {
|
||||
const filteredTake = this.document.system.inventory.take.filter(x => x);
|
||||
if (filteredTake.length < 3)
|
||||
await this.document.update({
|
||||
'system.inventory.take': [...filteredTake.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (target.classList.contains('choice-b-section')) {
|
||||
const filteredChoiceB = this.document.system.inventory.choiceB.filter(x => x);
|
||||
if (filteredChoiceB.length < 2)
|
||||
await this.document.update({
|
||||
'system.inventory.choiceB': [...filteredChoiceB.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,8 @@ export default class DhpAdversary extends BaseDataActor {
|
|||
experiences: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
name: new fields.StringField(),
|
||||
value: new fields.NumberField({ required: true, integer: true, initial: 1 })
|
||||
value: new fields.NumberField({ required: true, integer: true, initial: 1 }),
|
||||
description: new fields.StringField()
|
||||
})
|
||||
),
|
||||
bonuses: new fields.SchemaField({
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import DhLevelData from '../levelData.mjs';
|
|||
import BaseDataActor from './base.mjs';
|
||||
import { attributeField, resourceField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs';
|
||||
import { ActionField } from '../fields/actionField.mjs';
|
||||
import DHCharacterSettings from '../../applications/sheets-configs/character-settings.mjs';
|
||||
|
||||
export default class DhCharacter extends BaseDataActor {
|
||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Character'];
|
||||
|
|
@ -12,6 +13,7 @@ export default class DhCharacter extends BaseDataActor {
|
|||
return foundry.utils.mergeObject(super.metadata, {
|
||||
label: 'TYPES.Actor.character',
|
||||
type: 'character',
|
||||
settingSheet: DHCharacterSettings,
|
||||
isNPC: false
|
||||
});
|
||||
}
|
||||
|
|
@ -22,7 +24,12 @@ export default class DhCharacter extends BaseDataActor {
|
|||
return {
|
||||
...super.defineSchema(),
|
||||
resources: new fields.SchemaField({
|
||||
hitPoints: resourceField(0, 'DAGGERHEART.GENERAL.HitPoints.plural', true),
|
||||
hitPoints: resourceField(
|
||||
0,
|
||||
'DAGGERHEART.GENERAL.HitPoints.plural',
|
||||
true,
|
||||
'DAGGERHEART.ACTORS.Character.maxHPBonus'
|
||||
),
|
||||
stress: resourceField(6, 'DAGGERHEART.GENERAL.stress', true),
|
||||
hope: resourceField(6, 'DAGGERHEART.GENERAL.hope')
|
||||
}),
|
||||
|
|
@ -56,7 +63,8 @@ export default class DhCharacter extends BaseDataActor {
|
|||
experiences: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
name: new fields.StringField(),
|
||||
value: new fields.NumberField({ integer: true, initial: 0 })
|
||||
value: new fields.NumberField({ integer: true, initial: 0 }),
|
||||
description: new fields.StringField()
|
||||
})
|
||||
),
|
||||
gold: new fields.SchemaField({
|
||||
|
|
@ -312,7 +320,7 @@ export default class DhCharacter extends BaseDataActor {
|
|||
}
|
||||
|
||||
get needsCharacterSetup() {
|
||||
return !this.class.value || !this.class.subclass;
|
||||
return !(this.class.value || this.class.subclass || this.ancestry || this.community);
|
||||
}
|
||||
|
||||
get spellcastModifier() {
|
||||
|
|
@ -399,11 +407,16 @@ export default class DhCharacter extends BaseDataActor {
|
|||
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) {
|
||||
if (this.class.subclass) {
|
||||
const subclassState = this.class.subclass.system.featureState;
|
||||
const subType = item.system.subType;
|
||||
const subclass =
|
||||
item.system.identifier === 'multiclass' ? this.multiclass.subclass : this.class.subclass;
|
||||
const featureType = subclass
|
||||
? (subclass.system.features.find(x => x.item?.uuid === item.uuid)?.type ?? null)
|
||||
: null;
|
||||
|
||||
if (
|
||||
subType === CONFIG.DH.ITEM.featureSubTypes.foundation ||
|
||||
(subType === CONFIG.DH.ITEM.featureSubTypes.specialization && subclassState >= 2) ||
|
||||
(subType === CONFIG.DH.ITEM.featureSubTypes.mastery && subclassState >= 3)
|
||||
featureType === CONFIG.DH.ITEM.featureSubTypes.foundation ||
|
||||
(featureType === CONFIG.DH.ITEM.featureSubTypes.specialization && subclassState >= 2) ||
|
||||
(featureType === CONFIG.DH.ITEM.featureSubTypes.mastery && subclassState >= 3)
|
||||
) {
|
||||
subclassFeatures.push(item);
|
||||
}
|
||||
|
|
@ -502,7 +515,7 @@ export default class DhCharacter extends BaseDataActor {
|
|||
}
|
||||
|
||||
prepareBaseData() {
|
||||
this.evasion = this.class.value?.system?.evasion ?? 0;
|
||||
this.evasion += this.class.value?.system?.evasion ?? 0;
|
||||
|
||||
const currentLevel = this.levelData.level.current;
|
||||
const currentTier =
|
||||
|
|
@ -511,37 +524,39 @@ export default class DhCharacter extends BaseDataActor {
|
|||
: Object.values(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers).find(
|
||||
tier => currentLevel >= tier.levels.start && currentLevel <= tier.levels.end
|
||||
).tier;
|
||||
for (let levelKey in this.levelData.levelups) {
|
||||
const level = this.levelData.levelups[levelKey];
|
||||
if (game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto) {
|
||||
for (let levelKey in this.levelData.levelups) {
|
||||
const level = this.levelData.levelups[levelKey];
|
||||
|
||||
this.proficiency += level.achievements.proficiency;
|
||||
this.proficiency += level.achievements.proficiency;
|
||||
|
||||
for (let selection of level.selections) {
|
||||
switch (selection.type) {
|
||||
case 'trait':
|
||||
selection.data.forEach(data => {
|
||||
this.traits[data].value += 1;
|
||||
this.traits[data].tierMarked = selection.tier === currentTier;
|
||||
});
|
||||
break;
|
||||
case 'hitPoint':
|
||||
this.resources.hitPoints.max += selection.value;
|
||||
break;
|
||||
case 'stress':
|
||||
this.resources.stress.max += selection.value;
|
||||
break;
|
||||
case 'evasion':
|
||||
this.evasion += selection.value;
|
||||
break;
|
||||
case 'proficiency':
|
||||
this.proficiency += selection.value;
|
||||
break;
|
||||
case 'experience':
|
||||
Object.keys(this.experiences).forEach(key => {
|
||||
const experience = this.experiences[key];
|
||||
experience.value += selection.value;
|
||||
});
|
||||
break;
|
||||
for (let selection of level.selections) {
|
||||
switch (selection.type) {
|
||||
case 'trait':
|
||||
selection.data.forEach(data => {
|
||||
this.traits[data].value += 1;
|
||||
this.traits[data].tierMarked = selection.tier === currentTier;
|
||||
});
|
||||
break;
|
||||
case 'hitPoint':
|
||||
this.resources.hitPoints.max += selection.value;
|
||||
break;
|
||||
case 'stress':
|
||||
this.resources.stress.max += selection.value;
|
||||
break;
|
||||
case 'evasion':
|
||||
this.evasion += selection.value;
|
||||
break;
|
||||
case 'proficiency':
|
||||
this.proficiency += selection.value;
|
||||
break;
|
||||
case 'experience':
|
||||
selection.data.forEach(id => {
|
||||
const experience = this.experiences[id];
|
||||
if (experience) experience.value += selection.value;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,15 @@ const attributeField = label =>
|
|||
tierMarked: new fields.BooleanField({ initial: false })
|
||||
});
|
||||
|
||||
const resourceField = (max = 0, label, reverse = false) =>
|
||||
const resourceField = (max = 0, label, reverse = false, maxLabel) =>
|
||||
new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, min: 0, integer: true, label }),
|
||||
max: new fields.NumberField({ initial: max, integer: true }),
|
||||
max: new fields.NumberField({
|
||||
initial: max,
|
||||
integer: true,
|
||||
label:
|
||||
maxLabel ?? game.i18n.format('DAGGERHEART.GENERAL.maxWithThing', { thing: game.i18n.localize(label) })
|
||||
}),
|
||||
isReversed: new fields.BooleanField({ initial: reverse })
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
}
|
||||
|
||||
if (this.actor && this.actor.type === 'character' && this.features) {
|
||||
const featureUpdates = {};
|
||||
for (let f of this.features) {
|
||||
const fBase = f.item ?? f;
|
||||
const feature = fBase.system ? fBase : await foundry.utils.fromUuid(fBase.uuid);
|
||||
|
|
@ -134,14 +135,26 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
system: {
|
||||
originItemType: this.parent.type,
|
||||
originId: data._id,
|
||||
identifier: feature.identifier,
|
||||
subType: feature.item ? feature.type : undefined
|
||||
identifier: this.isMulticlass ? 'multiclass' : null
|
||||
}
|
||||
},
|
||||
{ inplace: false }
|
||||
);
|
||||
await this.actor.createEmbeddedDocuments('Item', [createData]);
|
||||
const [doc] = await this.actor.createEmbeddedDocuments('Item', [createData]);
|
||||
|
||||
if (!featureUpdates.features)
|
||||
featureUpdates.features = this.features.map(x => (x.item ? { ...x, item: x.item.uuid } : x.uuid));
|
||||
|
||||
if (f.item) {
|
||||
const existingFeature = featureUpdates.features.find(x => x.item === f.item.uuid);
|
||||
existingFeature.item = doc.uuid;
|
||||
} else {
|
||||
const replaceIndex = featureUpdates.features.findIndex(x => x === f.uuid);
|
||||
featureUpdates.features.splice(replaceIndex, 1, doc.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
await this.updateSource(featureUpdates);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,16 +62,37 @@ export default class DHClass extends BaseDataItem {
|
|||
}
|
||||
|
||||
async _preCreate(data, options, user) {
|
||||
const allowed = await super._preCreate(data, options, user);
|
||||
if (allowed === false) return;
|
||||
|
||||
if (this.actor?.type === 'character') {
|
||||
const path = data.system.isMulticlass ? 'system.multiclass.value' : 'system.class.value';
|
||||
if (foundry.utils.getProperty(this.actor, path)) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.classAlreadySelected'));
|
||||
return false;
|
||||
const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
||||
if (levelupAuto) {
|
||||
const path = data.system.isMulticlass ? 'system.multiclass.value' : 'system.class.value';
|
||||
if (foundry.utils.getProperty(this.actor, path)) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.classAlreadySelected'));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (this.actor.system.class.value) {
|
||||
if (this.actor.system.multiclass.value) {
|
||||
ui.notifications.warn(
|
||||
game.i18n.localize('DAGGERHEART.UI.Notifications.multiclassAlreadyPresent')
|
||||
);
|
||||
return false;
|
||||
} else {
|
||||
const selectedDomain =
|
||||
await game.system.api.applications.dialogs.MulticlassChoiceDialog.configure(
|
||||
this.actor,
|
||||
this
|
||||
);
|
||||
if (!selectedDomain) return false;
|
||||
|
||||
await this.updateSource({ isMulticlass: true, domains: [selectedDomain] });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const allowed = await super._preCreate(data, options, user);
|
||||
if (allowed === false) return;
|
||||
}
|
||||
|
||||
_onCreate(data, options, userId) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ export default class DHFeature extends BaseDataItem {
|
|||
nullable: true,
|
||||
initial: null
|
||||
}),
|
||||
subType: new fields.StringField({ choices: CONFIG.DH.ITEM.featureSubTypes, nullable: true, initial: null }),
|
||||
originId: new fields.StringField({ nullable: true, initial: null }),
|
||||
identifier: new fields.StringField()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,27 +41,48 @@ export default class DHSubclass extends BaseDataItem {
|
|||
}
|
||||
|
||||
async _preCreate(data, options, user) {
|
||||
const allowed = await super._preCreate(data, options, user);
|
||||
if (allowed === false) return;
|
||||
|
||||
if (this.actor?.type === 'character') {
|
||||
const classData = this.actor.items.find(
|
||||
x => x.type === 'class' && x.system.isMulticlass === data.system.isMulticlass
|
||||
);
|
||||
const subclassData = this.actor.items.find(
|
||||
x => x.type === 'subclass' && x.system.isMulticlass === data.system.isMulticlass
|
||||
);
|
||||
if (!classData) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.missingClass'));
|
||||
return false;
|
||||
} else if (subclassData) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassAlreadySelected'));
|
||||
return false;
|
||||
} else if (classData.system.subclasses.every(x => x.uuid !== (data.uuid ?? `Item.${data._id}`))) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassNotInClass'));
|
||||
return false;
|
||||
if (this.actor.system.class.subclass) {
|
||||
if (this.actor.system.multiclass.subclass) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassesAlreadyPresent'));
|
||||
return false;
|
||||
} else {
|
||||
if (!this.actor.system.multiclass.value) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.missingMulticlass'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
this.actor.system.multiclass.value.system.subclasses.every(
|
||||
x => x.uuid !== (data.uuid ?? `Item.${data._id}`)
|
||||
)
|
||||
) {
|
||||
ui.notifications.error(
|
||||
game.i18n.localize('DAGGERHEART.UI.Notifications.subclassNotInMulticlass')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
await this.updateSource({ isMulticlass: true });
|
||||
}
|
||||
} else {
|
||||
if (!this.actor.system.class.value) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.missingClass'));
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
this.actor.system.class.value.system.subclasses.every(
|
||||
x => x.uuid !== (data.uuid ?? `Item.${data._id}`)
|
||||
)
|
||||
) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassNotInClass'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const allowed = await super._preCreate(data, options, user);
|
||||
if (allowed === false) return;
|
||||
}
|
||||
|
||||
_onCreate(data, options, userId) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ export default class DhAutomation extends foundry.abstract.DataModel {
|
|||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.hopeFear.players.label'
|
||||
})
|
||||
}),
|
||||
levelupAuto: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: true,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.levelupAuto.label'
|
||||
}),
|
||||
actionPoints: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
|
|
|
|||
|
|
@ -172,26 +172,30 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
|
||||
async levelUp(levelupData) {
|
||||
const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
||||
|
||||
const levelups = {};
|
||||
for (var levelKey of Object.keys(levelupData)) {
|
||||
const level = levelupData[levelKey];
|
||||
|
||||
for (var experienceKey in level.achievements.experiences) {
|
||||
const experience = level.achievements.experiences[experienceKey];
|
||||
await this.update({
|
||||
[`system.experiences.${experienceKey}`]: {
|
||||
name: experience.name,
|
||||
value: experience.modifier
|
||||
}
|
||||
});
|
||||
|
||||
if (this.system.companion) {
|
||||
await this.system.companion.update({
|
||||
if (levelupAuto) {
|
||||
for (var experienceKey in level.achievements.experiences) {
|
||||
const experience = level.achievements.experiences[experienceKey];
|
||||
await this.update({
|
||||
[`system.experiences.${experienceKey}`]: {
|
||||
name: '',
|
||||
name: experience.name,
|
||||
value: experience.modifier
|
||||
}
|
||||
});
|
||||
|
||||
if (this.system.companion) {
|
||||
await this.system.companion.update({
|
||||
[`system.experiences.${experienceKey}`]: {
|
||||
name: '',
|
||||
value: experience.modifier
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -250,74 +254,86 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
|
||||
for (var addition of featureAdditions) {
|
||||
for (var featureData of addition.features) {
|
||||
const feature = new DHFeature({
|
||||
...featureData,
|
||||
description: game.i18n.localize(featureData.description)
|
||||
});
|
||||
|
||||
const document = featureData.toPartner && this.system.partner ? this.system.partner : this;
|
||||
const embeddedItem = await document.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
if (levelupAuto) {
|
||||
for (var featureData of addition.features) {
|
||||
const feature = new DHFeature({
|
||||
...featureData,
|
||||
name: game.i18n.localize(featureData.name),
|
||||
type: 'feature',
|
||||
system: feature
|
||||
}
|
||||
]);
|
||||
const newFeature = {
|
||||
onPartner: Boolean(featureData.toPartner && this.system.partner),
|
||||
id: embeddedItem[0].id
|
||||
};
|
||||
addition.checkbox.features = !addition.checkbox.features
|
||||
? [newFeature]
|
||||
: [...addition.checkbox.features, newFeature];
|
||||
description: game.i18n.localize(featureData.description)
|
||||
});
|
||||
|
||||
const document = featureData.toPartner && this.system.partner ? this.system.partner : this;
|
||||
const embeddedItem = await document.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
...featureData,
|
||||
name: game.i18n.localize(featureData.name),
|
||||
type: 'feature',
|
||||
system: feature
|
||||
}
|
||||
]);
|
||||
const newFeature = {
|
||||
onPartner: Boolean(featureData.toPartner && this.system.partner),
|
||||
id: embeddedItem[0].id
|
||||
};
|
||||
addition.checkbox.features = !addition.checkbox.features
|
||||
? [newFeature]
|
||||
: [...addition.checkbox.features, newFeature];
|
||||
}
|
||||
}
|
||||
|
||||
selections.push(addition.checkbox);
|
||||
}
|
||||
|
||||
if (multiclass) {
|
||||
const subclassItem = await foundry.utils.fromUuid(multiclass.secondaryData.subclass);
|
||||
const subclassData = subclassItem.toObject();
|
||||
const multiclassItem = await foundry.utils.fromUuid(multiclass.data[0]);
|
||||
const multiclassData = multiclassItem.toObject();
|
||||
if (levelupAuto) {
|
||||
const subclassItem = await foundry.utils.fromUuid(multiclass.secondaryData.subclass);
|
||||
const subclassData = subclassItem.toObject();
|
||||
const multiclassItem = await foundry.utils.fromUuid(multiclass.data[0]);
|
||||
const multiclassData = multiclassItem.toObject();
|
||||
|
||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
...multiclassData,
|
||||
system: {
|
||||
...multiclassData.system,
|
||||
domains: [multiclass.secondaryData.domain],
|
||||
isMulticlass: true
|
||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
...multiclassData,
|
||||
system: {
|
||||
...multiclassData.system,
|
||||
domains: [multiclass.secondaryData.domain],
|
||||
isMulticlass: true
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
]);
|
||||
|
||||
await this.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
...subclassData,
|
||||
system: {
|
||||
...subclassData.system,
|
||||
isMulticlass: true
|
||||
await this.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
...subclassData,
|
||||
system: {
|
||||
...subclassData.system,
|
||||
isMulticlass: true
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
selections.push({ ...multiclass, itemUuid: embeddedItem[0].uuid });
|
||||
]);
|
||||
selections.push({ ...multiclass, itemUuid: embeddedItem[0].uuid });
|
||||
} else {
|
||||
selections.push({ ...multiclass });
|
||||
}
|
||||
}
|
||||
|
||||
for (var domainCard of domainCards) {
|
||||
const item = await foundry.utils.fromUuid(domainCard.data[0]);
|
||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [item.toObject()]);
|
||||
selections.push({ ...domainCard, itemUuid: embeddedItem[0].uuid });
|
||||
if (levelupAuto) {
|
||||
const item = await foundry.utils.fromUuid(domainCard.data[0]);
|
||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [item.toObject()]);
|
||||
selections.push({ ...domainCard, itemUuid: embeddedItem[0].uuid });
|
||||
} else {
|
||||
selections.push({ ...domainCard });
|
||||
}
|
||||
}
|
||||
|
||||
const achievementDomainCards = [];
|
||||
for (var card of Object.values(level.achievements.domainCards)) {
|
||||
const item = await foundry.utils.fromUuid(card.uuid);
|
||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [item.toObject()]);
|
||||
card.itemUuid = embeddedItem[0].uuid;
|
||||
achievementDomainCards.push(card);
|
||||
if (levelupAuto) {
|
||||
for (var card of Object.values(level.achievements.domainCards)) {
|
||||
const item = await foundry.utils.fromUuid(card.uuid);
|
||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [item.toObject()]);
|
||||
card.itemUuid = embeddedItem[0].uuid;
|
||||
achievementDomainCards.push(card);
|
||||
}
|
||||
}
|
||||
|
||||
if (subclassFeatureState.class) {
|
||||
|
|
|
|||
|
|
@ -263,24 +263,36 @@
|
|||
gap: 8px;
|
||||
|
||||
.experience-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
.experience-description {
|
||||
border-color: light-dark(@dark-blue, @golden);
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.experience-value {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 22px;
|
||||
border-left: 1px solid light-dark(@dark-blue, @golden);
|
||||
height: 100%;
|
||||
.experience-inner-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.experience-description {
|
||||
border-color: light-dark(@dark-blue, @golden);
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.experience-value {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 22px;
|
||||
border-left: 1px solid light-dark(@dark-blue, @golden);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
resize: none;
|
||||
border-color: light-dark(@dark-blue, @golden);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,3 +24,5 @@
|
|||
@import './dice-roll/roll-selection.less';
|
||||
@import './damage-reduction/damage-reduction-container.less';
|
||||
@import './damage-reduction/sheets.less';
|
||||
|
||||
@import './multiclass-choice/sheet.less';
|
||||
|
|
|
|||
|
|
@ -104,4 +104,10 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.levelup-footer {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
76
styles/less/dialog/multiclass-choice/sheet.less
Normal file
76
styles/less/dialog/multiclass-choice/sheet.less
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
.theme-light .daggerheart.dh-style.dialog.multiclass-choice {
|
||||
.multiclass-container .domain-choice-container button label {
|
||||
background-image: url(../assets/parchments/dh-parchment-light.png);
|
||||
}
|
||||
}
|
||||
|
||||
.daggerheart.dh-style.dialog.multiclass-choice {
|
||||
.multiclass-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.multiclass-explanation {
|
||||
margin-top: 0;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.multiclass-domains-container {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
|
||||
.domain-choice-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
button {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
background: light-dark(@dark-blue-10, @golden-10);
|
||||
color: light-dark(@dark-blue, @golden);
|
||||
|
||||
&.selected {
|
||||
background: light-dark(@dark-blue-40, @golden-40);
|
||||
}
|
||||
|
||||
label {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
font-family: @font-body;
|
||||
border-radius: 6px;
|
||||
border: 2px solid;
|
||||
padding: 0 2px;
|
||||
background-image: url(../assets/parchments/dh-parchment-dark.png);
|
||||
color: light-dark(@dark, @beige);
|
||||
}
|
||||
}
|
||||
|
||||
.domain-description {
|
||||
width: 240px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
font-style: italic;
|
||||
border: 1px solid light-dark(@dark-blue, @golden);
|
||||
border-radius: 6px;
|
||||
padding: 4px 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,22 +5,26 @@
|
|||
border: 1px solid light-dark(@dark-blue, @golden);
|
||||
|
||||
input[type='text'],
|
||||
input[type='number'] {
|
||||
input[type='number'],
|
||||
textarea {
|
||||
background: light-dark(transparent, transparent);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 30px @soft-shadow;
|
||||
backdrop-filter: blur(9.5px);
|
||||
-webkit-backdrop-filter: blur(9.5px);
|
||||
outline: none;
|
||||
outline: 2px solid transparent;
|
||||
color: light-dark(@dark-blue, @golden);
|
||||
border: 1px solid light-dark(@dark, @beige);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&::placeholder {
|
||||
color: light-dark(@dark-40, @beige-50);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:hover[type='text'],
|
||||
&:hover[type='number'],
|
||||
&:focus,
|
||||
&:focus[type='text'],
|
||||
&:focus[type='number'] {
|
||||
background: light-dark(@soft-shadow, @semi-transparent-dark-blue);
|
||||
|
|
@ -70,6 +74,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
color: light-dark(@dark, @beige);
|
||||
font-family: @font-body;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
|
||||
}
|
||||
|
||||
button {
|
||||
background: light-dark(transparent, @golden);
|
||||
border: 1px solid light-dark(@dark-blue, @dark-blue);
|
||||
|
|
@ -206,6 +217,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.inactive {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.fit-height {
|
||||
height: 95%;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,18 +12,33 @@
|
|||
.experience-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.experience-item {
|
||||
.experience-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
.experience-inner-item {
|
||||
display: grid;
|
||||
grid-template-columns: 3fr 1fr 30px;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
|
||||
&.no-controls {
|
||||
grid-template-columns: 3fr 1fr;
|
||||
}
|
||||
|
||||
a {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
resize: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
styles/less/sheets-settings/character-settings/sheet.less
Normal file
36
styles/less/sheets-settings/character-settings/sheet.less
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
.application.daggerheart.dh-style.dialog {
|
||||
.tab.details {
|
||||
.traits-inner-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
gap: 8px;
|
||||
|
||||
.trait-container {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: url(../assets/svg/trait-shield.svg) no-repeat;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
div {
|
||||
filter: drop-shadow(0 0 3px black);
|
||||
text-shadow: 0 0 3px black;
|
||||
font-family: @font-body;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
width: 32px;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
@import './adversary-settings/sheet.less';
|
||||
@import './adversary-settings/experiences.less';
|
||||
@import './adversary-settings/features.less';
|
||||
@import './character-settings/sheet.less';
|
||||
|
||||
@import './environment-settings/features.less';
|
||||
@import './environment-settings/adversaries.less';
|
||||
|
|
|
|||
|
|
@ -4,12 +4,24 @@
|
|||
|
||||
// Theme header backgrounds
|
||||
.appTheme({
|
||||
.character-header-sheet .trait {
|
||||
background: url(../assets/svg/trait-shield.svg) no-repeat;
|
||||
.character-header-sheet {
|
||||
.trait {
|
||||
background: url(../assets/svg/trait-shield.svg) no-repeat;
|
||||
}
|
||||
|
||||
.character-row .domains-section img {
|
||||
filter: invert(88%) sepia(98%) saturate(1784%) hue-rotate(311deg) brightness(104%) contrast(91%);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
.character-header-sheet .trait {
|
||||
.character-header-sheet {
|
||||
.trait {
|
||||
background: url('../assets/svg/trait-shield-light.svg') no-repeat;
|
||||
}
|
||||
|
||||
.character-row .domains-section img {
|
||||
filter: invert(87%) sepia(15%) saturate(343%) hue-rotate(333deg) brightness(110%) contrast(87%);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -88,6 +100,11 @@
|
|||
font-size: 12px;
|
||||
color: light-dark(@dark-blue, @golden);
|
||||
|
||||
.missing-header-feature {
|
||||
opacity: 0.5;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
span {
|
||||
padding: 3px;
|
||||
border-radius: 3px;
|
||||
|
|
@ -107,14 +124,27 @@
|
|||
|
||||
.character-row {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.hope-section {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.downtime-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
margin-left: auto;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.hope-section,
|
||||
.threshold-section {
|
||||
.domains-section {
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
|
|
@ -132,21 +162,24 @@
|
|||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
color: light-dark(@dark-blue, @golden);
|
||||
|
||||
&.threshold-value {
|
||||
color: light-dark(@dark, @beige);
|
||||
}
|
||||
}
|
||||
|
||||
.threshold-legend {
|
||||
position: absolute;
|
||||
bottom: -21px;
|
||||
color: light-dark(@golden, @dark-blue);
|
||||
background-color: light-dark(@dark-blue, @golden);
|
||||
padding: 3px;
|
||||
justify-self: anchor-center;
|
||||
border-radius: 0 0 3px 3px;
|
||||
text-transform: capitalize;
|
||||
.domain {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
color: light-dark(@dark-blue, @golden);
|
||||
}
|
||||
|
||||
img {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.hope-value {
|
||||
|
|
@ -193,14 +226,5 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.character-downtime-container {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
}
|
||||
|
||||
.character-header-sheet {
|
||||
position: relative;
|
||||
grid-row: 1;
|
||||
grid-column: 2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,62 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icons-list {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
align-items: end;
|
||||
justify-content: center;
|
||||
top: 45px;
|
||||
right: 10px;
|
||||
|
||||
.spellcast-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
text-align: center;
|
||||
padding-right: 8px;
|
||||
max-width: 50px;
|
||||
height: 50px;
|
||||
font-size: 1.2rem;
|
||||
background: light-dark(@dark-blue-60, @dark-golden-80);
|
||||
backdrop-filter: blur(8px);
|
||||
border: 4px double light-dark(@beige, @golden);
|
||||
color: light-dark(@beige, @golden);
|
||||
border-radius: 999px;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
.spellcast-label {
|
||||
font-size: 14px;
|
||||
opacity: 0;
|
||||
margin-right: 0.3rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
i {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
align-content: center;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
&:not(.no-label):hover {
|
||||
max-width: 300px;
|
||||
padding: 0 10px;
|
||||
border-radius: 60px;
|
||||
|
||||
.spellcast-label {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-section {
|
||||
|
|
@ -62,12 +118,13 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
top: -20px;
|
||||
gap: 30px;
|
||||
gap: 10px;
|
||||
margin-bottom: -16px;
|
||||
|
||||
.resources-section {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.status-bar {
|
||||
display: flex;
|
||||
|
|
@ -345,6 +402,32 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.threshold-section {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-self: center;
|
||||
gap: 10px;
|
||||
background-color: light-dark(transparent, @dark-blue);
|
||||
color: light-dark(@dark-blue, @golden);
|
||||
padding: 5px 10px;
|
||||
border: 1px solid light-dark(@dark-blue, @golden);
|
||||
border-radius: 6px;
|
||||
align-items: center;
|
||||
width: fit-content;
|
||||
height: 30px;
|
||||
|
||||
h4 {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
color: light-dark(@dark-blue, @golden);
|
||||
|
||||
&.threshold-value {
|
||||
color: light-dark(@dark, @beige);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.items-sidebar-list {
|
||||
|
|
@ -360,7 +443,7 @@
|
|||
.shortcut-items-section {
|
||||
overflow-y: hidden;
|
||||
max-height: 56%;
|
||||
padding-top: 16px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 20px;
|
||||
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
|
||||
|
||||
|
|
@ -393,35 +476,24 @@
|
|||
|
||||
.experience-row {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
width: 250px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
input[type='text'] {
|
||||
height: 32px;
|
||||
width: 180px;
|
||||
border: 1px solid transparent;
|
||||
outline: 2px solid transparent;
|
||||
.experience-value {
|
||||
height: 25px;
|
||||
width: 35px;
|
||||
font-size: 14px;
|
||||
font-family: @font-body;
|
||||
transition: all 0.3s ease;
|
||||
color: light-dark(@dark, @beige);
|
||||
|
||||
&:hover {
|
||||
outline: 2px solid light-dark(@dark, @beige);
|
||||
}
|
||||
align-content: center;
|
||||
text-align: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.experience-value {
|
||||
height: 25px;
|
||||
width: 35px;
|
||||
font-size: 14px;
|
||||
font-family: @font-body;
|
||||
color: light-dark(@dark, @beige);
|
||||
align-content: center;
|
||||
text-align: center;
|
||||
.controls {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,12 @@
|
|||
<div class="experiences-inner-container">
|
||||
{{#each experience.values as |experience id|}}
|
||||
<div class="experience-container">
|
||||
<input class="experience-description" type="text" name="{{concat "experiences." id ".name" }}" value="{{experience.name}}" placeholder="{{localize "DAGGERHEART.APPLICATIONS.CharacterCreation.newExperience"}}" />
|
||||
<div class="experience-value">{{numberFormat this.value sign=true}}</div>
|
||||
<div class="experience-inner-container">
|
||||
<input class="experience-description" type="text" name="{{concat "experiences." id ".name" }}" value="{{experience.name}}" placeholder="{{localize "DAGGERHEART.APPLICATIONS.CharacterCreation.newExperience"}}" />
|
||||
<div class="experience-value">{{numberFormat this.value sign=true}}</div>
|
||||
</div>
|
||||
|
||||
<textarea name="{{concat "experiences." id ".description"}}">{{experience.description}}</textarea>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
|||
23
templates/dialogs/multiclassChoice.hbs
Normal file
23
templates/dialogs/multiclassChoice.hbs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<div>
|
||||
<div class="multiclass-container">
|
||||
<h5 class="multiclass-explanation">{{localize "DAGGERHEART.APPLICATIONS.MulticlassChoice.explanation" class=multiclass.parent.name }}</h5>
|
||||
<h5 class="multiclass-explanation">{{localize "DAGGERHEART.APPLICATIONS.MulticlassChoice.selectDomainPrompt" }}</h5>
|
||||
|
||||
<div class="multiclass-domains-container">
|
||||
{{#each domainChoices as | choice |}}
|
||||
<div class="domain-choice-container">
|
||||
<button data-action="selectDomain" data-domain="{{choice.value}}" {{#if choice.selected}}class="selected"{{/if}} {{disabled choice.disabled}}>
|
||||
<label>{{choice.label}}</label>
|
||||
<img src="{{choice.src}}" />
|
||||
</button>
|
||||
<div class="domain-description">{{choice.description}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<button data-action="close">{{localize "Cancel"}}</button>
|
||||
<button data-action="save" {{disabled multiclassDisabled}}>{{localize "DAGGERHEART.GENERAL.multiclass"}}</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
8
templates/levelup/tabs/footer.hbs
Normal file
8
templates/levelup/tabs/footer.hbs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<section class='tab-footer'>
|
||||
{{#unless levelupAuto}}
|
||||
<div class="levelup-footer">
|
||||
<button type="button" data-action="close">{{localize "Cancel"}}</button>
|
||||
<button type="button" data-action="save">{{localize "Save"}}</button>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</section>
|
||||
|
|
@ -1,40 +1,44 @@
|
|||
<section class='tab-navigation'>
|
||||
<line-div></line-div>
|
||||
<div class="levelup-navigation-container">
|
||||
{{#if this.showTabs}}
|
||||
<nav class='feature-tab sheet-tabs tabs' data-group='primary'>
|
||||
{{#each tabs as |tab|}}
|
||||
{{#if (not (eq tab.id 'summary'))}}
|
||||
<div class="levelup-tab-container">
|
||||
<a class='{{tab.id}} {{tab.cssClass}}' data-action='tab' data-group='{{tab.group}}' data-tab='{{tab.id}}'>
|
||||
{{localize tab.label}}
|
||||
</a>
|
||||
{{#if tab.progress}}
|
||||
<div>{{tab.progress.selected}}/{{tab.progress.max}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</nav>
|
||||
{{/if}}
|
||||
<div class="levelup-navigation-actions {{#if (not this.showTabs)}}test{{/if}}">
|
||||
{{#if this.navigate.previous.fromSummary}}
|
||||
<button data-action="activatePart" data-part="advancements">{{localize "DAGGERHEART.APPLICATIONS.Levelup.navigateToLevelup"}}</button>
|
||||
{{else}}
|
||||
{{#if (not this.navigate.previous.disabled)}}
|
||||
<button data-action="updateCurrentLevel" >{{this.navigate.previous.label}}</button>
|
||||
{{/if}}
|
||||
{{#if levelupAuto}}
|
||||
<line-div></line-div>
|
||||
<div class="levelup-navigation-container">
|
||||
{{#if this.showTabs}}
|
||||
<nav class='feature-tab sheet-tabs tabs' data-group='primary'>
|
||||
{{#each tabs as |tab|}}
|
||||
{{#if (not (eq tab.id 'summary'))}}
|
||||
<div class="levelup-tab-container">
|
||||
<a class='{{tab.id}} {{tab.cssClass}}' data-action='tab' data-group='{{tab.group}}' data-tab='{{tab.id}}'>
|
||||
{{localize tab.label}}
|
||||
</a>
|
||||
{{#if tab.progress}}
|
||||
<div>{{tab.progress.selected}}/{{tab.progress.max}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</nav>
|
||||
{{/if}}
|
||||
{{#if this.navigate.next.show}}
|
||||
{{#if this.navigate.next.toSummary}}
|
||||
<button data-action="activatePart" data-part="summary" {{#if this.navigate.next.disabled}}disabled{{/if}}>{{localize "DAGGERHEART.APPLICATIONS.Levelup.navigateToSummary"}}</button>
|
||||
{{else}}
|
||||
<button data-action="updateCurrentLevel" data-forward="true" {{#if this.navigate.next.disabled}}disabled{{/if}}>{{this.navigate.next.label}}</button>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div></div>
|
||||
{{#if this.levelupAuto}}
|
||||
<div class="levelup-navigation-actions {{#if (not this.showTabs)}}test{{/if}}">
|
||||
{{#if this.navigate.previous.fromSummary}}
|
||||
<button data-action="activatePart" data-part="advancements">{{localize "DAGGERHEART.APPLICATIONS.Levelup.navigateToLevelup"}}</button>
|
||||
{{else}}
|
||||
{{#if (not this.navigate.previous.disabled)}}
|
||||
<button data-action="updateCurrentLevel" >{{this.navigate.previous.label}}</button>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if this.navigate.next.show}}
|
||||
{{#if this.navigate.next.toSummary}}
|
||||
<button data-action="activatePart" data-part="summary" {{#if this.navigate.next.disabled}}disabled{{/if}}>{{localize "DAGGERHEART.APPLICATIONS.Levelup.navigateToSummary"}}</button>
|
||||
{{else}}
|
||||
<button data-action="updateCurrentLevel" data-forward="true" {{#if this.navigate.next.disabled}}disabled{{/if}}>{{this.navigate.next.label}}</button>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div></div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<line-div></line-div>
|
||||
<line-div></line-div>
|
||||
{{/if}}
|
||||
</section>
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
{{formGroup settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints localize=true}}
|
||||
{{formGroup settingFields.schema.fields.hordeDamage value=settingFields._source.hordeDamage localize=true}}
|
||||
{{formGroup settingFields.schema.fields.effects.fields.rangeDependent value=settingFields._source.effects.rangeDependent localize=true}}
|
||||
{{formGroup settingFields.schema.fields.levelupAuto value=settingFields._source.levelupAuto localize=true}}
|
||||
|
||||
<footer class="form-footer">
|
||||
<button data-action="reset">
|
||||
|
|
|
|||
|
|
@ -12,9 +12,13 @@
|
|||
<ul class="experience-list">
|
||||
{{#each document.system.experiences as |experience key|}}
|
||||
<li class="experience-item">
|
||||
<input class="name" type="text" name="system.experiences.{{key}}.name" value="{{experience.name}}" />
|
||||
<input class="modifier" type="text" name="system.experiences.{{key}}.value" value="{{experience.value}}" data-dtype="Number" />
|
||||
<a data-action="removeExperience" data-experience="{{key}}" data-tooltip="{{localize 'CONTROLS.CommonDelete'}}"><i class="fa-solid fa-trash"></i></a>
|
||||
<div class="experience-inner-item">
|
||||
<input class="name" type="text" name="system.experiences.{{key}}.name" value="{{experience.name}}" />
|
||||
<input class="modifier" type="text" name="system.experiences.{{key}}.value" value="{{experience.value}}" data-dtype="Number" />
|
||||
<a data-action="removeExperience" data-experience="{{key}}" data-tooltip="{{localize 'CONTROLS.CommonDelete'}}"><i class="fa-solid fa-trash"></i></a>
|
||||
</div>
|
||||
|
||||
<textarea name="system.experiences.{{key}}.description">{{experience.description}}</textarea>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
|
|
|||
42
templates/sheets-settings/character-settings/details.hbs
Normal file
42
templates/sheets-settings/character-settings/details.hbs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<section
|
||||
class='tab {{tabs.details.cssClass}} {{tabs.details.id}}'
|
||||
data-tab='{{tabs.details.id}}'
|
||||
data-group='{{tabs.details.group}}'
|
||||
>
|
||||
<fieldset class="one-column">
|
||||
<legend>{{localize 'DAGGERHEART.GENERAL.Trait.plural'}}</legend>
|
||||
|
||||
<div class="nest-inputs">
|
||||
<div class="traits-inner-container">
|
||||
{{#each document._source.system.traits as | trait key |}}
|
||||
<div class="trait-container">
|
||||
<div>{{localize (concat "DAGGERHEART.CONFIG.Traits." key ".name" )}}</div>
|
||||
<input type="text" data-dtype="Number" name="{{concat "system.traits." key ".value"}}" value="{{trait.value}}" />
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="one-column">
|
||||
<legend>{{localize 'DAGGERHEART.GENERAL.basics'}}</legend>
|
||||
|
||||
<div class="two-columns even">
|
||||
{{formGroup systemFields.resources.fields.hitPoints.fields.value value=document._source.system.resources.hitPoints.value localize=true}}
|
||||
<span data-tooltip-text="{{localize "DAGGERHEART.UI.Tooltip.maxHPClassBound"}}">
|
||||
{{formGroup systemFields.resources.fields.hitPoints.fields.max value=document._source.system.resources.hitPoints.max localize=true}}
|
||||
</span>
|
||||
|
||||
{{formGroup systemFields.resources.fields.stress.fields.value value=document._source.system.resources.stress.value localize=true}}
|
||||
{{formGroup systemFields.resources.fields.stress.fields.max value=document._source.system.resources.stress.max localize=true}}
|
||||
|
||||
{{formGroup systemFields.resources.fields.hope.fields.value value=document._source.system.resources.hope.value localize=true}}
|
||||
{{formGroup systemFields.resources.fields.hope.fields.max value=document._source.system.resources.hope.max localize=true}}
|
||||
|
||||
{{formGroup systemFields.proficiency value=document._source.system.proficiency localize=true}}
|
||||
<span data-tooltip-text="{{localize "DAGGERHEART.UI.Tooltip.maxEvasionClassBound"}}">
|
||||
{{formGroup systemFields.evasion value=document._source.system.evasion label="DAGGERHEART.ACTORS.Character.maxEvasionBonus" localize=true}}
|
||||
</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
</section>
|
||||
25
templates/sheets-settings/character-settings/experiences.hbs
Normal file
25
templates/sheets-settings/character-settings/experiences.hbs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<section
|
||||
class='tab {{tabs.experiences.cssClass}} {{tabs.experiences.id}}'
|
||||
data-tab='{{tabs.experiences.id}}'
|
||||
data-group='{{tabs.experiences.group}}'
|
||||
>
|
||||
<button type="button" class="add-experience-btn" type="button" data-action="addExperience">
|
||||
<span>{{localize "DOCUMENT.New" type=(localize "DAGGERHEART.GENERAL.experience.single")}}</span>
|
||||
</button>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{localize tabs.experiences.label}}</legend>
|
||||
<ul class="experience-list">
|
||||
{{#each document._source.system.experiences as |experience key|}}
|
||||
<li class="experience-item">
|
||||
<div class="experience-inner-item {{#if @root.levelupAuto}}no-controls{{/if}}">
|
||||
<input class="name" type="text" name="system.experiences.{{key}}.name" value="{{experience.name}}" />
|
||||
<input class="modifier" type="text" name="system.experiences.{{key}}.value" value="{{experience.value}}" data-dtype="Number" />
|
||||
{{#unless @root.levelupAuto}}<a data-action="removeExperience" data-experience="{{key}}" data-tooltip="{{localize 'CONTROLS.CommonDelete'}}"><i class="fa-solid fa-trash"></i></a>{{/unless}}
|
||||
</div>
|
||||
<textarea name="system.experiences.{{key}}.description">{{experience.description}}</textarea>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</fieldset>
|
||||
</section>
|
||||
3
templates/sheets-settings/character-settings/header.hbs
Normal file
3
templates/sheets-settings/character-settings/header.hbs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<header class="dialog-header">
|
||||
<h1>{{document.name}}</h1>
|
||||
</header>
|
||||
|
|
@ -18,4 +18,5 @@
|
|||
{{/if}}
|
||||
{{/if}}
|
||||
</fieldset>
|
||||
{{> 'systems/daggerheart/templates/actionTypes/damage.hbs' fields=systemFields.attack.fields.damage.fields.parts.element.fields source=document.system.attack.damage path="system.attack."}}
|
||||
</section>
|
||||
|
|
@ -3,16 +3,24 @@
|
|||
data-tab='{{tabs.experiences.id}}'
|
||||
data-group='{{tabs.experiences.group}}'
|
||||
>
|
||||
<button type="button" class="add-experience-btn" type="button" data-action="addExperience">
|
||||
<span>{{localize "DOCUMENT.New" type=(localize "DAGGERHEART.GENERAL.experience.single")}}</span>
|
||||
</button>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{localize tabs.experiences.label}}</legend>
|
||||
<ul class="experience-list">
|
||||
{{#each document.system.experiences as |experience key|}}
|
||||
{{#each document._source.system.experiences as |experience key|}}
|
||||
<li class="experience-item">
|
||||
<input class="name" type="text" name="system.experiences.{{key}}.name" value="{{experience.name}}" />
|
||||
<input disabled class="modifier" type="text" name="system.experiences.{{key}}.value" value="{{experience.value}}" data-dtype="Number" />
|
||||
<div class="experience-inner-item {{#if @root.levelupAuto}}no-controls{{/if}}">
|
||||
<input class="name" type="text" name="system.experiences.{{key}}.name" value="{{experience.name}}" />
|
||||
<input class="modifier" type="text" name="system.experiences.{{key}}.value" value="{{experience.value}}" data-dtype="Number" />
|
||||
{{#unless @root.levelupAuto}}<a data-action="removeExperience" data-experience="{{key}}" data-tooltip="{{localize 'CONTROLS.CommonDelete'}}"><i class="fa-solid fa-trash"></i></a>{{/unless}}
|
||||
</div>
|
||||
|
||||
<textarea name="system.experiences.{{key}}.description">{{experience.description}}</textarea>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</fieldset>
|
||||
|
||||
</section>
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<div class="adversary-navigation">
|
||||
{{> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
|
||||
<button data-action="openSettings">
|
||||
<button data-action="openSettings" data-tooltip-text="{{localize "DAGGERHEART.UI.Tooltip.openSheetSettings"}}">
|
||||
<i class="fa-solid fa-wrench"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -98,17 +98,17 @@
|
|||
</div>
|
||||
<div class="experience-list">
|
||||
{{#each source.system.experiences as |experience id|}}
|
||||
<div class="experience-row">
|
||||
<div class="experience-value">
|
||||
+{{experience.value}}
|
||||
<div class="experience-row" data-tooltip-text="{{experience.description}}">
|
||||
<div class="experience-value">
|
||||
+{{experience.value}}
|
||||
</div>
|
||||
<span class="experience-name">{{experience.name}}</span>
|
||||
<div class="controls">
|
||||
<a data-action="sendExpToChat" data-id="{{id}}">
|
||||
<i class="fa-regular fa-message"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<span class="experience-name">{{experience.name}}</span>
|
||||
<div class="controls">
|
||||
<a data-action="sendExpToChat" data-id="{{id}}">
|
||||
<i class="fa-regular fa-message"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
class="level-button glow" data-tooltip="{{#if document.system.needsCharacterSetup}}{{localize "DAGGERHEART.APPLICATIONS.CharacterCreation.buttonTitle"}}{{else}}{{localize "DAGGERHEART.ACTORS.Character.levelUp"}}{{/if}}"
|
||||
data-action="levelManagement"
|
||||
>
|
||||
<i class="fa-solid fa-triangle-exclamation"></i>
|
||||
<i class="fa-solid fa-angles-up"></i>
|
||||
</button>
|
||||
{{/if}}
|
||||
{{localize 'DAGGERHEART.GENERAL.level'}}
|
||||
|
|
@ -31,25 +31,25 @@
|
|||
{{#if document.system.class.value}}
|
||||
<span data-action="editDoc" data-item-uuid="{{document.system.class.value.uuid}}">{{document.system.class.value.name}}</span>
|
||||
{{else}}
|
||||
<span data-action="openPack" data-key="daggerheart.classes">{{localize 'TYPES.Item.class'}}</span>
|
||||
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.classes">{{localize 'TYPES.Item.class'}}</span>
|
||||
{{/if}}
|
||||
<span class="dot">•</span>
|
||||
{{#if document.system.class.subclass}}
|
||||
<span data-action="editDoc" data-item-uuid="{{document.system.class.subclass.uuid}}">{{document.system.class.subclass.name}}</span>
|
||||
{{else}}
|
||||
<span data-action="openPack" data-key="daggerheart.subclass">{{localize 'TYPES.Item.subclass'}}</span>
|
||||
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.subclasses">{{localize 'TYPES.Item.subclass'}}</span>
|
||||
{{/if}}
|
||||
<span class="dot">•</span>
|
||||
{{#if document.system.community}}
|
||||
<span data-action="editDoc" data-item-uuid="{{document.system.community.uuid}}">{{document.system.community.name}}</span>
|
||||
{{else}}
|
||||
<span data-action="openPack" data-key="daggerheart.community">{{localize 'TYPES.Item.community'}}</span>
|
||||
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.communities">{{localize 'TYPES.Item.community'}}</span>
|
||||
{{/if}}
|
||||
<span class="dot">•</span>
|
||||
{{#if document.system.ancestry}}
|
||||
<span data-action="editDoc" data-item-uuid="{{document.system.ancestry.uuid}}">{{document.system.ancestry.name}}</span>
|
||||
{{else}}
|
||||
<span data-action="openPack" data-key="daggerheart.ancestry">{{localize 'TYPES.Item.ancestry'}}</span>
|
||||
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.ancestries">{{localize 'TYPES.Item.ancestry'}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
{{#if document.system.multiclass.subclass}}
|
||||
<span data-action="editDoc" data-item-uuid="{{document.system.multiclass.subclass.uuid}}">{{document.system.multiclass.subclass.name}}</span>
|
||||
{{else}}
|
||||
<span data-action="openPack" data-key="daggerheart.subclass">{{localize 'TYPES.Item.subclass'}}</span>
|
||||
<span class="missing-header-feature" data-action="openPack" data-key="daggerheart.subclasses">{{localize 'TYPES.Item.subclass'}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
@ -85,12 +85,23 @@
|
|||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
<div class="threshold-section">
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.minor"}}</h4>
|
||||
<h4 class="threshold-value">{{document.system.damageThresholds.major}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.major"}}</h4>
|
||||
<h4 class="threshold-value">{{document.system.damageThresholds.severe}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.severe"}}</h4>
|
||||
{{#if document.system.class.value}}
|
||||
<div class="domains-section">
|
||||
{{#each document.system.class.value.system.domains as |domain|}}
|
||||
<div class="domain">
|
||||
<span class="label">{{localize (concat 'DAGGERHEART.GENERAL.Domain.' domain '.label')}}</span>
|
||||
<img src="{{concat 'systems/daggerheart/assets/icons/domains/' domain '.svg'}}" alt="">
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="downtime-section">
|
||||
<button type="button" data-action="useDowntime" data-type="shortRest" data-tooltip="{{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}}">
|
||||
<i class="fa-solid fa-utensils"></i>
|
||||
</button>
|
||||
<button type="button" data-action="useDowntime" data-type="longRest" data-tooltip="{{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}}">
|
||||
<i class="fa-solid fa-bed"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -117,13 +128,6 @@
|
|||
</div>
|
||||
|
||||
{{#> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
|
||||
<div class="character-downtime-container">
|
||||
<button type="button" data-action="useDowntime" data-type="shortRest" data-tooltip="{{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}}">
|
||||
<i class="fa-solid fa-chair"></i>
|
||||
</button>
|
||||
<button type="button" data-action="useDowntime" data-type="longRest" data-tooltip="{{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}}">
|
||||
<i class="fa-solid fa-bed"></i>
|
||||
</button>
|
||||
</div>
|
||||
<button data-action="openSettings" data-tooltip-text="{{localize "DAGGERHEART.UI.Tooltip.openSheetSettings"}}"><i class="fa-solid fa-wrench"></i></button>
|
||||
{{/'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
|
||||
</header>
|
||||
|
|
@ -1,6 +1,17 @@
|
|||
<aside class="character-sidebar-sheet">
|
||||
<div class="portrait {{#if isDeath}}death-roll{{/if}}">
|
||||
<img src="{{document.img}}" alt="{{document.name}}" data-action='editImage' data-edit="img">
|
||||
{{#if document.system.class.subclass.system.spellcastingTrait}}
|
||||
<div class="icons-list">
|
||||
<span class="spellcast-icon {{#if isDeath}}no-label{{/if}}">
|
||||
<span class="spellcast-label">
|
||||
{{localize "DAGGERHEART.ITEMS.Subclass.spellcastingTrait"}}:
|
||||
{{localize (concat 'DAGGERHEART.CONFIG.Traits.' document.system.class.subclass.system.spellcastingTrait '.short')}}
|
||||
</span>
|
||||
<i class="fa-solid fa-wand-sparkles"></i>
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
<a class="death-roll-btn" data-tooltip="DAGGERHEART.UI.Tooltip.makeDeathMove" {{#if
|
||||
isDeath}}data-action="makeDeathMove" {{/if}}><i class="fas fa-skull death-save"></i></a>
|
||||
</div>
|
||||
|
|
@ -87,6 +98,13 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="threshold-section">
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.minor"}}</h4>
|
||||
<h4 class="threshold-value">{{document.system.damageThresholds.major}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.major"}}</h4>
|
||||
<h4 class="threshold-value">{{document.system.damageThresholds.severe}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.severe"}}</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="shortcut-items-section">
|
||||
|
|
@ -142,18 +160,17 @@
|
|||
</div>
|
||||
<div class="experience-list">
|
||||
{{#each document.system.experiences as |experience id|}}
|
||||
<div class="experience-row">
|
||||
<div class="experience-value">
|
||||
+{{experience.value}}
|
||||
<div class="experience-row" data-tooltip-text="{{experience.description}}">
|
||||
<div class="experience-value">
|
||||
+{{experience.value}}
|
||||
</div>
|
||||
<span>{{experience.name}}</span>
|
||||
<div class="controls">
|
||||
<a data-action="sendExpToChat" data-type="experience" data-id="{{id}}">
|
||||
<i class="fa-regular fa-message"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<input name="system.experiences.{{id}}.name" data-experience={{id}}
|
||||
value="{{experience.name}}" type="text" />
|
||||
<div class="controls">
|
||||
<a data-action="sendExpToChat" data-type="experience" data-id="{{id}}">
|
||||
<i class="fa-regular fa-message"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
</div>
|
||||
<div class="companion-navigation">
|
||||
{{> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
|
||||
<button type="button" data-action="openSettings">
|
||||
<button type="button" data-action="openSettings" data-tooltip-text="{{localize "DAGGERHEART.UI.Tooltip.openSheetSettings"}}">
|
||||
<i class="fa-solid fa-wrench"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -23,38 +23,40 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{localize "TYPES.Item.subclass"}}</legend>
|
||||
<div class="feature-list">
|
||||
{{#each source.system.subclasses as |subclass index|}}
|
||||
<li class='feature-item'>
|
||||
<div class='feature-line'>
|
||||
<img class='image' src='{{subclass.img}}' />
|
||||
<h4>
|
||||
{{subclass.name}}
|
||||
</h4>
|
||||
<div class='controls'>
|
||||
<a
|
||||
class='effect-control'
|
||||
data-action='editDoc'
|
||||
data-item-uuid={{subclass.uuid}}
|
||||
data-tooltip='{{localize "DAGGERHEART.UI.Tooltip.openItemWorld"}}'
|
||||
>
|
||||
<i class="fa-solid fa-globe"></i>
|
||||
</a>
|
||||
<a
|
||||
class='effect-control'
|
||||
data-action='removeItemFromCollection'
|
||||
data-target="subclasses"
|
||||
data-uuid={{subclass.uuid}}
|
||||
data-tooltip='{{localize "CONTROLS.CommonDelete"}}'
|
||||
>
|
||||
<i class='fas fa-trash'></i>
|
||||
</a>
|
||||
{{#unless (eq document.parent.type 'character')}}
|
||||
<fieldset>
|
||||
<legend>{{localize "TYPES.Item.subclass"}}</legend>
|
||||
<div class="feature-list">
|
||||
{{#each source.system.subclasses as |subclass index|}}
|
||||
<li class='feature-item'>
|
||||
<div class='feature-line'>
|
||||
<img class='image' src='{{subclass.img}}' />
|
||||
<h4>
|
||||
{{subclass.name}}
|
||||
</h4>
|
||||
<div class='controls'>
|
||||
<a
|
||||
class='effect-control'
|
||||
data-action='editDoc'
|
||||
data-item-uuid={{subclass.uuid}}
|
||||
data-tooltip='{{localize "DAGGERHEART.UI.Tooltip.openItemWorld"}}'
|
||||
>
|
||||
<i class="fa-solid fa-globe"></i>
|
||||
</a>
|
||||
<a
|
||||
class='effect-control'
|
||||
data-action='removeItemFromCollection'
|
||||
data-target="subclasses"
|
||||
data-uuid={{subclass.uuid}}
|
||||
data-tooltip='{{localize "CONTROLS.CommonDelete"}}'
|
||||
>
|
||||
<i class='fas fa-trash'></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
</fieldset>
|
||||
</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
</fieldset>
|
||||
{{/unless}}
|
||||
</div>
|
||||
|
|
@ -31,10 +31,10 @@
|
|||
<span>{{localize "DAGGERHEART.CONFIG.Traits.knowledge.name"}}</span>
|
||||
<input type="text" name="system.characterGuide.suggestedTraits.knowledge" value="{{source.system.characterGuide.suggestedTraits.knowledge}}" />
|
||||
</fieldset>
|
||||
|
||||
|
||||
<fieldset class="one-column">
|
||||
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedEquipment"}}</legend>
|
||||
<fieldset class="one-column drop-section primary-weapon-section">
|
||||
<fieldset class="one-column drop-section primary-weapon-section {{#if (eq document.parent.type 'character')}}inactive{{/if}}">
|
||||
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedPrimaryWeaponTitle"}}</legend>
|
||||
<div class="drop-section-body list-items">
|
||||
{{#if document.system.characterGuide.suggestedPrimaryWeapon}}
|
||||
|
|
@ -42,14 +42,14 @@
|
|||
<img class="image" src="{{document.system.characterGuide.suggestedPrimaryWeapon.img}}" />
|
||||
<span>{{document.system.characterGuide.suggestedPrimaryWeapon.name}}</span>
|
||||
<div class="controls">
|
||||
<a data-action="removeSuggestedItem" data-target="suggestedPrimaryWeapon"><i class="fa-solid fa-trash icon-button"></i></a>
|
||||
{{#unless (eq document.parent.type 'character')}}<a data-action="removeSuggestedItem" data-target="suggestedPrimaryWeapon"><i class="fa-solid fa-trash icon-button"></i></a>{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="one-column drop-section secondary-weapon-section">
|
||||
<fieldset class="one-column drop-section secondary-weapon-section {{#if (eq document.parent.type 'character')}}inactive{{/if}}">
|
||||
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedSecondaryWeaponTitle"}}</legend>
|
||||
<div class="drop-section-body list-items">
|
||||
{{#if document.system.characterGuide.suggestedSecondaryWeapon}}
|
||||
|
|
@ -57,14 +57,14 @@
|
|||
<img class="image" src="{{document.system.characterGuide.suggestedSecondaryWeapon.img}}" />
|
||||
<span>{{document.system.characterGuide.suggestedSecondaryWeapon.name}}</span>
|
||||
<div class="controls">
|
||||
<a data-action="removeSuggestedItem" data-target="suggestedSecondaryWeapon"><i class="fa-solid fa-trash icon-button"></i></a>
|
||||
{{#unless (eq document.parent.type 'character')}}<a data-action="removeSuggestedItem" data-target="suggestedSecondaryWeapon"><i class="fa-solid fa-trash icon-button"></i></a>{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="one-column drop-section armor-section">
|
||||
<fieldset class="one-column drop-section armor-section {{#if (eq document.parent.type 'character')}}inactive{{/if}}">
|
||||
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.suggestedArmorTitle"}}</legend>
|
||||
<div class="drop-section-body list-items">
|
||||
{{#if document.system.characterGuide.suggestedArmor}}
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
<img class="image" src="{{document.system.characterGuide.suggestedArmor.img}}" />
|
||||
<span>{{document.system.characterGuide.suggestedArmor.name}}</span>
|
||||
<div class="controls">
|
||||
<a data-action="removeSuggestedItem" data-target="suggestedArmor"><i class="fa-solid fa-trash icon-button"></i></a>
|
||||
{{#unless (eq document.parent.type 'character')}}<a data-action="removeSuggestedItem" data-target="suggestedArmor"><i class="fa-solid fa-trash icon-button"></i></a>{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
<fieldset class="one-column">
|
||||
<legend>{{localize "DAGGERHEART.GENERAL.inventory"}}</legend>
|
||||
<fieldset class="one-column drop-section take-section">
|
||||
<fieldset class="one-column drop-section take-section {{#if (eq document.parent.type 'character')}}inactive{{/if}}">
|
||||
<legend>{{localize "DAGGERHEART.GENERAL.take"}}</legend>
|
||||
<div class="drop-section-body list-items">
|
||||
{{#each source.system.inventory.take}}
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
<img class="image" src="{{this.img}}" />
|
||||
<span>{{this.name}}</span>
|
||||
<div class="controls">
|
||||
<a data-action="removeItemFromCollection" data-target="inventory.take" data-uuid="{{this.uuid}}"><i class="fa-solid fa-trash icon-button"></i></a>
|
||||
{{#unless (eq document.parent.type 'character')}}<a data-action="removeItemFromCollection" data-target="inventory.take" data-uuid="{{this.uuid}}"><i class="fa-solid fa-trash icon-button"></i></a>{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
@ -99,7 +99,7 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="one-column drop-section choice-a-section">
|
||||
<fieldset class="one-column drop-section choice-a-section {{#if (eq document.parent.type 'character')}}inactive{{/if}}">
|
||||
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.inventory.thenChoose"}}</legend>
|
||||
<div class="drop-section-body list-items">
|
||||
{{#each source.system.inventory.choiceA}}
|
||||
|
|
@ -108,7 +108,7 @@
|
|||
<img class="image" src="{{this.img}}" />
|
||||
<span>{{this.name}}</span>
|
||||
<div class="controls">
|
||||
<a data-action="removeItemFromCollection" data-target="inventory.choiceA" data-uuid="{{this.uuid}}"><i class="fa-solid fa-trash icon-button"></i></a>
|
||||
{{#unless (eq document.parent.type 'character')}}<a data-action="removeItemFromCollection" data-target="inventory.choiceA" data-uuid="{{this.uuid}}"><i class="fa-solid fa-trash icon-button"></i></a>{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
@ -116,7 +116,7 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="one-column drop-section choice-b-section">
|
||||
<fieldset class="one-column drop-section choice-b-section {{#if (eq document.parent.type 'character')}}inactive{{/if}}">
|
||||
<legend>{{localize "DAGGERHEART.ITEMS.Class.guide.inventory.andEither"}}</legend>
|
||||
<div class="drop-section-body list-items">
|
||||
{{#each source.system.inventory.choiceB}}
|
||||
|
|
@ -125,7 +125,7 @@
|
|||
<img class="image" src="{{this.img}}" />
|
||||
<span>{{this.name}}</span>
|
||||
<div class="controls">
|
||||
<a data-action="removeItemFromCollection" data-target="inventory.choiceB" data-uuid="{{this.uuid}}"><i class="fa-solid fa-trash icon-button"></i></a>
|
||||
{{#unless (eq document.parent.type 'character')}}<a data-action="removeItemFromCollection" data-target="inventory.choiceB" data-uuid="{{this.uuid}}"><i class="fa-solid fa-trash icon-button"></i></a>{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue