From c2a7fbb4b5bb8d280ed8e74f556c945ed1c5b9e9 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnien Date: Fri, 10 Mar 2023 18:32:13 +0100 Subject: [PATCH] New slots --- lang/en.json | 16 ++++- modules/warhero-actor-sheet.js | 9 ++- modules/warhero-actor.js | 98 +++++++++++++++++++++++------- modules/warhero-config.js | 26 ++++++-- modules/warhero-main.js | 2 + modules/warhero-party-sheet.js | 57 ++++++++++++++++++ modules/warhero-utility.js | 1 + system.json | 4 +- template.json | 8 ++- templates/actor-sheet.html | 59 ++++-------------- templates/partial-container.html | 49 +++++++++++++++ templates/party-sheet.html | 100 +++++++++++++++++++++++++++++++ 12 files changed, 345 insertions(+), 84 deletions(-) create mode 100644 modules/warhero-party-sheet.js create mode 100644 templates/partial-container.html create mode 100644 templates/party-sheet.html diff --git a/lang/en.json b/lang/en.json index b984772..9e223e7 100644 --- a/lang/en.json +++ b/lang/en.json @@ -53,7 +53,18 @@ "WH.conf.beltpouch1": "Beltpouch 1", "WH.conf.beltpouch2": "Beltpouch 2", "WH.conf.beltpouch3": "Beltpouch 3", - + "WH.conf.scrollcase": "Scroll case", + "WH.conf.wandcase": "Wand case", + "WH.conf.potioncase": "Potion case", + "WH.conf.bagholding": "Bag of holding", + "WH.conf.quiverholding": "Quiver of holding", + "WH.conf.backpackholding": "Backpack of holding", + "WH.conf.smallchest": "Small chest", + "WH.conf.mediumchest": "Medium chest", + "WH.conf.largechest": "Large chest", + "WH.conf.hugechest": "Huge chest", + "WH.conf.partystorage": "Party chest/storage", + "WH.conf.unknown": "Unknown", "WH.conf.yes": "Yes", "WH.conf.no": "No", @@ -192,6 +203,9 @@ "WH.ui.raceSkills": "Race skills", "WH.ui.identified": "Identified", + "WH.ui.bodyslots": "Body", + "WH.ui.containerslot": "Containers", + "WH.chat.save": "Save", "WH.chat.mweaponmalus": "Multiple weapons malus ", "WH.chat.diceresult": "Dice result", diff --git a/modules/warhero-actor-sheet.js b/modules/warhero-actor-sheet.js index ef1ef06..b9e4850 100644 --- a/modules/warhero-actor-sheet.js +++ b/modules/warhero-actor-sheet.js @@ -52,13 +52,12 @@ export class WarheroActorSheet extends ActorSheet { armors: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getArmors())), shields: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getShields())), powers: this.actor.sortPowers(), - equipments: this.actor.checkAndPrepareEquipments(duplicate(this.actor.getEquipmentsOnly()) ), - slotEquipments: this.actor.buildEquipmentsSlot(), subActors: duplicate(this.actor.getSubActors()), competency: this.actor.getCompetency(), race: duplicate(race), classes: duplicate(this.actor.getClasses()), totalMoney: this.actor.computeTotalMoney(), + equipments: duplicate(this.actor.getEquipmentsOnly()), //moneys: duplicate(this.actor.getMoneys()), description: await TextEditor.enrichHTML(this.object.system.biodata.description, {async: true}), notes: await TextEditor.enrichHTML(this.object.system.biodata.notes, {async: true}), @@ -66,6 +65,12 @@ export class WarheroActorSheet extends ActorSheet { owner: this.document.isOwner, editScore: this.options.editScore, isGM: game.user.isGM + } + if (this.actor.type == "party") { + formData.partySlots = this.actor.buildPartySlots() + } else { + formData.equipmentContainers = this.actor.buildEquipmentsSlot() + formData.bodyContainers = this.actor.buildBodySlot() } // Dynamic patch formData.system.secondary.counterspell.hasmax = false diff --git a/modules/warhero-actor.js b/modules/warhero-actor.js index 5bc6b52..6e7ed5a 100644 --- a/modules/warhero-actor.js +++ b/modules/warhero-actor.js @@ -181,29 +181,82 @@ export class WarheroActor extends Actor { /* -------------------------------------------- */ computeTotalMoney() { let nbMoney = 0 - this.items.forEach(it => {if (it.type == 'money') { nbMoney += it.system.quantity} } ) + this.items.forEach(it => { if (it.type == 'money') { nbMoney += it.system.quantity } }) return nbMoney - } + } + + /* -------------------------------------------- */ + buildPartySlots() { + let containers = {} + for (let slotName in game.system.warhero.config.partySlotNames) { + let slotDef = game.system.warhero.config.partySlotNames[slotName] + containers[slotName] = duplicate(slotDef) + containers[slotName].content = this.items.filter(it => (it.type == 'money' || it.type == 'weapon' || it.type == 'armor' || it.type == 'shield' || it.type == 'equipment') ) + let slotUsed = 0 + for (let item of containers[slotName].content) { + let q = (item.system.quantity) ? item.system.quantity : 1 + containers[slotName].nbslots += (item.system.providedslot ?? 0) * q + if (item.type == "money") { + slotUsed += Math.ceil(item.system.quantity / 1000) + } else { + slotUsed += item.system.slotused * q + } + } + slotUsed = Math.ceil(slotUsed) + containers[slotName].slotUsed = slotUsed + } + return containers + } + + /* -------------------------------------------- */ + buildBodySlot() { + let containers = {} + for (let slotName in game.system.warhero.config.slotNames) { + let slotDef = game.system.warhero.config.slotNames[slotName] + if (!slotDef.container) { + containers[slotName] = duplicate(slotDef) + containers[slotName].content = this.items.filter(it => (it.type == 'money' || it.type == 'weapon' || it.type == 'armor' || it.type == 'shield' || it.type == 'equipment') + && it.system.slotlocation == slotName) + let slotUsed = 0 + for (let item of containers[slotName].content) { + let q = (item.system.quantity) ? item.system.quantity : 1 + containers[slotName].nbslots += (item.system.providedslot ?? 0) * q + if (item.type == "money") { + slotUsed += Math.ceil(item.system.quantity / 1000) + } else { + slotUsed += item.system.slotused * q + } + } + slotUsed = Math.ceil(slotUsed) + containers[slotName].slotUsed = slotUsed + } + } + return containers + } + + /* -------------------------------------------- */ buildEquipmentsSlot() { let containers = {} for (let slotName in game.system.warhero.config.slotNames) { let slotDef = game.system.warhero.config.slotNames[slotName] - containers[slotName] = duplicate(slotDef) - containers[slotName].content = this.items.filter(it => (it.type == 'money' || it.type == 'weapon' || it.type == 'armor' || it.type == 'shield' || it.type == 'equipment') - && it.system.slotlocation == slotName) - let slotUsed = 0 - for (let item of containers[slotName].content) { - let q = (item.system.quantity) ? item.system.quantity : 1 - containers[slotName].nbslots += (item.system.providedslot?? 0) * q - if ( item.type == "money") { - slotUsed += Math.ceil(item.system.quantity / 1000) - } else { - slotUsed += item.system.slotused * q + if (slotDef.container) { + containers[slotName] = duplicate(slotDef) + containers[slotName].content = this.items.filter(it => (it.type == 'money' || it.type == 'weapon' || it.type == 'armor' || it.type == 'shield' || it.type == 'equipment') + && it.system.slotlocation == slotName) + let slotUsed = 0 + for (let item of containers[slotName].content) { + let q = (item.system.quantity) ? item.system.quantity : 1 + containers[slotName].nbslots += (item.system.providedslot ?? 0) * q + if (item.type == "money") { + slotUsed += Math.ceil(item.system.quantity / 1000) + } else { + slotUsed += item.system.slotused * q + } } + slotUsed = Math.ceil(slotUsed) + containers[slotName].slotUsed = slotUsed } - slotUsed = Math.ceil(slotUsed) - containers[slotName].slotUsed = slotUsed } return containers } @@ -322,7 +375,7 @@ export class WarheroActor extends Actor { /* ------------------------------------------- */ getEquipments() { - return this.items.filter(item => item.type == 'shield' || item.type == 'armor' || item.type == "weapon" || item.type == "equipment" || item.type == "potion" || item.type == "poison"|| item.type == "trap" || item.type == "classitem"); + return this.items.filter(item => item.type == 'shield' || item.type == 'armor' || item.type == "weapon" || item.type == "equipment" || item.type == "potion" || item.type == "poison" || item.type == "trap" || item.type == "classitem"); } getCompetencyItems() { return duplicate(this.items.filter(item => item.type == "competency") || []) @@ -485,7 +538,7 @@ export class WarheroActor extends Actor { } /* -------------------------------------------- */ async getInitiativeScore(combatId, combatantId) { - let roll = new Roll("1d20+"+this.system.attributes.ini.value).roll({async: false}) + let roll = new Roll("1d20+" + this.system.attributes.ini.value).roll({ async: false }) await WarheroUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode")) return roll.total } @@ -578,7 +631,7 @@ export class WarheroActor extends Actor { return } newUse = Math.max(newUse, 0) - this.updateEmbeddedDocuments('Item', [{ _id: skill.id, 'system.currentuse': newUse }]) + this.updateEmbeddedDocuments('Item', [{ _id: skill.id, 'system.currentuse': newUse }]) } } /* -------------------------------------------- */ @@ -668,12 +721,12 @@ export class WarheroActor extends Actor { this.update({ 'system.attributes.mana': mana }) return true } - + /* -------------------------------------------- */ incrementUse(rollData) { let stat = duplicate(this.system[rollData.mode][rollData.statKey]) stat.nbuse++ - this.update( { [`system.${rollData.mode}.${rollData.statKey}`]: stat }) + this.update({ [`system.${rollData.mode}.${rollData.statKey}`]: stat }) } /* -------------------------------------------- */ @@ -695,11 +748,10 @@ export class WarheroActor extends Actor { rollData.mode = rollType rollData.statKey = rollKey rollData.stat = stat - if (stat && stat.stat) - { + if (stat && stat.stat) { rollData.statBonus = duplicate(this.system.statistics[stat.stat]) } - if ( stat.hasuse && stat.nbuse >= stat.maxuse) { + if (stat.hasuse && stat.nbuse >= stat.maxuse) { ui.notifications.warn(game.i18n.localize("WH.notif.toomanyuses")) return } diff --git a/modules/warhero-config.js b/modules/warhero-config.js index 4a52e77..81f4550 100644 --- a/modules/warhero-config.js +++ b/modules/warhero-config.js @@ -21,6 +21,10 @@ export const WARHERO_CONFIG = { medium: {parry: "3", label: "WH.conf.mediumshield"}, tower: {parry: "5", label: "WH.conf.towershield"}, }, + + partySlotNames : { + storage: {nbslots: 2000, itemtype:"equipment", label: "WH.conf.partystorage"} + }, slotNames : { head: {nbslots: 1, itemtype:"armor", label: "WH.conf.head"}, @@ -31,14 +35,24 @@ export const WARHERO_CONFIG = { ring: {nbslots: 10, itemtype:"equipment",label: "WH.conf.ring"}, dress: {nbslots: 1, itemtype:"equipment",label: "WH.conf.dress"}, boots: {nbslots: 1, itemtype:"equipment",label: "WH.conf.boots"}, - belt: {nbslots: 6, itemtype:"equipment",label: "WH.conf.belt"}, - quiver: {nbslots: 20, itemtype:"equipment",label: "WH.conf.quiver"}, armor: {nbslots: 1, itemtype:"armor",label: "WH.conf.armor"}, shield: {nbslots: 1, itemtype:"shield",label: "WH.conf.shield"}, - backpack: {nbslots: 12, itemtype:"equipment",label: "WH.conf.backpack"}, - beltpouch1: {nbslots: 4, itemtype:"equipment",label: "WH.conf.beltpouch1"}, - beltpouch2: {nbslots: 4, itemtype:"equipment", label: "WH.conf.beltpouch2"}, - beltpouch3: {nbslots: 4, itemtype:"equipment", label: "WH.conf.beltpouch3"}, + belt: {nbslots: 6, itemtype:"equipment", container: true, available: true, parent: undefined, label: "WH.conf.belt"}, + quiver: {nbslots: 20, itemtype:"equipment",container: true, available: true, parent: undefined, label: "WH.conf.quiver"}, + backpack: {nbslots: 12, itemtype:"equipment",container: true, available: true, parent: undefined, label: "WH.conf.backpack"}, + beltpouch1: {nbslots: 4, itemtype:"equipment",container: true, available: true, parent: undefined, label: "WH.conf.beltpouch1"}, + beltpouch2: {nbslots: 4, itemtype:"equipment", container: true, available: true, parent: undefined, label: "WH.conf.beltpouch2"}, + beltpouch3: {nbslots: 4, itemtype:"equipment", container: true, available: true, parent: undefined, label: "WH.conf.beltpouch3"}, + scrollcase: {nbslots: 17, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.scrollcase"}, + wandcase: {nbslots: 10, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.wandcase"}, + potioncase: {nbslots: 8, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.potioncase"}, + bagholding: {nbslots: 30, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.bagholding"}, + quiverholding: {nbslots: 9999, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.quiverholding"}, + backpackholding: {nbslots: 90, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.backpackholding"}, + smallchest: {nbslots: 6, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.smallchest"}, + mediumchest: {nbslots: 12, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.mediumchest"}, + largechest: {nbslots: 24, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.largechest"}, + hugechest: {nbslots: 24, itemtype:"equipment", container: true, available: false, parent: undefined, label: "WH.conf.hugechest"}, }, progressionList: { diff --git a/modules/warhero-main.js b/modules/warhero-main.js index dcd3a91..d3c2ffc 100644 --- a/modules/warhero-main.js +++ b/modules/warhero-main.js @@ -11,6 +11,7 @@ import { WarheroActor } from "./warhero-actor.js"; import { WarheroItemSheet } from "./warhero-item-sheet.js"; import { WarheroActorSheet } from "./warhero-actor-sheet.js"; +import { WarheroPartySheet } from "./warhero-party-sheet.js"; import { WarheroNPCSheet } from "./warhero-npc-sheet.js"; import { WarheroMonsterSheet } from "./warhero-monster-sheet.js"; import { WarheroUtility } from "./warhero-utility.js"; @@ -63,6 +64,7 @@ Hooks.once("init", async function () { Actors.registerSheet("fvtt-warhero", WarheroActorSheet, { types: ["character"], makeDefault: true }); Actors.registerSheet("fvtt-warhero", WarheroNPCSheet, { types: ["npc"], makeDefault: false }); Actors.registerSheet("fvtt-warhero", WarheroMonsterSheet, { types: ["monster"], makeDefault: false }); + Actors.registerSheet("fvtt-warhero", WarheroPartySheet, { types: ["party"], makeDefault: false }); Items.unregisterSheet("core", ItemSheet); Items.registerSheet("fvtt-warhero", WarheroItemSheet, { makeDefault: true }); diff --git a/modules/warhero-party-sheet.js b/modules/warhero-party-sheet.js new file mode 100644 index 0000000..d05fb98 --- /dev/null +++ b/modules/warhero-party-sheet.js @@ -0,0 +1,57 @@ +/** + * Extend the basic ActorSheet with some very simple modifications + * @extends {ActorSheet} + */ +import { WarheroActorSheet } from "./warhero-actor-sheet.js"; +import { WarheroUtility } from "./warhero-utility.js"; + +/* -------------------------------------------- */ +export class WarheroPartySheet extends WarheroActorSheet { + + /** @override */ + static get defaultOptions() { + + return mergeObject(super.defaultOptions, { + classes: ["warhero-rpg", "sheet", "actor"], + template: "systems/fvtt-warhero/templates/party-sheet.html", + width: 640, + height: 720, + tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }], + dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }], + editScore: true + }); + } + + /* -------------------------------------------- */ + async getData() { + + const objectData = duplicate(this.object.system) + + let formData = { + title: this.title, + id: this.actor.id, + type: this.actor.type, + img: this.actor.img, + name: this.actor.name, + editable: this.isEditable, + cssClass: this.isEditable ? "editable" : "locked", + system: objectData, + limited: this.object.limited, + totalMoney: this.actor.computeTotalMoney(), + equipments: duplicate(this.actor.getEquipmentsOnly()), + //moneys: duplicate(this.actor.getMoneys()), + description: await TextEditor.enrichHTML(this.object.system.biodata.description, {async: true}), + notes: await TextEditor.enrichHTML(this.object.system.biodata.notes, {async: true}), + options: this.options, + owner: this.document.isOwner, + editScore: this.options.editScore, + isGM: game.user.isGM + } + formData.partySlots = this.actor.buildPartySlots() + + this.formData = formData + console.log("PARTY : ", formData, this.object); + return formData; + } + +} diff --git a/modules/warhero-utility.js b/modules/warhero-utility.js index 7b32e56..b671e1f 100644 --- a/modules/warhero-utility.js +++ b/modules/warhero-utility.js @@ -231,6 +231,7 @@ export class WarheroUtility { 'systems/fvtt-warhero/templates/partial-item-description.html', 'systems/fvtt-warhero/templates/partial-item-common-equipment.html', 'systems/fvtt-warhero/templates/partial-actor-equipment.html', + 'systems/fvtt-warhero/templates/partial-container.html', ] return loadTemplates(templatePaths); } diff --git a/system.json b/system.json index 5cb503b..8187fdb 100644 --- a/system.json +++ b/system.json @@ -107,7 +107,7 @@ "styles": [ "styles/simple.css" ], - "version": "10.0.38", + "version": "10.0.40", "compatibility": { "minimum": "10", "verified": "10", @@ -115,7 +115,7 @@ }, "title": "Warhero RPG", "manifest": "https://www.uberwald.me/gitea/public/fvtt-warhero/raw/branch/master/system.json", - "download": "https://www.uberwald.me/gitea/uberwald/fvtt-warhero/archive/fvtt-warhero-10.0.38.zip", + "download": "https://www.uberwald.me/gitea/uberwald/fvtt-warhero/archive/fvtt-warhero-10.0.40.zip", "url": "https://www.uberwald.me/gitea/public/fvtt-warhero", "background": "images/ui/warhero_welcome_page.webp", "id": "fvtt-warhero" diff --git a/template.json b/template.json index 00bb6ce..13e6452 100644 --- a/template.json +++ b/template.json @@ -3,7 +3,8 @@ "types": [ "character", "npc", - "monster" + "monster", + "party" ], "templates": { "biodata": { @@ -212,6 +213,11 @@ "description": "" } }, + "party": { + "templates": [ + "biodata" + ] + }, "character": { "templates": [ "biodata", diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index f3588ea..7630d2d 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -486,58 +486,19 @@ - {{#each slotEquipments as |slot slotKey|}} - + {{#each bodyContainers as |slot slotKey|}} + {{> systems/fvtt-warhero/templates/partial-container.html slot=slot}} {{/each}} +
+

