193 lines
4.4 KiB
JavaScript
193 lines
4.4 KiB
JavaScript
import { filePath } from "../../consts.mjs";
|
|
import { GenericAppMixin } from "../mixins/GenericApp.mjs";
|
|
import { LaidOutAppMixin } from "../mixins/LaidOutAppMixin.mjs";
|
|
import { localizer } from "../../utils/Localizer.mjs";
|
|
import { editItemFromElement, deleteItemFromElement } from "../utils.mjs";
|
|
|
|
const { HandlebarsApplicationMixin } = foundry.applications.api;
|
|
const { ActorSheetV2 } = foundry.applications.sheets;
|
|
const { ContextMenu, TextEditor } = foundry.applications.ux;
|
|
|
|
export class BookGeistSheet extends
|
|
LaidOutAppMixin(
|
|
GenericAppMixin(
|
|
HandlebarsApplicationMixin(
|
|
ActorSheetV2,
|
|
))) {
|
|
// #region Options
|
|
static DEFAULT_OPTIONS = {
|
|
classes: [
|
|
`ripcrypt--actor`,
|
|
`BookGeistSheet`,
|
|
],
|
|
position: {
|
|
width: `auto`,
|
|
height: `auto`,
|
|
},
|
|
window: {
|
|
resizable: true,
|
|
},
|
|
form: {
|
|
submitOnChange: true,
|
|
closeOnSubmite: false,
|
|
},
|
|
};
|
|
|
|
static PARTS = {
|
|
layout: {
|
|
root: true,
|
|
template: filePath(`templates/Apps/BookGeistSheet/layout.hbs`),
|
|
},
|
|
image: { template: filePath(`templates/Apps/BookGeistSheet/image.hbs`) },
|
|
header: { template: filePath(`templates/Apps/BookGeistSheet/header.hbs`) },
|
|
stats: { template: filePath(`templates/Apps/BookGeistSheet/stats.hbs`) },
|
|
items: { template: filePath(`templates/Apps/BookGeistSheet/items.hbs`) },
|
|
};
|
|
// #endregion Options
|
|
|
|
// #region Lifecycle
|
|
async _onRender() {
|
|
await super._onRender();
|
|
|
|
new ContextMenu.implementation(
|
|
this.element,
|
|
`[data-ctx-menu="item"]`,
|
|
[
|
|
{
|
|
name: localizer(`RipCrypt.common.edit`),
|
|
condition: (el) => {
|
|
const itemId = el.dataset.itemId;
|
|
return itemId !== ``;
|
|
},
|
|
callback: editItemFromElement,
|
|
},
|
|
{
|
|
name: localizer(`RipCrypt.common.delete`),
|
|
condition: (el) => {
|
|
const itemId = el.dataset.itemId;
|
|
return itemId !== ``;
|
|
},
|
|
callback: deleteItemFromElement,
|
|
},
|
|
],
|
|
{ jQuery: false, fixed: true },
|
|
);
|
|
};
|
|
// #endregion Lifecycle
|
|
|
|
// #region Data Prep
|
|
async _preparePartContext(partID, ctx) {
|
|
|
|
switch (partID) {
|
|
case `layout`: await this._prepareLayoutContext(ctx); break;
|
|
case `image`: await this._prepareImageContext(ctx); break;
|
|
case `header`: await this._prepareHeaderContext(ctx); break;
|
|
case `stats`: await this._prepareStatsContext(ctx); break;
|
|
case `items`: await this._prepareItemsContext(ctx); break;
|
|
};
|
|
|
|
return ctx;
|
|
};
|
|
|
|
async _prepareLayoutContext(ctx) {
|
|
ctx.imageVisible = true;
|
|
};
|
|
|
|
async _prepareImageContext(ctx) {
|
|
ctx.url = this.actor.img;
|
|
};
|
|
|
|
async _prepareHeaderContext(ctx) {
|
|
ctx.name = this.actor.name;
|
|
ctx.rank = this.actor.system.level.rank;
|
|
ctx.ranks = Object.values(gameTerms.Rank)
|
|
.map((value, index) => ({
|
|
value,
|
|
label: index
|
|
}));
|
|
ctx.description = await TextEditor.implementation.enrichHTML(this.actor.system.description);
|
|
};
|
|
|
|
async _prepareStatsContext(ctx) {
|
|
const system = this.actor.system;
|
|
|
|
const fate = system.fate;
|
|
if (fate) {
|
|
ctx.path = {
|
|
full: localizer(`RipCrypt.common.ordinals.${fate}.full`),
|
|
abbv: localizer(`RipCrypt.common.ordinals.${fate}.abbv`),
|
|
};
|
|
}
|
|
else {
|
|
ctx.path = {
|
|
full: null,
|
|
abbv: localizer(`RipCrypt.common.empty`),
|
|
};
|
|
};
|
|
|
|
Object.assign(ctx, system.ability);
|
|
ctx.guts = system.guts;
|
|
ctx.speed = system.speed;
|
|
};
|
|
|
|
async _prepareItemsContext(ctx) {
|
|
ctx.defense = {
|
|
locations: `None`,
|
|
protection: 0,
|
|
shield: false,
|
|
};
|
|
ctx.traits = []; // Array<{name: string}>
|
|
|
|
for (const item of this.actor.items) {
|
|
switch (item.type) {
|
|
case `weapon`: {
|
|
if (!item.system.equipped) { continue };
|
|
ctx.attacks ??= [];
|
|
ctx.attacks.push(this._prepareWeapon(item));
|
|
break;
|
|
};
|
|
case `craft`: {
|
|
ctx.crafts ??= [];
|
|
ctx.crafts.push(this._prepareCraft(item));
|
|
break;
|
|
};
|
|
case `trait`: {
|
|
ctx.traits.push(this._prepareTrait(item));
|
|
break;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
_prepareWeapon(weapon) {
|
|
const hasShortRange = weapon.system.range.short != null;
|
|
const hasLongRange = weapon.system.range.long != null;
|
|
const isRanged = hasShortRange || hasLongRange;
|
|
return {
|
|
uuid: weapon.uuid,
|
|
name: weapon.name,
|
|
damage: weapon.system.damage,
|
|
isRanged,
|
|
range: weapon.system.range,
|
|
};
|
|
};
|
|
|
|
_prepareCraft(craft) {
|
|
return {
|
|
uuid: craft.uuid,
|
|
name: craft.name,
|
|
};
|
|
};
|
|
|
|
_prepareTrait(trait) {
|
|
return {
|
|
uuid: trait.uuid,
|
|
name: trait.name,
|
|
description: trait.system.description,
|
|
};
|
|
};
|
|
// #endregion Data Prep
|
|
|
|
// #region Actions
|
|
// #endregion Actions
|
|
};
|