diff --git a/assets/_credit.txt b/assets/_credit.txt index 43cf3fb..bac6dc2 100644 --- a/assets/_credit.txt +++ b/assets/_credit.txt @@ -1,6 +1,8 @@ Oliver Akins: - geist-silhouette.v2.svg : All rights reserved. - caster-silhouette.v1.svg : All rights reserved. + - icons/star-empty.svg : Modified from https://thenounproject.com/icon/star-7711815/ by Llisole + - icons/star.svg : Modified from https://thenounproject.com/icon/star-7711815/ by Llisole Kýnan Antos (Gritsilk Games): - hero-silhouette.svg : Licensed to Distribute and Modify within the bounds of the "Foundry-RipCrypt" system. diff --git a/assets/icons/star-empty.svg b/assets/icons/star-empty.svg new file mode 100644 index 0000000..8760cc9 --- /dev/null +++ b/assets/icons/star-empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/star.svg b/assets/icons/star.svg new file mode 100644 index 0000000..829431b --- /dev/null +++ b/assets/icons/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/langs/en-ca.json b/langs/en-ca.json index badf3f2..de9e051 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -173,12 +173,17 @@ "rollTarget": "Target", "difficulty": "(DC: {dc})", "RichEditor-no-collaborative": "Warning: This editor is not collaborative, that means that if you and someone else are editing it at the same time, you won't see that someone else is making changes until they save, and then your changes will be lost.", - "no-ammo": "You don't have any ammo!" + "AmmoTracker": { + "no-ammo": "You don't have any ammo!", + "pin-button": "Pin {name} to your character sheet", + "pin-button-tooltip": "Pin {name}" + } }, "notifs": { "error": { "cannot-equip": "Cannot equip the {itemType}, see console for more details.", - "invalid-delta": "The delta for \"{name}\" is not a number, cannot finish processing the action." + "invalid-delta": "The delta for \"{name}\" is not a number, cannot finish processing the action.", + "at-favourite-limit": "Cannot favourite more than three items, unfavourite one to make space." }, "warn": { "cannot-go-negative": "\"{name}\" is unable to be a negative number." diff --git a/module/Apps/ActorSheets/HeroSkillsCardV1.mjs b/module/Apps/ActorSheets/HeroSkillsCardV1.mjs index ccffbef..be8fb26 100644 --- a/module/Apps/ActorSheets/HeroSkillsCardV1.mjs +++ b/module/Apps/ActorSheets/HeroSkillsCardV1.mjs @@ -139,7 +139,23 @@ export class HeroSkillsCardV1 extends GenericAppMixin(HandlebarsApplicationMixin }; static async prepareAmmo(ctx) { - ctx.ammo = 0; + let total = 0; + ctx.favouriteAmmo = []; + + for (const ammo of ctx.actor.itemTypes.ammo) { + total += ammo.system.quantity; + + if (ctx.favouriteAmmo.length < 3 && ammo.getFlag(game.system.id, `favourited`)) { + ctx.favouriteAmmo.push({ + uuid: ammo.uuid, + name: ammo.name, + quantity: ammo.system.quantity, + }); + }; + }; + ctx.favouriteAmmo.length = 3; // assert array length + + ctx.ammo = total; return ctx; }; diff --git a/module/Apps/GenericApp.mjs b/module/Apps/GenericApp.mjs index 7c1077e..2e9c1c2 100644 --- a/module/Apps/GenericApp.mjs +++ b/module/Apps/GenericApp.mjs @@ -52,6 +52,11 @@ export function GenericAppMixin(HandlebarsApp) { }; }; + /** + * @override + * This override makes it so that if the application has any framable popovers + * within it that are currently open, they will rerender as well. + */ async _onRender() { await super._onRender(); for (const manager of this._popoverManagers.values()) { diff --git a/module/Apps/popovers/AmmoTracker.mjs b/module/Apps/popovers/AmmoTracker.mjs index e1203c0..8c4c798 100644 --- a/module/Apps/popovers/AmmoTracker.mjs +++ b/module/Apps/popovers/AmmoTracker.mjs @@ -1,5 +1,7 @@ import { filePath } from "../../consts.mjs"; import { GenericPopoverMixin } from "./GenericPopoverMixin.mjs"; +import { localizer } from "../../utils/Localizer.mjs"; +import { Logger } from "../../utils/Logger.mjs"; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -15,7 +17,10 @@ export class AmmoTracker extends GenericPopoverMixin(HandlebarsApplicationMixin( `ripcrypt--AmmoTracker`, ], }, - actions: {}, + actions: { + favourite: this.#favourite, + unfavourite: this.#unfavourite, + }, }; static PARTS = { @@ -26,17 +31,63 @@ export class AmmoTracker extends GenericPopoverMixin(HandlebarsApplicationMixin( // #endregion // #region Instance Data + _favouriteCount = 0; // #endregion // #region Lifecycle async _preparePartContext(partId, data) { const ctx = { partId }; - ctx.canPin = false; - ctx.ammos = data.ammos; + + let favouriteCount = 0; + ctx.ammos = data.ammos.map(ammo => { + const favourite = ammo.getFlag(game.system.id, `favourited`) ?? false; + if (favourite) { favouriteCount++ }; + + return { + ammo, + favourite, + }; + }); + + this._favouriteCount = favouriteCount; + ctx.atFavouriteLimit = favouriteCount >= 3; return ctx; }; // #endregion // #region Actions + static async #favourite(_, el) { + const targetEl = el.closest(`[data-item-id]`); + if (!targetEl) { + Logger.warn(`Cannot find a parent element with data-item-id`); + return; + }; + + // get count of favourites + if (this._favouriteCount > 3) { + ui.notifications.error(localizer(`RipCrypt.notifs.error.at-favourite-limit`)); + return; + }; + + const data = targetEl.dataset; + const item = await fromUuid(data.itemId); + if (!item) { return }; + + item.setFlag(game.system.id, `favourited`, true); + }; + + static async #unfavourite(_, el) { + const targetEl = el.closest(`[data-item-id]`); + if (!targetEl) { + Logger.warn(`Cannot find a parent element with data-item-id`); + return; + }; + + const data = targetEl.dataset; + const item = await fromUuid(data.itemId); + if (!item) { return }; + + item.unsetFlag(game.system.id, `favourited`); + }; // #endregion }; diff --git a/module/Apps/popovers/GenericPopoverMixin.mjs b/module/Apps/popovers/GenericPopoverMixin.mjs index 017c2b0..a64b067 100644 --- a/module/Apps/popovers/GenericPopoverMixin.mjs +++ b/module/Apps/popovers/GenericPopoverMixin.mjs @@ -81,7 +81,7 @@ export function GenericPopoverMixin(HandlebarsApp) { * want it to when being created. * * Most of this implementation is identical to the ApplicationV2 - * implementation, the biggest difference is how targetLeft and targetRight + * implementation, the biggest difference is how targetLeft and targetTop * are calculated. */ _updatePosition(position) { diff --git a/templates/Apps/HeroSkillsCardV1/content.hbs b/templates/Apps/HeroSkillsCardV1/content.hbs index 776f673..5259737 100644 --- a/templates/Apps/HeroSkillsCardV1/content.hbs +++ b/templates/Apps/HeroSkillsCardV1/content.hbs @@ -118,6 +118,24 @@ {{ ammo }} + {{#each favouriteAmmo as | data |}} + {{#if data}} +