Fix backpack slot bonus, class features display, and skills layout
- Fix itemSlots.bonus being overwritten by prepareDerivedData (now adds to AE value instead of replacing) - Add _prepareClassFeatures() to extract and display class features from class items on the abilities tab - Change skills grid to vertical column flow (grid-auto-flow: column) - Fix backpack.json effect _key to reference correct item ID 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5e743b8f7e
commit
07426484bd
@ -634,9 +634,10 @@ export default class CharacterData extends VagabondActorBase {
|
|||||||
|
|
||||||
// Calculate Item Slots: 8 + Might - Fatigue + bonus
|
// Calculate Item Slots: 8 + Might - Fatigue + bonus
|
||||||
const baseSlots = CONFIG.VAGABOND?.baseItemSlots || 8;
|
const baseSlots = CONFIG.VAGABOND?.baseItemSlots || 8;
|
||||||
// Sum up all bonus sources
|
// Sum up all bonus sources from the bonuses array and ADD to existing bonus
|
||||||
|
// (existing bonus may have been set by Active Effects before prepareDerivedData runs)
|
||||||
const totalBonus = this.itemSlots.bonuses.reduce((sum, b) => sum + b.value, 0);
|
const totalBonus = this.itemSlots.bonuses.reduce((sum, b) => sum + b.value, 0);
|
||||||
this.itemSlots.bonus = totalBonus;
|
this.itemSlots.bonus += totalBonus;
|
||||||
this.itemSlots.max =
|
this.itemSlots.max =
|
||||||
baseSlots + stats.might.value - this.resources.fatigue.value + this.itemSlots.bonus;
|
baseSlots + stats.might.value - this.resources.fatigue.value + this.itemSlots.bonus;
|
||||||
// Check if overburdened
|
// Check if overburdened
|
||||||
|
|||||||
@ -119,6 +119,45 @@ export default class VagabondCharacterSheet extends VagabondActorSheet {
|
|||||||
context.classes = context.items.classes;
|
context.classes = context.items.classes;
|
||||||
context.className = context.items.classes[0]?.name || "None";
|
context.className = context.items.classes[0]?.name || "None";
|
||||||
context.ancestryName = context.items.ancestry?.name || "None";
|
context.ancestryName = context.items.ancestry?.name || "None";
|
||||||
|
|
||||||
|
// Prepare class features from class items for display
|
||||||
|
context.classFeatures = this._prepareClassFeatures();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare class features for display on the abilities tab.
|
||||||
|
* Extracts features from class items at or below the character's current level.
|
||||||
|
* @returns {Object[]}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_prepareClassFeatures() {
|
||||||
|
const level = this.actor.system.level || 1;
|
||||||
|
const classFeatures = [];
|
||||||
|
|
||||||
|
for (const classItem of this.actor.items.filter((i) => i.type === "class")) {
|
||||||
|
const features = classItem.system.features || [];
|
||||||
|
for (const feature of features) {
|
||||||
|
// Only include features at or below current level
|
||||||
|
if (feature.level <= level) {
|
||||||
|
classFeatures.push({
|
||||||
|
name: feature.name,
|
||||||
|
description: feature.description,
|
||||||
|
passive: feature.passive,
|
||||||
|
level: feature.level,
|
||||||
|
sourceClass: classItem.name,
|
||||||
|
img: classItem.img || "icons/svg/book.svg",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by level, then alphabetically
|
||||||
|
classFeatures.sort((a, b) => {
|
||||||
|
if (a.level !== b.level) return a.level - b.level;
|
||||||
|
return a.name.localeCompare(b.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
return classFeatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"_id": "backpackSlotBonus",
|
"_id": "backpackSlotBonus",
|
||||||
"_key": "!items.effects!vagabondEquipBackpack.backpackSlotBonus",
|
"_key": "!items.effects!vgbdEqpbackpack0.backpackSlotBonus",
|
||||||
"name": "Backpack Slot Bonus",
|
"name": "Backpack Slot Bonus",
|
||||||
"icon": "icons/svg/item-bag.svg",
|
"icon": "icons/svg/item-bag.svg",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
|||||||
@ -609,7 +609,10 @@
|
|||||||
.skills-section {
|
.skills-section {
|
||||||
.skills-grid {
|
.skills-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
// 2 columns with vertical flow (fills columns top-to-bottom, then left-to-right)
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-template-rows: repeat(6, auto);
|
||||||
|
grid-auto-flow: column;
|
||||||
gap: $spacing-2;
|
gap: $spacing-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,18 @@
|
|||||||
<div class="abilities-section features">
|
<div class="abilities-section features">
|
||||||
<h2 class="section-header">{{localize "VAGABOND.Features"}}</h2>
|
<h2 class="section-header">{{localize "VAGABOND.Features"}}</h2>
|
||||||
<ul class="ability-list">
|
<ul class="ability-list">
|
||||||
|
{{!-- Display class features extracted from class items --}}
|
||||||
|
{{#each classFeatures}}
|
||||||
|
<li class="ability-item class-feature">
|
||||||
|
<img class="ability-img" src="{{this.img}}" alt="{{this.name}}" />
|
||||||
|
<div class="ability-info">
|
||||||
|
<span class="ability-name">{{this.name}}</span>
|
||||||
|
<span class="ability-source">{{this.sourceClass}} Lv{{this.level}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="ability-description">{{{this.description}}}</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
{{!-- Display standalone feature items --}}
|
||||||
{{#each items.features}}
|
{{#each items.features}}
|
||||||
<li class="ability-item" data-item-id="{{this.id}}">
|
<li class="ability-item" data-item-id="{{this.id}}">
|
||||||
<img class="ability-img" src="{{this.img}}" alt="{{this.name}}" />
|
<img class="ability-img" src="{{this.img}}" alt="{{this.name}}" />
|
||||||
@ -45,9 +57,13 @@
|
|||||||
<i class="fa-solid fa-trash"></i>
|
<i class="fa-solid fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{{else}}
|
|
||||||
<li class="ability-item empty">{{localize "VAGABOND.NoFeatures"}}</li>
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
{{!-- Show empty message only if both are empty --}}
|
||||||
|
{{#unless classFeatures.length}}
|
||||||
|
{{#unless items.features.length}}
|
||||||
|
<li class="ability-item empty">{{localize "VAGABOND.NoFeatures"}}</li>
|
||||||
|
{{/unless}}
|
||||||
|
{{/unless}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user