Add class adancement
This commit is contained in:
@@ -32,6 +32,7 @@ export default class PrismRPGClassSheet extends PrismRPGItemSheet {
|
||||
#getTabs() {
|
||||
const tabs = {
|
||||
details: { id: "details", group: "primary", label: "PRISMRPG.Label.details" },
|
||||
advancements: { id: "advancements", group: "primary", label: "PRISMRPG.Label.advancement" },
|
||||
description: { id: "description", group: "primary", label: "PRISMRPG.Label.description" },
|
||||
}
|
||||
for (const v of Object.values(tabs)) {
|
||||
@@ -56,6 +57,142 @@ export default class PrismRPGClassSheet extends PrismRPGItemSheet {
|
||||
context.enrichedFeatures[key] = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.features[key], { async: true })
|
||||
}
|
||||
|
||||
// Enrich all advancement descriptions
|
||||
context.enrichedAdvancements = {}
|
||||
context.advancementsByLevel = []
|
||||
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
const key = `level${i}`
|
||||
const advancements = this.document.system.advancements[key] || []
|
||||
context.enrichedAdvancements[key] = []
|
||||
|
||||
const enrichedAdvancementsList = []
|
||||
for (let j = 0; j < advancements.length; j++) {
|
||||
const enrichedDesc = await foundry.applications.ux.TextEditor.implementation.enrichHTML(advancements[j].description, { async: true })
|
||||
const enrichedAdv = {
|
||||
...advancements[j],
|
||||
enrichedDescription: enrichedDesc,
|
||||
index: j,
|
||||
levelKey: key
|
||||
}
|
||||
context.enrichedAdvancements[key].push(enrichedAdv)
|
||||
enrichedAdvancementsList.push(enrichedAdv)
|
||||
}
|
||||
|
||||
context.advancementsByLevel.push({
|
||||
level: i,
|
||||
levelKey: key,
|
||||
advancements: enrichedAdvancementsList
|
||||
})
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
/** @override */
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options)
|
||||
|
||||
// Add advancement button listeners
|
||||
this.element.querySelectorAll(".add-advancement").forEach(btn => {
|
||||
btn.addEventListener("click", this._onAddAdvancement.bind(this))
|
||||
})
|
||||
|
||||
// Delete advancement button listeners
|
||||
this.element.querySelectorAll(".delete-advancement").forEach(btn => {
|
||||
btn.addEventListener("click", this._onDeleteAdvancement.bind(this))
|
||||
})
|
||||
|
||||
// Edit advancement icon listeners
|
||||
this.element.querySelectorAll(".advancement-icon").forEach(img => {
|
||||
img.addEventListener("click", this._onEditAdvancementIcon.bind(this))
|
||||
})
|
||||
|
||||
// Toggle advancement description listeners
|
||||
this.element.querySelectorAll(".toggle-advancement-description").forEach(btn => {
|
||||
btn.addEventListener("click", this._onToggleAdvancementDescription.bind(this))
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle toggling advancement description visibility
|
||||
* @param {Event} event
|
||||
*/
|
||||
_onToggleAdvancementDescription(event) {
|
||||
event.preventDefault()
|
||||
const button = event.currentTarget
|
||||
const item = button.closest(".advancement-item")
|
||||
const description = item.querySelector(".advancement-description")
|
||||
const icon = button.querySelector("i")
|
||||
|
||||
description.classList.toggle("collapsed")
|
||||
|
||||
if (description.classList.contains("collapsed")) {
|
||||
icon.classList.remove("fa-chevron-up")
|
||||
icon.classList.add("fa-chevron-down")
|
||||
} else {
|
||||
icon.classList.remove("fa-chevron-down")
|
||||
icon.classList.add("fa-chevron-up")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle adding a new advancement to a level
|
||||
* @param {Event} event
|
||||
*/
|
||||
async _onAddAdvancement(event) {
|
||||
event.preventDefault()
|
||||
const level = event.currentTarget.dataset.level
|
||||
const advancements = foundry.utils.deepClone(this.document.system.advancements[level] || [])
|
||||
|
||||
advancements.push({
|
||||
icon: "systems/fvtt-prism-rpg/assets/icons/advancement.svg",
|
||||
name: "",
|
||||
description: ""
|
||||
})
|
||||
|
||||
await this.document.update({
|
||||
[`system.advancements.${level}`]: advancements
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle deleting an advancement from a level
|
||||
* @param {Event} event
|
||||
*/
|
||||
async _onDeleteAdvancement(event) {
|
||||
event.preventDefault()
|
||||
const level = event.currentTarget.dataset.level
|
||||
const index = parseInt(event.currentTarget.dataset.index)
|
||||
|
||||
const advancements = foundry.utils.deepClone(this.document.system.advancements[level] || [])
|
||||
advancements.splice(index, 1)
|
||||
|
||||
await this.document.update({
|
||||
[`system.advancements.${level}`]: advancements
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle editing an advancement icon
|
||||
* @param {Event} event
|
||||
*/
|
||||
async _onEditAdvancementIcon(event) {
|
||||
event.preventDefault()
|
||||
const level = event.currentTarget.dataset.level
|
||||
const index = parseInt(event.currentTarget.dataset.index)
|
||||
|
||||
const fp = new FilePicker({
|
||||
type: "image",
|
||||
current: this.document.system.advancements[level][index].icon,
|
||||
callback: async (path) => {
|
||||
const advancements = foundry.utils.deepClone(this.document.system.advancements[level] || [])
|
||||
advancements[index].icon = path
|
||||
await this.document.update({
|
||||
[`system.advancements.${level}`]: advancements
|
||||
})
|
||||
}
|
||||
})
|
||||
fp.render(true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,41 @@ export default class PrismRPGClass extends foundry.abstract.TypeDataModel {
|
||||
level10: new fields.HTMLField({ initial: "" })
|
||||
})
|
||||
|
||||
// Advancements (list of advancements per level with icon, name and description)
|
||||
const advancementSchema = () => new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
icon: new fields.StringField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Icon"
|
||||
}),
|
||||
name: new fields.StringField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Name"
|
||||
}),
|
||||
description: new fields.HTMLField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Description"
|
||||
})
|
||||
}),
|
||||
{ initial: [] }
|
||||
)
|
||||
|
||||
schema.advancements = new fields.SchemaField({
|
||||
level1: advancementSchema(),
|
||||
level2: advancementSchema(),
|
||||
level3: advancementSchema(),
|
||||
level4: advancementSchema(),
|
||||
level5: advancementSchema(),
|
||||
level6: advancementSchema(),
|
||||
level7: advancementSchema(),
|
||||
level8: advancementSchema(),
|
||||
level9: advancementSchema(),
|
||||
level10: advancementSchema()
|
||||
})
|
||||
|
||||
// Proficiencies granted by this class
|
||||
schema.weaponProficiencies = new fields.StringField({
|
||||
required: true,
|
||||
@@ -156,4 +191,36 @@ export default class PrismRPGClass extends foundry.abstract.TypeDataModel {
|
||||
}
|
||||
return features
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current level's advancements
|
||||
*/
|
||||
get currentLevelAdvancements() {
|
||||
return this.advancements[`level${this.level}`] || []
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all advancements up to current level
|
||||
*/
|
||||
get allAdvancementsUpToLevel() {
|
||||
const advancements = []
|
||||
for (let i = 1; i <= this.level; i++) {
|
||||
const levelAdvancements = this.advancements[`level${i}`]
|
||||
if (levelAdvancements && levelAdvancements.length > 0) {
|
||||
advancements.push({
|
||||
level: i,
|
||||
advancements: levelAdvancements
|
||||
})
|
||||
}
|
||||
}
|
||||
return advancements
|
||||
}
|
||||
|
||||
/**
|
||||
* Get advancements for a specific level
|
||||
*/
|
||||
getAdvancementsForLevel(level) {
|
||||
if (level < 1 || level > 10) return []
|
||||
return this.advancements[`level${level}`] || []
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user