256 lines
8.9 KiB
JavaScript
256 lines
8.9 KiB
JavaScript
import EcrymeBaseActorSheet from "./base-actor-sheet.js"
|
|
import { EcrymeUtility } from "../../common/ecryme-utility.js"
|
|
|
|
/**
|
|
* Actor sheet for PC and NPC types using Application V2.
|
|
*/
|
|
export default class EcrymeActorSheet extends EcrymeBaseActorSheet {
|
|
|
|
/** @override */
|
|
static DEFAULT_OPTIONS = {
|
|
classes: ["pc-npc"],
|
|
position: { width: 860, height: 680 },
|
|
actions: {
|
|
openAnnency: EcrymeActorSheet.#onOpenAnnency,
|
|
itemEdit: EcrymeActorSheet.#onItemEdit,
|
|
itemDelete: EcrymeActorSheet.#onItemDelete,
|
|
itemCreate: EcrymeActorSheet.#onItemCreate,
|
|
subactorEdit: EcrymeActorSheet.#onSubactorEdit,
|
|
subactorDelete: EcrymeActorSheet.#onSubactorDelete,
|
|
rollSkill: EcrymeActorSheet.#onRollSkill,
|
|
rollSpec: EcrymeActorSheet.#onRollSpec,
|
|
rollSkillConfront: EcrymeActorSheet.#onRollSkillConfront,
|
|
rollCephaly: EcrymeActorSheet.#onRollCephaly,
|
|
rollWeaponConfront:EcrymeActorSheet.#onRollWeaponConfront,
|
|
impactModify: EcrymeActorSheet.#onImpactModify,
|
|
rollWeapon: EcrymeActorSheet.#onRollWeapon,
|
|
lockUnlock: EcrymeActorSheet.#onLockUnlock,
|
|
equipItem: EcrymeActorSheet.#onEquipItem,
|
|
quantityMinus: EcrymeActorSheet.#onQuantityMinus,
|
|
quantityPlus: EcrymeActorSheet.#onQuantityPlus,
|
|
},
|
|
}
|
|
|
|
/** @override */
|
|
static PARTS = {
|
|
header: { template: "systems/fvtt-ecryme/templates/actors/partials/actor-header.hbs" },
|
|
tabs: { template: "templates/generic/tab-navigation.hbs" },
|
|
skills: { template: "systems/fvtt-ecryme/templates/actors/actor-skills.hbs" },
|
|
traits: { template: "systems/fvtt-ecryme/templates/actors/actor-traits.hbs" },
|
|
combat: { template: "systems/fvtt-ecryme/templates/actors/actor-combat.hbs" },
|
|
cephaly: { template: "systems/fvtt-ecryme/templates/actors/actor-cephaly.hbs" },
|
|
equipements:{ template: "systems/fvtt-ecryme/templates/actors/actor-equipements.hbs" },
|
|
biodata: { template: "systems/fvtt-ecryme/templates/actors/actor-biodata.hbs" },
|
|
}
|
|
|
|
/** @override */
|
|
tabGroups = { primary: "skills" }
|
|
|
|
/** Build tabs, conditionally adding cephaly if the module is active */
|
|
_getTabs() {
|
|
const hasCephaly = EcrymeUtility.hasCephaly()
|
|
const tabs = {
|
|
skills: { id: "skills", group: "primary", label: "ECRY.ui.skills" },
|
|
traits: { id: "traits", group: "primary", label: "ECRY.ui.traits" },
|
|
combat: { id: "combat", group: "primary", label: "ECRY.ui.healthcombat" },
|
|
equipements:{ id: "equipements", group: "primary", label: "ECRY.ui.equipment" },
|
|
biodata: { id: "biodata", group: "primary", label: "ECRY.ui.bionotes" },
|
|
}
|
|
if (hasCephaly) {
|
|
// Insert cephaly after combat, rebuilding the object to preserve insertion order
|
|
const ordered = {}
|
|
for (const [k, v] of Object.entries(tabs)) {
|
|
ordered[k] = v
|
|
if (k === "combat") ordered.cephaly = { id: "cephaly", group: "primary", label: "ECRY.ui.cephaly" }
|
|
}
|
|
for (const tab of Object.values(ordered)) {
|
|
tab.active = this.tabGroups[tab.group] === tab.id
|
|
tab.cssClass = tab.active ? "active" : ""
|
|
}
|
|
return ordered
|
|
}
|
|
for (const tab of Object.values(tabs)) {
|
|
tab.active = this.tabGroups[tab.group] === tab.id
|
|
tab.cssClass = tab.active ? "active" : ""
|
|
}
|
|
return tabs
|
|
}
|
|
|
|
/** @override */
|
|
async _prepareContext() {
|
|
const actor = this.document
|
|
return {
|
|
actor,
|
|
system: actor.system,
|
|
source: actor.toObject(),
|
|
fields: actor.schema.fields,
|
|
systemFields: actor.system.schema.fields,
|
|
type: actor.type,
|
|
img: actor.img,
|
|
name: actor.name,
|
|
isEditable: this.isEditable,
|
|
config: game.system.ecryme.config,
|
|
hasCephaly: EcrymeUtility.hasCephaly(),
|
|
hasBoheme: EcrymeUtility.hasBoheme(),
|
|
hasAmertume: EcrymeUtility.hasAmertume(),
|
|
skills: actor.prepareSkills(),
|
|
traits: actor.getRollTraits(),
|
|
ideal: actor.getIdeal(),
|
|
spleen: actor.getSpleen(),
|
|
weapons: actor.getWeapons(),
|
|
maneuvers: actor.getManeuvers(),
|
|
impactsMalus: actor.getImpactsMalus(),
|
|
equipments: actor.getEquipments(),
|
|
cephalySkills:actor.getCephalySkills(),
|
|
confrontations: actor.getConfrontations(),
|
|
subActors: actor.getSubActors(),
|
|
annency: actor.getAnnency(),
|
|
owner: this.document.isOwner,
|
|
isGM: game.user.isGM,
|
|
editScore: this.options.editScore ?? true,
|
|
tabs: this._getTabs(),
|
|
}
|
|
}
|
|
|
|
/** @override */
|
|
async _preparePartContext(partId, context) {
|
|
context = await super._preparePartContext(partId, context)
|
|
switch (partId) {
|
|
case "skills":
|
|
case "traits":
|
|
case "combat":
|
|
case "cephaly":
|
|
case "equipements":
|
|
context.tab = context.tabs[partId] ?? { cssClass: "" }
|
|
break
|
|
case "biodata":
|
|
context.tab = context.tabs.biodata
|
|
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
|
this.document.system.biodata.description, { async: true }
|
|
)
|
|
context.enrichedGmnotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
|
this.document.system.biodata.gmnotes, { async: true }
|
|
)
|
|
break
|
|
}
|
|
return context
|
|
}
|
|
|
|
// #region Drag and Drop
|
|
|
|
/** Handle incoming drops: Items from sidebar/compendium, Actors as subactors */
|
|
async _onDrop(event) {
|
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event)
|
|
if (!data?.type) return
|
|
|
|
if (data.type === "Item") {
|
|
const item = await fromUuid(data.uuid)
|
|
if (!item) return
|
|
await this.document.createEmbeddedDocuments("Item", [item.toObject()])
|
|
} else if (data.type === "Actor") {
|
|
const actor = fromUuidSync(data.uuid)
|
|
if (actor) await this.actor.addSubActor(actor.id)
|
|
}
|
|
}
|
|
|
|
/** Handle outgoing drag from embedded item rows */
|
|
_onDragStart(event) {
|
|
const li = event.currentTarget.closest("[data-item-id]")
|
|
if (!li) return
|
|
const item = this.document.items.get(li.dataset.itemId)
|
|
if (!item) return
|
|
event.dataTransfer.setData("text/plain", JSON.stringify(item.toDragData()))
|
|
}
|
|
|
|
// #endregion
|
|
|
|
// #region Static Action Handlers
|
|
|
|
static #onOpenAnnency(event, target) {
|
|
const actorId = target.dataset.annencyId
|
|
game.actors.get(actorId)?.sheet.render(true)
|
|
}
|
|
|
|
static #onItemEdit(event, target) {
|
|
const li = target.closest("[data-item-id]")
|
|
const itemId = li?.dataset.itemId ?? target.dataset.itemId
|
|
this.document.items.get(itemId)?.sheet.render(true)
|
|
}
|
|
|
|
static async #onItemDelete(event, target) {
|
|
const li = target.closest("[data-item-id]")
|
|
EcrymeUtility.confirmDelete(this, $(li)).catch(() => {})
|
|
}
|
|
|
|
static #onItemCreate(event, target) {
|
|
const dataType = target.dataset.type
|
|
this.document.createEmbeddedDocuments("Item", [{ name: "NewItem", type: dataType }], { renderSheet: true })
|
|
}
|
|
|
|
static #onSubactorEdit(event, target) {
|
|
const li = target.closest("[data-actor-id]")
|
|
game.actors.get(li?.dataset.actorId)?.sheet.render(true)
|
|
}
|
|
|
|
static #onSubactorDelete(event, target) {
|
|
const li = target.closest("[data-actor-id]")
|
|
this.actor.delSubActor(li?.dataset.actorId)
|
|
}
|
|
|
|
static #onRollSkill(event, target) {
|
|
this.actor.rollSkill(target.dataset.categoryKey, target.dataset.skillKey)
|
|
}
|
|
|
|
static #onRollSpec(event, target) {
|
|
this.actor.rollSpec(target.dataset.categoryKey, target.dataset.skillKey, target.dataset.specId)
|
|
}
|
|
|
|
static #onRollSkillConfront(event, target) {
|
|
this.actor.rollSkillConfront(target.dataset.categoryKey, target.dataset.skillKey)
|
|
}
|
|
|
|
static #onRollCephaly(event, target) {
|
|
this.actor.rollCephalySkillConfront(target.dataset.skillKey)
|
|
}
|
|
|
|
static #onRollWeaponConfront(event, target) {
|
|
const li = target.closest("[data-item-id]")
|
|
this.actor.rollWeaponConfront(li?.dataset.itemId)
|
|
}
|
|
|
|
static #onImpactModify(event, target) {
|
|
this.actor.modifyImpact(
|
|
target.dataset.impactType,
|
|
target.dataset.impactLevel,
|
|
Number(target.dataset.impactModifier)
|
|
)
|
|
}
|
|
|
|
static #onRollWeapon(event, target) {
|
|
this.actor.rollArme(target.dataset.armeId)
|
|
}
|
|
|
|
static #onLockUnlock(event, target) {
|
|
this.options.editScore = !this.options.editScore
|
|
this.render(true)
|
|
}
|
|
|
|
static #onEquipItem(event, target) {
|
|
const li = target.closest("[data-item-id]")
|
|
this.actor.equipItem(li?.dataset.itemId)
|
|
this.render(true)
|
|
}
|
|
|
|
static #onQuantityMinus(event, target) {
|
|
const li = target.closest("[data-item-id]")
|
|
this.actor.incDecQuantity(li?.dataset.itemId, -1)
|
|
}
|
|
|
|
static #onQuantityPlus(event, target) {
|
|
const li = target.closest("[data-item-id]")
|
|
this.actor.incDecQuantity(li?.dataset.itemId, +1)
|
|
}
|
|
|
|
// #endregion
|
|
}
|