{{localize "WH.ui.containerslot"}} :

+ + {{#each equipmentContainers as |slot slotKey|}} + {{> systems/fvtt-warhero/templates/partial-container.html slot=slot}} + {{/each}}
diff --git a/templates/partial-container.html b/templates/partial-container.html new file mode 100644 index 0000000..0c07b1c --- /dev/null +++ b/templates/partial-container.html @@ -0,0 +1,49 @@ + diff --git a/templates/party-sheet.html b/templates/party-sheet.html new file mode 100644 index 0000000..90b2f6b --- /dev/null +++ b/templates/party-sheet.html @@ -0,0 +1,100 @@ +
+ + {{!-- Sheet Header --}} +
+
+

+
+ +
+
+
+ +
+
+ + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
+ + + {{!-- Equipement Tab --}} +
+ + {{#each partySlots as |slot slotKey|}} +
    +
  • + +

    +
    + + + + + + + + + + + + +
     
    +
    + +
    +
  • + {{#each slot.content as |item itemKey|}} +
  • + + {{item.name}} + + + + + + + + +
     
    +
    + +
    +
  • + {{/each}} +
+ {{/each}} + + +
+ +
+ + {{!-- Biography Tab --}} +
+
+

{{localize "WH.ui.background"}} :

+
+ {{editor description target="system.biodata.description" button=true owner=owner + editable=editable}} +
+
+

{{localize "WH.ui.notes"}} :

+
+ {{editor notes target="system.biodata.notes" button=true owner=owner editable=editable}} +
+
+ +
+ +
+
\ No newline at end of file