From ab3ffa353bb9c61b7343ae9f7c9f553232fcd11a Mon Sep 17 00:00:00 2001 From: Russell Date: Tue, 15 Oct 2024 00:42:08 -0500 Subject: [PATCH 1/3] placeholder initial v2 item sheet --- src/apps/sheets/actor/base.js | 13 +- src/apps/sheets/item/base.js | 572 ++++++++++++++++++ static/templates/sheets/item/item-header.hbs | 1 + static/templates/sheets/item/item-tabs.hbs | 8 + .../sheets/item/tabs/item-description.hbs | 3 + .../sheets/item/tabs/item-details.hbs | 3 + .../sheets/item/tabs/item-effects.hbs | 3 + wfrp4e.js | 3 +- 8 files changed, 593 insertions(+), 13 deletions(-) create mode 100644 src/apps/sheets/item/base.js create mode 100644 static/templates/sheets/item/item-header.hbs create mode 100644 static/templates/sheets/item/item-tabs.hbs create mode 100644 static/templates/sheets/item/tabs/item-description.hbs create mode 100644 static/templates/sheets/item/tabs/item-details.hbs create mode 100644 static/templates/sheets/item/tabs/item-effects.hbs diff --git a/src/apps/sheets/actor/base.js b/src/apps/sheets/actor/base.js index 738116a26..1f7c3b30f 100644 --- a/src/apps/sheets/actor/base.js +++ b/src/apps/sheets/actor/base.js @@ -93,18 +93,7 @@ export default class BaseWFRP4eActorSheet extends WarhammerActorSheetV2 return context; } - - _setupContextMenus() - { - // return - return [ - WarhammerContextMenu.create(this, this.element, ".list-row:not(.nocontext)", this._getListContextOptions()), - WarhammerContextMenu.create(this, this.element, ".context-menu", this._getListContextOptions(), {eventName : "click"}), - WarhammerContextMenu.create(this, this.element, ".context-menu-alt", this._getListContextOptions()) - ]; - } - - _getListContextOptions() + _getContetMenuOptions() { return [ { diff --git a/src/apps/sheets/item/base.js b/src/apps/sheets/item/base.js new file mode 100644 index 000000000..8a766f19d --- /dev/null +++ b/src/apps/sheets/item/base.js @@ -0,0 +1,572 @@ +export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 +{ + + static DEFAULT_OPTIONS = { + classes: ["wfrp4e"], + actions : { + + }, + defaultTab : "description" + } + + async _prepareContext(options) + { + let context = await super._prepareContext(options); + return context; + } + + static TABS = { + description: { + id: "description", + group: "primary", + label: "Description", + }, + details: { + id: "details", + group: "primary", + label: "Details", + }, + effects: { + id: "effects", + group: "primary", + label: "Effects", + } + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-details.hbs' }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } + + + _getContetMenuOptions() + { + return [ + { + name: "Edit", + icon: '', + condition: li => !!li.data("uuid") || !!li.parents("[data-uuid]"), + callback: async li => { + let uuid = li.data("uuid") || li.parents("[data-uuid]").data("uuid"); + const document = await fromUuid(uuid); + document.sheet.render(true); + } + }, + { + name: "Remove", + icon: '', + condition: li => { + let uuid = li.data("uuid") || li.parents("[data-uuid]")?.data("uuid") + if (uuid) + { + let doc = fromUuidSync(uuid); + if (doc?.documentName == "ActiveEffect") + { + return true; + } + } + else return false; + }, + callback: async li => + { + let uuid = li.data("uuid") || li.parents("[data-uuid]").data("uuid"); + const document = await fromUuid(uuid); + document.delete(); + } + }, + { + name: "Duplicate", + icon: '', + condition: li => { + let uuid = li.data("uuid") || li.parents("[data-uuid]")?.data("uuid") + if (uuid) + { + let doc = fromUuidSync(uuid); + return doc?.documentName == "ActiveEffect" + } + else return false; + }, + callback: async li => + { + let uuid = li.data("uuid") || li.parents("[data-uuid]").data("uuid"); + const document = await fromUuid(uuid); + this.actor.createEmbeddedDocuments("ActiveEffect", [document.toObject()]); + } + }, + ]; + } + + async _onDropItem(data, ev) + { + let containerDropElement = this._getParent(ev.target, ".container-drop") + if (containerDropElement) + { + let document = await fromUuid(data.uuid); + let container = await fromUuid(containerDropElement.dataset.uuid); + + // + if (container.id == document.system.location.value) + { + return super._onDropItem(data, ev); + } + if (container) + { + document.update({"system.location.value" : container.id}) + } + } + else + { + return super._onDropItem(data, ev); + } + } + + // From Income results - drag money value over to add + _onDropIncome(data) + { + this.document.updateEmbeddedDocuments("Item", MarketWFRP4e.addMoneyTo(this.document, data.amount)); + } + + //#region Effects + +// _prepareEffectsContext(context) { +// super._prepareEffectsContext(context); + +// context.effects.passive = this._consolidateEffects(context.effects.passive) +// context.effects.temporary = this._consolidateEffects(context.effects.temporary) +// context.effects.disabled = this._consolidateEffects(context.effects.disabled) +// context.effects.system = game.wfrp4e.utility.getSystemEffects(this.actor.type == "vehicle"); + +// } + + + _getConditionData(context) { + try { + let conditions = foundry.utils.duplicate(game.wfrp4e.config.statusEffects).map(e => new ActiveEffectWFRP4e(e)); + let currentConditions = this.actor.effects.filter(e => e.isCondition); + delete conditions.splice(conditions.length - 1, 1) + + for (let condition of conditions) { + let owned = currentConditions.find(e => e.conditionId == condition.conditionId) + if (owned) { + condition.existing = true + condition.system.condition.value = owned.conditionValue; + } + else if (condition.isNumberedCondition) { + condition.system.condition.value = 0 + } + } + return conditions; + } + catch (e) + { + ui.notifications.error("Error Adding Condition Data: " + e); + } + } + + _consolidateEffects(effects) { + let consolidated = [] + for (let effect of effects) { + let existing = consolidated.find(e => e.name == effect.name) + if (!existing) + consolidated.push(effect) + } + for (let effect of consolidated) { + let count = effects.filter(e => e.name == effect.name).length + effect.count = count + } + return consolidated + } + + //#endregion + + _addEventListeners() + { + super._addEventListeners(); + this.element.querySelectorAll('.symptom-tag').forEach(el => el.addEventListener("click", WFRP_Utility.handleSymptomClick.bind(WFRP_Utility))) + this.element.querySelectorAll('.condition-chat').forEach(el => el.addEventListener("click", WFRP_Utility.handleConditionClick.bind(WFRP_Utility))) + this.element.querySelectorAll('.property-chat').forEach(el => el.addEventListener("click", WFRP_Utility.handlePropertyClick.bind(WFRP_Utility))) + this.element.querySelectorAll('.table-click').forEach(el => el.addEventListener("click", WFRP_Utility.handleTableClick.bind(WFRP_Utility))) + this.element.querySelectorAll('.pay-link').forEach(el => el.addEventListener("click", WFRP_Utility.handlePayClick.bind(WFRP_Utility))) + this.element.querySelectorAll('.credit-link').forEach(el => el.addEventListener("click", WFRP_Utility.handleCreditClick.bind(WFRP_Utility))) + this.element.querySelectorAll('.corruption-link').forEach(el => el.addEventListener("click", WFRP_Utility.handleCorruptionClick.bind(WFRP_Utility))) + this.element.querySelectorAll('.fear-link').forEach(el => el.addEventListener("click", WFRP_Utility.handleFearClick.bind(WFRP_Utility))) + this.element.querySelectorAll('.terror-link').forEach(el => el.addEventListener("click", WFRP_Utility.handleTerrorClick.bind(WFRP_Utility))) + this.element.querySelectorAll('.exp-link').forEach(el => el.addEventListener("click", WFRP_Utility.handleExpClick.bind(WFRP_Utility))) + + this.element.querySelector(".system-effects")?.addEventListener("change", (ev) => { + let key = ev.target.value; + this.actor.addSystemEffect(key) + }); + + this.element.querySelectorAll(".rollable").forEach(element => { + element.addEventListener("mouseenter", ev => { + let img = ev.target.matches("img") ? ev.target : ev.target.querySelector("img") ; + if (img) + { + this._icon = img.src; + img.src = "systems/wfrp4e/ui/buttons/d10.webp"; + } + }) + element.addEventListener("mouseleave", ev => { + let img = ev.target.matches("img") ? ev.target : ev.target.querySelector("img") ; + if (img) + { + img.src = this._icon; + } + }) + }); + } + + + async _handleEnrichment() { + let enrichment = {} + return expandObject(enrichment) + } + + /** + * Prevent effects from stacking up each form submission + * @override + */ + async _processSubmitData(event, form, submitData) { + let diffData = foundry.utils.diffObject(this.document.toObject(false), submitData) + await this.document.update(diffData); + } + + + //#region Action Handlers + static async _onCreateEffect(ev) + { + let type = ev.target.dataset.category; + let effectData = { name: localize("WH.NewEffect"), img: "icons/svg/aura.svg" }; + if (type == "temporary") + { + effectData["duration.rounds"] = 1; + } + else if (type == "disabled") + { + effectData.disabled = true; + } + + // If Item effect, use item name for effect name + if (this.object.documentName == "Item") + { + effectData.name = this.object.name; + effectData.img = this.object.img; + } + this.object.createEmbeddedDocuments("ActiveEffect", [effectData]).then(effects => effects[0].sheet.render(true)); + } + + static async _onCreateItem(ev) + { + let type = this._getParent(ev.target, "[data-type]").dataset.type; + let category = this._getParent(ev.target, "[data-type]").dataset.category; + let itemData = {type, name : `New ${game.i18n.localize(CONFIG.Item.typeLabels[type])}`} + + if (type == "trapping") + { + itemData["system.trappingType.value"] = category; + } + else if (type == "spell" && category == "petty") + { + itemData["system.lore.value"] = category; + } + else if (type == "prayer") + { + itemData["system.type.value"] = category; + } + + this.document.createEmbeddedDocuments("Item", [itemData]).then(item => item[0].sheet.render(true)); + } + + static async _onConfigureActor(ev) + { + new ActorSettings(this.actor).render(true); + } + + static async _onUseAspect(ev) + { + let document = await this._getDocumentAsync(ev); + if (document && document.system.usable) + { + document.system.use(); + } + } + + static async _onRollTest(ev) + { + let test; + let document = await this._getDocumentAsync(ev); + let options = {fields : {}}; + let target = this._getParent(ev.target, "[data-action='rollTest']") + if (target) + { + options.fields.modifier = Number(target.dataset.modifier) || 0; + } + switch (target.dataset.type) + { + case "characteristic": + test = await this.document.setupCharacteristic(ev.target.dataset.characteristic, options) + break; + case "skill": + test = await this.document.setupSkill(document.name, options) + break; + case "extendedTest": + test = await this.document.setupExtendedTest(document, options); + break; + case "trait": + test = await this.document.setupTrait(document, options); + break; + case "weapon": + test = await this.document.setupWeapon(document, options); + break; + case "spell": + test = await this.castOrChannelPrompt(document, options); + break; + case "prayer": + test = await this.actor.setupPrayer(document, options); + break; + } + + test?.roll(); + } + + castOrChannelPrompt(spell, options = {}) { + // Do not show the dialog for Petty spells, just cast it. + if (spell.system.lore.value == "petty" || spell.system.lore.value == game.i18n.localize("WFRP4E.MagicLores.petty")) + { + return this.actor.setupCast(spell, options) + } + else { + return Dialog.wait({ + title: game.i18n.localize("DIALOG.CastOrChannel"), + content: `
+

${game.i18n.localize("DIALOG.CastChannel")}

+
`, + buttons: { + cast: { + label: game.i18n.localize("Cast"), + callback: btn => { + return this.actor.setupCast(spell, options); + } + }, + channel: { + label: game.i18n.localize("Channel"), + callback: async btn => { + return this.actor.setupChannell(spell, options); + // TODO: move this elsewhere + // await test.roll(); + // if (test.context.channelUntilSuccess) { + // await warhammer.utility.sleep(200); + // do { + // if (test.item.cn.SL >= test.item.cn.value) { + // break; + // } + // if (test.result.minormis || test.result.majormis || test.result.catastrophicmis) { + // break; + // } + // test.context.messageId = null; // Clear message so new message is made + // await test.roll(); + // await warhammer.utility.sleep(200); + // } while (true); + // } + } + } + }, + default: 'cast' + }); + } + } + + static async _toggleExtendedTests(ev) + { + let parent = this._getParent(ev.target, ".tab") + Array.from(parent.querySelectorAll(".extended-tests, .skill-lists, .extended-toggle")).forEach(el => el.classList.toggle("hidden")) + } + + static _onRemoveAttacker(ev) { + this.actor.update({ "flags.-=oppose": null }) + } + + static _onClickCondition(ev) { + let conditionKey = this._getParent(ev.target, ".condition")?.dataset.key + let existing = this.actor.hasCondition(conditionKey) + + if (!existing?.isNumberedCondition && ev.button == 0) + { + this.actor.removeCondition(conditionKey); + } + + ev.button == 0 ? this.actor.addCondition(conditionKey) : this.actor.removeCondition(conditionKey) + } + + static async _onRemoveItemFromContainer(ev) + { + let item = await this._getDocumentAsync(ev); + return item.update({ "system.location.value": "" }) + } + + + static async _toggleSummary(ev) + { + let item = await this._getDocumentAsync(ev); + if (item) + { + let expandData = await item.system.expandData({secrets: this.actor.isOwner}); + this._toggleDropdown(ev, expandData.description.value); + } + } + + async _toggleDropdown(ev, content, parentSelector=".list-row") + { + let dropdownElement = this._getParent(ev.target, parentSelector).querySelector(".dropdown-content"); + if (dropdownElement.classList.contains("collapsed")) + { + dropdownElement.innerHTML = content; + dropdownElement.style.height = `${dropdownElement.scrollHeight}px`; + dropdownElement.classList.replace("collapsed", "expanded"); + // Fit content can't be animated, but we would like it be flexible height, so wait until animation finishes then add fit-content + // sleep(500).then(() => dropdownElement.style.height = `fit-content`); + + } + else if (dropdownElement.classList.contains("expanded")) + { + // dropdownElement.style.height = `${dropdownElement.scrollHeight}px`; + dropdownElement.style.height = `0px`; + dropdownElement.classList.replace("expanded", "collapsed"); + } + } + + static async _onItemPropertyDropdown(ev) { + let item = await this._getDocumentAsync(ev); + let type = ev.target.dataset.type; + let properties = Object.values(item.system.properties[type]) + if (type == "qualities") + { + properties = properties.concat(Object.values(item.system.properties.unusedQualities), Object.values(item.system.properties.inactiveQualities)); + } + let propData = properties.find(p => p.display == ev.target.text); + let key = propData.key; + let value = propData.value; + let propertyDescriptions = foundry.utils.mergeObject(foundry.utils.deepClone(game.wfrp4e.config.qualityDescriptions), game.wfrp4e.config.flawDescriptions); + if (key) + { + let description = propertyDescriptions[key]?.replace("(Rating)", value) || `Description for ${ev.target.text} was not found`; + + this._toggleDropdown(ev, description) + } + } + + static async _onCombatDropdown(ev) { + let property = ev.target.dataset.property; + let item = await this._getDocumentAsync(ev); + let description = ""; + + switch(property) + { + case "group": + description = game.wfrp4e.config.weaponGroupDescriptions[item.system.weaponGroup.value]; + break; + case "reach": + description = game.wfrp4e.config.reachDescription[item.system.reach.value]; + break; + case "special": + description = item.system.properties.special; + break; + case "specialAmmmo": + description = item.system.properties.specialAmmo; + break; + case "range": + if (!game.settings.get("wfrp4e", "mooRangeBands")) + { + + description = + `${item.system.range.bands[`${game.i18n.localize("Point Blank")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Point Blank")}`].range[1]} ${game.i18n.localize("yds")}: ${game.wfrp4e.config.difficultyLabels[game.wfrp4e.config.rangeModifiers["Point Blank"]]}
+ ${item.system.range.bands[`${game.i18n.localize("Short Range")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Short Range")}`].range[1]} ${game.i18n.localize("yds")}: ${game.wfrp4e.config.difficultyLabels[game.wfrp4e.config.rangeModifiers["Short Range"]]}
+ ${item.system.range.bands[`${game.i18n.localize("Normal")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Normal")}`].range[1]} ${game.i18n.localize("yds")}: ${game.wfrp4e.config.difficultyLabels[game.wfrp4e.config.rangeModifiers["Normal"]]}
+ ${item.system.range.bands[`${game.i18n.localize("Long Range")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Long Range")}`].range[1]} ${game.i18n.localize("yds")}: ${game.wfrp4e.config.difficultyLabels[game.wfrp4e.config.rangeModifiers["Long Range"]]}
+ ${item.system.range.bands[`${game.i18n.localize("Extreme")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Extreme")}`].range[1]} ${game.i18n.localize("yds")}: ${game.wfrp4e.config.difficultyLabels[game.wfrp4e.config.rangeModifiers["Extreme"]]}
+ ` + + } + //@HOUSE + else { + game.wfrp4e.utility.logHomebrew("mooRangeBands") + description = + `${item.system.range.bands[`${game.i18n.localize("Point Blank")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Point Blank")}`].range[1]} ${game.i18n.localize("yds")}: ${item.system.range.bands[`${game.i18n.localize("Point Blank")}`].modifier}
+ ${item.system.range.bands[`${game.i18n.localize("Short Range")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Short Range")}`].range[1]} ${game.i18n.localize("yds")}: ${item.system.range.bands[`${game.i18n.localize("Short Range")}`].modifier}
+ ${item.system.range.bands[`${game.i18n.localize("Normal")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Normal")}`].range[1]} ${game.i18n.localize("yds")}: ${item.system.range.bands[`${game.i18n.localize("Normal")}`].modifier}
+ ${item.system.range.bands[`${game.i18n.localize("Long Range")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Long Range")}`].range[1]} ${game.i18n.localize("yds")}: ${item.system.range.bands[`${game.i18n.localize("Long Range")}`].modifier}
+ ${item.system.range.bands[`${game.i18n.localize("Extreme")}`].range[0]} ${game.i18n.localize("yds")} - ${item.system.range.bands[`${game.i18n.localize("Extreme")}`].range[1]} ${game.i18n.localize("yds")}: ${item.system.range.bands[`${game.i18n.localize("Extreme")}`].modifier}
+ ` + } + break; + } + + this._toggleDropdown(ev, description) + } + + static _onConvertCurrency(ev) + { + + ev.preventDefault(); + let type = this._getParent(ev.target, "a").dataset.type; + let money = this.actor.itemTypes.money; + let itemData = MarketWFRP4e.convertMoney(money, type); + return this.actor.updateEmbeddedDocuments("Item", itemData) + } + + static _onConsolidateCurrency(ev) + { + ev.preventDefault(); + let money = this.actor.itemTypes.money; + let newMoney = MarketWFRP4e.consolidateMoney(money.map(i => i.toObject())); + return this.actor.updateEmbeddedDocuments("Item", newMoney) + } + + static _onCollapseSection(ev) + { + let section = this._getParent(ev.target, "a").dataset.section; + let collapsed = this.actor.getFlag("wfrp4e", "sheetCollapsed")?.[section] + + this.actor.setFlag("wfrp4e", `sheetCollapsed.${section}`, !collapsed); + } + + static async _onContainerSort(ev) + { + let direction = this._getParent(ev.target, "a").dataset.direction + + let container = await this._getDocumentAsync(ev); + + // All Containers on the same level as the sorted container + let containers = this.actor.itemTags.container.sort((a, b) => a.sort - b.sort).filter(i => i.system.location.value == container.system.location.value); + + // Index of the sorted container + let index = containers.findIndex(i => i.id == container.id); + + if ((index == 0 && direction == "up") || (index == containers.length - 1 && direction == "down")) + { + return; + } + + // Index of the target container + let targetIndex = direction == "up" ? index - 1 : index + 1; + let target = containers[targetIndex]; + + // Remove sorted container + containers = containers.filter(i => i.id != container.id); + + let sorted = SortingHelpers.performIntegerSort(container, {target, siblings: containers}); + this.actor.updateEmbeddedDocuments("Item", sorted.map(s => + { + return foundry.utils.mergeObject({ + _id : s.target.id, + }, s.update); + })); + + } + + //#endregion +} diff --git a/static/templates/sheets/item/item-header.hbs b/static/templates/sheets/item/item-header.hbs new file mode 100644 index 000000000..82571e1ef --- /dev/null +++ b/static/templates/sheets/item/item-header.hbs @@ -0,0 +1 @@ +

test

\ No newline at end of file diff --git a/static/templates/sheets/item/item-tabs.hbs b/static/templates/sheets/item/item-tabs.hbs new file mode 100644 index 000000000..a0b1c0bf5 --- /dev/null +++ b/static/templates/sheets/item/item-tabs.hbs @@ -0,0 +1,8 @@ + diff --git a/static/templates/sheets/item/tabs/item-description.hbs b/static/templates/sheets/item/tabs/item-description.hbs new file mode 100644 index 000000000..4885c07ae --- /dev/null +++ b/static/templates/sheets/item/tabs/item-description.hbs @@ -0,0 +1,3 @@ +
+

test1

+
\ No newline at end of file diff --git a/static/templates/sheets/item/tabs/item-details.hbs b/static/templates/sheets/item/tabs/item-details.hbs new file mode 100644 index 000000000..996fcfb59 --- /dev/null +++ b/static/templates/sheets/item/tabs/item-details.hbs @@ -0,0 +1,3 @@ +
+

test2

+
\ No newline at end of file diff --git a/static/templates/sheets/item/tabs/item-effects.hbs b/static/templates/sheets/item/tabs/item-effects.hbs new file mode 100644 index 000000000..411323666 --- /dev/null +++ b/static/templates/sheets/item/tabs/item-effects.hbs @@ -0,0 +1,3 @@ +
+

test3

+
\ No newline at end of file diff --git a/wfrp4e.js b/wfrp4e.js index 0f8d5cb88..a63ff4e6d 100644 --- a/wfrp4e.js +++ b/wfrp4e.js @@ -78,6 +78,7 @@ import ActorSheetWFRP4eCharacterV2 from "./src/apps/sheets/actor/character-sheet import { GenericAspectModel } from "./modules/model/item/generic.js"; import ActorSheetWFRP4eNPCV2 from "./src/apps/sheets/actor/npc-sheet.js"; import ActorSheetWFRP4eCreatureV2 from "./src/apps/sheets/actor/creature-sheet.js"; +import BaseWFRP4eItemSheet from "./src/apps/sheets/item/base.js"; /* -------------------------------------------- */ /* Foundry VTT Initialization */ @@ -101,7 +102,7 @@ Hooks.once("init", function () { Actors.registerSheet("wfrp4e", ActorSheetWFRP4eVehicle, { types: ["vehicle"], makeDefault: true }); Items.unregisterSheet("core", ItemSheet); - Items.registerSheet("wfrp4e", ItemSheetWfrp4e, { makeDefault: true }); + Items.registerSheet("wfrp4e", BaseWFRP4eItemSheet, { makeDefault: true }); DocumentSheetConfig.registerSheet(RollTable, "wfrp4e", WFRPTableConfig, {makeDefault: true}) DocumentSheetConfig.registerSheet(ActiveEffect, "wfrp4e", WFRP4eActiveEffectConfig, {makeDefault :true}) // DocumentSheetConfig.registerSheet(JournalEntry, "wfrp4e", WFRPJournalSheet, {makeDefault :true}) From 701b51ee19b39195fcc4c5f395c6d1ae359c4202 Mon Sep 17 00:00:00 2001 From: Russell Date: Fri, 29 Nov 2024 16:27:59 -0600 Subject: [PATCH 2/3] Implement ItemSheetV2 --- modules/hooks/init.js | 2 + modules/model/actor/components/details.js | 4 +- modules/model/item/ammunition.js | 8 +- modules/model/item/armour.js | 5 +- modules/model/item/career.js | 52 +- modules/model/item/cargo.js | 6 +- modules/model/item/components/base.js | 4 +- modules/model/item/components/locational.js | 4 + modules/model/item/container.js | 2 + modules/model/item/corruption.js | 22 - modules/model/item/critical.js | 3 + modules/model/item/disease.js | 9 +- modules/model/item/extendedTest.js | 7 +- modules/model/item/injury.js | 4 + modules/model/item/money.js | 2 + modules/model/item/mutation.js | 9 +- modules/model/item/prayer.js | 4 +- modules/model/item/skill.js | 10 +- modules/model/item/spell.js | 2 + modules/model/item/talent.js | 4 +- modules/model/item/trait.js | 11 +- modules/model/item/trapping.js | 3 +- modules/model/item/vehicleMod.js | 3 +- modules/model/item/vehicleRole.js | 1 + modules/model/item/vehicleTest.js | 1 + modules/model/item/weapon.js | 9 +- modules/system/config-wfrp4e.js | 1 + src/apps/sheets/item/ammunition-sheet.js | 18 + src/apps/sheets/item/armour-sheet.js | 18 + src/apps/sheets/item/base.js | 31 +- src/apps/sheets/item/career-sheet.js | 55 ++ src/apps/sheets/item/cargo.js | 26 + src/apps/sheets/item/container-sheet.js | 18 + src/apps/sheets/item/critical-sheet.js | 19 + src/apps/sheets/item/disease-sheet.js | 25 + src/apps/sheets/item/extendedTest-sheet.js | 18 + src/apps/sheets/item/injury-sheet.js | 18 + src/apps/sheets/item/money.js | 26 + src/apps/sheets/item/mutation-sheet.js | 18 + src/apps/sheets/item/prayer-sheet.js | 18 + src/apps/sheets/item/psychology-sheet.js | 30 ++ src/apps/sheets/item/skill-sheet.js | 18 + src/apps/sheets/item/spell-sheet.js | 18 + src/apps/sheets/item/talent-sheet.js | 12 +- src/apps/sheets/item/trait-sheet.js | 25 + src/apps/sheets/item/trapping-sheet.js | 18 + src/apps/sheets/item/vehicleMod-sheet.js | 18 + src/apps/sheets/item/vehicleRole-sheet.js | 18 + src/apps/sheets/item/vehicleTest-sheet.js | 18 + src/apps/sheets/item/weapon-sheet.js | 18 + static/lang/en.json | 499 ++++++++++++++++++ static/templates/items/item-weapon-sheet.hbs | 1 - static/templates/sheets/item/item-header.hbs | 53 +- .../sheets/item/tabs/item-description.hbs | 12 +- .../sheets/item/tabs/item-effects.hbs | 98 +++- .../sheets/item/types/ammunition.hbs | 11 + static/templates/sheets/item/types/armour.hbs | 14 + static/templates/sheets/item/types/career.hbs | 88 +++ static/templates/sheets/item/types/cargo.hbs | 7 + .../templates/sheets/item/types/container.hbs | 5 + .../templates/sheets/item/types/critical.hbs | 5 + .../templates/sheets/item/types/disease.hbs | 23 + .../sheets/item/types/extendedTest.hbs | 12 + static/templates/sheets/item/types/injury.hbs | 8 + static/templates/sheets/item/types/money.hbs | 3 + .../templates/sheets/item/types/mutation.hbs | 3 + static/templates/sheets/item/types/prayer.hbs | 22 + static/templates/sheets/item/types/skill.hbs | 10 + static/templates/sheets/item/types/spell.hbs | 44 ++ static/templates/sheets/item/types/talent.hbs | 7 + static/templates/sheets/item/types/trait.hbs | 21 + .../templates/sheets/item/types/trapping.hbs | 4 + .../sheets/item/types/vehicleMod.hbs | 3 + .../sheets/item/types/vehicleRole.hbs | 3 + .../sheets/item/types/vehicleTest.hbs | 5 + static/templates/sheets/item/types/weapon.hbs | 25 + .../sheets/partials/extra-overcast.hbs | 81 +++ .../sheets/partials/item-properties.hbs | 8 + style/sheets/_light.scss | 3 + style/sheets/actors/_actor.scss | 72 --- style/sheets/items/_index.scss | 1 + style/sheets/items/_item.scss | 135 +++++ style/wfrp4e.scss | 3 +- wfrp4e.js | 47 +- 84 files changed, 1874 insertions(+), 155 deletions(-) delete mode 100644 modules/model/item/corruption.js create mode 100644 src/apps/sheets/item/ammunition-sheet.js create mode 100644 src/apps/sheets/item/armour-sheet.js create mode 100644 src/apps/sheets/item/career-sheet.js create mode 100644 src/apps/sheets/item/cargo.js create mode 100644 src/apps/sheets/item/container-sheet.js create mode 100644 src/apps/sheets/item/critical-sheet.js create mode 100644 src/apps/sheets/item/disease-sheet.js create mode 100644 src/apps/sheets/item/extendedTest-sheet.js create mode 100644 src/apps/sheets/item/injury-sheet.js create mode 100644 src/apps/sheets/item/money.js create mode 100644 src/apps/sheets/item/mutation-sheet.js create mode 100644 src/apps/sheets/item/prayer-sheet.js create mode 100644 src/apps/sheets/item/psychology-sheet.js create mode 100644 src/apps/sheets/item/skill-sheet.js create mode 100644 src/apps/sheets/item/spell-sheet.js create mode 100644 src/apps/sheets/item/trait-sheet.js create mode 100644 src/apps/sheets/item/trapping-sheet.js create mode 100644 src/apps/sheets/item/vehicleMod-sheet.js create mode 100644 src/apps/sheets/item/vehicleRole-sheet.js create mode 100644 src/apps/sheets/item/vehicleTest-sheet.js create mode 100644 src/apps/sheets/item/weapon-sheet.js create mode 100644 static/templates/sheets/item/types/ammunition.hbs create mode 100644 static/templates/sheets/item/types/armour.hbs create mode 100644 static/templates/sheets/item/types/career.hbs create mode 100644 static/templates/sheets/item/types/cargo.hbs create mode 100644 static/templates/sheets/item/types/container.hbs create mode 100644 static/templates/sheets/item/types/critical.hbs create mode 100644 static/templates/sheets/item/types/disease.hbs create mode 100644 static/templates/sheets/item/types/extendedTest.hbs create mode 100644 static/templates/sheets/item/types/injury.hbs create mode 100644 static/templates/sheets/item/types/money.hbs create mode 100644 static/templates/sheets/item/types/mutation.hbs create mode 100644 static/templates/sheets/item/types/prayer.hbs create mode 100644 static/templates/sheets/item/types/skill.hbs create mode 100644 static/templates/sheets/item/types/spell.hbs create mode 100644 static/templates/sheets/item/types/talent.hbs create mode 100644 static/templates/sheets/item/types/trait.hbs create mode 100644 static/templates/sheets/item/types/trapping.hbs create mode 100644 static/templates/sheets/item/types/vehicleMod.hbs create mode 100644 static/templates/sheets/item/types/vehicleRole.hbs create mode 100644 static/templates/sheets/item/types/vehicleTest.hbs create mode 100644 static/templates/sheets/item/types/weapon.hbs create mode 100644 static/templates/sheets/partials/extra-overcast.hbs create mode 100644 static/templates/sheets/partials/item-properties.hbs create mode 100644 style/sheets/items/_index.scss create mode 100644 style/sheets/items/_item.scss diff --git a/modules/hooks/init.js b/modules/hooks/init.js index 08268d1af..2bb42b2d0 100644 --- a/modules/hooks/init.js +++ b/modules/hooks/init.js @@ -739,6 +739,8 @@ export default function() { rangedWeapons: "systems/wfrp4e/templates/sheets/partials/ranged-weapons.hbs", armourLocation: "systems/wfrp4e/templates/sheets/partials/armour-location.hbs", creatureArmour: "systems/wfrp4e/templates/sheets/partials/creature-armour.hbs", + itemProperties: "systems/wfrp4e/templates/sheets/partials/item-properties.hbs", + extraOvercast: "systems/wfrp4e/templates/sheets/partials/extra-overcast.hbs", }); // Load name construction from files diff --git a/modules/model/actor/components/details.js b/modules/model/actor/components/details.js index 37d8a216b..771fba48a 100644 --- a/modules/model/actor/components/details.js +++ b/modules/model/actor/components/details.js @@ -134,10 +134,10 @@ export class VehicleDetailsModel extends foundry.abstract.DataModel { value: new fields.NumberField({min: 1, initial : 25}) }); schema.description = new fields.SchemaField({ - value: new fields.StringField({ initial: "" }) + value: new fields.HTMLField() }); schema.gmdescription = new fields.SchemaField({ - value: new fields.StringField({ initial: "" }), + value: new fields.HTMLField() }); schema.price = new fields.SchemaField({ gc: new fields.NumberField({initial : 0}) diff --git a/modules/model/item/ammunition.js b/modules/model/item/ammunition.js index b69f28aa9..3aafac5c6 100644 --- a/modules/model/item/ammunition.js +++ b/modules/model/item/ammunition.js @@ -4,11 +4,13 @@ let fields = foundry.data.fields; export class AmmunitionModel extends PropertiesMixin(PhysicalItemModel) { + static LOCALIZATION_PREFIXES = ["WH.Models.ammunition"]; + static defineSchema() { let schema = super.defineSchema(); schema.ammunitionType = new fields.SchemaField({ - value: new fields.StringField() + value: new fields.StringField({choices : game.wfrp4e.config.ammunitionGroups}) }); schema.range = new fields.SchemaField({ value: new fields.StringField() @@ -17,9 +19,7 @@ export class AmmunitionModel extends PropertiesMixin(PhysicalItemModel) value: new fields.StringField(), dice: new fields.StringField({ initial: "" }) }); - schema.ammunitionType = new fields.SchemaField({ - value: new fields.StringField() - }); + schema.special = new fields.SchemaField({ value: new fields.StringField() }); diff --git a/modules/model/item/armour.js b/modules/model/item/armour.js index a90610bdd..c35d903ff 100644 --- a/modules/model/item/armour.js +++ b/modules/model/item/armour.js @@ -8,10 +8,11 @@ let fields = foundry.data.fields; * @mixes PropertiesMixin */ export class ArmourModel extends PropertiesMixin(EquippableItemModel) { - static defineSchema() { + static LOCALIZATION_PREFIXES = ["WH.Models.armour"]; + static defineSchema() { let schema = super.defineSchema(); schema.armorType = new fields.SchemaField({ // TODO migrate this to the "correct" spelling - value: new fields.StringField() + value: new fields.StringField({}),//choices : game.wfrp4e.config.armorTypes}) }); schema.penalty = new fields.SchemaField({ value: new fields.StringField() diff --git a/modules/model/item/career.js b/modules/model/item/career.js index 9c518781a..cf86acc05 100644 --- a/modules/model/item/career.js +++ b/modules/model/item/career.js @@ -3,6 +3,7 @@ let fields = foundry.data.fields; export class CareerModel extends BaseItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.career"]; static defineSchema() { let schema = super.defineSchema(); @@ -19,13 +20,26 @@ export class CareerModel extends BaseItemModel value: new fields.BooleanField() }); schema.level = new fields.SchemaField({ - value: new fields.NumberField({min: 1}) + // value: new fields.NumberField({min: 1, choices : [1, 2, 3, 4], initial : 1}) + value: new fields.NumberField({min: 1, choices : {1 : "1", 2 : "2", 3 : "3", 4 : "4"}, initial : 1}) }); schema.status = new fields.SchemaField({ standing: new fields.NumberField({min: 1}), - tier: new fields.StringField({choices: ["b", "s", "g"]}) + tier: new fields.StringField({choices: game.wfrp4e.config.statusTiers}) }); - schema.characteristics = new fields.ArrayField(new fields.StringField()); + schema.characteristics = new fields.SchemaField({ + ws: new fields.BooleanField(), + bs: new fields.BooleanField(), + s: new fields.BooleanField(), + t: new fields.BooleanField(), + i: new fields.BooleanField(), + ag: new fields.BooleanField(), + dex: new fields.BooleanField(), + int: new fields.BooleanField(), + wp: new fields.BooleanField(), + fel: new fields.BooleanField(), + }) + schema.skills = new fields.ArrayField(new fields.StringField()); schema.addedSkills = new fields.ArrayField(new fields.StringField()); schema.talents = new fields.ArrayField(new fields.StringField()); @@ -185,4 +199,36 @@ export class CareerModel extends BaseItemModel properties.push(`${game.i18n.localize("Income")}: ${this.incomeSkill.map(i => " " + this.skills[i])}`); return properties; } + + static migrateData(data) + { + if (data.characteristics instanceof Array) + { + data.characteristics = { + ws : data.characteristics.includes("ws"), + bs : data.characteristics.includes("bs"), + s : data.characteristics.includes("s"), + t : data.characteristics.includes("t"), + i : data.characteristics.includes("i"), + ag : data.characteristics.includes("ag"), + dex : data.characteristics.includes("dex"), + int : data.characteristics.includes("int"), + wp : data.characteristics.includes("wp"), + fel : data.characteristics.includes("fel") + } + } + + // if (data.skills instanceof Array) + // { + // data.skills = {list : data.skills}; + // } + // if (data.talents instanceof Array) + // { + // data.talents = {list : data.talents}; + // } + // if (data.trappings instanceof Array) + // { + // data.trappings = {list : data.trappings}; + // } + } } \ No newline at end of file diff --git a/modules/model/item/cargo.js b/modules/model/item/cargo.js index 4c8df8a95..8fb6f9c35 100644 --- a/modules/model/item/cargo.js +++ b/modules/model/item/cargo.js @@ -3,11 +3,13 @@ let fields = foundry.data.fields; export class CargoModel extends PhysicalItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.cargo"]; static defineSchema() { + let schema = super.defineSchema(); schema.cargoType = new fields.SchemaField({ - value: new fields.StringField() + value: new fields.StringField({}) }); schema.unitPrice = new fields.SchemaField({ value: new fields.NumberField() @@ -18,7 +20,7 @@ export class CargoModel extends PhysicalItemModel schema.quality = new fields.SchemaField({ value: new fields.StringField({initial : "average"}) }); - schema.tradeType = new fields.StringField({initial : "river"}) + schema.tradeType = new fields.StringField({initial : "river", choices : {river : "River", maritime : "Maritime"}}) return schema; } diff --git a/modules/model/item/components/base.js b/modules/model/item/components/base.js index 019b75a21..f9d356c0f 100644 --- a/modules/model/item/components/base.js +++ b/modules/model/item/components/base.js @@ -7,10 +7,10 @@ let fields = foundry.data.fields; { return { description : new fields.SchemaField({ - value: new fields.StringField() + value: new fields.HTMLField() }), gmdescription : new fields.SchemaField({ - value: new fields.StringField() + value: new fields.HTMLField() }), } } diff --git a/modules/model/item/components/locational.js b/modules/model/item/components/locational.js index 2ef9159d7..7a8fe32c6 100644 --- a/modules/model/item/components/locational.js +++ b/modules/model/item/components/locational.js @@ -2,6 +2,10 @@ import { BaseItemModel } from "./base"; let fields = foundry.data.fields; export class LocationalItemModel extends BaseItemModel { + + static LOCALIZATION_PREFIXES = ["WH.Components.Locational"]; + + static defineSchema() { let schema = super.defineSchema(); schema.prompt = new fields.BooleanField(); diff --git a/modules/model/item/container.js b/modules/model/item/container.js index 6e7c0b19f..f416af5d7 100644 --- a/modules/model/item/container.js +++ b/modules/model/item/container.js @@ -7,6 +7,8 @@ let fields = foundry.data.fields; * @extends EquippableItemModel */ export class ContainerModel extends EquippableItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.container"]; + static defineSchema() { let schema = super.defineSchema(); schema.wearable = new fields.SchemaField({ diff --git a/modules/model/item/corruption.js b/modules/model/item/corruption.js deleted file mode 100644 index 17876db31..000000000 --- a/modules/model/item/corruption.js +++ /dev/null @@ -1,22 +0,0 @@ -import { BaseItemModel } from "./components/base"; -let fields = foundry.data.fields; - -export class CorruptionModel extends BaseItemModel -{ - static defineSchema() - { - let schema = super.defineSchema(); - schema.category = new fields.StringField(); - return schema; - } - - /** - * Used to identify an Item as one being a child or instance of CorruptionModel - * - * @final - * @returns {boolean} - */ - get isCorruption() { - return true; - } -} \ No newline at end of file diff --git a/modules/model/item/critical.js b/modules/model/item/critical.js index 767d571d5..6ef754b25 100644 --- a/modules/model/item/critical.js +++ b/modules/model/item/critical.js @@ -2,6 +2,9 @@ import { LocationalItemModel } from "./components/locational"; let fields = foundry.data.fields; export class CriticalModel extends LocationalItemModel { + + static LOCALIZATION_PREFIXES = ["WH.Models.critical"]; + static defineSchema() { let schema = super.defineSchema(); schema.wounds = new fields.SchemaField({ diff --git a/modules/model/item/disease.js b/modules/model/item/disease.js index d8d60212b..5affe90b3 100644 --- a/modules/model/item/disease.js +++ b/modules/model/item/disease.js @@ -7,6 +7,8 @@ let fields = foundry.data.fields; */ export class DiseaseModel extends BaseItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.disease"]; + static defineSchema() { let schema = super.defineSchema(); schema.contraction = new fields.SchemaField({ @@ -44,6 +46,11 @@ export class DiseaseModel extends BaseItemModel { { this.start("duration"); } + + if (foundry.utils.hasProperty(options, "changed.system.symptoms.value") && !options.skipSymptomHandling) + { + this.updateSymptoms(this.symptoms.value); + } } async _onCreate(data, options, user) @@ -136,7 +143,7 @@ export class DiseaseModel extends BaseItemModel { // Add symptoms from input await this.parent.createEmbeddedDocuments("ActiveEffect", symptomEffects) - return this.parent.update({ "system.symptoms.value": text }) + return this.parent.update({ "system.symptoms.value": text }, {skipSymptomHandling : true}) } async start(type, update=false) diff --git a/modules/model/item/extendedTest.js b/modules/model/item/extendedTest.js index 9c79a29fa..64bf08035 100644 --- a/modules/model/item/extendedTest.js +++ b/modules/model/item/extendedTest.js @@ -2,6 +2,9 @@ import { BaseItemModel } from "./components/base"; let fields = foundry.data.fields; export class ExtendedTestModel extends BaseItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.extendedTest"]; + + static defineSchema() { let schema = super.defineSchema(); @@ -23,7 +26,7 @@ export class ExtendedTestModel extends BaseItemModel { }); schema.completion = new fields.SchemaField({ - value: new fields.StringField({ initial: "none" }) + value: new fields.StringField({ initial: "none", choices : game.wfrp4e.config.extendedTestCompletion}) }); schema.hide = new fields.SchemaField({ @@ -32,7 +35,7 @@ export class ExtendedTestModel extends BaseItemModel { }); schema.difficulty = new fields.SchemaField({ - value: new fields.StringField({ initial: "challenging" }) + value: new fields.StringField({ initial: "challenging", choices : game.wfrp4e.config.difficultyLabels }) }); return schema; diff --git a/modules/model/item/injury.js b/modules/model/item/injury.js index 63165231b..ed2bd162c 100644 --- a/modules/model/item/injury.js +++ b/modules/model/item/injury.js @@ -4,6 +4,10 @@ let fields = foundry.data.fields; export class InjuryModel extends LocationalItemModel { + + static LOCALIZATION_PREFIXES = ["WH.Models.injury"]; + + static defineSchema() { let schema = super.defineSchema(); diff --git a/modules/model/item/money.js b/modules/model/item/money.js index c7d38d074..93e1fd635 100644 --- a/modules/model/item/money.js +++ b/modules/model/item/money.js @@ -3,6 +3,8 @@ let fields = foundry.data.fields; export class MoneyModel extends PhysicalItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.money"]; + static defineSchema() { // Patron Fields diff --git a/modules/model/item/mutation.js b/modules/model/item/mutation.js index 8c70c9f7d..e3ae62520 100644 --- a/modules/model/item/mutation.js +++ b/modules/model/item/mutation.js @@ -3,22 +3,19 @@ let fields = foundry.data.fields; export class MutationModel extends BaseItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.mutation"]; + static defineSchema() { // Patron Fields let schema = super.defineSchema(); schema.mutationType = new fields.SchemaField({ - value : new fields.StringField(), + value : new fields.StringField({choices : game.wfrp4e.config.mutationTypes}), }); schema.modifier = new fields.SchemaField({ value : new fields.StringField(), }) - - schema.modifiesSkills = new fields.SchemaField({ - value : new fields.BooleanField(), - }); - return schema; } diff --git a/modules/model/item/prayer.js b/modules/model/item/prayer.js index 125266900..fbd544bb3 100644 --- a/modules/model/item/prayer.js +++ b/modules/model/item/prayer.js @@ -5,12 +5,14 @@ let fields = foundry.data.fields; export class PrayerModel extends OvercastItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.prayer"]; + static defineSchema() { let schema = super.defineSchema(); schema.type = new fields.SchemaField({ - value : new fields.StringField(), + value : new fields.StringField({initial : "blessing", choices : game.wfrp4e.config.prayerTypes}), }); schema.god = new fields.SchemaField({ value : new fields.StringField(), diff --git a/modules/model/item/skill.js b/modules/model/item/skill.js index d7bfcfc7d..f664a88fe 100644 --- a/modules/model/item/skill.js +++ b/modules/model/item/skill.js @@ -4,16 +4,18 @@ import { BaseItemModel } from "./components/base"; let fields = foundry.data.fields; export class SkillModel extends BaseItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.skill"]; + static defineSchema() { let schema = super.defineSchema(); schema.advanced = new fields.SchemaField({ - value: new fields.StringField(), + value: new fields.StringField({initial : "bsc", choices : game.wfrp4e.config.skillTypes}), }); schema.grouped = new fields.SchemaField({ - value: new fields.StringField({ initial: "noSpec" }) + value: new fields.StringField({ initial: "noSpec", choices : game.wfrp4e.config.skillGroup }) }); schema.characteristic = new fields.SchemaField({ - value: new fields.StringField({ initial: "ws" }), + value: new fields.StringField({ initial: "ws", choices : game.wfrp4e.config.characteristics }), }); schema.advances = new fields.SchemaField({ value: new fields.NumberField(), @@ -80,7 +82,7 @@ export class SkillModel extends BaseItemModel { if (this.parent.isEmbedded) { // If skill has (any) or (), ask for a specialisation - if (this.parent.specifier.toLowerCase() == game.i18n.localize("SPEC.Any").toLowerCase() || this.grouped.value && !this.parent.specifier) + if (this.parent.specifier.toLowerCase() == game.i18n.localize("SPEC.Any").toLowerCase() || (this.grouped.value == "isSpec" && !(this.parent.specifier))) { let skills = await warhammer.utility.findAllItems("skill", "Loading Skills", true); let specialisations = skills.filter(i => i.name.split("(")[0]?.trim() == this.parent.baseName); diff --git a/modules/model/item/spell.js b/modules/model/item/spell.js index 3dba4b60e..6c9754d57 100644 --- a/modules/model/item/spell.js +++ b/modules/model/item/spell.js @@ -5,6 +5,8 @@ import { OvercastItemModel } from "./components/overcast"; let fields = foundry.data.fields; export class SpellModel extends OvercastItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.spell"]; + static defineSchema() { let schema = super.defineSchema(); diff --git a/modules/model/item/talent.js b/modules/model/item/talent.js index 55b8b2fb5..7e2ebc68e 100644 --- a/modules/model/item/talent.js +++ b/modules/model/item/talent.js @@ -1,11 +1,13 @@ import { BaseItemModel } from "./components/base"; let fields = foundry.data.fields; + export class TalentModel extends BaseItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.talent"]; static defineSchema() { let schema = super.defineSchema(); schema.max = new fields.SchemaField({ - value: new fields.StringField() + value: new fields.StringField({choices : game.wfrp4e.config.talentMax}) }); schema.advances = new fields.SchemaField({ value: new fields.NumberField({initial : 1, min: 1}), diff --git a/modules/model/item/trait.js b/modules/model/item/trait.js index ccaa0f22b..a2ace4ac9 100644 --- a/modules/model/item/trait.js +++ b/modules/model/item/trait.js @@ -4,22 +4,23 @@ let fields = foundry.data.fields; export class TraitModel extends PropertiesMixin(BaseItemModel) { + static LOCALIZATION_PREFIXES = ["WH.Models.trait"]; static defineSchema() { let schema = super.defineSchema(); - schema.category = new fields.StringField({initial : "standard"}); + schema.category = new fields.StringField({initial : "standard", choices : {standard : "Standard", vehicle : "Vehicle"}}); schema.rollable = new fields.SchemaField({ value : new fields.BooleanField({}), damage : new fields.BooleanField({}), skill : new fields.StringField({}), - rollCharacteristic : new fields.StringField({}), - bonusCharacteristic : new fields.StringField({}), + rollCharacteristic : new fields.StringField({choices : game.wfrp4e.config.characteristics}), + bonusCharacteristic : new fields.StringField({choices : game.wfrp4e.config.characteristics, initial : "s"}), dice : new fields.StringField({}), - defaultDifficulty : new fields.StringField({}), + defaultDifficulty : new fields.StringField({initial : "challenging", choices : game.wfrp4e.config.difficultyLabels}), SL : new fields.BooleanField({}), - attackType : new fields.StringField({initial: "melee"}), + attackType : new fields.StringField({initial: "melee", choices : {melee : "Melee", ranged : "Ranged"}}) }); schema.specification = new fields.SchemaField({ diff --git a/modules/model/item/trapping.js b/modules/model/item/trapping.js index 0bd3b3101..bd2b2b866 100644 --- a/modules/model/item/trapping.js +++ b/modules/model/item/trapping.js @@ -9,11 +9,12 @@ let fields = foundry.data.fields; */ export class TrappingModel extends PropertiesMixin(EquippableItemModel) { + static LOCALIZATION_PREFIXES = ["WH.Models.trapping"]; static defineSchema() { let schema = super.defineSchema(); schema.trappingType = new fields.SchemaField({ - value: new fields.StringField() + value: new fields.StringField({choices: game.wfrp4e.config.trappingTypes}) }), schema.spellIngredient = new fields.SchemaField({ value: new fields.StringField() diff --git a/modules/model/item/vehicleMod.js b/modules/model/item/vehicleMod.js index d73f6fcaf..610e1871b 100644 --- a/modules/model/item/vehicleMod.js +++ b/modules/model/item/vehicleMod.js @@ -3,11 +3,12 @@ let fields = foundry.data.fields; export class VehicleModModel extends PhysicalItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.vehicleMod"]; static defineSchema() { let schema = super.defineSchema(); schema.modType = new fields.SchemaField({ - value : new fields.StringField({}) + value : new fields.StringField({choices: game.wfrp4e.config.modTypes}) }) return schema; } diff --git a/modules/model/item/vehicleRole.js b/modules/model/item/vehicleRole.js index fff4f34a5..c9dec1b54 100644 --- a/modules/model/item/vehicleRole.js +++ b/modules/model/item/vehicleRole.js @@ -3,6 +3,7 @@ import { BaseItemModel } from "./components/base"; let fields = foundry.data.fields; export class VehicleRoleModel extends BaseItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.vehicleRole"]; static defineSchema() { let schema = super.defineSchema(); schema.test = new fields.StringField(); diff --git a/modules/model/item/vehicleTest.js b/modules/model/item/vehicleTest.js index 026876576..27a618f19 100644 --- a/modules/model/item/vehicleTest.js +++ b/modules/model/item/vehicleTest.js @@ -4,6 +4,7 @@ import { BaseItemModel } from "./components/base"; let fields = foundry.data.fields; export class VehicleTestModel extends BaseItemModel { + static LOCALIZATION_PREFIXES = ["WH.Models.vehicleTest"]; static defineSchema() { let schema = super.defineSchema(); schema.roles = new fields.SchemaField({ diff --git a/modules/model/item/weapon.js b/modules/model/item/weapon.js index 877411e79..b66932b10 100644 --- a/modules/model/item/weapon.js +++ b/modules/model/item/weapon.js @@ -11,6 +11,7 @@ let fields = foundry.data.fields; * @mixes PropertiesMixin */ export class WeaponModel extends PropertiesMixin(EquippableItemModel) { + static LOCALIZATION_PREFIXES = ["WH.Models.weapon"]; static defineSchema() { let schema = super.defineSchema(); schema.damage = new fields.SchemaField({ @@ -18,10 +19,10 @@ export class WeaponModel extends PropertiesMixin(EquippableItemModel) { dice: new fields.StringField({ initial: "" }) }); schema.weaponGroup = new fields.SchemaField({ - value: new fields.StringField({ initial: "basic" }) + value: new fields.StringField({ initial: "basic", blank : true, choices : game.wfrp4e.config.weaponGroups}) }); schema.reach = new fields.SchemaField({ - value: new fields.StringField({ initial: "" }) + value: new fields.StringField({ initial: "", blank : true, choices : game.wfrp4e.config.weaponReaches }) }); schema.range = new fields.SchemaField({ value: new fields.StringField({ initial: "" }) @@ -30,13 +31,13 @@ export class WeaponModel extends PropertiesMixin(EquippableItemModel) { value: new fields.StringField({ initial: "" }) }); schema.modeOverride = new fields.SchemaField({ - value: new fields.StringField({ initial: "" }) + value: new fields.StringField({ initial: "", blank: true, choices : game.wfrp4e.config.weaponTypes }) }); schema.twohanded = new fields.SchemaField({ value: new fields.BooleanField({ initial: false }) }); schema.ammunitionGroup = new fields.SchemaField({ - value: new fields.StringField({ initial: "" }) + value: new fields.StringField({ initial: "", blank : true, choices : game.wfrp4e.config.ammunitionGroups }) }); schema.currentAmmo = new fields.SchemaField({ value: new fields.StringField({ initial: "" }) diff --git a/modules/system/config-wfrp4e.js b/modules/system/config-wfrp4e.js index 13687c3a2..20fbf8f48 100644 --- a/modules/system/config-wfrp4e.js +++ b/modules/system/config-wfrp4e.js @@ -398,6 +398,7 @@ WFRP4E.weaponReaches = { // Ammo Groups WFRP4E.ammunitionGroups = { + "none": "NoneAmmo", "BPandEng": "WFRP4E.BPandEng", "bow": "WFRP4E.Bow", "crossbow": "WFRP4E.Crossbow", diff --git a/src/apps/sheets/item/ammunition-sheet.js b/src/apps/sheets/item/ammunition-sheet.js new file mode 100644 index 000000000..4b4f06dc4 --- /dev/null +++ b/src/apps/sheets/item/ammunition-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class AmmunitionSheet extends BaseWFRP4eItemSheet +{ + static type="ammunition" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/armour-sheet.js b/src/apps/sheets/item/armour-sheet.js new file mode 100644 index 000000000..073b505f1 --- /dev/null +++ b/src/apps/sheets/item/armour-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class ArmourSheet extends BaseWFRP4eItemSheet +{ + static type="armour" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/base.js b/src/apps/sheets/item/base.js index eab5a075a..fe9fea23e 100644 --- a/src/apps/sheets/item/base.js +++ b/src/apps/sheets/item/base.js @@ -1,10 +1,16 @@ +import ItemProperties from "../../../../modules/apps/item-properties"; + export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 { + static type="" + static DEFAULT_OPTIONS = { classes: ["wfrp4e"], - actions : {}, - defaultTab : "decription", + defaultTab : "description", + position : { + height: 600 + }, window : { controls : [ { @@ -15,15 +21,22 @@ export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 ] }, actions : { - postToChat : () => this.item.postItem(), + postToChat : function() {this.item.postItem()}, + configureProperties : this._onConfigureProperties } } - - async _prepareContext(options) { let context = await super._prepareContext(options); + context.physical = this.item.system.tags.has("physical"); + context.hide = { + quantity : false, + encumbrance : false, + price : false, + availability : false, + category : true + } return context; } @@ -45,7 +58,6 @@ export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 } } - //#region Effects @@ -116,7 +128,7 @@ export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 async _handleEnrichment() { let enrichment = {} enrichment["system.description.value"] = await TextEditor.enrichHTML(this.item.system.description.value, { async: true, secrets: this.item.isOwner, relativeTo: this.item }) - enrichment["system.gmdescription.gmnotes.value"] = await TextEditor.enrichHTML(this.item.system.gmdescription.value, { async: true, secrets: this.item.isOwner, relativeTo: this.item }) + enrichment["system.gmdescription.value"] = await TextEditor.enrichHTML(this.item.system.gmdescription.value, { async: true, secrets: this.item.isOwner, relativeTo: this.item }) return expandObject(enrichment) } @@ -124,7 +136,10 @@ export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 //#region Action Handlers - + static _onConfigureProperties() + { + new ItemProperties(this.document).render(true) + } //#endregion } diff --git a/src/apps/sheets/item/career-sheet.js b/src/apps/sheets/item/career-sheet.js new file mode 100644 index 000000000..981f4784e --- /dev/null +++ b/src/apps/sheets/item/career-sheet.js @@ -0,0 +1,55 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class CareerSheet extends BaseWFRP4eItemSheet +{ + static type="career" + + static DEFAULT_OPTIONS = { + classes: [this.type] + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } + + async _prepareContext(options) + { + let context = await super._prepareContext(options); + context.physical = this.item.system.tags.has("physical"); + return context; + } + + + _focus = null; + + _addEventListeners() + { + super._addEventListeners(); + this.element.querySelectorAll(".skill,.talent,.trapping").forEach(e => { + e.style.width = e.value.length + 2 + "ch" + }) + + this.element.querySelectorAll(".empty").forEach(e => { + e.addEventListener("keydown", e => { + if (e.key === "Tab") + { + let parent = this._getParent(e.target, ".form-group"); + this.focus = parent.dataset.group; + } + else + { + this.focus = null; + } + })}) + + if (this.focus) + { + this.element.querySelector(`.${this.focus} .empty`)?.focus(); + } + } + +} diff --git a/src/apps/sheets/item/cargo.js b/src/apps/sheets/item/cargo.js new file mode 100644 index 000000000..aa681dd3a --- /dev/null +++ b/src/apps/sheets/item/cargo.js @@ -0,0 +1,26 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class CargoSheet extends BaseWFRP4eItemSheet +{ + static type="cargo" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } + + async _prepareContext(options) + { + let context = await super._prepareContext(options); + context.cargoTypes = game.wfrp4e.trade.tradeData[this.item.system.tradeType]?.cargoTypes || {}; + context.hide.quantity = true; + return context; + } +} diff --git a/src/apps/sheets/item/container-sheet.js b/src/apps/sheets/item/container-sheet.js new file mode 100644 index 000000000..b142b7f75 --- /dev/null +++ b/src/apps/sheets/item/container-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class ContainerSheet extends BaseWFRP4eItemSheet +{ + static type="container" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/critical-sheet.js b/src/apps/sheets/item/critical-sheet.js new file mode 100644 index 000000000..210285b74 --- /dev/null +++ b/src/apps/sheets/item/critical-sheet.js @@ -0,0 +1,19 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class CriticalSheet extends BaseWFRP4eItemSheet +{ + static type="critical" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } + +} diff --git a/src/apps/sheets/item/disease-sheet.js b/src/apps/sheets/item/disease-sheet.js new file mode 100644 index 000000000..605d0d7a8 --- /dev/null +++ b/src/apps/sheets/item/disease-sheet.js @@ -0,0 +1,25 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class DiseaseSheet extends BaseWFRP4eItemSheet +{ + static type="disease" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } + + async _prepareContext(options) + { + let context = await super._prepareContext(options); + context.units = {"minutes" : "Minutes", "hours" : "Hours", "days": "Days"} + return context; + } +} diff --git a/src/apps/sheets/item/extendedTest-sheet.js b/src/apps/sheets/item/extendedTest-sheet.js new file mode 100644 index 000000000..0be5e5a95 --- /dev/null +++ b/src/apps/sheets/item/extendedTest-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class ExtendedTestSheet extends BaseWFRP4eItemSheet +{ + static type="extendedTest" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/injury-sheet.js b/src/apps/sheets/item/injury-sheet.js new file mode 100644 index 000000000..ea19d4d78 --- /dev/null +++ b/src/apps/sheets/item/injury-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class InjurySheet extends BaseWFRP4eItemSheet +{ + static type="injury" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/money.js b/src/apps/sheets/item/money.js new file mode 100644 index 000000000..03c42117f --- /dev/null +++ b/src/apps/sheets/item/money.js @@ -0,0 +1,26 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class MoneySheet extends BaseWFRP4eItemSheet +{ + static type="money" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } + + async _prepareContext(options) + { + let context = await super._prepareContext(options); + context.hide.availability = true; + context.hide.price = true; + return context; + } +} diff --git a/src/apps/sheets/item/mutation-sheet.js b/src/apps/sheets/item/mutation-sheet.js new file mode 100644 index 000000000..d20c3f15f --- /dev/null +++ b/src/apps/sheets/item/mutation-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class MutationSheet extends BaseWFRP4eItemSheet +{ + static type="mutation" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/prayer-sheet.js b/src/apps/sheets/item/prayer-sheet.js new file mode 100644 index 000000000..ae4adcd47 --- /dev/null +++ b/src/apps/sheets/item/prayer-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class PrayerSheet extends BaseWFRP4eItemSheet +{ + static type="prayer" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} \ No newline at end of file diff --git a/src/apps/sheets/item/psychology-sheet.js b/src/apps/sheets/item/psychology-sheet.js new file mode 100644 index 000000000..837c59b01 --- /dev/null +++ b/src/apps/sheets/item/psychology-sheet.js @@ -0,0 +1,30 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class PsychologySheet extends BaseWFRP4eItemSheet +{ + static type="injury" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static TABS = { + description: { + id: "description", + group: "primary", + label: "Description", + }, + effects: { + id: "effects", + group: "primary", + label: "Effects", + } + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/skill-sheet.js b/src/apps/sheets/item/skill-sheet.js new file mode 100644 index 000000000..6682848ac --- /dev/null +++ b/src/apps/sheets/item/skill-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class SkillSheet extends BaseWFRP4eItemSheet +{ + static type="skill" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} \ No newline at end of file diff --git a/src/apps/sheets/item/spell-sheet.js b/src/apps/sheets/item/spell-sheet.js new file mode 100644 index 000000000..606441d68 --- /dev/null +++ b/src/apps/sheets/item/spell-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class SpellSheet extends BaseWFRP4eItemSheet +{ + static type="spell" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} \ No newline at end of file diff --git a/src/apps/sheets/item/talent-sheet.js b/src/apps/sheets/item/talent-sheet.js index d4b166b6a..5783e3638 100644 --- a/src/apps/sheets/item/talent-sheet.js +++ b/src/apps/sheets/item/talent-sheet.js @@ -1,16 +1,18 @@ -import ItemSheetWfrp4e from "../../../../modules/item/item-sheet"; +import BaseWFRP4eItemSheet from "./base"; -export default class TalentSheet extends ItemSheetWfrp4e +export default class TalentSheet extends BaseWFRP4eItemSheet { + static type="talent" + static DEFAULT_OPTIONS = { - classes: ["talent"], + classes: [this.type], } - + static PARTS = { header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, - details: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-details.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, } } diff --git a/src/apps/sheets/item/trait-sheet.js b/src/apps/sheets/item/trait-sheet.js new file mode 100644 index 000000000..c2519427b --- /dev/null +++ b/src/apps/sheets/item/trait-sheet.js @@ -0,0 +1,25 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class TraitSheet extends BaseWFRP4eItemSheet +{ + static type="trait" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } + + async _prepareContext(options) + { + let context = await super._prepareContext(options); + context.hide.category = false; + return context; + } +} diff --git a/src/apps/sheets/item/trapping-sheet.js b/src/apps/sheets/item/trapping-sheet.js new file mode 100644 index 000000000..426ccbbbd --- /dev/null +++ b/src/apps/sheets/item/trapping-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class TrappingSheet extends BaseWFRP4eItemSheet +{ + static type="trapping" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/vehicleMod-sheet.js b/src/apps/sheets/item/vehicleMod-sheet.js new file mode 100644 index 000000000..d9ef01454 --- /dev/null +++ b/src/apps/sheets/item/vehicleMod-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class VehicleModSheet extends BaseWFRP4eItemSheet +{ + static type="vehicleMod" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/vehicleRole-sheet.js b/src/apps/sheets/item/vehicleRole-sheet.js new file mode 100644 index 000000000..05a7d097b --- /dev/null +++ b/src/apps/sheets/item/vehicleRole-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class VehicleRoleSheet extends BaseWFRP4eItemSheet +{ + static type="vehicleRole" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/vehicleTest-sheet.js b/src/apps/sheets/item/vehicleTest-sheet.js new file mode 100644 index 000000000..0571a8c25 --- /dev/null +++ b/src/apps/sheets/item/vehicleTest-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class VehicleTestSheet extends BaseWFRP4eItemSheet +{ + static type="vehicleTest" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/src/apps/sheets/item/weapon-sheet.js b/src/apps/sheets/item/weapon-sheet.js new file mode 100644 index 000000000..b6b4a683c --- /dev/null +++ b/src/apps/sheets/item/weapon-sheet.js @@ -0,0 +1,18 @@ +import BaseWFRP4eItemSheet from "./base"; + +export default class WeaponSheet extends BaseWFRP4eItemSheet +{ + static type="weapon" + + static DEFAULT_OPTIONS = { + classes: [this.type], + } + + static PARTS = { + header : {scrollable: [""], template : 'systems/wfrp4e/templates/sheets/item/item-header.hbs', classes: ["sheet-header"] }, + tabs: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/item-tabs.hbs' }, + description: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-description.hbs' }, + details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, + effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, + } +} diff --git a/static/lang/en.json b/static/lang/en.json index c6ca4c4ad..3002f97f0 100644 --- a/static/lang/en.json +++ b/static/lang/en.json @@ -277,6 +277,7 @@ "SHEET.CannotDeleteItemEffect" : "This effect is from an Item on this Actor. Delete the Item itself or the effect from the Item's sheet.", "SHEET.CannotDeleteCrewEffect" : "This effect is from a Vehicle this Actor is on, and must be deleted from that Vehicle.", "SHEET.Attacker" : "Attacker", + "SHEET.LocationAP" : "Location AP", "ACTOR.BasicSkillsTitle" : "Add Basic Skills", "ACTOR.BasicSkillsPrompt": "Add Basic Skills?", @@ -1917,6 +1918,504 @@ "WH" : { "TransferType" : { "Crew" : "Crew" + }, + + "Models" : { + "ammunition" : { + "FIELDS" : { + "ammunitionType.value" : { + "label" : "Ammunition Type", + "hint" : "Designates what types of Weapons can use this Ammunition" + }, + "range.value" : { + "label" : "Range", + "hint" : "Modifies the Range of the Weapon using this Ammunition. e.g. Add: +2, Subtract: -2, Multiply: *2, Divide: /2" + }, + "damage.value" : { + "label" : "Damage", + "hint" : "Modifies the Damage of the Weapon using this Ammunition. See Range examples above." + }, + "damage.dice" : { + "label" : "Dice", + "hint" : "Add a dice roll to Damage" + }, + "special.value" : { + "label" : "Special" + } + } + }, + "armour" : { + "FIELDS" : { + "armorType.value" : { + "label" : "Armour Type" + }, + "AP" : { + "head" : { + "label" : "Head" + }, + "lArm" : { + "label" : "Left Arm" + }, + "rArm" : { + "label" : "Right Arm" + }, + "lLeg" : { + "label" : "Left Leg" + }, + "rLeg" : { + "label" : "Right Leg" + }, + "body" : { + "label" : "Body" + } + }, + "special.value" : { + "label" : "Special", + "hint" : "Miscellaneous text that will show in the chat card." + } + } + }, + "career" : { + "FIELDS" : { + "class.value" : { + "label" : "Class" + }, + "careergroup.value" : { + "label" : "Career Group" + }, + "level.value" : { + "label" : "Career Level" + }, + "status" : { + "tier" : { + "label" : "Tier" + }, + "standing" : { + "label" : "Standing " + } + } + } + }, + "cargo" : { + "FIELDS" : { + "tradeType" : { + "label" : "Trade Type" + }, + "cargoType.value" : { + "label" : "Cargo Type" + }, + "unitPrice.value" : { + "label" : "Unit Price" + }, + "origin.value" : { + "label" : "Origin" + }, + "quality" : { + "value" : { + "label" : "Quality" + } + } + } + }, + "container" : { + "FIELDS" : { + "wearable.value" : { + "label" : "Wearable" + }, + "carries.value" : { + "label" : "Carries" + }, + "countEnc.value" : { + "label" : "Count Encumbrance", + "hint" : "Add this encumbrance to character's encumbrance (uncheck if not carried around e.g. a cart)" + } + } + }, + "disease" : { + "FIELDS" : { + "contraction.value" : { + "label" : "Contraction" + }, + "incubation.value" : { + "label" : "Incubation" + }, + "duration.value" : { + "label" : "Duration" + }, + "symptoms.value" : { + "label" : "Symptoms" + }, + "permanent.value" : { + "label" : "Permanent" + } + } + }, + "extendedTest" : { + "FIELDS" : { + "SL.target" : { + "label" : "Target SL" + }, + "test.value" : { + "label" : "Test" + }, + "difficulty.value" : { + "label" : "Default Difficulty" + }, + "negativePossible.value" : { + "label" : "Negative SL Possible", + "hint" : "Allow the progress of this Test to go below 0" + }, + "failingDecreases.value" : { + "label" : "Failing Decreases Progress", + "hint" : "Reduce Progress on failed Tests" + }, + "completion.value" : { + "label" : "On Completion", + "hint" : "Once complete, perform this action" + }, + "hide.test" : { + "label" : "Hide Test", + "hint" : "Hide this Test from Players" + }, + "hide.progress" : { + "label" : "Hide Progress", + "hint" : "Hide Test progress from Players" + } + } + }, + "money" : { + "FIELDS" : { + "coinValue.value" : { + "label" : "Coin Value", + "hint" : "Value of this coin type (in brass pennies)." + } + } + }, + "skill" : { + "FIELDS" : { + "advanced.value" : { + "label" : "Skill Type" + }, + "grouped.value" : { + "label" : "Specialization" + }, + "characteristic.value" : { + "label" : "Characteristic" + }, + "modifier.value" : { + "label" : "Modifier" + }, + "advances.force" : { + "label" : "Force Advancement Indicator", + "hint" : "Show the Advancement Indicator regardless of career, which will allow you to automate spending experience." + }, + "advances.costModifier" : { + "label" : "XP Cost Modifier" + } + } + }, + "talent" : { + "FIELDS" : { + "tests.value" : { + "label" : "Tests" + }, + "max.value" : { + "label" : "Max" + }, + "advances.force" : { + "label" : "Force Advancement Indicator", + "hint" : "Show the Advancement Indicator regardless of career, which will allow you to automate spending experience." + } + } + }, + "mutation" : { + "FIELDS" : { + "mutationType.value" : { + "label" : "Mutation Type" + } + } + }, + "critical" : { + "FIELDS" : { + "wounds.value" : { + "label" : "Wounds" + }, + "prompt" : { + "label" : "Prompt Location", + "hint" : "Prompt for a location when added to an Actor." + }, + "location.value" : { + "label" : "Location" + } + } + }, + "injury" : { + "FIELDS" : { + "duration" : { + "value" : { + "label": "Duration" + }, + "permanent" : { + "label" : "Permanent" + } + }, + "prompt" : { + "label" : "Prompt Location", + "hint" : "Prompt for a left or right location when added to an Actor." + }, + "location.value" : { + "label" : "Location" + } + } + }, + "prayer" : { + "FIELDS" : { + "type.value" : { + "label" : "Type" + }, + "god.value" : { + "label" : "God" + }, + "range.value" : { + "label" : "Range" + }, + "duration.value" : { + "label" : "Duration" + }, + "target" : { + "value" : { + "label" : "Target" + }, + "aoe" : { + "label" : "Area of Effect" + }, + "extendableAoE" : { + "label" : "Extendable AoE", + "hint" : "Can the AoE be enlarged with extra SL?" + } + }, + "damage" : { + "value" : { + "label" : "Formula" + }, + "dice" : { + "label" : "Dice", + "hint" : "Add a dice roll to Damage" + }, + "addSL" : { + "label" : "Add SL", + "hint" : "Add SL to Damage value" + } + }, + "overcast" : { + "enabled" : { + "label" : "Extra Overcast Options" + } + } + } + }, + "spell" : { + "FIELDS" : { + "cn.value" : { + "label" : "Casting Number" + }, + "lore.value" : { + "label" : "Lore" + }, + "skill.value" : { + "label" : "Casting Skill" + }, + "wind.value" : { + "label" : "Channelling Skill" + }, + "ritual.value" : { + "label" : "Ritual" + }, + "ritual.xp" : { + "label" : "Learning XP" + }, + "range.vortex" : { + "label" : "Random Vortex" + }, + "range.value" : { + "label" : "Range" + }, + "duration.value" : { + "label" : "Duration" + }, + "duration.extendable" : { + "label" : "Extendable Duration", + "hint" : "When the spell should end, you may make a Willpower Test to extend the Duration for +1 round." + }, + "magicMissile.value" : { + "label" : "Magic Missile" + }, + + "target" : { + "value" : { + "label" : "Target" + }, + "aoe" : { + "label" : "Area of Effect" + } + }, + "damage" : { + "value" : { + "label" : "Formula" + }, + "dice" : { + "label" : "Dice", + "hint" : "Add a dice roll to Damage" + } + }, + "overcast" : { + "enabled" : { + "label" : "Extra Overcast Options" + } + } + } + }, + "trait" : { + "FIELDS" : { + "category" : { + "label" : "Category" + }, + "rollable" : { + "value" : { + "label" : "Rollable" + }, + "damage" : { + "label" : "Does Damage" + }, + "skill" : { + "label" : "Skill" + }, + "rollCharacteristic" : { + "label" : "Roll Characteristic" + }, + "bonusCharacteristic" : { + "label" : "Bonus Characteristic" + }, + "dice" : { + "label" : "Dice Roll" + }, + "defaultDifficulty" : { + "label" : "Difficulty" + }, + "SL" : { + "label" : "Add SL" + }, + "attackType" : { + "label" : "Attack Type" + } + }, + "specification.value" : { + "label" : "Specification" + } + } + }, + "trapping" : { + "FIELDS" : { + "trappingType.value" : { + "label" : "Trapping Type" + } + } + }, + "vehicleMod" : { + "FIELDS" : { + "modType.value" : { + "label" : "Modification Type" + } + } + }, + "vehicleRole" : { + "FIELDS" : { + "test" : { + "label" : "Test Skill" + } + } + }, + "vehicleTest" : { + "FIELDS" : { + "roles" : { + "value" : { + "label" : "Roles" + }, + "vital" : { + "label" : "Vital Roles" + } + }, + "handling" : { + "label" : "Vehicle Handling" + } + } + }, + "weapon" : { + "FIELDS" : { + "weaponGroup.value" : { + "label" : "Weapon Group" + }, + "skill.value" : { + "label" : "Skill" + }, + "modeOverride.value" : { + "label" : "Attack Type" + }, + "damage" : { + "value" : { + "label" : "Formula" + }, + "dice" : { + "label" : "Dice", + "hint" : "Add a dice roll to Damage" + } + }, + "reach" : { + "value" : { + "label" : "Reach" + } + }, + "range" : { + "value" : { + "label" : "Range" + } + }, + "ammunitionGroup" : { + "value" : { + "label" : "Ammunition Group" + } + }, + "consumesAmmo" : { + "value" : { + "label" : "Consumes Ammo" + } + }, + "twohanded" : { + "value" : { + "label" : "Two-handed" + } + }, + "special" : { + "value" : { + "label" : "Special" + } + } + } + } + }, + + "Components" : { + "Locational" : { + "FIELDS" : { + "prompt" : { + "label" : "Prompt Location", + "hint" : "Prompt for a location when added to an Actor." + }, + "location.value" : { + "label" : "Location" + } + } + } } } } diff --git a/static/templates/items/item-weapon-sheet.hbs b/static/templates/items/item-weapon-sheet.hbs index fbb567e4c..3a5b35097 100644 --- a/static/templates/items/item-weapon-sheet.hbs +++ b/static/templates/items/item-weapon-sheet.hbs @@ -111,7 +111,6 @@ + + {{#if physical}} +
+ {{#unless hide.quantity}} +
+
+
+
+ {{/unless}} + {{#unless hide.encumbrance}} +
+
+
+
+ {{/unless}} +
+
+ {{#unless hide.price}} +
+
+
+
+
+
+ {{/unless}} + {{#unless hide.availability}} +
+
+
+
+ {{/unless}} +
+ {{/if}} + + {{#unless hide.category}} +
+
+
+
+
+ {{!-- {{formGroup fields.category value=source.system.category}} --}} +
+ {{/unless}} + + + diff --git a/static/templates/sheets/item/tabs/item-description.hbs b/static/templates/sheets/item/tabs/item-description.hbs index 4885c07ae..fac4f9572 100644 --- a/static/templates/sheets/item/tabs/item-description.hbs +++ b/static/templates/sheets/item/tabs/item-description.hbs @@ -1,3 +1,13 @@
-

test1

+ {{#if (isGM)}} +
+
{{localize "GM Notes"}}
+ {{formInput fields.gmdescription.fields.value value=source.system.gmdescription.value enriched=enriched.system.gmdescription.value toggled=true}} +
+ {{/if}} + +
+
{{localize "Notes"}}
+ {{formInput fields.description.fields.value value=source.system.description.value enriched=enriched.system.description.value toggled=true}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/tabs/item-effects.hbs b/static/templates/sheets/item/tabs/item-effects.hbs index 411323666..bb447496a 100644 --- a/static/templates/sheets/item/tabs/item-effects.hbs +++ b/static/templates/sheets/item/tabs/item-effects.hbs @@ -1,3 +1,99 @@
-

test3

+
+ {{#each effects.conditions}} +
+ {{localize this.name}} +
+ {{#if this.isNumberedCondition}} + {{this.conditionValue}} + {{else}} + {{#if this.existing}} + + {{else}} + + {{/if}} + {{/if}} +
+
+ {{/each}} +
+ + {{#if effects.temporary.length}} +
+
+
{{localize "SHEET.TemporaryEffects"}}
+
+
+ {{#each effects.temporary}} +
+
+ + +
+ + +
+
+
+ {{/each}} +
+
+ {{/if}} + +
+
+
{{localize "Effects"}}
+
+ + + +
+
+
+ {{#each effects.active}} +
+
+ + +
+ + +
+
+
+ {{/each}} +
+
+ + {{#if effects.disabled.length}} +
+
+
{{localize "SHEET.DisabledEffects"}}
+
+
+ {{#each effects.disabled}} +
+
+ + +
+ + +
+
+
+ {{/each}} +
+
+ {{/if}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/ammunition.hbs b/static/templates/sheets/item/types/ammunition.hbs new file mode 100644 index 000000000..ccbba3b7c --- /dev/null +++ b/static/templates/sheets/item/types/ammunition.hbs @@ -0,0 +1,11 @@ +
+ {{formGroup fields.ammunitionType.fields.value value=source.system.ammunitionType.value}} +
+ {{localize "Weapon Modifiers"}} + {{formGroup fields.range.fields.value value=source.system.range.value}} + {{formGroup fields.damage.fields.value value=source.system.damage.value}} + {{formGroup fields.damage.fields.dice value=source.system.damage.dice}} +
+ {{> itemProperties}} + {{formGroup fields.special.fields.value value=source.system.special.value}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/armour.hbs b/static/templates/sheets/item/types/armour.hbs new file mode 100644 index 000000000..a69ae8de0 --- /dev/null +++ b/static/templates/sheets/item/types/armour.hbs @@ -0,0 +1,14 @@ +
+ {{formGroup fields.armorType.fields.value value=source.system.armorType.value choices=(config "armorTypes")}} +
+ {{localize "SHEET.LocationAP"}} + {{formGroup fields.AP.fields.head value=source.AP.head.head}} + {{formGroup fields.AP.fields.lArm value=source.AP.head.lArm}} + {{formGroup fields.AP.fields.rArm value=source.AP.head.rArm}} + {{formGroup fields.AP.fields.lLeg value=source.AP.head.lLeg}} + {{formGroup fields.AP.fields.rLeg value=source.AP.head.rLeg}} + {{formGroup fields.AP.fields.body value=source.AP.head.body}} +
+ {{> itemProperties}} + {{formGroup fields.special.fields.value value=source.system.special.value}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/career.hbs b/static/templates/sheets/item/types/career.hbs new file mode 100644 index 000000000..27a8321f3 --- /dev/null +++ b/static/templates/sheets/item/types/career.hbs @@ -0,0 +1,88 @@ +
+ {{formGroup fields.class.fields.value value=source.system.class.value}} + {{formGroup fields.careergroup.fields.value value=source.system.careergroup.value}} + {{formGroup fields.level.fields.value value=source.system.level.value}} +
+ {{localize "Status"}} +
+ + + + +
+ {{!-- {{formGroup fields.status.fields.tier value=source.system.status.tier}} --}} + {{!-- {{formGroup fields.status.fields.standing value=source.system.status.standing}} --}} +
+
+
+ +
+ {{#each system.characteristics}} + + {{configLookup "characteristicsAbbrev" @key}} + + {{/each}} +
+
+
+ +
+
+ +
+ {{#each system.skills}} + + + {{/each}} + +
+
+
+ +
+
+ +
+
+ {{#each system.incomeSkill}} + + + {{/each}} + +
+
+
+
+ +
+
+ +
+ {{#each system.talents}} + + + {{/each}} + +
+
+
+ +
+
+ +
+ {{#each system.trappings}} + + + {{/each}} + +
+
+
+ +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/cargo.hbs b/static/templates/sheets/item/types/cargo.hbs new file mode 100644 index 000000000..7928906de --- /dev/null +++ b/static/templates/sheets/item/types/cargo.hbs @@ -0,0 +1,7 @@ +
+ {{formGroup fields.tradeType value=source.system.tradeType}} + {{formGroup fields.cargoType.fields.value value=source.system.cargoType.value choices=cargoTypes}} + {{formGroup fields.unitPrice.fields.value value=source.system.unitPrice.value}} + {{formGroup fields.origin.fields.value value=source.system.origin.value}} + {{formGroup fields.quality.fields.value value=source.system.quality.value}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/container.hbs b/static/templates/sheets/item/types/container.hbs new file mode 100644 index 000000000..eb13cbb90 --- /dev/null +++ b/static/templates/sheets/item/types/container.hbs @@ -0,0 +1,5 @@ +
+ {{formGroup fields.wearable.fields.value value=source.system.wearable.value}} + {{formGroup fields.carries.fields.value value=source.system.carries.value}} + {{formGroup fields.countEnc.fields.value value=source.system.countEnc.value}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/critical.hbs b/static/templates/sheets/item/types/critical.hbs new file mode 100644 index 000000000..7b3ecb152 --- /dev/null +++ b/static/templates/sheets/item/types/critical.hbs @@ -0,0 +1,5 @@ +
+ {{formGroup fields.wounds.fields.value value=source.system.wounds.value}} + {{formGroup fields.location.fields.value value=source.system.location.value}} + {{formGroup fields.prompt value=source.system.prompt}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/disease.hbs b/static/templates/sheets/item/types/disease.hbs new file mode 100644 index 000000000..33f0e7769 --- /dev/null +++ b/static/templates/sheets/item/types/disease.hbs @@ -0,0 +1,23 @@ +
+ {{formGroup fields.contraction.fields.value value=source.system.contraction.value}} +
+ +
+ + +
+
+
+ +
+ + +
+
+ {{formGroup fields.symptoms.fields.value value=source.system.symptoms.value}} + {{formGroup fields.permanent.fields.value value=source.system.permanent.value}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/extendedTest.hbs b/static/templates/sheets/item/types/extendedTest.hbs new file mode 100644 index 000000000..98bd48bf7 --- /dev/null +++ b/static/templates/sheets/item/types/extendedTest.hbs @@ -0,0 +1,12 @@ +
+ {{formGroup fields.SL.fields.target value=source.system.SL.target}} + {{formGroup fields.test.fields.value value=source.system.test.value placeholder=(localize 'TestPlaceholder')}} + {{formGroup fields.difficulty.fields.value value=source.system.difficulty.value}} + {{formGroup fields.negativePossible.fields.value value=source.system.negativePossible.value}} + {{formGroup fields.failingDecreases.fields.value value=source.system.failingDecreases.value}} + {{formGroup fields.completion.fields.value value=source.system.completion.value}} + {{#if (isGM)}} + {{formGroup fields.hide.fields.test value=source.system.hide.test}} + {{formGroup fields.hide.fields.progress value=source.system.hide.progress}} + {{/if}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/injury.hbs b/static/templates/sheets/item/types/injury.hbs new file mode 100644 index 000000000..ae07094d1 --- /dev/null +++ b/static/templates/sheets/item/types/injury.hbs @@ -0,0 +1,8 @@ +
+ {{formGroup fields.location.fields.value value=source.system.location.value}} + {{formGroup fields.prompt value=source.system.prompt}} + {{formGroup fields.duration.fields.permanent value=source.system.duration.permanent}} + {{#unless source.system.duration.permanent}} + {{formGroup fields.duration.fields.value value=source.system.duration.value}} + {{/unless}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/money.hbs b/static/templates/sheets/item/types/money.hbs new file mode 100644 index 000000000..54febfd66 --- /dev/null +++ b/static/templates/sheets/item/types/money.hbs @@ -0,0 +1,3 @@ +
+ {{formGroup fields.coinValue.fields.value value=source.system.coinValue.value}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/mutation.hbs b/static/templates/sheets/item/types/mutation.hbs new file mode 100644 index 000000000..18c2924e6 --- /dev/null +++ b/static/templates/sheets/item/types/mutation.hbs @@ -0,0 +1,3 @@ +
+ {{formGroup fields.mutationType.fields.value value=source.system.mutationType.value}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/prayer.hbs b/static/templates/sheets/item/types/prayer.hbs new file mode 100644 index 000000000..87c2a6c24 --- /dev/null +++ b/static/templates/sheets/item/types/prayer.hbs @@ -0,0 +1,22 @@ +
+ {{formGroup fields.type.fields.value value=source.system.type.value}} + {{formGroup fields.god.fields.value value=source.system.god.value}} + {{formGroup fields.range.fields.value value=source.system.range.value}} + {{formGroup fields.duration.fields.value value=source.system.duration.value}} + {{formGroup fields.target.fields.aoe value=source.system.target.aoe}} + {{#if source.system.target.aoe}} + {{formGroup fields.target.fields.value value=source.system.target.value label="Radius"}} + {{formGroup fields.target.fields.extendableAoE value=source.system.target.extendableAoE}} + {{else}} + {{formGroup fields.target.fields.value value=source.system.target.value}} + {{/if}} +
+ {{localize "Damage"}} + {{formGroup fields.damage.fields.value value=source.system.damage.value}} + {{formGroup fields.damage.fields.dice value=source.system.damage.dice}} + {{formGroup fields.damage.fields.addSL value=source.system.damage.addSL}} +
+ + {{> extraOvercast}} + +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/skill.hbs b/static/templates/sheets/item/types/skill.hbs new file mode 100644 index 000000000..994f17dd3 --- /dev/null +++ b/static/templates/sheets/item/types/skill.hbs @@ -0,0 +1,10 @@ +
+ {{formGroup fields.characteristic.fields.value value=source.system.characteristic.value}} + {{formGroup fields.advanced.fields.value value=source.system.advanced.value}} + {{formGroup fields.grouped.fields.value value=source.system.grouped.value}} + {{#if item.isOwned}} + {{formGroup fields.modifier.fields.value value=source.system.modifier.value}} + {{formGroup fields.advances.fields.force value=source.system.advances.force}} + {{formGroup fields.advances.fields.costModifier value=source.system.advances.costModifier}} + {{/if}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/spell.hbs b/static/templates/sheets/item/types/spell.hbs new file mode 100644 index 000000000..9b2a992ed --- /dev/null +++ b/static/templates/sheets/item/types/spell.hbs @@ -0,0 +1,44 @@ +
+ {{formGroup fields.cn.fields.value value=source.system.cn.value}} + {{formGroup fields.lore.fields.value value=source.system.lore.value}} +
+ {{localize "Overrides"}} + {{formGroup fields.skill.fields.value value=source.system.skill.value}} + {{formGroup fields.wind.fields.value value=source.system.wind.value}} +
+ {{formGroup fields.ritual.fields.value value=source.system.ritual.value}} + {{#unless system.ritual.value}} + + {{#unless source.system.range.vortex}} + {{formGroup fields.range.fields.value value=source.system.range.value}} + {{else}} + {{formGroup fields.range.fields.value value="Random Vortex" disabled=true}} + {{/unless}} + {{formGroup fields.range.fields.vortex value=source.system.range.vortex}} + + {{formGroup fields.duration.fields.value value=source.system.duration.value}} + {{formGroup fields.duration.fields.extendable value=source.system.duration.extendable}} + + {{formGroup fields.target.fields.aoe value=source.system.target.aoe}} + {{#if source.system.target.aoe}} + {{formGroup fields.target.fields.value value=source.system.target.value label="Radius"}} + {{else}} + {{formGroup fields.target.fields.value value=source.system.target.value}} + {{/if}} + +
+ {{localize "Damage"}} + {{formGroup fields.damage.fields.value value=source.system.damage.value}} + {{formGroup fields.damage.fields.dice value=source.system.damage.dice}} +
+ + {{formGroup fields.magicMissile.fields.value value=source.system.magicMissile.value}} + {{> extraOvercast}} + + {{else}} + {{formGroup fields.ritual.fields.xp value=source.system.ritual.xp}} + + {{/unless}} + + +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/talent.hbs b/static/templates/sheets/item/types/talent.hbs new file mode 100644 index 000000000..69df5f73d --- /dev/null +++ b/static/templates/sheets/item/types/talent.hbs @@ -0,0 +1,7 @@ +
+ {{formGroup fields.tests.fields.value value=source.system.tests.value}} + {{formGroup fields.max.fields.value value=source.system.max.value}} + {{#if item.isOwned}} + {{formGroup fields.advances.fields.force value=source.system.advances.force}} + {{/if}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/trait.hbs b/static/templates/sheets/item/types/trait.hbs new file mode 100644 index 000000000..7f9dc62b2 --- /dev/null +++ b/static/templates/sheets/item/types/trait.hbs @@ -0,0 +1,21 @@ +
+ {{formGroup fields.rollable.fields.value value=source.system.rollable.value}} + {{#if source.system.rollable.value}} + {{formGroup fields.rollable.fields.rollCharacteristic value=source.system.rollable.rollCharacteristic}} + {{formGroup fields.rollable.fields.skill value=source.system.rollable.skill}} + {{formGroup fields.rollable.fields.defaultDifficulty value=source.system.rollable.defaultDifficulty}} + {{formGroup fields.rollable.fields.damage value=source.system.rollable.damage}} + {{#if source.system.rollable.damage}} + {{formGroup fields.rollable.fields.bonusCharacteristic value=source.system.rollable.bonusCharacteristic}} + {{formGroup fields.rollable.fields.attackType value=source.system.rollable.attackType}} + {{formGroup fields.rollable.fields.dice value=source.system.rollable.dice}} + {{formGroup fields.rollable.fields.SL value=source.system.rollable.SL}} + {{formGroup fields.specification.fields.value value=source.system.specification.value label="SHEET.DamageValue" localize=true}} + {{> itemProperties}} + {{else}} + {{formGroup fields.specification.fields.value value=source.system.specification.value}} + {{/if}} + {{else}} + {{formGroup fields.specification.fields.value value=source.system.specification.value}} + {{/if}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/trapping.hbs b/static/templates/sheets/item/types/trapping.hbs new file mode 100644 index 000000000..095260818 --- /dev/null +++ b/static/templates/sheets/item/types/trapping.hbs @@ -0,0 +1,4 @@ +
+ {{formGroup fields.trappingType.fields.value value=source.system.trappingType.value}} + {{> itemProperties}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/vehicleMod.hbs b/static/templates/sheets/item/types/vehicleMod.hbs new file mode 100644 index 000000000..3ef70e81a --- /dev/null +++ b/static/templates/sheets/item/types/vehicleMod.hbs @@ -0,0 +1,3 @@ +
+ {{formGroup fields.modType.fields.value value=source.system.modType.value}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/vehicleRole.hbs b/static/templates/sheets/item/types/vehicleRole.hbs new file mode 100644 index 000000000..a4afc1e2c --- /dev/null +++ b/static/templates/sheets/item/types/vehicleRole.hbs @@ -0,0 +1,3 @@ +
+ {{formGroup fields.test value=source.system.test}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/vehicleTest.hbs b/static/templates/sheets/item/types/vehicleTest.hbs new file mode 100644 index 000000000..bea92c927 --- /dev/null +++ b/static/templates/sheets/item/types/vehicleTest.hbs @@ -0,0 +1,5 @@ +
+ {{formGroup fields.roles.fields.value value=source.system.roles.value}} + {{formGroup fields.roles.fields.vital value=source.system.roles.vital}} + {{formGroup fields.handling value=source.system.handling}} +
\ No newline at end of file diff --git a/static/templates/sheets/item/types/weapon.hbs b/static/templates/sheets/item/types/weapon.hbs new file mode 100644 index 000000000..a4430e384 --- /dev/null +++ b/static/templates/sheets/item/types/weapon.hbs @@ -0,0 +1,25 @@ +
+ {{formGroup fields.weaponGroup.fields.value value=source.system.weaponGroup.value}} +
+ {{localize "Overrides"}} + {{formGroup fields.skill.fields.value value=source.system.skill.value}} + {{formGroup fields.modeOverride.fields.value value=source.system.modeOverride.value}} +
+ + {{#if item.system.isMelee}} + {{formGroup fields.reach.fields.value value=source.system.reach.value}} + {{else}} + {{formGroup fields.range.fields.value value=source.system.range.value}} + {{formGroup fields.ammunitionGroup.fields.value value=source.system.ammunitionGroup.value}} + {{formGroup fields.consumesAmmo.fields.value value=source.system.consumesAmmo.value}} + {{/if}} + {{formGroup fields.twohanded.fields.value value=source.system.twohanded.value}} +
+ {{localize "Damage"}} + {{formGroup fields.damage.fields.value value=source.system.damage.value}} + {{formGroup fields.damage.fields.dice value=source.system.damage.dice}} +
+ + {{> itemProperties}} + {{formGroup fields.special.fields.value value=source.system.special.value}} +
\ No newline at end of file diff --git a/static/templates/sheets/partials/extra-overcast.hbs b/static/templates/sheets/partials/extra-overcast.hbs new file mode 100644 index 000000000..a21f40e74 --- /dev/null +++ b/static/templates/sheets/partials/extra-overcast.hbs @@ -0,0 +1,81 @@ +{{formGroup fields.overcast.fields.enabled value=source.system.overcast.enabled}} +{{#if system.overcast.enabled}} +
+ +
+ +
+
+ +
+ +
+ + + + {{#if (eq system.overcast.initial.type "value")}} + + + + + {{else if (eq system.overcast.initial.type "SL")}} + + + + {{else if (eq system.overcast.initial.type "characteristic")}} + + + + {{localize "Bonus"}} + + {{/if}} +
+
+ + +
+ +
+ + + + {{#if (eq system.overcast.valuePerOvercast.type "value")}} + + + + + {{else if (eq system.overcast.valuePerOvercast.type "SL")}} + + + + {{else if (eq system.overcast.valuePerOvercast.type "characteristic")}} + + + + {{localize "Bonus"}} + + {{/if}} +
+
+{{/if}} \ No newline at end of file diff --git a/static/templates/sheets/partials/item-properties.hbs b/static/templates/sheets/partials/item-properties.hbs new file mode 100644 index 000000000..eb9600ab0 --- /dev/null +++ b/static/templates/sheets/partials/item-properties.hbs @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/style/sheets/_light.scss b/style/sheets/_light.scss index 02a096dd3..39922a645 100644 --- a/style/sheets/_light.scss +++ b/style/sheets/_light.scss @@ -28,4 +28,7 @@ --advances-border : #999; --container-lines : var(--color-dark-6); + + --career-header : rgba(0, 0, 0, 0.1); + } \ No newline at end of file diff --git a/style/sheets/actors/_actor.scss b/style/sheets/actors/_actor.scss index 9e1532bb4..c9880b352 100644 --- a/style/sheets/actors/_actor.scss +++ b/style/sheets/actors/_actor.scss @@ -5,21 +5,8 @@ --characteristic-header : transparent; --characteristic-total : transparent; --characteristic-border : var(--color-cool-3); - --attribute-input : var(--color-cool-4); - --attribute-input-border : transparent; - --attribute-border : var(--color-cool-3); - --attribute-locked-input : transparent; - --attribute-locked-border : transparent; - --attribute-label : transparent; - --attribute-field : transparent; --property-icon : var(--color-cool-3); - - input { - &:focus { - } - } - section.tab { overflow-y: auto } @@ -159,65 +146,6 @@ .attribute-box { margin: 5px 5px; - &:first-child { - margin-left: 0px; - } - &:last-child { - margin-right: 0px; - } - - flex: 1; - border: 1px solid var(--attribute-border); - border-right: none; - height: 45px; - - display: grid; - grid-template-columns: repeat(12, 8.333%); - grid-template-rows: repeat(2, 50%); - - > div { - display: flex; - align-items: center; - justify-content: center; - } - - input { - height: 100%; - width: 100%; - border-radius: 0px; - text-align: center; - background-color: var(--attribute-input); - border : 1px solid var(--attribute-input-border); - } - - input:disabled, - input[readonly] - { - background-color: var(--attribute-locked-input); - border : 1px solid var(--attribute-locked-border); - } - - .field { - border-right: 1px solid var(--attribute-border); - width: 100%; - background: var(--attribute-field); - } - - .interact { - &.bottom { - border-top: 1px solid var(--attribute-border); - } - background: var(--attribute-input); - display: flex; - justify-content: space-evenly; - } - - .label { - border-right: 1px solid var(--attribute-border); - width: 100%; - background: var(--attribute-label); - } - &.movement { flex: 2; div:nth-child(-n + 3) { diff --git a/style/sheets/items/_index.scss b/style/sheets/items/_index.scss new file mode 100644 index 000000000..69a4fe48b --- /dev/null +++ b/style/sheets/items/_index.scss @@ -0,0 +1 @@ +@import "./item"; \ No newline at end of file diff --git a/style/sheets/items/_item.scss b/style/sheets/items/_item.scss new file mode 100644 index 000000000..e6ec93e27 --- /dev/null +++ b/style/sheets/items/_item.scss @@ -0,0 +1,135 @@ +.wfrp4e.item.sheet.application { + + --header-label-line : var(--color-cool-3); + + --attribute-input : var(--color-cool-4); + --attribute-input-border : transparent; + --attribute-border : var(--color-cool-3); + --attribute-locked-input : transparent; + --attribute-locked-border : transparent; + --attribute-label : transparent; + --attribute-field : transparent; + + --career-header: var(--color-cool-3); + + section.tab { + overflow-y: auto + } + + .sheet-header { + display: flex; + flex-direction: row; + + .header-fields { + flex: 1; + } + + input { + text-align: crgba(247, 165, 165, 0.1); + text-align: center; + } + img { + width: 80px; + height: 80px; + &.img-border { + border: 2px dotted var(--header-label-line); + } + + } + .header-row { + display: flex; + flex-wrap: nowrap; + align-items: center; + padding: 0px 5px; + } + + .attribute-box:not(.single) + { + .label { + border-bottom: 1px solid var(--attribute-border) + } + } + + .gc { + input { + color: #FFD700; + text-shadow: 0px 0px 5px #FFD700 + + } + } + .ss { + input { + color: #C0C0C0; + text-shadow: 0px 0px 3px #C0C0C0 + } + } + .bp { + input { + color: #c2742f + } + } + } + + + section[data-tab="details"] { + .form-group { + margin: 10px 0px; + } + + .attribute-box { + margin: 5px 0px; + } + } + + &.career + { + .career-list { + label { + width: 100%; + height: 1.5rem; + line-height: 1.5rem; + text-align: center; + background-color: var(--career-header); + } + display: flex; + flex-direction: column; + .list-container { + padding: 5px 0px; + display: flex; + flex-wrap: wrap; + justify-content: center; + } + .characteristic { + margin: 5px; + border: 1px solid var(--color-warm-2); + width: 3rem; + border-radius: 5px; + flex: 0 0 3rem; + text-align: center; + font-weight: bold; + &.active { + background-color: var(--color-warm-2); + } + } + + select, + input { + // width: fit-content; + border-radius: 5px; + margin: 5px; + height: 1.5rem; + text-align: center; + } + + a[data-action='listDelete'] { + border: 1px solid var(--color-cool-3); + background: var(--color-cool-3); + border-radius: 50%; + width: 1rem; + height: 1rem; + text-align: center; + margin-left: -1rem; + } + } + } +} \ No newline at end of file diff --git a/style/wfrp4e.scss b/style/wfrp4e.scss index 245f55dc8..a026c15d4 100644 --- a/style/wfrp4e.scss +++ b/style/wfrp4e.scss @@ -1,4 +1,5 @@ @import "./mixins/index"; @import "./sheets/temp"; @import "./sheets/light"; -@import "./sheets/actors/index"; \ No newline at end of file +@import "./sheets/actors/index"; +@import "./sheets/items/index"; \ No newline at end of file diff --git a/wfrp4e.js b/wfrp4e.js index a63ff4e6d..b52ba8a74 100644 --- a/wfrp4e.js +++ b/wfrp4e.js @@ -78,7 +78,28 @@ import ActorSheetWFRP4eCharacterV2 from "./src/apps/sheets/actor/character-sheet import { GenericAspectModel } from "./modules/model/item/generic.js"; import ActorSheetWFRP4eNPCV2 from "./src/apps/sheets/actor/npc-sheet.js"; import ActorSheetWFRP4eCreatureV2 from "./src/apps/sheets/actor/creature-sheet.js"; -import BaseWFRP4eItemSheet from "./src/apps/sheets/item/base.js"; +import TalentSheet from "./src/apps/sheets/item/talent-sheet.js"; +import MutationSheet from "./src/apps/sheets/item/mutation-sheet.js"; +import CriticalSheet from "./src/apps/sheets/item/critical-sheet.js"; +import InjurySheet from "./src/apps/sheets/item/injury-sheet.js"; +import AmmunitionSheet from "./src/apps/sheets/item/ammunition-sheet.js"; +import SkillSheet from "./src/apps/sheets/item/skill-sheet.js"; +import ArmourSheet from "./src/apps/sheets/item/armour-sheet.js"; +import CareerSheet from "./src/apps/sheets/item/career-sheet.js"; +import CargoSheet from "./src/apps/sheets/item/cargo.js"; +import ContainerSheet from "./src/apps/sheets/item/container-sheet.js"; +import ExtendedTestSheet from "./src/apps/sheets/item/extendedTest-sheet.js"; +import DiseaseSheet from "./src/apps/sheets/item/disease-sheet.js"; +import MoneySheet from "./src/apps/sheets/item/money.js"; +import PrayerSheet from "./src/apps/sheets/item/prayer-sheet.js"; +import PsychologySheet from "./src/apps/sheets/item/psychology-sheet.js"; +import SpellSheet from "./src/apps/sheets/item/spell-sheet.js"; +import TraitSheet from "./src/apps/sheets/item/trait-sheet.js"; +import TrappingSheet from "./src/apps/sheets/item/trapping-sheet.js"; +import VehicleModSheet from "./src/apps/sheets/item/vehicleMod-sheet.js"; +import VehicleRoleSheet from "./src/apps/sheets/item/vehicleRole-sheet.js"; +import VehicleTestSheet from "./src/apps/sheets/item/vehicleTest-sheet.js"; +import WeaponSheet from "./src/apps/sheets/item/weapon-sheet.js"; /* -------------------------------------------- */ /* Foundry VTT Initialization */ @@ -102,7 +123,29 @@ Hooks.once("init", function () { Actors.registerSheet("wfrp4e", ActorSheetWFRP4eVehicle, { types: ["vehicle"], makeDefault: true }); Items.unregisterSheet("core", ItemSheet); - Items.registerSheet("wfrp4e", BaseWFRP4eItemSheet, { makeDefault: true }); + Items.registerSheet("wfrp4e", ItemSheetWfrp4e, { makeDefault: true }); + Items.registerSheet("wfrp4e", AmmunitionSheet, { types: ["ammunition"], makeDefault: true }); + Items.registerSheet("wfrp4e", ArmourSheet, { types: ["armour"], makeDefault: true }); + Items.registerSheet("wfrp4e", CareerSheet, { types: ["career"], makeDefault: true }); + Items.registerSheet("wfrp4e", CargoSheet, { types: ["cargo"], makeDefault: true }); + Items.registerSheet("wfrp4e", ContainerSheet, { types: ["container"], makeDefault: true }); + Items.registerSheet("wfrp4e", CriticalSheet, { types: ["critical"], makeDefault: true }); + Items.registerSheet("wfrp4e", DiseaseSheet, { types: ["disease"], makeDefault: true }); + Items.registerSheet("wfrp4e", ExtendedTestSheet, { types: ["extendedTest"], makeDefault: true }); + Items.registerSheet("wfrp4e", InjurySheet, { types: ["injury"], makeDefault: true }); + Items.registerSheet("wfrp4e", MoneySheet, { types: ["money"], makeDefault: true }); + Items.registerSheet("wfrp4e", MutationSheet, { types: ["mutation"], makeDefault: true }); + Items.registerSheet("wfrp4e", PrayerSheet, { types: ["prayer"], makeDefault: true }); + Items.registerSheet("wfrp4e", PsychologySheet, { types: ["psychology"], makeDefault: true }); + Items.registerSheet("wfrp4e", SkillSheet, { types: ["skill"], makeDefault: true }); + Items.registerSheet("wfrp4e", SpellSheet, { types: ["spell"], makeDefault: true }); + Items.registerSheet("wfrp4e", TalentSheet, { types: ["talent"], makeDefault: true }); + Items.registerSheet("wfrp4e", TraitSheet, { types: ["trait"], makeDefault: true }); + Items.registerSheet("wfrp4e", TrappingSheet, { types: ["trapping"], makeDefault: true }); + Items.registerSheet("wfrp4e", VehicleModSheet, { types: ["vehicleMod"], makeDefault: true }); + Items.registerSheet("wfrp4e", VehicleRoleSheet, { types: ["vehicleRole"], makeDefault: true }); + Items.registerSheet("wfrp4e", VehicleTestSheet, { types: ["vehicleTest"], makeDefault: true }); + Items.registerSheet("wfrp4e", WeaponSheet, { types: ["weapon"], makeDefault: true }); DocumentSheetConfig.registerSheet(RollTable, "wfrp4e", WFRPTableConfig, {makeDefault: true}) DocumentSheetConfig.registerSheet(ActiveEffect, "wfrp4e", WFRP4eActiveEffectConfig, {makeDefault :true}) // DocumentSheetConfig.registerSheet(JournalEntry, "wfrp4e", WFRPJournalSheet, {makeDefault :true}) From 88a87c90d52995e990ace757c54d7a62af35d3fe Mon Sep 17 00:00:00 2001 From: Russell Date: Fri, 29 Nov 2024 16:29:02 -0600 Subject: [PATCH 3/3] Add condition fields to item effect tab --- src/apps/sheets/item/base.js | 33 +++++++++++-- src/apps/sheets/item/critical-sheet.js | 1 + src/apps/sheets/item/disease-sheet.js | 1 + src/apps/sheets/item/injury-sheet.js | 1 + src/apps/sheets/item/mutation-sheet.js | 1 + src/apps/sheets/item/spell-sheet.js | 15 ++++++ src/apps/sheets/item/weapon-sheet.js | 6 +++ .../sheets/item/tabs/item-effects.hbs | 5 ++ static/templates/sheets/item/types/spell.hbs | 13 +++++- static/templates/sheets/item/types/weapon.hbs | 10 ++++ style/sheets/_sheet.scss | 46 +++++++++++++++++++ style/sheets/actors/tabs/_effects.scss | 41 +---------------- style/sheets/items/_item.scss | 6 +++ style/wfrp4e.scss | 1 + 14 files changed, 136 insertions(+), 44 deletions(-) create mode 100644 style/sheets/_sheet.scss diff --git a/src/apps/sheets/item/base.js b/src/apps/sheets/item/base.js index fe9fea23e..5272a704a 100644 --- a/src/apps/sheets/item/base.js +++ b/src/apps/sheets/item/base.js @@ -1,10 +1,13 @@ import ItemProperties from "../../../../modules/apps/item-properties"; +import ActiveEffectWFRP4e from "../../../../modules/system/effect-wfrp4e"; export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 { static type="" + static hasConditionEffects = false + static DEFAULT_OPTIONS = { classes: ["wfrp4e"], defaultTab : "description", @@ -22,7 +25,8 @@ export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 }, actions : { postToChat : function() {this.item.postItem()}, - configureProperties : this._onConfigureProperties + configureProperties : this._onConfigureProperties, + clickCondition : {buttons : [0, 2], handler : this._onClickCondition} } } @@ -61,10 +65,10 @@ export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 //#region Effects - _getConditionData(context) { + _getConditionData() { try { let conditions = foundry.utils.duplicate(game.wfrp4e.config.statusEffects).filter(i => !["fear", "grappling", "engaged"].includes(i.id)).map(e => new ActiveEffectWFRP4e(e)); - let currentConditions = this.actor.effects.filter(e => e.isCondition); + let currentConditions = this.item.effects.filter(e => e.isCondition); delete conditions.splice(conditions.length - 1, 1) for (let condition of conditions) { @@ -85,6 +89,16 @@ export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 } } + _prepareEffectsContext(context) + { + super._prepareEffectsContext(context); + if (this.constructor.hasConditionEffects) + { + context.effects.conditions = this._getConditionData() + } + return context; + } + //#endregion _getContetMenuOptions() @@ -141,5 +155,18 @@ export default class BaseWFRP4eItemSheet extends WarhammerItemSheetV2 new ItemProperties(this.document).render(true) } + + static _onClickCondition(ev) { + let conditionKey = this._getParent(ev.target, ".condition")?.dataset.key + let existing = this.item.hasCondition(conditionKey) + + if (!existing?.isNumberedCondition && ev.button == 0) + { + this.item.removeCondition(conditionKey); + } + + ev.button == 0 ? this.item.addCondition(conditionKey) : this.item.removeCondition(conditionKey) + } + //#endregion } diff --git a/src/apps/sheets/item/critical-sheet.js b/src/apps/sheets/item/critical-sheet.js index 210285b74..70cd73d5a 100644 --- a/src/apps/sheets/item/critical-sheet.js +++ b/src/apps/sheets/item/critical-sheet.js @@ -3,6 +3,7 @@ import BaseWFRP4eItemSheet from "./base"; export default class CriticalSheet extends BaseWFRP4eItemSheet { static type="critical" + static hasConditionEffects = true; static DEFAULT_OPTIONS = { classes: [this.type], diff --git a/src/apps/sheets/item/disease-sheet.js b/src/apps/sheets/item/disease-sheet.js index 605d0d7a8..e1226937c 100644 --- a/src/apps/sheets/item/disease-sheet.js +++ b/src/apps/sheets/item/disease-sheet.js @@ -3,6 +3,7 @@ import BaseWFRP4eItemSheet from "./base"; export default class DiseaseSheet extends BaseWFRP4eItemSheet { static type="disease" + static hasConditionEffects = true; static DEFAULT_OPTIONS = { classes: [this.type], diff --git a/src/apps/sheets/item/injury-sheet.js b/src/apps/sheets/item/injury-sheet.js index ea19d4d78..2c0464312 100644 --- a/src/apps/sheets/item/injury-sheet.js +++ b/src/apps/sheets/item/injury-sheet.js @@ -3,6 +3,7 @@ import BaseWFRP4eItemSheet from "./base"; export default class InjurySheet extends BaseWFRP4eItemSheet { static type="injury" + static hasConditionEffects = true; static DEFAULT_OPTIONS = { classes: [this.type], diff --git a/src/apps/sheets/item/mutation-sheet.js b/src/apps/sheets/item/mutation-sheet.js index d20c3f15f..b9f03febb 100644 --- a/src/apps/sheets/item/mutation-sheet.js +++ b/src/apps/sheets/item/mutation-sheet.js @@ -3,6 +3,7 @@ import BaseWFRP4eItemSheet from "./base"; export default class MutationSheet extends BaseWFRP4eItemSheet { static type="mutation" + static hasConditionEffects = true; static DEFAULT_OPTIONS = { classes: [this.type], diff --git a/src/apps/sheets/item/spell-sheet.js b/src/apps/sheets/item/spell-sheet.js index 606441d68..8d0cca422 100644 --- a/src/apps/sheets/item/spell-sheet.js +++ b/src/apps/sheets/item/spell-sheet.js @@ -15,4 +15,19 @@ export default class SpellSheet extends BaseWFRP4eItemSheet details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, } + + async _prepareContext(options) + { + let context = await super._prepareContext(options); + if (game.wfrp4e.config.magicLores[this.item.lore.value]) + { + context.loreValue = game.wfrp4e.config.magicLores[this.item.lore.value] + } + else + { + context.loreValue = this.item.lore.value; + } + return context; + } + } \ No newline at end of file diff --git a/src/apps/sheets/item/weapon-sheet.js b/src/apps/sheets/item/weapon-sheet.js index b6b4a683c..347883ab1 100644 --- a/src/apps/sheets/item/weapon-sheet.js +++ b/src/apps/sheets/item/weapon-sheet.js @@ -15,4 +15,10 @@ export default class WeaponSheet extends BaseWFRP4eItemSheet details: { scrollable: [""], template: `systems/wfrp4e/templates/sheets/item/types/${this.type}.hbs` }, effects: { scrollable: [""], template: 'systems/wfrp4e/templates/sheets/item/tabs/item-effects.hbs' }, } + + async _prepareContext(options) + { + let context = await super._prepareContext(options); + return context; + } } diff --git a/static/templates/sheets/item/tabs/item-effects.hbs b/static/templates/sheets/item/tabs/item-effects.hbs index bb447496a..c5d56ed91 100644 --- a/static/templates/sheets/item/tabs/item-effects.hbs +++ b/static/templates/sheets/item/tabs/item-effects.hbs @@ -1,4 +1,5 @@
+ {{#if effects.conditions}}
{{#each effects.conditions}}
@@ -17,7 +18,9 @@
{{/each}}
+ {{/if}} +
{{#if effects.temporary.length}}
@@ -95,5 +98,7 @@
{{/if}} +
+
\ No newline at end of file diff --git a/static/templates/sheets/item/types/spell.hbs b/static/templates/sheets/item/types/spell.hbs index 9b2a992ed..c1dcc7dc4 100644 --- a/static/templates/sheets/item/types/spell.hbs +++ b/static/templates/sheets/item/types/spell.hbs @@ -1,6 +1,17 @@
{{formGroup fields.cn.fields.value value=source.system.cn.value}} - {{formGroup fields.lore.fields.value value=source.system.lore.value}} + {{!-- {{formGroup fields.lore.fields.value value=source.system.lore.value}} --}} +
+ +
+ +
+
+ + {{#each (config "magicLores")}} + + {{/each}} +
{{localize "Overrides"}} {{formGroup fields.skill.fields.value value=source.system.skill.value}} diff --git a/static/templates/sheets/item/types/weapon.hbs b/static/templates/sheets/item/types/weapon.hbs index a4430e384..efcebb617 100644 --- a/static/templates/sheets/item/types/weapon.hbs +++ b/static/templates/sheets/item/types/weapon.hbs @@ -10,6 +10,16 @@ {{formGroup fields.reach.fields.value value=source.system.reach.value}} {{else}} {{formGroup fields.range.fields.value value=source.system.range.value}} + {{#if (settings "mooRangeBands")}} +
+ +
+ +
+
+ {{/if}} {{formGroup fields.ammunitionGroup.fields.value value=source.system.ammunitionGroup.value}} {{formGroup fields.consumesAmmo.fields.value value=source.system.consumesAmmo.value}} {{/if}} diff --git a/style/sheets/_sheet.scss b/style/sheets/_sheet.scss new file mode 100644 index 000000000..d37c21e3b --- /dev/null +++ b/style/sheets/_sheet.scss @@ -0,0 +1,46 @@ +.wfrp4e.sheet.application { + --condition-label : transparent; +--condition-border : var(--color-cool-3); +--condition-control-bg : var(--color-cool-4); + + + section.tab[data-tab="effects"] { + &.active { + display : flex; + } + .condition-section { + display: flex; + flex-direction: column; + flex: 0 0 8rem; + margin-top: 8px; + margin-right: 5px; + .condition { + border: 1px solid var(--condition-border); + background: var(--condition-label); + margin: 3px; + height: 2rem; + line-height: 2rem; + display : flex; + justify-content: space-between; + > :first-of-type { + padding: 0px 5px; + } + .controls { + background: var(--condition-control-bg); + text-align: center; + font-size: var(--font-size-16); + flex: 0 0 2rem; + } + } + } + + .effect-lists { + flex: 1; + .flex { + i { + margin-right: 3px; + } + } + } + } +} \ No newline at end of file diff --git a/style/sheets/actors/tabs/_effects.scss b/style/sheets/actors/tabs/_effects.scss index cef9b7780..b315588e2 100644 --- a/style/sheets/actors/tabs/_effects.scss +++ b/style/sheets/actors/tabs/_effects.scss @@ -1,46 +1,7 @@ .wfrp4e.actor.sheet { - --condition-label : transparent; - --condition-border : var(--color-cool-3); - --condition-control-bg : var(--color-cool-4); + section.tab[data-tab="effects"] { height: calc(100% - 200px); - &.active { - display : flex; - } - .condition-section { - display: flex; - flex-direction: column; - flex: 0 0 8rem; - margin-top: 8px; - margin-right: 5px; - .condition { - border: 1px solid var(--condition-border); - background: var(--condition-label); - margin: 3px; - height: 2rem; - line-height: 2rem; - display : flex; - justify-content: space-between; - > :first-of-type { - padding: 0px 5px; - } - .controls { - background: var(--condition-control-bg); - text-align: center; - font-size: var(--font-size-16); - flex: 0 0 2rem; - } - } - } - - .effect-lists { - flex: 1; - .flex { - i { - margin-right: 3px; - } - } - } } } \ No newline at end of file diff --git a/style/sheets/items/_item.scss b/style/sheets/items/_item.scss index e6ec93e27..e1d770d2c 100644 --- a/style/sheets/items/_item.scss +++ b/style/sheets/items/_item.scss @@ -81,6 +81,12 @@ } } + section[data-tab="effects"] { + .condition-section { + margin-top: 0px; + } + } + &.career { .career-list { diff --git a/style/wfrp4e.scss b/style/wfrp4e.scss index a026c15d4..e0033259a 100644 --- a/style/wfrp4e.scss +++ b/style/wfrp4e.scss @@ -1,4 +1,5 @@ @import "./mixins/index"; +@import "./sheets/sheet"; @import "./sheets/temp"; @import "./sheets/light"; @import "./sheets/actors/index";