diff --git a/lang/en.json b/lang/en.json index e5f09217..a06fa69d 100755 --- a/lang/en.json +++ b/lang/en.json @@ -233,13 +233,14 @@ }, "APPLICATIONS": { "CharacterCreation": { - "setupTabs": { + "tabs": { "ancestry": "Ancestry", "community": "Community", "class": "Class", "experience": "Experience", "traits": "Traits", - "domainCards": "Domain Cards" + "domainCards": "Domain Cards", + "equipment": "Equipment" }, "ancestryNamePlaceholder": "Your ancestry's name", "buttonTitle": "Character Setup", diff --git a/module/applications/characterCreation/characterCreation.mjs b/module/applications/characterCreation/characterCreation.mjs index 1cadd6d4..693f6c5a 100644 --- a/module/applications/characterCreation/characterCreation.mjs +++ b/module/applications/characterCreation/characterCreation.mjs @@ -13,7 +13,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl this.setup = { traits: this.character.system.traits, - ancestryName: '', + ancestryName: { + primary: '', + secondary: '' + }, mixedAncestry: false, primaryAncestry: this.character.system.ancestry ?? {}, secondaryAncestry: {}, @@ -83,131 +86,70 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl static PARTS = { tabs: { template: 'systems/daggerheart/templates/characterCreation/tabs.hbs' }, - setup: { template: 'systems/daggerheart/templates/characterCreation/tabs/setup.hbs' }, - ancestry: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/ancestry.hbs' }, - community: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/community.hbs' }, - class: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/class.hbs' }, - traits: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/traits.hbs' }, - experience: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/experience.hbs' }, - domainCards: { template: 'systems/daggerheart/templates/characterCreation/setupTabs/domainCards.hbs' }, - equipment: { template: 'systems/daggerheart/templates/characterCreation/tabs/equipment.hbs' }, - // story: { template: 'systems/daggerheart/templates/characterCreation/tabs/story.hbs' }, + ancestry: { template: 'systems/daggerheart/templates/characterCreation/tabs/ancestry.hbs' }, + community: { template: 'systems/daggerheart/templates/characterCreation/tabs/community.hbs' }, + class: { template: 'systems/daggerheart/templates/characterCreation/tabs/class.hbs' }, + traits: { template: 'systems/daggerheart/templates/characterCreation/tabs/traits.hbs' }, + experience: { template: 'systems/daggerheart/templates/characterCreation/tabs/experience.hbs' }, + domainCards: { template: 'systems/daggerheart/templates/characterCreation/tabs/domainCards.hbs' }, + equipment: { template: 'systems/daggerheart/templates/characterCreation/equipment.hbs' }, + // story: { template: 'systems/daggerheart/templates/characterCreation/story.hbs' }, footer: { template: 'systems/daggerheart/templates/characterCreation/footer.hbs' } }; static TABS = { - setup: { - active: true, - cssClass: '', - group: 'primary', - id: 'setup', - label: 'DAGGERHEART.GENERAL.Tabs.setup' - }, - equipment: { - active: false, - cssClass: '', - group: 'primary', - id: 'equipment', - label: 'DAGGERHEART.GENERAL.Tabs.equipment', - optional: true - } - // story: { - // active: false, - // cssClass: '', - // group: 'primary', - // id: 'story', - // label: 'DAGGERHEART.GENERAL.Tabs.story', - // optional: true - // } - }; - - static SETUPTABS = { ancestry: { active: true, cssClass: '', group: 'setup', id: 'ancestry', - label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.ancestry' + label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.ancestry' }, community: { active: false, cssClass: '', group: 'setup', id: 'community', - label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.community' + label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.community' }, class: { active: false, cssClass: '', group: 'setup', id: 'class', - label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.class' + label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.class' }, traits: { active: false, cssClass: '', group: 'setup', id: 'traits', - label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.traits' + label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.traits' }, experience: { active: false, cssClass: '', group: 'setup', id: 'experience', - label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.experience' + label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.experience' }, domainCards: { active: false, cssClass: '', group: 'setup', id: 'domainCards', - label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.setupTabs.domainCards' + label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.domainCards' + }, + equipment: { + active: false, + cssClass: '', + group: 'setup', + id: 'equipment', + label: 'DAGGERHEART.APPLICATIONS.CharacterCreation.tabs.equipment' } }; _getTabs(tabs) { - for (const v of Object.values(tabs)) { - v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active; - v.cssClass = v.active ? 'active' : ''; - - switch (v.id) { - case 'setup': - const ancestryFinished = this.setup.primaryAncestry.uuid; - const communityFinished = this.setup.community.uuid; - const classFinished = this.setup.class.uuid && this.setup.subclass.uuid; - const traitsFinished = Object.values(this.setup.traits).every(x => x.value !== null); - const experiencesFinished = Object.values(this.setup.experiences).every(x => x.name); - const domainCardsFinished = Object.values(this.setup.domainCards).every(x => x.uuid); - v.finished = - ancestryFinished && - communityFinished && - classFinished && - traitsFinished && - experiencesFinished && - domainCardsFinished; - break; - case 'equipment': - const armorFinished = this.equipment.armor?.uuid; - const primaryFinished = this.equipment.primaryWeapon?.uuid; - const secondaryFinished = - this.equipment.secondaryWeapon?.uuid || - (primaryFinished && this.equipment.primaryWeapon.system.burden == burden.twoHanded.value); - const choiceAFinished = this.equipment.inventory.choiceA?.uuid; - const choiceBFinished = this.equipment.inventory.choiceB?.uuid; - - v.finished = - armorFinished && primaryFinished && secondaryFinished && choiceAFinished && choiceBFinished; - } - } - - tabs.equipment.cssClass = tabs.setup.finished ? tabs.equipment.cssClass : 'disabled'; - // tabs.story.cssClass = tabs.setup.finished ? tabs.story.cssClass : 'disabled'; - - return tabs; - } - - _getSetupTabs(tabs) { for (const v of Object.values(tabs)) { v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id @@ -232,37 +174,15 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl case 'domainCards': v.disabled = this.setup.visibility < 6; break; + case 'equipment': + v.disabled = this.setup.visibility < 7; + break; } } return tabs; } - changeTab(tab, group, options) { - super.changeTab(tab, group, options); - - if (group === 'primary') { - for (var listTab of Object.keys(this.constructor.TABS)) { - const marker = options.navElement.querySelector(`a[data-action="tab"].${listTab} .finish-marker`); - if (listTab === tab) { - marker.classList.add('active'); - } else { - marker.classList.remove('active'); - } - } - - if (tab === 'equipment') { - this.tabGroups.setup = null; - this.element.querySelector('section[data-group="setup"].active')?.classList?.remove?.('active'); - } else { - this.tabGroups.setup = 'domainCards'; - this.element - .querySelector('section[data-group="setup"][data-tab="domainCards"]') - ?.classList?.add?.('active'); - } - } - } - _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); @@ -274,14 +194,71 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl }); } - async _preFirstRender(_context, _options) { - this.tabGroups.primary = 'setup'; - this.tabGroups.setup = 'ancestry'; - } - async _prepareContext(_options) { + this.tabGroups.setup = this.tabGroups.setup ?? 'ancestry'; const context = await super._prepareContext(_options); + context.tabs = this._getTabs(this.constructor.TABS); + const availableTraitModifiers = game.settings + .get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew) + .traitArray.map(trait => ({ key: trait, name: trait })); + for (let trait of Object.values(this.setup.traits).filter(x => x.value !== null)) { + const index = availableTraitModifiers.findIndex(x => x.key === trait.value); + if (index !== -1) { + availableTraitModifiers.splice(index, 1); + } + } + + context.suggestedTraits = this.setup.class.system + ? Object.keys(this.setup.class.system.characterGuide.suggestedTraits).map(traitKey => { + const trait = this.setup.class.system.characterGuide.suggestedTraits[traitKey]; + return `${game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${traitKey}.short`)} ${trait > 0 ? `+${trait}` : trait}`; + }) + : []; + context.traits = { + values: Object.keys(this.setup.traits).map(traitKey => { + const trait = this.setup.traits[traitKey]; + const options = [...availableTraitModifiers]; + if (trait.value !== null && !options.some(x => x.key === trait.value)) + options.push({ key: trait.value, name: trait.value }); + + return { + ...trait, + key: traitKey, + name: game.i18n.localize(abilities[traitKey].label), + options: options + }; + }) + }; + context.traits.nrTotal = Object.keys(context.traits.values).length; + context.traits.nrSelected = this.getNrSelectedTrait(); + + context.experience = { + values: this.setup.experiences, + nrTotal: Object.keys(this.setup.experiences).length, + nrSelected: Object.values(this.setup.experiences).reduce((acc, exp) => acc + (exp.name ? 1 : 0), 0) + }; + + context.mixedAncestry = Number(this.setup.mixedAncestry); + + const { primary, secondary, overwrite } = this.setup.ancestryName; + context.ancestryName = overwrite ?? (primary && secondary ? `${primary}/${secondary}` : primary); + context.primaryAncestry = { ...this.setup.primaryAncestry, compendium: 'ancestries' }; + context.secondaryAncestry = { ...this.setup.secondaryAncestry, compendium: 'ancestries' }; + context.community = { ...this.setup.community, compendium: 'communities' }; + context.class = { ...this.setup.class, compendium: 'classes' }; + context.subclass = { ...this.setup.subclass, compendium: 'subclasses' }; + + const allDomainData = CONFIG.DH.DOMAIN.allDomains(); + context.classDomains = context.class.uuid + ? context.class.system.domains.map(key => game.i18n.localize(allDomainData[key].label)) + : []; + context.domainCards = Object.keys(this.setup.domainCards).reduce((acc, x) => { + acc[x] = { ...this.setup.domainCards[x], compendium: 'domains' }; + return acc; + }, {}); + + context.visibility = this.setup.visibility; return context; } @@ -289,7 +266,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl async _preparePartContext(partId, context) { switch (partId) { case 'footer': - context.isLastTab = this.tabGroups.setup === 'domainCards' || this.tabGroups.primary !== 'setup'; + context.isLastTab = this.tabGroups.setup === 'equipment'; switch (this.tabGroups.setup) { case null: case 'ancestry': @@ -307,69 +284,11 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl case 'experience': context.nextDisabled = this.setup.visibility === 5; break; + case 'domainCards': + context.nextDisabled = this.setup.visibility === 6; + break; } - break; - case 'setup': - context.setupTabs = this._getSetupTabs(this.constructor.SETUPTABS); - const availableTraitModifiers = game.settings - .get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew) - .traitArray.map(trait => ({ key: trait, name: trait })); - for (let trait of Object.values(this.setup.traits).filter(x => x.value !== null)) { - const index = availableTraitModifiers.findIndex(x => x.key === trait.value); - if (index !== -1) { - availableTraitModifiers.splice(index, 1); - } - } - - context.suggestedTraits = this.setup.class.system - ? Object.keys(this.setup.class.system.characterGuide.suggestedTraits).map(traitKey => { - const trait = this.setup.class.system.characterGuide.suggestedTraits[traitKey]; - return `${game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${traitKey}.short`)} ${trait > 0 ? `+${trait}` : trait}`; - }) - : []; - context.traits = { - values: Object.keys(this.setup.traits).map(traitKey => { - const trait = this.setup.traits[traitKey]; - const options = [...availableTraitModifiers]; - if (trait.value !== null && !options.some(x => x.key === trait.value)) - options.push({ key: trait.value, name: trait.value }); - - return { - ...trait, - key: traitKey, - name: game.i18n.localize(abilities[traitKey].label), - options: options - }; - }) - }; - context.traits.nrTotal = Object.keys(context.traits.values).length; - context.traits.nrSelected = this.getNrSelectedTrait(); - - context.experience = { - values: this.setup.experiences, - nrTotal: Object.keys(this.setup.experiences).length, - nrSelected: Object.values(this.setup.experiences).reduce((acc, exp) => acc + (exp.name ? 1 : 0), 0) - }; - - context.mixedAncestry = Number(this.setup.mixedAncestry); - context.ancestryName = this.setup.ancestryName; - context.primaryAncestry = { ...this.setup.primaryAncestry, compendium: 'ancestries' }; - context.secondaryAncestry = { ...this.setup.secondaryAncestry, compendium: 'ancestries' }; - context.community = { ...this.setup.community, compendium: 'communities' }; - context.class = { ...this.setup.class, compendium: 'classes' }; - context.subclass = { ...this.setup.subclass, compendium: 'subclasses' }; - - const allDomainData = CONFIG.DH.DOMAIN.allDomains(); - context.classDomains = context.class.uuid - ? context.class.system.domains.map(key => game.i18n.localize(allDomainData[key].label)) - : []; - context.domainCards = Object.keys(this.setup.domainCards).reduce((acc, x) => { - acc[x] = { ...this.setup.domainCards[x], compendium: 'domains' }; - return acc; - }, {}); - - context.visibility = this.setup.visibility; break; case 'equipment': const suggestions = await this.getEquipmentSuggestions( @@ -438,8 +357,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl getUpdateVisibility() { switch (this.setup.visibility) { + case 7: + return 7; case 6: - return 6; + return Object.values(this.setup.domainCards).every(x => x.uuid) ? 7 : 6; case 5: return Object.values(this.setup.experiences).every(x => x.name) ? 6 : 5; case 4: @@ -505,7 +426,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl const presets = { compendium: 'daggerheart', - folder: equipment.includes(type) ? "equipments" : type, + folder: equipment.includes(type) ? 'equipments' : type, render: { noFolder: true } @@ -565,6 +486,9 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl case 6: this.tabGroups.setup = 'domainCards'; break; + case 7: + this.tabGroups.setup = 'equipment'; + break; } this.render(); @@ -576,9 +500,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl ? this.setup.secondaryAncestry.system.secondaryFeature : this.setup.primaryAncestry.system.secondaryFeature; + const { primary, secondary, overwrite } = this.setup.ancestryName; const ancestry = { ...this.setup.primaryAncestry, - name: this.setup.ancestryName ?? this.setup.primaryAncestry.name, + name: overwrite ?? (primary && secondary ? `${primary}/${secondary}` : primary), system: { ...this.setup.primaryAncestry.system, features: [ @@ -650,13 +575,14 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const item = await foundry.utils.fromUuid(data.uuid); if (item.type === 'ancestry' && event.target.closest('.primary-ancestry-card')) { - this.setup.ancestryName = item.name; + this.setup.ancestryName.primary = item.name; this.setup.primaryAncestry = { ...item, effects: Array.from(item.effects).map(x => x.toObject()), uuid: item.uuid }; } else if (item.type === 'ancestry' && event.target.closest('.secondary-ancestry-card')) { + this.setup.ancestryName.secondary = item.name; this.setup.secondaryAncestry = { ...item, effects: Array.from(item.effects).map(x => x.toObject()), diff --git a/styles/less/dialog/character-creation/tab-navigation.less b/styles/less/dialog/character-creation/tab-navigation.less index dbf285f6..709e0adc 100644 --- a/styles/less/dialog/character-creation/tab-navigation.less +++ b/styles/less/dialog/character-creation/tab-navigation.less @@ -3,59 +3,16 @@ .daggerheart.dh-style.dialog.character-creation { .tab-navigation { nav { - flex: 1; + border-bottom: 0; + border-top: 0; a { - flex: 1; - text-align: center; - display: flex; - justify-content: center; - position: relative; + font-family: @font-body; + color: light-dark(@dark-blue, @golden); - &.disabled { + &[disabled] { opacity: 0.4; } - - .nav-section-text { - position: relative; - display: flex; - align-items: center; - } - - .finish-marker { - position: absolute; - align-self: center; - top: -8px; - padding: 4px; - border: 1px solid; - border-radius: 50%; - height: 16px; - width: 16px; - font-size: 12px; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-cool-4); - content: ''; - - &.active { - background-color: var(--color-warm-2); - } - } - - .descriptor { - position: absolute; - bottom: -8px; - font-size: 12px; - border-radius: 8px; - width: 56px; - text-align: center; - line-height: 1; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url(../assets/parchments/dh-parchment-light.png); - } } } } diff --git a/templates/characterCreation/tabs/equipment.hbs b/templates/characterCreation/equipment.hbs similarity index 100% rename from templates/characterCreation/tabs/equipment.hbs rename to templates/characterCreation/equipment.hbs diff --git a/templates/characterCreation/footer.hbs b/templates/characterCreation/footer.hbs index 47321c7a..95b86cfb 100644 --- a/templates/characterCreation/footer.hbs +++ b/templates/characterCreation/footer.hbs @@ -1,7 +1,7 @@