RC-63 | Display skills in sheet

This commit is contained in:
Oliver-Akins 2025-01-30 21:49:16 -07:00
parent df35c00c5d
commit 1302d91469
9 changed files with 142 additions and 24 deletions

View file

@ -80,6 +80,7 @@ export class CombinedHeroSheet extends GenericAppMixin(HandlebarsApplicationMixi
ctx = await HeroSkillsCardV1.prepareGear(ctx);
ctx = await HeroSkillsCardV1.prepareAmmo(ctx);
ctx = await HeroSkillsCardV1.prepareSkills(ctx);
Logger.debug(`Context:`, ctx);
return ctx;

View file

@ -1,5 +1,5 @@
import { deleteItemFromElement, editItemFromElement } from "../utils.mjs";
import { filePath } from "../../consts.mjs";
import { documentSorter, filePath } from "../../consts.mjs";
import { gameTerms } from "../../gameTerms.mjs";
import { GenericAppMixin } from "../GenericApp.mjs";
import { localizer } from "../../utils/Localizer.mjs";
@ -52,7 +52,7 @@ export class HeroSkillsCardV1 extends GenericAppMixin(HandlebarsApplicationMixin
} = options;
new ContextMenu(
element,
`[data-ctx-menu="gear"]`,
`[data-ctx-menu="gear"],[data-ctx-menu="skill"]`,
[
{
name: localizer(`RipCrypt.common.edit`),
@ -81,6 +81,7 @@ export class HeroSkillsCardV1 extends GenericAppMixin(HandlebarsApplicationMixin
ctx = await HeroSkillsCardV1.prepareGear(ctx);
ctx = await HeroSkillsCardV1.prepareAmmo(ctx);
ctx = await HeroSkillsCardV1.prepareSkills(ctx);
Logger.debug(`Context:`, ctx);
return ctx;
@ -122,6 +123,48 @@ export class HeroSkillsCardV1 extends GenericAppMixin(HandlebarsApplicationMixin
ctx.ammo = 0;
return ctx;
};
static async prepareSkills(ctx) {
ctx.skills = {};
const abilities = Object.values(gameTerms.Abilities);
const heroRank = ctx.actor.system.level.rank;
const embeddedSkills = ctx.actor.itemTypes.skill.sort(documentSorter);
for (let ability of abilities) {
const skills = [];
for (const skill of embeddedSkills) {
if (skill.system.ability !== ability) { continue };
skills.push({
uuid: skill.uuid,
name: skill.name,
use: skill.system.advances[heroRank],
});
};
// Thin Glim is grouped with full glim.
if (ability === gameTerms.Abilities.THINGLIM) {
ability = gameTerms.Abilities.GLIM;
};
ctx.skills[ability] ??= [];
ctx.skills[ability].push(...skills);
};
const limit = ctx.actor.system.limit.skills;
for (const ability of abilities) {
if (ctx.skills[ability] == null) { continue };
const length = ctx.skills[ability].length;
if (length >= limit) {
ctx.skills[ability] = ctx.skills[ability].slice(0, limit);
} else {
ctx.skills[ability] = ctx.skills[ability]
.concat(Array(limit - length).fill(null))
.slice(0, limit);
};
}
return ctx;
};
// #endregion
// #region Actions

View file

@ -1,8 +1,12 @@
// App imports
import { CombinedHeroSheet } from "./Apps/ActorSheets/CombinedHeroSheet.mjs";
import { DicePool } from "./Apps/DicePool.mjs";
import { HeroSkillsCardV1 } from "./Apps/ActorSheets/HeroSkillsCardV1.mjs";
import { HeroSummaryCardV1 } from "./Apps/ActorSheets/HeroSummaryCardV1.mjs";
// Util imports
import { documentSorter } from "./consts.mjs";
const { deepFreeze } = foundry.utils;
Object.defineProperty(
@ -16,6 +20,9 @@ Object.defineProperty(
HeroSummaryCardV1,
HeroSkillsCardV1,
},
utils: {
documentSorter,
},
}),
writable: false,
},

View file

@ -5,3 +5,13 @@ export function filePath(path) {
};
return `systems/ripcrypt/${path}`;
};
// MARK: documentSorter
export function documentSorter(a, b) {
const sortDelta = b.sort - a.sort;
if (sortDelta !== 0) {
return sortDelta;
};
// TODO alphabetical sort
return 0;
};

View file

@ -132,6 +132,7 @@ export class HeroData extends foundry.abstract.TypeDataModel {
this.limit = {
weapons: 4,
equipment: 12,
skills: 4,
};
};

View file

@ -2,19 +2,17 @@ import { gameTerms } from "../../gameTerms.mjs";
const { fields } = foundry.data;
const abilityPaths = [`grit`, `gait`, `grip`, `glim`, `thin-glim`];
export class SkillData extends foundry.abstract.TypeDataModel {
// MARK: Schema
static defineSchema() {
const schema = {
ability: new fields.StringField({
initial: abilityPaths[0],
initial: gameTerms.Abilities.GRIT,
blank: true,
trim: true,
nullable: false,
required: true,
choices: () => abilityPaths,
choices: () => Object.values(gameTerms.Abilities),
}),
};
@ -53,7 +51,7 @@ export class SkillData extends foundry.abstract.TypeDataModel {
label: `RipCrypt.common.ability`,
path: `system.ability`,
value: this.ability,
options: abilityPaths.map(ability => ({
options: Object.values(gameTerms.Abilities).map(ability => ({
label: `RipCrypt.common.abilities.${ability}`,
value: ability,
})),

View file

@ -1,4 +1,11 @@
export const gameTerms = Object.preventExtensions({
Abilities: Object.freeze({
GRIT: `grit`,
GRIP: `grip`,
GAIT: `gait`,
GLIM: `glim`,
THINGLIM: `thin-glim`,
}),
FatePath: [
`North`,
`East`,