mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Added DomainCard selection
This commit is contained in:
parent
07c533c82c
commit
66defbffce
18 changed files with 823 additions and 132 deletions
|
|
@ -285,6 +285,7 @@ const preloadHandlebarsTemplates = async function () {
|
|||
'systems/daggerheart/templates/sheets/pc/parts/advancementCard.hbs',
|
||||
'systems/daggerheart/templates/views/parts/level.hbs',
|
||||
'systems/daggerheart/templates/components/slider.hbs',
|
||||
'systems/daggerheart/templates/components/card-preview.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs'
|
||||
]);
|
||||
};
|
||||
|
|
|
|||
30
lang/en.json
30
lang/en.json
|
|
@ -142,6 +142,12 @@
|
|||
"Or": "Or",
|
||||
"Description": "Description",
|
||||
"Features": "Features",
|
||||
"proficiency": "Proficiency",
|
||||
"unarmored": "Unarmored",
|
||||
"Experience": {
|
||||
"Single": "Experience",
|
||||
"plural": "Experiences"
|
||||
},
|
||||
"RefreshType": {
|
||||
"Session": "Session",
|
||||
"Shortrest": "Short Rest",
|
||||
|
|
@ -744,14 +750,38 @@
|
|||
"TakeDowntime": "Take Downtime"
|
||||
},
|
||||
"LevelUp": {
|
||||
"Title": "{actor} Level Up",
|
||||
"Tabs": {
|
||||
"advancement": "Level Advancement",
|
||||
"selections": "Advancement Choices",
|
||||
"summary": "Summary"
|
||||
},
|
||||
"AdvanceLevel": "Continue To Level {level}",
|
||||
"TakeLevelUp": "Finish Level Up",
|
||||
"Selections": {
|
||||
"emptyDomainCardHint": "Domain Card Level {level} or below"
|
||||
},
|
||||
"summary": {
|
||||
"levelAchievements": "Level Achievements",
|
||||
"levelAdvancements": "Level Advancements",
|
||||
"proficiencyIncrease": "Proficiency Increased: {proficiency}",
|
||||
"statisticIncreases": "Statistic Increases",
|
||||
"damageThresholdMajorIncrease": "Major: {threshold}",
|
||||
"damageThresholdSevereIncrease": "Severe: {threshold}",
|
||||
"newExperiences": "New Experiences",
|
||||
"experiencePlaceholder": "A new experience..",
|
||||
"domainCards": "Domain Cards"
|
||||
},
|
||||
"notifications": {
|
||||
"info": {
|
||||
"tierAdvancementInfo": "Advancements from a higher tier can always be used to select advancements in a lower tier.",
|
||||
"remainingAdvancementInfo": "Remaining Choices: {choices}",
|
||||
"insufficentAdvancements": "You don't have enough advancements left.",
|
||||
"insufficientTierAdvancements": "You have no available advancements for this tier."
|
||||
},
|
||||
"error": {
|
||||
"domainCardWrongDomain": "You don't have access to that Domain",
|
||||
"domainCardToHighLevel": "The Domain Card is too high level to be selected"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,13 +11,16 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
|
||||
const playerLevelupData = actor.system.levelData;
|
||||
this.levelup = new DhLevelup(DhLevelup.initializeData(this.levelTiers, playerLevelupData, actor.system.level));
|
||||
|
||||
this._dragDrop = this._createDragDropHandlers();
|
||||
}
|
||||
|
||||
get title() {
|
||||
return `${this.actor.name} - Level Up`;
|
||||
return game.i18n.format('DAGGERHEART.Application.LevelUp.Title', { actor: this.actor.name });
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'levelup'],
|
||||
position: { width: 1000, height: 'auto' },
|
||||
window: {
|
||||
|
|
@ -25,31 +28,188 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
},
|
||||
actions: {
|
||||
save: this.save
|
||||
}
|
||||
},
|
||||
form: {
|
||||
handler: this.updateForm,
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false
|
||||
},
|
||||
dragDrop: [{ dragSelector: null, dropSelector: '.levelup-card-selection .card-preview-container' }]
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
form: {
|
||||
id: 'levelup',
|
||||
template: 'systems/daggerheart/templates/views/levelup.hbs'
|
||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||
advancements: { template: 'systems/daggerheart/templates/views/levelup/tabs/advancements.hbs' },
|
||||
selections: { template: 'systems/daggerheart/templates/views/levelup/tabs/selections.hbs' },
|
||||
summary: { template: 'systems/daggerheart/templates/views/levelup/tabs/summary.hbs' }
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
advancements: {
|
||||
active: true,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'advancements',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.Application.LevelUp.Tabs.advancement'
|
||||
},
|
||||
selections: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'selections',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.Application.LevelUp.Tabs.selections'
|
||||
},
|
||||
summary: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'summary',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.Application.LevelUp.Tabs.summary'
|
||||
}
|
||||
};
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.levelup = this.levelup;
|
||||
context.tabs = this._getTabs(this.constructor.TABS);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
async _preparePartContext(partId, context) {
|
||||
switch (partId) {
|
||||
case 'selections':
|
||||
context.advancementChoices = this.levelup.selectionData.reduce((acc, data) => {
|
||||
const advancementChoice = {
|
||||
...data,
|
||||
path: `tiers.${data.tier}.levels.${data.level}.optionSelections.${data.optionKey}.${data.checkboxNr}.data`
|
||||
};
|
||||
if (acc[data.type]) acc[data.type].push(advancementChoice);
|
||||
else acc[data.type] = [advancementChoice];
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
context.newExperiences = this.levelup.allInitialAchievements.newExperiences;
|
||||
const allDomainCards = {
|
||||
...context.advancementChoices.domainCard,
|
||||
...this.levelup.domainCards
|
||||
};
|
||||
const allDomainCardValues = Object.values(allDomainCards);
|
||||
|
||||
context.domainCards = [];
|
||||
for (var domainCard of allDomainCardValues) {
|
||||
const uuid = domainCard.data ?? domainCard.uuid;
|
||||
const card = uuid ? await foundry.utils.fromUuid(uuid) : { path: domainCard.path };
|
||||
context.domainCards.push({
|
||||
...(card.toObject?.() ?? card),
|
||||
emptySubtext: game.i18n.format(
|
||||
'DAGGERHEART.Application.LevelUp.Selections.emptyDomainCardHint',
|
||||
{ level: domainCard.level }
|
||||
),
|
||||
limit: domainCard.level
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case 'summary':
|
||||
const actorArmor = this.actor.system.armor;
|
||||
const { current: currentLevel, changed: changedLevel } = this.actor.system.levelData.level;
|
||||
context.levelAchievements = {
|
||||
statisticIncreases: {
|
||||
proficiency: {
|
||||
old: this.actor.system.proficiency,
|
||||
new: this.actor.system.proficiency + this.levelup.allInitialAchievements.proficiency
|
||||
},
|
||||
damageThresholds: {
|
||||
major: {
|
||||
old: this.actor.system.damageThresholds.major,
|
||||
new: this.actor.system.damageThresholds.major + changedLevel - currentLevel
|
||||
},
|
||||
severe: {
|
||||
old: this.actor.system.damageThresholds.severe,
|
||||
new:
|
||||
this.actor.system.damageThresholds.severe +
|
||||
(actorArmor ? changedLevel - currentLevel : (changedLevel - currentLevel) * 2)
|
||||
},
|
||||
unarmored: !actorArmor
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
_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' : '';
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
_createDragDropHandlers() {
|
||||
return this.options.dragDrop.map(d => {
|
||||
d.callbacks = {
|
||||
drop: this._onDrop.bind(this)
|
||||
};
|
||||
return new foundry.applications.ux.DragDrop.implementation(d);
|
||||
});
|
||||
}
|
||||
|
||||
_attachPartListeners(partId, htmlElement, options) {
|
||||
super._attachPartListeners(partId, htmlElement, options);
|
||||
$(htmlElement).find('.selection-checkbox').on('change', this.selectionClick.bind(this));
|
||||
htmlElement
|
||||
.querySelectorAll('.selection-checkbox')
|
||||
.forEach(element => element.addEventListener('change', this.selectionClick.bind(this)));
|
||||
this._dragDrop.forEach(d => d.bind(htmlElement));
|
||||
}
|
||||
|
||||
static async updateForm(event, _, formData) {
|
||||
const { levelup } = foundry.utils.expandObject(formData.object);
|
||||
await this.levelup.updateSource(levelup);
|
||||
this.render();
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
const data = foundry.applications.ux.TextEditor.getDragEventData(event);
|
||||
const item = await fromUuid(data.uuid);
|
||||
if (event.currentTarget.parentElement?.classList?.contains('domain-cards')) {
|
||||
if (item.type === 'domainCard') {
|
||||
if (!this.actor.system.class.system.domains.includes(item.system.domain)) {
|
||||
// Also needs to check for multiclass adding a new domain
|
||||
ui.notifications.error(
|
||||
game.i18n.localize('DAGGERHEART.Application.LevelUp.notifications.error.domainCardWrongDomain')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.system.level > Number(event.currentTarget.dataset.limit)) {
|
||||
ui.notifications.error(
|
||||
game.i18n.localize('DAGGERHEART.Application.LevelUp.notifications.error.domainCardToHighLevel')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const achievementCard = event.currentTarget.dataset.path.startsWith('domainCards');
|
||||
await this.levelup.updateSource({ [event.currentTarget.dataset.path]: item.uuid });
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async selectionClick(event) {
|
||||
event.stopPropagation();
|
||||
const button = event.currentTarget;
|
||||
|
||||
// const advancementSelections = this.getAdvancementSelectionUpdates(button);
|
||||
if (!button.checked) {
|
||||
await this.levelup.updateSource({
|
||||
[`tiers.${button.dataset.tier}.levels.${button.dataset.level}.optionSelections.${button.dataset.option}.-=${button.dataset.checkboxNr}`]:
|
||||
|
|
@ -101,12 +261,7 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
}
|
||||
|
||||
static async save() {
|
||||
await this.actor.update({
|
||||
'system.levelData': {
|
||||
'level.current': this.actor.system.levelData.level.changed,
|
||||
'selections': this.levelup.playerData
|
||||
}
|
||||
});
|
||||
await this.actor.levelUp(this.levelup.selectionData);
|
||||
|
||||
this.close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,9 +182,9 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
htmlElement
|
||||
.querySelectorAll('.experience-value')
|
||||
.forEach(element => element.addEventListener('change', this.experienceValueChange.bind(this)));
|
||||
htmlElement
|
||||
.querySelectorAll('[data-item]')
|
||||
.forEach(element => element.addEventListener.on('change', this.itemUpdate.bind(this)));
|
||||
// htmlElement
|
||||
// .querySelectorAll('[data-item]')
|
||||
// .forEach(element => element.addEventListener.on('change', this.itemUpdate.bind(this)));
|
||||
htmlElement.querySelector('.level-value').addEventListener('change', this.onLevelChange.bind(this));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,19 +61,31 @@ class DhLevelOption extends foundry.abstract.DataModel {
|
|||
export const LevelOptionType = {
|
||||
trait: {
|
||||
id: 'trait',
|
||||
label: 'Character Trait'
|
||||
label: 'Character Trait',
|
||||
dataPath: ''
|
||||
},
|
||||
hitPoint: {
|
||||
id: 'hitPoint',
|
||||
label: 'Hit Points'
|
||||
label: 'Hit Points',
|
||||
dataPath: 'resources.hitPoints',
|
||||
dataPathData: {
|
||||
property: 'max',
|
||||
dependencies: ['value']
|
||||
}
|
||||
},
|
||||
stress: {
|
||||
id: 'stress',
|
||||
label: 'Stress'
|
||||
label: 'Stress',
|
||||
dataPath: 'resources.stress',
|
||||
dataPathData: {
|
||||
property: 'max',
|
||||
dependencies: ['value']
|
||||
}
|
||||
},
|
||||
evasion: {
|
||||
id: 'evasion',
|
||||
label: 'Evasion'
|
||||
label: 'Evasion',
|
||||
dataPath: 'evasion'
|
||||
},
|
||||
proficiency: {
|
||||
id: 'proficiency',
|
||||
|
|
@ -108,8 +120,8 @@ export const defaultLevelTiers = {
|
|||
},
|
||||
initialAchievements: {
|
||||
experience: {
|
||||
nr: 2,
|
||||
modifier: 1
|
||||
nr: 1,
|
||||
modifier: 2
|
||||
},
|
||||
proficiency: 1
|
||||
},
|
||||
|
|
@ -171,8 +183,8 @@ export const defaultLevelTiers = {
|
|||
},
|
||||
initialAchievements: {
|
||||
experience: {
|
||||
nr: 2,
|
||||
modifier: 1
|
||||
nr: 1,
|
||||
modifier: 2
|
||||
},
|
||||
proficiency: 1
|
||||
},
|
||||
|
|
@ -252,8 +264,8 @@ export const defaultLevelTiers = {
|
|||
},
|
||||
initialAchievements: {
|
||||
experience: {
|
||||
nr: 2,
|
||||
modifier: 1
|
||||
nr: 1,
|
||||
modifier: 2
|
||||
},
|
||||
proficiency: 1
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,17 +7,63 @@ export class DhLevelup extends foundry.abstract.DataModel {
|
|||
const tierKeys = Object.keys(levelTierData.tiers);
|
||||
const maxLevel = levelTierData.tiers[tierKeys[tierKeys.length - 1]].levels.end;
|
||||
|
||||
return {
|
||||
tiers: tierKeys.reduce((acc, key) => {
|
||||
acc[key] = DhLevelupTier.initializeData(
|
||||
levelTierData.tiers[key],
|
||||
maxLevel,
|
||||
pcLevelData.selections.filter(x => x.tier === Number(key)),
|
||||
pcLevelData.level.changed
|
||||
);
|
||||
const totalLevelProgression = [];
|
||||
for (var level = pcLevelData.level.current + 1; level <= pcLevelData.level.changed; level++) {
|
||||
totalLevelProgression.push(level);
|
||||
}
|
||||
|
||||
const tiers = tierKeys.reduce((acc, key) => {
|
||||
acc[key] = DhLevelupTier.initializeData(
|
||||
levelTierData.tiers[key],
|
||||
maxLevel,
|
||||
pcLevelData.selections.filter(x => x.tier === Number(key)),
|
||||
pcLevelData.level.changed
|
||||
);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const allInitialAchievements = Object.values(tiers).reduce(
|
||||
(acc, tier) => {
|
||||
const levelThreshold = Math.min(...tier.belongingLevels);
|
||||
|
||||
if (totalLevelProgression.includes(levelThreshold)) {
|
||||
acc.proficiency += tier.initialAchievements.proficiency;
|
||||
[...Array(tier.initialAchievements.experience.nr).keys()].forEach(_ => {
|
||||
acc.newExperiences[foundry.utils.randomID()] = {
|
||||
name: '',
|
||||
modifier: tier.initialAchievements.experience.modifier
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {}),
|
||||
},
|
||||
{ newExperiences: {}, proficiency: 0 }
|
||||
);
|
||||
|
||||
const domainCards = Object.keys(tiers).reduce((acc, tierKey) => {
|
||||
const tier = tiers[tierKey];
|
||||
for (var level of tier.belongingLevels) {
|
||||
if (level <= pcLevelData.level.changed) {
|
||||
for (var domainCardSlot = 1; domainCardSlot <= tier.domainCardByLevel; domainCardSlot++) {
|
||||
const cardId = foundry.utils.randomID();
|
||||
acc[cardId] = {
|
||||
uuid: null,
|
||||
tier: tierKey,
|
||||
level: level,
|
||||
domainCardSlot: domainCardSlot,
|
||||
path: `domainCards.${cardId}.uuid`
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return {
|
||||
tiers: tiers,
|
||||
maxSelections: [...Array(pcLevelData.level.changed).keys()].reduce((acc, index) => {
|
||||
const level = index + 1;
|
||||
const availableChoices = availableChoicesPerLevel[level];
|
||||
|
|
@ -26,7 +72,12 @@ export class DhLevelup extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
return acc;
|
||||
}, 0)
|
||||
}, 0),
|
||||
allInitialAchievements: {
|
||||
newExperiences: allInitialAchievements.newExperiences,
|
||||
proficiency: allInitialAchievements.proficiency
|
||||
},
|
||||
domainCards: domainCards
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -35,7 +86,28 @@ export class DhLevelup extends foundry.abstract.DataModel {
|
|||
|
||||
return {
|
||||
tiers: new fields.TypedObjectField(new fields.EmbeddedDataField(DhLevelupTier)),
|
||||
maxSelections: new fields.NumberField({ required: true, integer: true })
|
||||
maxSelections: new fields.NumberField({ required: true, integer: true }),
|
||||
allInitialAchievements: new fields.SchemaField({
|
||||
newExperiences: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
name: new fields.StringField({ required: true }),
|
||||
modifier: new fields.NumberField({ required: true, integer: true })
|
||||
})
|
||||
),
|
||||
proficiency: new fields.NumberField({ required: true, integer: true })
|
||||
}),
|
||||
domainCards: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
uuid: new fields.StringField({ required: true, nullable: true, initial: null }),
|
||||
tier: new fields.NumberField({ required: true, integer: true }),
|
||||
level: new fields.NumberField({ required: true, integer: true }),
|
||||
domainCardSlot: new fields.NumberField({ required: true, integer: true }),
|
||||
path: new fields.StringField({ required: true })
|
||||
})
|
||||
)
|
||||
// advancementSelections: new fields.SchemaField({
|
||||
// experiences: new fields.SetField(new fields.StringField()),
|
||||
// }),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +129,7 @@ export class DhLevelup extends foundry.abstract.DataModel {
|
|||
);
|
||||
}
|
||||
|
||||
get playerData() {
|
||||
get selectionData() {
|
||||
return Object.keys(this.tiers).flatMap(tierKey => {
|
||||
const tier = this.tiers[tierKey];
|
||||
return Object.keys(tier.levels).flatMap(levelKey => {
|
||||
|
|
@ -66,15 +138,19 @@ export class DhLevelup extends foundry.abstract.DataModel {
|
|||
const selection = level.optionSelections[optionSelectionKey];
|
||||
const optionSelect = tier.options[optionSelectionKey];
|
||||
|
||||
return Object.keys(selection).map(checkboxNr => ({
|
||||
tier: Number(tierKey),
|
||||
level: Number(levelKey),
|
||||
optionKey: optionSelectionKey,
|
||||
type: optionSelect.type,
|
||||
checkboxNr: Number(checkboxNr),
|
||||
value: optionSelect.value,
|
||||
amount: optionSelect.amount
|
||||
}));
|
||||
return Object.keys(selection).map(checkboxNr => {
|
||||
const selectionObj = selection[checkboxNr];
|
||||
return {
|
||||
tier: Number(tierKey),
|
||||
level: Number(levelKey),
|
||||
optionKey: optionSelectionKey,
|
||||
type: optionSelect.type,
|
||||
checkboxNr: Number(checkboxNr),
|
||||
value: optionSelect.value,
|
||||
amount: optionSelect.amount,
|
||||
data: selectionObj.data
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -108,6 +184,8 @@ class DhLevelupTier extends foundry.abstract.DataModel {
|
|||
return acc;
|
||||
}, {}),
|
||||
belongingLevels: belongingLevels,
|
||||
initialAchievements: levelTier.initialAchievements,
|
||||
domainCardByLevel: levelTier.domainCardByLevel,
|
||||
levels: levels
|
||||
};
|
||||
}
|
||||
|
|
@ -121,10 +199,22 @@ class DhLevelupTier extends foundry.abstract.DataModel {
|
|||
active: new fields.BooleanField({ required: true, initial: true }),
|
||||
options: new fields.TypedObjectField(new fields.EmbeddedDataField(DhLevelupTierOption)),
|
||||
belongingLevels: new fields.ArrayField(new fields.NumberField({ required: true, integer: true })),
|
||||
initialAchievements: new fields.SchemaField({
|
||||
experience: new fields.SchemaField({
|
||||
nr: new fields.NumberField({ required: true, initial: 1 }),
|
||||
modifier: new fields.NumberField({ required: true, initial: 2 })
|
||||
}),
|
||||
proficiency: new fields.NumberField({ integer: true, initial: 1 })
|
||||
}),
|
||||
domainCardByLevel: new fields.NumberField({ required: true, integer: true }),
|
||||
levels: new fields.TypedObjectField(new fields.EmbeddedDataField(DhLevelupLevel))
|
||||
};
|
||||
}
|
||||
|
||||
get initialAchievementData() {
|
||||
return this.active ? this.initialAchievements : null;
|
||||
}
|
||||
|
||||
get selections() {
|
||||
const allSelections = Object.keys(this.levels).reduce(
|
||||
(acc, key) => {
|
||||
|
|
@ -223,7 +313,8 @@ class DhLevelupLevel extends foundry.abstract.DataModel {
|
|||
new fields.SchemaField({
|
||||
selected: new fields.BooleanField({ required: true, initial: true }),
|
||||
minCost: new fields.NumberField({ required: true, integer: true }),
|
||||
locked: new fields.BooleanField({ required: true, initial: false })
|
||||
locked: new fields.BooleanField({ required: true, initial: false }),
|
||||
data: new fields.StringField()
|
||||
})
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@ const attributeField = () =>
|
|||
new fields.SchemaField({
|
||||
data: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
base: new fields.NumberField({ initial: 0, integer: true }),
|
||||
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||
actualValue: new fields.NumberField({ initial: 0, integer: true }),
|
||||
overrideValue: new fields.NumberField({ initial: 0, integer: true })
|
||||
bonus: new fields.NumberField({ initial: 0, integer: true })
|
||||
})
|
||||
});
|
||||
|
||||
|
|
@ -52,11 +49,7 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
|||
presence: attributeField(),
|
||||
knowledge: attributeField()
|
||||
}),
|
||||
proficiency: new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 1, integer: true }),
|
||||
min: new fields.NumberField({ initial: 1, integer: true }),
|
||||
max: new fields.NumberField({ initial: 6, integer: true })
|
||||
}),
|
||||
proficiency: new fields.NumberField({ required: true, initial: 1, integer: true }),
|
||||
evasion: new fields.NumberField({ initial: 0, integer: true }),
|
||||
experiences: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
|
|
@ -347,7 +340,15 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
|||
|
||||
this.evasion = this.class?.system?.evasion ?? 0;
|
||||
// this.armor.value = this.activeArmor?.baseScore ?? 0;
|
||||
// this.damageThresholds = this.computeDamageThresholds();
|
||||
const armor = this.armor;
|
||||
this.damageThresholds = {
|
||||
major: armor
|
||||
? armor.system.baseThresholds.major + this.levelData.level.current
|
||||
: this.levelData.level.current,
|
||||
severe: armor
|
||||
? armor.system.baseThresholds.severe + this.levelData.level.current
|
||||
: this.levelData.level.current * 2
|
||||
};
|
||||
|
||||
this.applyLevels();
|
||||
this.applyEffects();
|
||||
|
|
|
|||
|
|
@ -45,6 +45,15 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
}
|
||||
|
||||
async levelUp(levelupData) {
|
||||
await this.actor.update({
|
||||
'system.levelData': {
|
||||
'level.current': this.system.levelData.level.changed,
|
||||
'selections': levelupData
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async diceRoll(modifier, shiftKey) {
|
||||
if (this.type === 'pc') {
|
||||
return await this.dualityRoll(modifier, shiftKey);
|
||||
|
|
|
|||
|
|
@ -3,22 +3,19 @@ import { getWidthOfText } from './utils.mjs';
|
|||
export default class RegisterHandlebarsHelpers {
|
||||
static registerHelpers() {
|
||||
Handlebars.registerHelper({
|
||||
looseEq: this.looseEq,
|
||||
times: this.times,
|
||||
join: this.join,
|
||||
add: this.add,
|
||||
subtract: this.subtract,
|
||||
objectSelector: this.objectSelector,
|
||||
includes: this.includes,
|
||||
simpleEditor: this.simpleEditor,
|
||||
debug: this.debug
|
||||
debug: this.debug,
|
||||
signedNumber: this.signedNumber,
|
||||
switch: this.switch,
|
||||
case: this.case
|
||||
});
|
||||
}
|
||||
|
||||
static looseEq(a, b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
static times(nr, block) {
|
||||
var accum = '';
|
||||
for (var i = 0; i < nr; ++i) accum += block.fn(i);
|
||||
|
|
@ -77,33 +74,25 @@ export default class RegisterHandlebarsHelpers {
|
|||
return new Handlebars.SafeString(html);
|
||||
}
|
||||
|
||||
static rangePicker(options) {
|
||||
let { name, value, min, max, step } = options.hash;
|
||||
name = name || 'range';
|
||||
value = value ?? '';
|
||||
if (Number.isNaN(value)) value = '';
|
||||
const html = `<input type="range" name="${name}" value="${value}" min="${min}" max="${max}" step="${step}"/>
|
||||
<span class="range-value">${value}</span>`;
|
||||
return new Handlebars.SafeString(html);
|
||||
}
|
||||
|
||||
static includes(list, item) {
|
||||
return list.includes(item);
|
||||
}
|
||||
|
||||
static simpleEditor(content, options) {
|
||||
const {
|
||||
target,
|
||||
editable = true,
|
||||
button,
|
||||
engine = 'tinymce',
|
||||
collaborate = false,
|
||||
class: cssClass
|
||||
} = options.hash;
|
||||
const config = { name: target, value: content, button, collaborate, editable, engine };
|
||||
const element = foundry.applications.fields.createEditorInput(config);
|
||||
if (cssClass) element.querySelector('.editor-content').classList.add(cssClass);
|
||||
return new Handlebars.SafeString(element.outerHTML);
|
||||
static signedNumber(number) {
|
||||
return number >= 0 ? `+${number}` : number;
|
||||
}
|
||||
|
||||
static switch(value, options) {
|
||||
this.switch_value = value;
|
||||
this.switch_break = false;
|
||||
return options.fn(this);
|
||||
}
|
||||
|
||||
static case(value, options) {
|
||||
if (value == this.switch_value) {
|
||||
this.switch_break = true;
|
||||
return options.fn(this);
|
||||
}
|
||||
}
|
||||
|
||||
static debug(a) {
|
||||
|
|
|
|||
|
|
@ -2791,6 +2791,11 @@ div.daggerheart.views.multiclass {
|
|||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.daggerheart.levelup section .section-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.daggerheart.levelup .tiers-container {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
|
|
@ -2844,9 +2849,75 @@ div.daggerheart.views.multiclass {
|
|||
font-size: 14px;
|
||||
font-style: italic;
|
||||
}
|
||||
.daggerheart.levelup .levelup-selections-container .achievement-experience-cards {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
.daggerheart.levelup .levelup-selections-container .achievement-experience-cards .achievement-experience-card {
|
||||
border: 1px solid;
|
||||
border-radius: 4px;
|
||||
padding-right: 4px;
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.daggerheart.levelup .levelup-selections-container .achievement-experience-cards .achievement-experience-card .achievement-experience-marker {
|
||||
border: 1px solid;
|
||||
border-radius: 50%;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
.daggerheart.levelup .levelup-selections-container .levelup-card-selection {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
gap: 40px;
|
||||
padding-right: 120px;
|
||||
}
|
||||
.daggerheart.levelup .levelup-summary-container .level-achievements-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.daggerheart.levelup .levelup-summary-container .level-achievements-container h2,
|
||||
.daggerheart.levelup .levelup-summary-container .level-achievements-container h3,
|
||||
.daggerheart.levelup .levelup-summary-container .level-achievements-container h4,
|
||||
.daggerheart.levelup .levelup-summary-container .level-achievements-container h5 {
|
||||
margin: 0;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.daggerheart.levelup .levelup-summary-container .increase-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 20px;
|
||||
}
|
||||
.daggerheart.levelup .levelup-footer {
|
||||
display: flex;
|
||||
}
|
||||
.daggerheart.levelup .levelup-footer .advancement-information-container {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
border-bottom: 3px solid;
|
||||
border-radius: 4px;
|
||||
margin-left: 8px;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
border-color: #9f8475;
|
||||
}
|
||||
.daggerheart.levelup .levelup-footer .advancement-information-container .advancement-tier-stats {
|
||||
border: 1px solid;
|
||||
padding: 0 2px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.daggerheart.levelup .levelup-footer .advancement-information-container .advancement-tier-info {
|
||||
font-size: 14px;
|
||||
}
|
||||
.application.sheet.daggerheart.dh-style.feature .item-sheet-header {
|
||||
display: flex;
|
||||
}
|
||||
|
|
@ -2892,14 +2963,14 @@ div.daggerheart.views.multiclass {
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype');
|
||||
src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype');
|
||||
src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype');
|
||||
}
|
||||
.application.sheet.daggerheart.dh-style h1 {
|
||||
font-family: 'Cinzel Decorative', serif;
|
||||
|
|
@ -3167,6 +3238,60 @@ div.daggerheart.views.multiclass {
|
|||
.application.setting.dh-style footer button {
|
||||
flex: 1;
|
||||
}
|
||||
.theme-light .application .component.dh-style.card.card-preview-container {
|
||||
background-image: url('../assets/parchments/dh-parchment-light.png');
|
||||
}
|
||||
.theme-light .application .component.dh-style.card.card-preview-container .preview-text-container {
|
||||
background-image: url(../assets/parchments/dh-parchment-dark.png);
|
||||
}
|
||||
.application .component.dh-style.card-preview-container {
|
||||
border-radius: 6px;
|
||||
border: 2px solid var(--color-tabs-border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
aspect-ratio: 0.75;
|
||||
background-image: url('../assets/parchments/dh-parchment-dark.png');
|
||||
}
|
||||
.application .component.dh-style.card-preview-container.empty {
|
||||
cursor: pointer;
|
||||
}
|
||||
.application .component.dh-style.card-preview-container .preview-image-container {
|
||||
flex: 1;
|
||||
border-radius: 4px 4px 0;
|
||||
}
|
||||
.application .component.dh-style.card-preview-container .preview-text-container {
|
||||
flex: 1;
|
||||
border-radius: 0 0 4px 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
color: var(--color-text-selection-bg);
|
||||
background-image: url(../assets/parchments/dh-parchment-light.png);
|
||||
}
|
||||
.application .component.dh-style.card-preview-container .preview-empty-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
}
|
||||
.application .component.dh-style.card-preview-container .preview-empty-container .preview-empty-inner-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.application .component.dh-style.card-preview-container .preview-empty-container .preview-empty-inner-container .preview-add-icon {
|
||||
font-size: 48px;
|
||||
}
|
||||
.application .component.dh-style.card-preview-container .preview-empty-container .preview-empty-inner-container .preview-empty-subtext {
|
||||
position: absolute;
|
||||
bottom: -48px;
|
||||
font-size: 18px;
|
||||
font-variant: small-caps;
|
||||
text-align: center;
|
||||
}
|
||||
.sheet.daggerheart.dh-style .tab-navigation {
|
||||
margin: 5px 0;
|
||||
height: 40px;
|
||||
|
|
@ -3399,6 +3524,12 @@ div.daggerheart.views.multiclass {
|
|||
/* Flex */
|
||||
/****/
|
||||
}
|
||||
.daggerheart .vertical-separator {
|
||||
border-left: 2px solid black;
|
||||
height: 56px;
|
||||
flex: 0;
|
||||
align-self: center;
|
||||
}
|
||||
.daggerheart .flex-centered {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -212,3 +212,77 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.theme-light {
|
||||
.application {
|
||||
.component.dh-style.card {
|
||||
&.card-preview-container {
|
||||
background-image: url('../assets/parchments/dh-parchment-light.png');
|
||||
|
||||
.preview-text-container {
|
||||
background-image: url(../assets/parchments/dh-parchment-dark.png);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.application {
|
||||
.component.dh-style {
|
||||
&.card-preview-container {
|
||||
border-radius: 6px;
|
||||
border: 2px solid var(--color-tabs-border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
aspect-ratio: 0.75;
|
||||
background-image: url('../assets/parchments/dh-parchment-dark.png');
|
||||
|
||||
&.empty {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.preview-image-container {
|
||||
flex: 1;
|
||||
border-radius: 4px 4px 0;
|
||||
}
|
||||
|
||||
.preview-text-container {
|
||||
flex: 1;
|
||||
border-radius: 0 0 4px 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
color: var(--color-text-selection-bg);
|
||||
background-image: url(../assets/parchments/dh-parchment-light.png);
|
||||
}
|
||||
|
||||
.preview-empty-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
|
||||
.preview-empty-inner-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.preview-add-icon {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.preview-empty-subtext {
|
||||
position: absolute;
|
||||
bottom: -48px;
|
||||
font-size: 18px;
|
||||
font-variant: small-caps;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@
|
|||
gap: 8px;
|
||||
}
|
||||
|
||||
section {
|
||||
.section-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.tiers-container {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
|
|
@ -73,13 +81,72 @@
|
|||
}
|
||||
}
|
||||
|
||||
.levelup-selections-container {
|
||||
.achievement-experience-cards {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.achievement-experience-card {
|
||||
border: 1px solid;
|
||||
border-radius: 4px;
|
||||
padding-right: 4px;
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
.achievement-experience-marker {
|
||||
border: 1px solid;
|
||||
border-radius: 50%;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.levelup-card-selection {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
gap: 40px;
|
||||
padding-right: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
.levelup-summary-container {
|
||||
.level-achievements-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
margin: 0;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.increase-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.levelup-footer {
|
||||
display: flex;
|
||||
|
||||
.advancement-information-container {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
border: 1px solid;
|
||||
border-bottom: 3px solid;
|
||||
border-radius: 4px;
|
||||
margin-left: 8px;
|
||||
align-items: center;
|
||||
|
|
|
|||
13
templates/components/card-preview.hbs
Normal file
13
templates/components/card-preview.hbs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<div class="component dh-style card-preview-container" data-path="{{this.path}}" data-limit="{{this.limit}}">
|
||||
{{#if this.img}}
|
||||
<img class="preview-image-container" src="{{this.img}}" />
|
||||
<div class="preview-text-container">{{this.name}}</div>
|
||||
{{else}}
|
||||
<div class="preview-empty-container">
|
||||
<div class="preview-empty-inner-container">
|
||||
<i class="preview-add-icon fa-solid fa-plus"></i>
|
||||
<div class="preview-empty-subtext">{{this.emptySubtext}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<div>
|
||||
<div class="tiers-container">
|
||||
{{#each this.levelup.tiers as |tier key|}}
|
||||
<fieldset class="tier-container {{#if (not tier.active)}}inactive{{/if}}">
|
||||
<legend>{{tier.name}}</legend>
|
||||
|
||||
{{#each tier.tierCheckboxGroups}}
|
||||
<div class="checkbox-group-container">
|
||||
<div class="checkboxes-container">
|
||||
{{#each this.checkboxGroups}}
|
||||
<div class="checkbox-grouping-coontainer {{#if this.multi}}multi{{/if}}">
|
||||
{{#each this.checkboxes}}
|
||||
<input
|
||||
type="checkbox" class="selection-checkbox{{#if (gt this.cost 1)}} multi{{/if}}" {{checked this.selected}} {{#if this.disabled}}disabled{{/if}}
|
||||
data-tier="{{this.tier}}"
|
||||
data-level="{{this.level}}"
|
||||
data-option="{{this.optionKey}}"
|
||||
data-checkbox-nr="{{this.checkboxNr}}"
|
||||
data-cost="{{this.cost}}"
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="checkbox-group-label">{{this.label}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</fieldset>
|
||||
{{/each}}
|
||||
</div>
|
||||
<footer class="levelup-footer">
|
||||
<button data-action="save">{{localize "Finish Levelup"}}</button>
|
||||
<div class="advancement-information-container">
|
||||
{{localize "DAGGERHEART.Application.LevelUp.notifications.info.remainingAdvancementInfo" choices=this.levelup.levelSelections.totalAvailable}}
|
||||
|
||||
{{#each this.levelup.tiers as |tier key|}}
|
||||
<div class="advancement-tier-stats">Tier {{tier.tier}}: {{tier.selections.totalAvailable}}</div>
|
||||
{{/each}}
|
||||
<i class="advancement-tier-info fa-solid fa-circle-question" data-tooltip="{{localize "DAGGERHEART.Application.LevelUp.notifications.info.tierAdvancementInfo"}}"></i>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
29
templates/views/levelup/advancementSelection.hbs
Normal file
29
templates/views/levelup/advancementSelection.hbs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{{#switch}}
|
||||
{{#case 'trait'}}
|
||||
|
||||
{{/case}}
|
||||
{{/switch}}
|
||||
|
||||
|
||||
|
||||
trait: {
|
||||
id: 'trait',
|
||||
label: 'Character Trait',
|
||||
dataPath: ''
|
||||
},
|
||||
experience: {
|
||||
id: 'experience',
|
||||
label: 'Experience'
|
||||
},
|
||||
domainCard: {
|
||||
id: 'domainCard',
|
||||
label: 'Domain Card'
|
||||
},
|
||||
subclass: {
|
||||
id: 'subclass',
|
||||
label: 'Subclass'
|
||||
},
|
||||
multiclass: {
|
||||
id: 'multiclass',
|
||||
label: 'Multiclass'
|
||||
}
|
||||
37
templates/views/levelup/tabs/advancements.hbs
Normal file
37
templates/views/levelup/tabs/advancements.hbs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<section
|
||||
class='tab {{tabs.advancements.cssClass}} {{tabs.advancements.id}}'
|
||||
data-tab='{{tabs.advancements.id}}'
|
||||
data-group='{{tabs.advancements.group}}'
|
||||
>
|
||||
<div class="section-container">
|
||||
<div class="tiers-container">
|
||||
{{#each this.levelup.tiers as |tier key|}}
|
||||
<fieldset class="tier-container {{#if (not tier.active)}}inactive{{/if}}">
|
||||
<legend>{{tier.name}}</legend>
|
||||
|
||||
{{#each tier.tierCheckboxGroups}}
|
||||
<div class="checkbox-group-container">
|
||||
<div class="checkboxes-container">
|
||||
{{#each this.checkboxGroups}}
|
||||
<div class="checkbox-grouping-coontainer {{#if this.multi}}multi{{/if}}">
|
||||
{{#each this.checkboxes}}
|
||||
<input
|
||||
type="checkbox" class="selection-checkbox{{#if (gt this.cost 1)}} multi{{/if}}" {{checked this.selected}} {{#if this.disabled}}disabled{{/if}}
|
||||
data-tier="{{this.tier}}"
|
||||
data-level="{{this.level}}"
|
||||
data-option="{{this.optionKey}}"
|
||||
data-checkbox-nr="{{this.checkboxNr}}"
|
||||
data-cost="{{this.cost}}"
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="checkbox-group-label">{{this.label}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</fieldset>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
34
templates/views/levelup/tabs/selections.hbs
Normal file
34
templates/views/levelup/tabs/selections.hbs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<section
|
||||
class='tab {{tabs.selections.cssClass}} {{tabs.selections.id}}'
|
||||
data-tab='{{tabs.selections.id}}'
|
||||
data-group='{{tabs.selections.group}}'
|
||||
>
|
||||
<div class="section-container levelup-selections-container">
|
||||
<div>
|
||||
<h3>{{localize "DAGGERHEART.Application.LevelUp.summary.newExperiences"}}</h3>
|
||||
<div class="achievement-experience-cards">
|
||||
{{#each this.newExperiences as |experience key|}}
|
||||
<div class="achievement-experience-card">
|
||||
<div class="flexrow">
|
||||
<input type="text" name="{{concat "levelup.allInitialAchievements.newExperiences." key ".name"}}" value="{{experience.name}}" placeholder="{{localize "DAGGERHEART.Application.LevelUp.summary.experiencePlaceholder"}}" />
|
||||
<div class="flex0">{{signedNumber experience.modifier}}</div>
|
||||
</div>
|
||||
<div class="achievement-experience-marker">
|
||||
{{#if experience.name}}<i class="fa-solid fa-check"></i>{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>{{localize "DAGGERHEART.Application.LevelUp.summary.domainCards"}}</h3>
|
||||
|
||||
<div class="levelup-card-selection domain-cards">
|
||||
{{#each this.domainCards}}
|
||||
{{> "systems/daggerheart/templates/components/card-preview.hbs" img=this.img name=this.name path=this.path }}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
60
templates/views/levelup/tabs/summary.hbs
Normal file
60
templates/views/levelup/tabs/summary.hbs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<section
|
||||
class='tab {{tabs.summary.cssClass}} {{tabs.summary.id}}'
|
||||
data-tab='{{tabs.summary.id}}'
|
||||
data-group='{{tabs.summary.group}}'
|
||||
>
|
||||
<div class="section-container levelup-summary-container">
|
||||
<fieldset>
|
||||
<legend>{{localize "DAGGERHEART.Application.LevelUp.summary.levelAchievements"}}</legend>
|
||||
|
||||
<div class="level-achievements-container">
|
||||
<div>
|
||||
<h3>{{localize "DAGGERHEART.Application.LevelUp.summary.statisticIncreases"}}</h3>
|
||||
<div class="increase-container">
|
||||
{{localize "DAGGERHEART.Application.LevelUp.summary.proficiencyIncrease" proficiency=this.levelAchievements.statisticIncreases.proficiency.old }}
|
||||
<i class="fa-solid fa-arrow-right-long"></i>
|
||||
{{this.levelAchievements.statisticIncreases.proficiency.new}}
|
||||
</div>
|
||||
<h5>{{localize "Damage Thresholds"}}{{#if this.levelAchievements.statisticIncreases.damageThresholds.unarmored}}({{localize "DAGGERHEART.General.unarmored"}}){{/if}}</h5>
|
||||
<div class="increase-container">
|
||||
{{localize "DAGGERHEART.Application.LevelUp.summary.damageThresholdMajorIncrease" threshold=this.levelAchievements.statisticIncreases.damageThresholds.major.old }}
|
||||
<i class="fa-solid fa-arrow-right-long"></i>
|
||||
{{this.levelAchievements.statisticIncreases.damageThresholds.major.new}}
|
||||
</div>
|
||||
<div class="increase-container">
|
||||
{{localize "DAGGERHEART.Application.LevelUp.summary.damageThresholdSevereIncrease" threshold=this.levelAchievements.statisticIncreases.damageThresholds.severe.old }}
|
||||
<i class="fa-solid fa-arrow-right-long"></i>
|
||||
{{this.levelAchievements.statisticIncreases.damageThresholds.severe.new}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{localize "DAGGERHEART.Application.LevelUp.summary.levelAdvancements"}}</legend>
|
||||
|
||||
{{!-- <div>
|
||||
<h4>{{localize "DAGGERHEART.General.Experience.plural"}}</h4>
|
||||
<div class="level-experience-cards">
|
||||
{{#each this.levelAchievements.experience}}
|
||||
<div class="level-experience-card">
|
||||
{{this.label}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div> --}}
|
||||
</fieldset>
|
||||
|
||||
<footer class="levelup-footer">
|
||||
<button data-action="save">{{localize "Finish Levelup"}}</button>
|
||||
<div class="advancement-information-container">
|
||||
{{localize "DAGGERHEART.Application.LevelUp.notifications.info.remainingAdvancementInfo" choices=this.levelup.levelSelections.totalAvailable}}
|
||||
|
||||
{{#each this.levelup.tiers as |tier key|}}
|
||||
<div class="advancement-tier-stats">Tier {{tier.tier}}: {{tier.selections.totalAvailable}}</div>
|
||||
{{/each}}
|
||||
<i class="advancement-tier-info fa-solid fa-circle-question" data-tooltip="{{localize "DAGGERHEART.Application.LevelUp.notifications.info.tierAdvancementInfo"}}"></i>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</section>
|
||||
Loading…
Add table
Add a link
Reference in a new issue