From 597a7cf6f3774078182fefe4e4d9c4b252b565d3 Mon Sep 17 00:00:00 2001 From: aeauseth Date: Sat, 14 Dec 2024 18:15:22 -0800 Subject: [PATCH 1/6] ActiveEffect UI improvements (flag data) --- module/actor/active-effect-config.mjs | 31 ++++ module/actor/actor-active-effects.mjs | 19 +++ module/herosystem6e.mjs | 39 ++++- module/utility/adjustment.mjs | 4 +- scss/components/_active-effects.scss | 7 + scss/herosystem6e.scss | 3 + templates/actor/active-effect-config.hbs | 189 +++++++++++++++++++++++ 7 files changed, 287 insertions(+), 5 deletions(-) create mode 100644 module/actor/active-effect-config.mjs create mode 100644 scss/components/_active-effects.scss create mode 100644 templates/actor/active-effect-config.hbs diff --git a/module/actor/active-effect-config.mjs b/module/actor/active-effect-config.mjs new file mode 100644 index 00000000..4b74ad19 --- /dev/null +++ b/module/actor/active-effect-config.mjs @@ -0,0 +1,31 @@ +import { HEROSYS } from "../herosystem6e.mjs"; + +export class HeroSystemActiveEffectConfig extends ActiveEffectConfig { + static get defaultOptions() { + const defaultOptions = super.defaultOptions; + return foundry.utils.mergeObject(defaultOptions, { + //classes: ["herosystem6e", "sheet", "item"], + // width: 520, + // height: 660, + // scrollY: [".sheet-body"], + classes: ["sheet", "herosystem-active-effect-config", "active-effect-sheet"], + template: `systems/${HEROSYS.module}/templates/actor/active-effect-config.hbs`, + }); + } + + async getData() { + const context = await super.getData(); + for (let i = 0; i < context.data.changes.length; i++) { + context.data.changes[i] = { ...context.data.changes[i], ...context.data.flags.changes?.[i] }; + } + return context; + } + + // async _updateObject(event, formData) { + // await super._updateObject(event, formData); + + // // if (formData.changes) { + // // await this.object.update({ changes: formData.changes }); + // // } + // } +} diff --git a/module/actor/actor-active-effects.mjs b/module/actor/actor-active-effects.mjs index 376b13c9..937ba959 100644 --- a/module/actor/actor-active-effects.mjs +++ b/module/actor/actor-active-effects.mjs @@ -2,6 +2,25 @@ import { HEROSYS } from "../herosystem6e.mjs"; import { RoundFavorPlayerUp } from "../utility/round.mjs"; export class HeroSystem6eActorActiveEffects extends ActiveEffect { + // static defineSchema() { + // const schema2 = this.schema; // foundry.deepClone(super.defineSchema()); + // schema2.changes = new foundry.data.fields.ArrayField( + // new foundry.data.fields.SchemaField({ + // key: new foundry.data.fields.StringField({ required: true, label: "EFFECT.ChangeKey" }), + // value: new foundry.data.fields.StringField({ required: true, label: "EFFECT.ChangeValue" }), + // mode: new foundry.data.fields.NumberField({ + // integer: true, + // initial: CONST.ACTIVE_EFFECT_MODES.ADD, + // label: "EFFECT.ChangeMode", + // }), + // priority: new foundry.data.fields.NumberField(), + // seconds: new foundry.data.fields.NumberField({ integer: true, label: "EFFECT.Seconds" }), + // }), + // ); + // return schema2; + // } + //ActiveEffect.schema.fields.changes.element.fields + // All status effects static statusEffectsObj; diff --git a/module/herosystem6e.mjs b/module/herosystem6e.mjs index 2b144d92..54cb8144 100644 --- a/module/herosystem6e.mjs +++ b/module/herosystem6e.mjs @@ -14,8 +14,8 @@ import HeroSystem6eMeasuredTemplate from "./measuretemplate.mjs"; import { HeroSystem6eCombat } from "./combat.mjs"; import { HeroSystem6eCombatTracker } from "./combatTracker.mjs"; import SettingsHelpers from "./settings/settings-helpers.mjs"; -import { HeroSystem6eTokenHud } from "./bar3/tokenHud.mjs"; -import { extendTokenConfig } from "./bar3/extendTokenConfig.mjs"; +//import { HeroSystem6eTokenHud } from "./bar3/tokenHud.mjs"; +//import { extendTokenConfig } from "./bar3/extendTokenConfig.mjs"; import { HeroRuler } from "./ruler.mjs"; import { initializeHandlebarsHelpers } from "./handlebars-helpers.mjs"; import { expireEffects, getCharacteristicInfoArrayForActor } from "./utility/util.mjs"; @@ -33,6 +33,7 @@ import "./utility/chat-dice.mjs"; import "./testing/testing-main.mjs"; import { EffectsPanel } from "./effects-panel.mjs"; +import { HeroSystemActiveEffectConfig } from "./actor/active-effect-config.mjs"; Hooks.once("init", async function () { // Custom HeroSystem VisionMode @@ -83,6 +84,7 @@ Hooks.once("init", async function () { CONFIG.Token.objectClass = HeroSystem6eToken; CONFIG.MeasuredTemplate.objectClass = HeroSystem6eMeasuredTemplate; CONFIG.ActiveEffect.documentClass = HeroSystem6eActorActiveEffects; + // CONFIG.ActiveEffect.dataModels.base = HeroSystem6eActorActiveEffects.defineSchema(); CONFIG.Canvas.rulerClass = HeroRuler; CONFIG.Canvas.visionSourceClass = HeroPointVisionSource; @@ -106,6 +108,12 @@ Hooks.once("init", async function () { makeDefault: true, }); + //Not sure why ActiveEffect.registerSheet is missing. + DocumentSheetConfig.registerSheet(ActiveEffect, "herosystem6e", HeroSystemActiveEffectConfig, { + makeDefault: true, + label: "HeroSystemActiveEffectConfig", + }); + const templatePaths = [ `systems/${HEROSYS.module}/templates/item/item-common-partial.hbs`, `systems/${HEROSYS.module}/templates/item/item-effects-partial.hbs`, @@ -120,6 +128,7 @@ Hooks.once("init", async function () { `systems/${HEROSYS.module}/templates/actor/actor-sheet-partial-powers-item.hbs`, `systems/${HEROSYS.module}/templates/actor/actor-sheet-partial-equipment.hbs`, `systems/${HEROSYS.module}/templates/actor/actor-sheet-partial-equipment-item.hbs`, + `systems/${HEROSYS.module}/templates/actor/active-effect-config.hbs`, // `systems/${HEROSYS.module}/templates/sidebar/partials/document-partial.hbs`, `systems/${HEROSYS.module}/templates/system/effects-panel.hbs`, `systems/${HEROSYS.module}/templates/system/heroRoll-panel.hbs`, @@ -527,8 +536,8 @@ Hooks.on("getActorDirectoryEntryContext", (_dialog, html) => { }); //Modify TokenHUD (need 3 bars: end, stun, body) -Hooks.on("renderTokenHUD", HeroSystem6eTokenHud); -Hooks.on("renderTokenConfig", extendTokenConfig); +// Hooks.on("renderTokenHUD", HeroSystem6eTokenHud); +// Hooks.on("renderTokenConfig", extendTokenConfig); // Expire ActiveEffects let secondsSinceRecovery = 0; @@ -922,3 +931,25 @@ Hooks.on("renderSidebarTab", async (app, html) => { } }); }); + +// Hooks.on("renderActiveEffectConfig", (activeEffectConfig, html, data) => { +// console.log(activeEffectConfig, html, data); + +// const effectsTab = html.find("section[data-tab='effects']"); +// const header = effectsTab.find("header"); +// const headerValue = header.find("div.value"); +// headerValue.after("
Seconds
"); + +// const changesList = effectsTab.find("ol.changes-list"); +// changesList.find("li").each(function (idx) { +// const liValue = $(this).find("div.value"); +// //const idx = liValue.name.match(/changes\.(\d+)/)[1]; +// liValue.after(``); +// }); + +// const submitButton = html.find("button[type='submit']"); +// submitButton.one("submit", function () { +// debugger; +// console.log(this); +// }); +// }); diff --git a/module/utility/adjustment.mjs b/module/utility/adjustment.mjs index 561cc665..c2193db7 100644 --- a/module/utility/adjustment.mjs +++ b/module/utility/adjustment.mjs @@ -212,11 +212,13 @@ export function determineCostPerActivePoint(targetCharacteristic, targetPower, t } function _findExistingMatchingEffect(item, potentialCharacteristic, powerTargetName, targetSystem) { + // Kluge: Ignore any negative changes as we want each DRAIN to be separate so we can properly track the fades. // Caution: The item may no longer exist. return targetSystem.effects.find( (effect) => effect.origin === item.uuid && - effect.flags.target[0] === (powerTargetName?.uuid || potentialCharacteristic), + effect.flags.target[0] === (powerTargetName?.uuid || potentialCharacteristic) && + parseInt(effect.changes?.[0].value || 0) >= 0, ); } diff --git a/scss/components/_active-effects.scss b/scss/components/_active-effects.scss new file mode 100644 index 00000000..ce5955d1 --- /dev/null +++ b/scss/components/_active-effects.scss @@ -0,0 +1,7 @@ +// div.herosystem-active-effect-config { +// background: red; +// } + +// div.herosystem-active-effect-config > .window-content { +// background: red; +// } diff --git a/scss/herosystem6e.scss b/scss/herosystem6e.scss index a96a4914..1b78ceab 100644 --- a/scss/herosystem6e.scss +++ b/scss/herosystem6e.scss @@ -57,3 +57,6 @@ /* Styles for Notes */ @include meta.load-css("components/notes"); + +/* Styles for Notes */ +@include meta.load-css("components/active-effects"); diff --git a/templates/actor/active-effect-config.hbs b/templates/actor/active-effect-config.hbs new file mode 100644 index 00000000..a8371a15 --- /dev/null +++ b/templates/actor/active-effect-config.hbs @@ -0,0 +1,189 @@ +{{log 'active-effect-config' this}} +
+ + +
+ +

+ +

+
+ + + + + +
+
+ +
+ +
+
+ +
+ + {{editor descriptionHTML target="description" button=false editable=editable engine="prosemirror" collaborate=false}} +
+ +
+ + +
+ + {{#if isActorEffect}} +
+ +
+ +
+
+ {{/if}} + + {{#if isItemEffect}} +
+ +
+ +
+

{{ labels.transfer.hint }}

+
+ {{/if}} + +
+ +
+ + {{#each statuses as |status|}} + + {{/each}} + +
+
+ + {{! Custom HeroSystem Flags--}} +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ + +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ + + + +
+
+
+ +
+ +
+
+ +
+ +
+ + + + +
+
+
+ + +
+
+
{{ localize "EFFECT.ChangeKey" }}
+
{{ localize "EFFECT.ChangeMode" }}
+
{{ localize "EFFECT.ChangeValue" }}
+ {{!--
{{ localize "EFFECT.Seconds" }}
--}} +
+ +
+
+
    + {{#each data.changes as |change i|}} +
  1. +
    + +
    +
    + +
    +
    + +
    + {{!--
    + +
    --}} +
    + +
    +
  2. + {{/each}} +
+
+ +
+ +
+
From 3093475fa96c4621e42c8050ec9702c3ce7b0969 Mon Sep 17 00:00:00 2001 From: aeauseth Date: Sat, 14 Dec 2024 19:15:08 -0800 Subject: [PATCH 2/6] multiple drains have correct fades, but partial AP are lost. --- module/actor/active-effect-config.mjs | 5 +++++ module/actor/actor.mjs | 6 +++++- module/effects-panel.mjs | 10 ++++++++-- module/item/item.mjs | 12 ++++++------ module/utility/adjustment.mjs | 3 ++- scss/components/_active-effects.scss | 7 +++++++ templates/actor/active-effect-config.hbs | 16 ++++++++++++++-- 7 files changed, 47 insertions(+), 12 deletions(-) diff --git a/module/actor/active-effect-config.mjs b/module/actor/active-effect-config.mjs index 4b74ad19..eb264c86 100644 --- a/module/actor/active-effect-config.mjs +++ b/module/actor/active-effect-config.mjs @@ -18,6 +18,11 @@ export class HeroSystemActiveEffectConfig extends ActiveEffectConfig { for (let i = 0; i < context.data.changes.length; i++) { context.data.changes[i] = { ...context.data.changes[i], ...context.data.flags.changes?.[i] }; } + const originItem = fromUuidSync(context.data.origin); + const token = fromUuidSync(context.data.origin.match(/(.*).Actor/)?.[1]); + context.originText = originItem + ? `${token?.name || originItem.actor?.name}: ${originItem.name}` + : context.data.origin; return context; } diff --git a/module/actor/actor.mjs b/module/actor/actor.mjs index e9f95dfb..2efb4c81 100644 --- a/module/actor/actor.mjs +++ b/module/actor/actor.mjs @@ -77,9 +77,13 @@ export class HeroSystem6eActor extends Actor { newEffect.statuses = [activeEffect.id]; // Check if this ActiveEffect already exists - const existingEffect = this.effects.find((o) => o.statuses.has(activeEffect.id)); + const existingEffect = this.effects.find( + (o) => o.statuses.has(activeEffect.id) && !activeEffect.id.includes("DRAIN"), + ); if (!existingEffect) { await this.createEmbeddedDocuments("ActiveEffect", [newEffect]); + } else { + console.warn("There was a pre-existing ActiveEffect, so the new AE was not added."); } } diff --git a/module/effects-panel.mjs b/module/effects-panel.mjs index 6fbba88d..e6166eff 100644 --- a/module/effects-panel.mjs +++ b/module/effects-panel.mjs @@ -50,12 +50,18 @@ export class EffectsPanel extends Application { // Sometimes ae.parent?.system.active is false, but the power is active, unclear why. // Consider making active a getter (looking for the AE) instead of using system.actor. if (ae.parent instanceof HeroSystem6eItem && ae.duration.seconds) { - ae.flags.label = `${ae.duration.startTime + ae.duration.seconds - game.time.worldTime} seconds`; + const d = ae._prepareDuration(); + ae.flags.label = d.label; + //ae.flags.label = `${ae.duration.startTime + ae.duration.seconds - game.time.worldTime} seconds`; + for (const target of ae.flags.target) { + const item = fromUuidSync(target); + ae.flags.targetDisplay = `${item?.name} [${item.system.XMLID}]`; + } } else { const d = ae._prepareDuration(); ae.flags.label = d.label; + ae.flags.targetDisplay = ae.flags.target; } - ae.flags.targetDisplay = ae.flags.target; } } diff --git a/module/item/item.mjs b/module/item/item.mjs index 048c54c7..ec314628 100644 --- a/module/item/item.mjs +++ b/module/item/item.mjs @@ -5057,12 +5057,12 @@ export class HeroSystem6eItem extends Item { async addActiveEffect(activeEffect) { const newEffect = foundry.utils.deepClone(activeEffect); - // newEffect.duration.duration ??= newEffect.duration.seconds; - // newEffect.duration.startTime ??= game.time.worldTime; - // newEffect.duration.startRound ??= game.combat.current.round; - // newEffect.duration.startTurn ??= game.combat.current.turn; - // newEffect.duration.type ??= "seconds"; - newEffect.transfer = false; + newEffect.duration.duration ??= newEffect.duration.seconds; + newEffect.duration.startTime ??= game.time.worldTime; + newEffect.duration.startRound ??= game.combat.current.round; + newEffect.duration.startTurn ??= game.combat.current.turn; + newEffect.duration.type ??= "seconds"; + //newEffect.transfer = false; //const ae = await this.createEmbeddedDocuments("ActiveEffect", [newEffect]); //ae.duration = ae.updateDuration(); diff --git a/module/utility/adjustment.mjs b/module/utility/adjustment.mjs index c2193db7..f85dce49 100644 --- a/module/utility/adjustment.mjs +++ b/module/utility/adjustment.mjs @@ -213,6 +213,7 @@ export function determineCostPerActivePoint(targetCharacteristic, targetPower, t function _findExistingMatchingEffect(item, potentialCharacteristic, powerTargetName, targetSystem) { // Kluge: Ignore any negative changes as we want each DRAIN to be separate so we can properly track the fades. + // This introduces issues where the AP of multiple DRAINs don't add up partial drains. // Caution: The item may no longer exist. return targetSystem.effects.find( (effect) => @@ -303,7 +304,7 @@ function _createNewAdjustmentEffect( attackerTokenId: action?.current?.attackerTokenId, }, origin: item.uuid, - //description: item.system.description, // Issues with core FoundryVTT where description doesn't show, nor is editable. + description: item.system.description, // Issues with core FoundryVTT where description doesn't show, nor is editable. transfer: true, disabled: false, }; diff --git a/scss/components/_active-effects.scss b/scss/components/_active-effects.scss index ce5955d1..32095e2a 100644 --- a/scss/components/_active-effects.scss +++ b/scss/components/_active-effects.scss @@ -5,3 +5,10 @@ // div.herosystem-active-effect-config > .window-content { // background: red; // } + +div.herosystem-active-effect-config div.description { + background-color: rgba(0, 0, 0, 0.2); + border: 1px dashed rgba(0, 0, 0, 0.5); + padding: 5px; + max-width: 100%; +} diff --git a/templates/actor/active-effect-config.hbs b/templates/actor/active-effect-config.hbs index a8371a15..ee13b2a7 100644 --- a/templates/actor/active-effect-config.hbs +++ b/templates/actor/active-effect-config.hbs @@ -25,9 +25,13 @@ -
+ {{!--
{{editor descriptionHTML target="description" button=false editable=editable engine="prosemirror" collaborate=false}} +
--}} + +
+ {{data.description}}
@@ -39,7 +43,15 @@
- + {{!-- --}} + +
+
+ {{else}} +
+ +
+
{{/if}} From e43f9b57df0f5fd251734eaa1b2cdda8f2a66f49 Mon Sep 17 00:00:00 2001 From: aeauseth Date: Sat, 14 Dec 2024 19:41:04 -0800 Subject: [PATCH 3/6] user-select: text for item descriptions --- scss/components/_active-effects.scss | 1 + scss/components/_actor-sheet.scss | 1 + 2 files changed, 2 insertions(+) diff --git a/scss/components/_active-effects.scss b/scss/components/_active-effects.scss index 32095e2a..fb534cba 100644 --- a/scss/components/_active-effects.scss +++ b/scss/components/_active-effects.scss @@ -11,4 +11,5 @@ div.herosystem-active-effect-config div.description { border: 1px dashed rgba(0, 0, 0, 0.5); padding: 5px; max-width: 100%; + user-select: text; } diff --git a/scss/components/_actor-sheet.scss b/scss/components/_actor-sheet.scss index 83108508..70970498 100644 --- a/scss/components/_actor-sheet.scss +++ b/scss/components/_actor-sheet.scss @@ -410,6 +410,7 @@ form div.attack-card div.description { margin: 15px 0; padding: 5px; max-width: 100%; + user-select: text; } .herosystem6e.sheet.item tr.modifier-adder td:first-child { From 9fae5561a6922e735f2bee3bd58814f4ecbe91c5 Mon Sep 17 00:00:00 2001 From: aeauseth Date: Sat, 14 Dec 2024 19:43:08 -0800 Subject: [PATCH 4/6] lighten up description background --- scss/components/_active-effects.scss | 2 +- scss/components/_actor-sheet.scss | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scss/components/_active-effects.scss b/scss/components/_active-effects.scss index fb534cba..50b90acf 100644 --- a/scss/components/_active-effects.scss +++ b/scss/components/_active-effects.scss @@ -7,7 +7,7 @@ // } div.herosystem-active-effect-config div.description { - background-color: rgba(0, 0, 0, 0.2); + background-color: rgba(0, 0, 0, 0.1); border: 1px dashed rgba(0, 0, 0, 0.5); padding: 5px; max-width: 100%; diff --git a/scss/components/_actor-sheet.scss b/scss/components/_actor-sheet.scss index 70970498..0dde4d34 100644 --- a/scss/components/_actor-sheet.scss +++ b/scss/components/_actor-sheet.scss @@ -406,6 +406,7 @@ form.item-sheet h1.charname input { .herosystem6e.sheet.item div.description, form div.attack-card div.description { + background-color: rgba(0, 0, 0, 0.1); border: 1px dashed rgb(0 0 0 / 50%); margin: 15px 0; padding: 5px; From 781329ac015b83cf09fda81511c0542438ee2204 Mon Sep 17 00:00:00 2001 From: aeauseth Date: Sat, 14 Dec 2024 19:46:17 -0800 Subject: [PATCH 5/6] lint scss --- scss/components/_active-effects.scss | 4 ++-- scss/components/_actor-sheet.scss | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scss/components/_active-effects.scss b/scss/components/_active-effects.scss index 50b90acf..177a6b40 100644 --- a/scss/components/_active-effects.scss +++ b/scss/components/_active-effects.scss @@ -7,8 +7,8 @@ // } div.herosystem-active-effect-config div.description { - background-color: rgba(0, 0, 0, 0.1); - border: 1px dashed rgba(0, 0, 0, 0.5); + background-color: rgba(0 0 0 / 10%); + border: 1px dashed rgb(0 0 0 / 50%); padding: 5px; max-width: 100%; user-select: text; diff --git a/scss/components/_actor-sheet.scss b/scss/components/_actor-sheet.scss index 0dde4d34..4dc66097 100644 --- a/scss/components/_actor-sheet.scss +++ b/scss/components/_actor-sheet.scss @@ -406,7 +406,7 @@ form.item-sheet h1.charname input { .herosystem6e.sheet.item div.description, form div.attack-card div.description { - background-color: rgba(0, 0, 0, 0.1); + background-color: rgba(0 0 0 / 10%); border: 1px dashed rgb(0 0 0 / 50%); margin: 15px 0; padding: 5px; From 9d85a07a50f59ef11ec9647f1ead347970302000 Mon Sep 17 00:00:00 2001 From: aeauseth Date: Sat, 14 Dec 2024 19:48:19 -0800 Subject: [PATCH 6/6] lint --- eslint.config.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eslint.config.mjs b/eslint.config.mjs index 30e15d0c..3730a978 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -72,6 +72,8 @@ export default [ ui: "readonly", DetectionMode: "readonly", OutlineOverlayFilter: "readonly", + DocumentSheetConfig: "readonly", + ActiveEffectConfig: "readonly", }, }, },