diff --git a/src/module/actor/character-sheet.js b/src/module/actor/character-sheet.js index 1050177..ef0e977 100644 --- a/src/module/actor/character-sheet.js +++ b/src/module/actor/character-sheet.js @@ -47,89 +47,11 @@ export class OseActorSheetCharacter extends OseActorSheet { ); data.config.ascendingAC = game.settings.get("ose", "ascendingAC"); data.config.individualInit = game.settings.get("ose", "individualInit"); - - // Compute treasure - let total = 0; - data.owned.items.forEach((item) => { - if (item.data.treasure) { - total += item.data.quantity.value * item.data.cost; - } - }); - data.treasure = total; - data.config.encumbrance = game.settings.get("ose", "encumbranceOption"); - let basic = data.config.encumbrance == "basic"; - // Compute encumbrance - let totalWeight = 0; - Object.values(data.owned).forEach((cat) => { - cat.forEach((item) => { - if (item.type == "item" && (!basic || item.data.treasure)) { - totalWeight += item.data.quantity.value * item.data.weight; - } else if (!basic) { - totalWeight += item.data.weight; - } - }); - }); - data.encumbrance = { - pct: Math.clamped( - (100 * parseFloat(totalWeight)) / data.data.encumbrance.max, - 0, - 100 - ), - max: data.data.encumbrance.max, - encumbered: totalWeight > data.data.encumbrance.max, - value: totalWeight, - }; - - if (data.data.config.movementAuto) { - this._calculateMovement(data, totalWeight); - } return data; } - _calculateMovement(data, weight) { - if (data.config.encumbrance == "disabled") return; - let delta = data.encumbrance.max - 1600; - if (data.config.encumbrance == "detailed") { - if (weight > data.encumbrance.max) { - data.data.movement.base = 0; - } else if (weight > 800 + delta) { - data.data.movement.base = 30; - } else if (weight > 600 + delta) { - data.data.movement.base = 60; - } else if (weight > 400 + delta) { - data.data.movement.base = 90; - } else { - data.data.movement.base = 120; - } - } else if (data.config.encumbrance == "basic") { - let heaviest = 0; - data.owned.armors.forEach((a) => { - if (a.data.equipped) { - if (a.data.type == "light" && heaviest == 0) { - heaviest = 1; - } else if (a.data.type == "heavy") { - heaviest = 2; - } - } - }); - switch (heaviest) { - case 0: - data.data.movement.base = 120; - break; - case 1: - data.data.movement.base = 90; - break; - case 2: - data.data.movement.base = 60; - break; - } - if (weight > game.settings.get("ose", "significantTreasure")) { - data.data.movement.base -= 30; - } - } - } async _chooseLang() { let choices = CONFIG.OSE.languages; diff --git a/src/module/actor/entity.js b/src/module/actor/entity.js index 25db1a8..f3106c0 100644 --- a/src/module/actor/entity.js +++ b/src/module/actor/entity.js @@ -13,6 +13,8 @@ export class OseActor extends Actor { this.computeModifiers(); this._isSlow(); this.computeAC(); + this.computeEncumbrance(); + this.computeTreasure(); // Determine Initiative if (game.settings.get("ose", "individualInit")) { @@ -24,7 +26,6 @@ export class OseActor extends Actor { data.initiative.value = 0; } data.movement.encounter = data.movement.base / 3; - } /* -------------------------------------------- */ /* Socket Listeners and Handlers @@ -216,8 +217,8 @@ export class OseActor extends Actor { data: data, skipDialog: skip, speaker: ChatMessage.getSpeaker({ actor: this }), - flavor: game.i18n.format("OSE.roll.attribute", {attribute: label}), - title: game.i18n.format("OSE.roll.attribute", {attribute: label}), + flavor: game.i18n.format("OSE.roll.attribute", { attribute: label }), + title: game.i18n.format("OSE.roll.attribute", { attribute: label }), }); } @@ -272,8 +273,8 @@ export class OseActor extends Actor { data: data, skipDialog: true, speaker: ChatMessage.getSpeaker({ actor: this }), - flavor: game.i18n.localize('OSE.roll.appearing'), - title: game.i18n.localize('OSE.roll.appearing'), + flavor: game.i18n.localize("OSE.roll.appearing"), + title: game.i18n.localize("OSE.roll.appearing"), }); } @@ -303,8 +304,8 @@ export class OseActor extends Actor { data: data, skipDialog: skip, speaker: ChatMessage.getSpeaker({ actor: this }), - flavor: game.i18n.format("OSE.roll.exploration", {exploration: label}), - title: game.i18n.format("OSE.roll.exploration", {exploration: label}), + flavor: game.i18n.format("OSE.roll.exploration", { exploration: label }), + title: game.i18n.format("OSE.roll.exploration", { exploration: label }), }); } @@ -353,7 +354,7 @@ export class OseActor extends Actor { const data = this.data.data; const rollParts = ["1d20"]; const dmgParts = []; - let label = game.i18n.format('OSE.roll.attacks', {name: this.data.name}) + let label = game.i18n.format("OSE.roll.attacks", { name: this.data.name }); if ( !attData.dmg || (!game.settings.get("ose", "variableWeaponDamage") && @@ -361,7 +362,7 @@ export class OseActor extends Actor { ) { dmgParts.push("1d6"); } else { - label = game.i18n.format('OSE.roll.attacksWith', {name: attData.label}) + label = game.i18n.format("OSE.roll.attacksWith", { name: attData.label }); dmgParts.push(attData.dmg); } @@ -450,6 +451,101 @@ export class OseActor extends Actor { }); } + computeEncumbrance() { + if (this.data.type != "character") { + return; + } + const data = this.data.data; + let option = game.settings.get("ose", "encumbranceOption"); + let basic = option == "basic"; + + // Compute encumbrance + let owned = ["weapon", "armor", "item"]; + let totalWeight = 0; + Object.values(this.data.items).forEach((item) => { + if (item.type == "item" && (!basic || item.data.treasure)) { + totalWeight += item.data.quantity.value * item.data.weight; + } else if (!basic && owned.includes(item.type)) { + totalWeight += item.data.weight; + } + }); + + data.encumbrance = { + pct: Math.clamped( + (100 * parseFloat(totalWeight)) / data.encumbrance.max, + 0, + 100 + ), + max: data.encumbrance.max, + encumbered: totalWeight > data.encumbrance.max, + value: totalWeight, + }; + + if (data.config.movementAuto && option != 'disabled') { + this._calculateMovement(); + } + } + + _calculateMovement() { + const data = this.data.data; + let option = game.settings.get("ose", "encumbranceOption"); + let weight = data.encumbrance.value; + let delta = data.encumbrance.max - 1600; + if (option == "detailed") { + if (weight > data.encumbrance.max) { + data.movement.base = 0; + } else if (weight > 800 + delta) { + data.movement.base = 30; + } else if (weight > 600 + delta) { + data.movement.base = 60; + } else if (weight > 400 + delta) { + data.movement.base = 90; + } else { + data.movement.base = 120; + } + } else if (option == "basic") { + const armors = this.data.items.filter(i => i.type == "armor"); + let heaviest = 0; + armors.forEach((a) => { + if (a.data.equipped) { + if (a.data.type == "light" && heaviest == 0) { + heaviest = 1; + } else if (a.data.type == "heavy") { + heaviest = 2; + } + } + }); + switch (heaviest) { + case 0: + data.movement.base = 120; + break; + case 1: + data.movement.base = 90; + break; + case 2: + data.movement.base = 60; + break; + } + if (weight > game.settings.get("ose", "significantTreasure")) { + data.movement.base -= 30; + } + } + } + + computeTreasure() { + if (this.data.type != "character") { + return; + } + const data = this.data.data; + // Compute treasure + let total = 0; + let treasure = this.data.items.filter(i => (i.type == "item" && i.data.treasure)) + treasure.forEach((item) => { + total += item.data.quantity.value * item.data.cost; + }); + data.treasure = total; + } + computeAC() { if (this.data.type != "character") { return; @@ -461,7 +557,7 @@ export class OseActor extends Actor { const data = this.data.data; data.aac.naked = baseAc + data.scores.dex.mod; data.ac.naked = baseAc - data.scores.dex.mod; - const armors = this.data.items.filter(i => i.type == 'armor'); + const armors = this.data.items.filter((i) => i.type == "armor"); armors.forEach((a) => { if (a.data.equipped && a.data.type != "shield") { baseAc = a.data.ac.value; diff --git a/src/module/dialog/party-sheet.js b/src/module/dialog/party-sheet.js index cd3aa1c..5cb627f 100644 --- a/src/module/dialog/party-sheet.js +++ b/src/module/dialog/party-sheet.js @@ -4,7 +4,7 @@ export class OsePartySheet extends FormApplication { (options.classes = ["ose", "dialog", "party-sheet"]), (options.id = "party-sheet"); options.template = "systems/ose/templates/apps/party-sheet.html"; - options.width = 700; + options.width = 280; return options; } @@ -25,10 +25,14 @@ export class OsePartySheet extends FormApplication { * @return {Object} */ getData() { + const settings = { + ascending: game.settings.get('ose', 'ascendingAC') + }; let data = { data: this.object, config: CONFIG.OSE, - user: game.user + user: game.user, + settings: settings }; return data; } @@ -115,5 +119,9 @@ export class OsePartySheet extends FormApplication { .click(this._selectActors.bind(this)); html.find("button[data-action='deal-xp']").click(this._dealXP.bind(this)); html.find("a.resync").click(() => this.render(true)); + html.find(".field-img").click((ev) => { + let actorId = ev.currentTarget.parentElement.dataset.actorId; + game.actors.get(actorId).sheet.render(true); + }) } } diff --git a/src/module/party.js b/src/module/party.js index 4caa3d6..cb81955 100644 --- a/src/module/party.js +++ b/src/module/party.js @@ -1,7 +1,7 @@ import { OsePartySheet } from "./dialog/party-sheet.js"; export const addControl = (object, html) => { - let control = ``; + let control = ``; html.find(".fas.fa-search").replaceWith($(control)) html.find('.ose-party-sheet').click(ev => { showPartySheet(object); @@ -11,7 +11,17 @@ export const addControl = (object, html) => { export const showPartySheet = (object) => { event.preventDefault(); new OsePartySheet(object, { - top: window.screen.height / 2, - left:window.screen.width / 2, + top: window.screen.height / 2 - 180, + left:window.screen.width / 2 - 140, }).render(true); +} + +export const update = (actor, data) => { + if (actor.getFlag('ose', 'party')) { + Object.values(ui.windows).forEach(w => { + if (w instanceof OsePartySheet) { + w.render(true); + } + }) + } } \ No newline at end of file diff --git a/src/module/settings.js b/src/module/settings.js index 59a023d..683eba7 100644 --- a/src/module/settings.js +++ b/src/module/settings.js @@ -49,6 +49,7 @@ export const registerSettings = function () { basic: "OSE.Setting.EncumbranceBasic", detailed: "OSE.Setting.EncumbranceDetailed", }, + onChange: _ => window.location.reload() }); game.settings.register("ose", "significantTreasure", { @@ -58,5 +59,6 @@ export const registerSettings = function () { scope: "world", type: Number, config: true, + onChange: _ => window.location.reload() }); }; diff --git a/src/ose.js b/src/ose.js index 8d6a38e..cbf351f 100644 --- a/src/ose.js +++ b/src/ose.js @@ -124,5 +124,5 @@ Hooks.on("preUpdateCombat", async (combat, data, diff, id) => { Hooks.on("renderChatLog", (app, html, data) => OseItem.chatListeners(html)); Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions); Hooks.on("renderChatMessage", chat.addChatMessageButtons); - -Hooks.on("renderRollTableConfig", treasure.augmentTable); \ No newline at end of file +Hooks.on("renderRollTableConfig", treasure.augmentTable); +Hooks.on("updateActor", party.update); \ No newline at end of file diff --git a/src/scss/apps.scss b/src/scss/apps.scss index 98ba8ec..5d7ecc8 100644 --- a/src/scss/apps.scss +++ b/src/scss/apps.scss @@ -8,7 +8,7 @@ .ose.dialog.party-sheet { .window-content { padding: 0; - height: 200px; + height: 400px; } .header { color: whitesmoke; @@ -19,24 +19,25 @@ .actor-list { margin: 0; overflow: auto; - height: 180px; + height: 350px; list-style: none; padding: 0; .actor { &:nth-child(even) { background-color: rgba(0, 0, 0, 0.1); } - padding: 2px; + .fas { + padding: 0 2px; + } + padding: 4px; font-size: 12px; - height: 35px; text-align: center; - line-height: 35px; .field-img { - flex: 0 0 32px; + flex: 0 0 50px; img { border: none; - width: 32px; - height: 32px; + width: 50px; + height: 50px; } } } @@ -45,24 +46,16 @@ text-align: left; text-indent: 10px; } - .field-short { - flex: 0 0 45px; - } - .field-long { - flex: 0 0 80px; - } - .field-longer { - flex: 0 0 180px; - } } #sidebar #actors .directory-header .header-search { .ose-party-sheet { - width: 30px; + width: 32px; text-align: center; + line-height: 20px; } input { - width: calc(100% - 30px); + width: calc(100% - 45px); } } diff --git a/src/scss/character.scss b/src/scss/character.scss index 2ad4d6b..5561fa3 100644 --- a/src/scss/character.scss +++ b/src/scss/character.scss @@ -36,7 +36,7 @@ .modifiers-btn { position: absolute; left: 0; - top: -5px; + top: -8px; } } } diff --git a/src/templates/actors/partials/character-inventory-tab.html b/src/templates/actors/partials/character-inventory-tab.html index 14af2c6..30666d8 100644 --- a/src/templates/actors/partials/character-inventory-tab.html +++ b/src/templates/actors/partials/character-inventory-tab.html @@ -146,7 +146,7 @@