From c02a4c65d8823e3a568e2f82d994dfe7992dd4b8 Mon Sep 17 00:00:00 2001 From: Ralph Mack Date: Sat, 12 Aug 2023 16:20:08 -0400 Subject: [PATCH] Bugfixes: unlinked tokens and OSE sources. Features: API for macros, help dialogs, "Reclaiming the Wild" support. --- CHANGELOG.md | 11 ++- README.md | 45 +++++++++-- api.js | 100 ++++++++++++++++++++++++ hud.js | 55 ++++++++++--- lang/cn.json | 6 +- lang/de.json | 6 +- lang/en.json | 6 +- lang/es.json | 6 +- lang/fr.json | 6 +- lang/pt-BR.json | 6 +- lang/zh-TW.json | 6 +- module.json | 4 +- sources.json | 203 +++++++++++++++++++++++++++++++++++++++++++++++- token.js | 9 +++ torch.js | 33 ++++---- torch.zip | Bin 28840 -> 34420 bytes 16 files changed, 460 insertions(+), 42 deletions(-) create mode 100644 api.js diff --git a/CHANGELOG.md b/CHANGELOG.md index a5fafde..341a658 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Middle Kingdom - v10 -> main branch +### 2.8.0 - August 12, 2022 +- [FEATURE] (Daverd-GM) Provided light sources for "Reclaiming the Wild". +- [FEATURE] (Lupestro) When user has no light sources, a question mark icon comes up instead of the flame icon, opening a dialog explaining what to do. +- [FEATURE] (Lupestro) When a light source is exhausted, clicking the slashed out flame opens a dialog that describes what to do. +- [FEATURE] (Lupestro) Supplied an API of async functions that can be used by macros. Many thanks to Tarubain for the suggestion. +- [BUGFIX] (Lupestro) Fixed problem with unlinked tokens, which no longer have an actor property at all. +- [BUGFIX] (Feldherren) Corrected light source name for "Torches" for OSE. + ### 2.7.0 - June 2, 2022 - [FEATURE] (Lupestro) Bumped to install on FoundryVTT 11 @@ -19,7 +27,8 @@ - [FEATURE] (Lupestro) Now supporting Dungeon Crawl Classics. Many thanks to marcusadmortati for supplying the data and testing. ### 2.2.2 - December 9, 2022 -- [BUGFIX] (MrPrimate) Didn't load light sources properly if Foundry was not at root of site. (Thanks MrPrimate for the PR!) +- [BUGFIX] (MrPrimate) Didn't load light sources properly if +Foundry was not at root of site. (Thanks MrPrimate for the PR!) ### 2.2.1 - December 8, 2022 - [BUGFIX] (Lupestro) Fixed URLs in manifest to point to /main/ not /v10/. (Thanks ckdragons for heads-up.) diff --git a/README.md b/README.md index 3e17bb8..a920ee3 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,35 @@ Even without adding a topology, you can still use Torch with any new system - by The easiest way I've found to do this is to set an actor's prototype token to use the types you're interested in and then export the actor from the sidebar. When you examine the file it creates, you should be able to see what it called that property on the prototype token's "light" value. That will tell you what string to use for its value in the Torch user settings to get the desired effect. +## API for macro authors + +As of 2.8, macro authors can access the following functions of the module through `game.Torch`. All functions are async. + +### `game.Torch.toggle(sceneId, tokenId)` +Walks the current light source of the specified token to its next state, returning the name of the state (typically 'on' or 'off' for simple two-state sources). + +### `game.Torch.extinguish(sceneId, tokenId)` +Advances the current light source of the specified token to its 'off' state. + +### `game.Torch.currentSource(sceneId, tokenId)` +Returns the name of the current light source for the specified token, if any. + +### `game.Torch.currentState(sceneId, tokenId)` +Returns the current state of the current light source for the specified token. + +### `game.Torch.equippedSources(sceneId, tokenId)` +Returns an array of the names of the light sources equipped by the specified token. + +### `game.Torch.selectSource(sceneId, tokenId, source)` +Selects an equipped light source to be the current light source of the token. + +### `game.Torch.inventory(sceneId, tokenId, source)` +Returns the remaining quantity of the specified light source for the specified token. + + +### `game.Torch.sourceExhausted(sceneId, tokenId, source)` +Returns true if the specified light source is consumable, and the instance held by the specified token has no more inventory. + ## Changelog - now in [separate file](./CHANGELOG.md) ## Translation Status @@ -124,17 +153,17 @@ The following is the current status of translation. Some features have arrived, | Language | Completion | Contributors | | -------- | ---------- | ------------ | -| de | `[##################]` 18/18 (100%) | ToGreedy | -| en | `[##################]` 18/18 (100%) | deuce, lupestro | -| es | `[############------]` 12/18 (67%) | lozalojo | -| fr | `[##################]` 18/18 (100%) | Aymeeric | -| pt-br | `[############------]` 12/18 (67%) | rinnocenti | -| zh-cn | `[##########--------]` 10/18 (56%) | xticime | -| zh-tw | `[############------]` 12/18 (67%) | zeteticl | +| de | `[##################----]` 18/22 (82%) | ToGreedy | +| en | `[######################]` 22/22 (100%) | deuce, lupestro | +| es | `[############----------]` 12/22 (55%) | lozanoje | +| fr | `[##################----]` 18/22 (82%) | Aymeeric | +| pt-br | `[############----------]` 12/22 (55%) | rinnocenti | +| zh-cn | `[##########------------]` 10/22 (56%) | xticime | +| zh-tw | `[############----------]` 12/22 (45%) | zeteticl | PRs for further translations will be dealt with promptly. While Japanese, and Korean are most especially desired - our translation story seems deeply incomplete without them - all others are welcome. -It's only 18 strings so far, a satisfying afternoon, even for someone who's never committed to an open source project before, and your name will go into the readme right here next to the language. Fork, clone, update, _test locally_, commit, and then submit a PR. Holler for @lupestro on Discord if you need help getting started. +Even now, it's only 22 strings, a satisfying afternoon, even for someone who's never committed to an open source project before, and your name will go into the readme right here next to the language. Fork, clone, update, _test locally_, commit, and then submit a PR. Holler for `@lupestro` on Discord if you need help getting started. ## History diff --git a/api.js b/api.js new file mode 100644 index 0000000..070ed1b --- /dev/null +++ b/api.js @@ -0,0 +1,100 @@ +import Settings from "./settings.js"; +import SourceLibrary from "./library.js"; +import TorchToken from './token.js'; + +export default class TorchAPI { + async #setup(sceneId, tokenId) { + let scene = game.scenes.get(sceneId); + let tokenDoc = scene.tokens.get(tokenId); + let actor = game.actors.get(tokenDoc.actorId); + + let library = await SourceLibrary.load( + game.system.id, + Settings.lightRadii.bright, + Settings.lightRadii.dim, + Settings.inventoryItemName, + Settings.gameLightSources, + actor.prototypeToken.light, + ); + return new TorchToken(tokenDoc, library); + } + #parmCheck2(fnname, sceneId, tokenId){ + const idPattern = /[A-Za-z0-9]+/; + let result; + if (typeof sceneId !== "string" || !idPattern.test(sceneId)) { + result = "first parm - scene id - isn't an id string"; + } + if (typeof tokenId !== "string" || !idPattern.test(tokenId)) { + result = "second parm - token id - isn't an id string"; + } + if (result) { + throw (`${fnname} : ${result}`); + } + } + + #parmCheck3(fnname, sceneId, tokenId, source){ + const idPattern = /[A-Za-z0-9]+/; + let result; + if (typeof sceneId !== "string" || !idPattern.test(sceneId)) { + rresult = "first parm - scene id - isn't an id string"; + } + if (typeof tokenId !== "string" || !idPattern.test(tokenId)) { + result = "second parm - token id - isn't an id string"; + } + if (typeof source !== "string" || source.length < 1) { + result = "third parm - source name - isn't the name of a light source"; + } + if (result) { + throw (`${fnname} : ${result}`); + } + } + + async toggle(sceneId, tokenId) { + this.#parmCheck2("toggle", sceneId, tokenId); + let token = await this.#setup(sceneId, tokenId); + return await token.advanceState(); + }; + + async extinguish(sceneId, tokenId) { + this.#parmCheck2("extinguish", sceneId, tokenId); + let token = await this.#setup(sceneId, tokenId); + return await token.forceStateOff(); + } + + async currentSource(sceneId, tokenId) { + this.#parmCheck2("currentSource", sceneId, tokenId); + let token = await this.#setup(sceneId, tokenId); + return await token.currentLightSource; + } + + async currentState(sceneId, tokenId) { + this.#parmCheck2("currentState", sceneId, tokenId); + let token = await this.#setup(sceneId, tokenId); + return await token.lightSourceState; + }; + + async equippedSources(sceneId, tokenId) { + this.#parmCheck2("equippedSources", sceneId, tokenId); + let token = await this.#setup(sceneId, tokenId); + return await token.ownedLightSources.map(item => item.name); + } + + async selectSource(sceneId, tokenId, source) { + this.#parmCheck3("selectSource", sceneId, tokenId, source); + let token = await this.#setup(sceneId, tokenId); + return await token.setCurrentLightSource(source); + }; + + async inventory(sceneId, tokenId, source) { + this.#parmCheck3("inventory", sceneId, tokenId, source); + let token = await this.#setup(sceneId, tokenId); + return await token.getInventory(source); + } + + async sourceExhausted(sceneId, tokenId, source) { + this.#parmCheck3("sourceExhausted", sceneId, tokenId, source); + let token = await this.#setup(sceneId, tokenId); + return await token.lightSourceIsExhausted(source); + }; + +} diff --git a/hud.js b/hud.js index 97f6e36..e9e29ab 100644 --- a/hud.js +++ b/hud.js @@ -1,4 +1,5 @@ const BUTTON_HTML = `
`; +const QUERY_BUTTON_HTML = `
`; const DISABLED_ICON_HTML = ``; const SOURCE_MENU = `
`; const SOURCE_MENU_ITEM = (img, tooltip) => { @@ -8,6 +9,31 @@ const SOURCE_MENU_ITEM = (img, tooltip) => { }; export default class TokenHUD { + /* + * Add a button to instruct users how to use the module + */ + static async addQueryButton( + token, + hudHtml + ) { + let tbutton = $(QUERY_BUTTON_HTML); + hudHtml.find(".col.left").prepend(tbutton); + tbutton.find("i").click(async (event) => { + event.preventDefault(); + event.stopPropagation(); + new Dialog({ + title: game.i18n.localize("torch.help.setupSources.title"), + content: game.i18n.localize("torch.help.setupSources.body"), + buttons: { + close: { + icon: '', + label: "Close" + } + }, + default: "close" + }).render(true); + }); + } /* * Add a torch button to the Token HUD - called from TokenHUD render hook */ @@ -21,7 +47,6 @@ export default class TokenHUD { ) { let state = token.lightSourceState; let disabled = token.lightSourceIsExhausted(token.currentLightSource); - let allowEvent = !disabled; let tbutton = $(BUTTON_HTML); if (state === token.STATE_ON) { tbutton.addClass("active"); @@ -42,11 +67,23 @@ export default class TokenHUD { TokenHUD.toggleSourceMenu(tbutton, token, changeLightSource); } }); - if (allowEvent) { - tbutton.find("i").click(async (event) => { - event.preventDefault(); - event.stopPropagation(); - if (!tbutton.next().hasClass("light-source-menu")) { + tbutton.find("i").click(async (event) => { + event.preventDefault(); + event.stopPropagation(); + if (!tbutton.next().hasClass("light-source-menu")) { + if (token.lightSourceIsExhausted(token.currentLightSource)) { + new Dialog({ + title: game.i18n.localize("torch.help.supplyExhausted.title"), + content: game.i18n.localize("torch.help.supplyExhausted.body"), + buttons: { + close: { + icon: '', + label: "Close" + } + }, + default: "close" + }).render(true); + } else { if (event.shiftKey) { togglelightHeld(token); } else if (event.altKey) { @@ -55,10 +92,10 @@ export default class TokenHUD { } else { await toggleLightSource(token); TokenHUD.syncFlameButtonState(tbutton, token); - } + } } - }); - } + } + }); } static toggleSourceMenu(button, token, changeLightSource) { diff --git a/lang/cn.json b/lang/cn.json index 1506f61..0deefa2 100644 --- a/lang/cn.json +++ b/lang/cn.json @@ -19,5 +19,9 @@ "torch.gameLightSources.name": "Additional Light Sources", "torch.gameLightSources.hint": "JSON file containing additional light sources to use beyond those supplied", "torch.brightRadius.name": "Bright Light Radius", - "torch.dimRadius.name": "Dim Light Radius" + "torch.dimRadius.name": "Dim Light Radius", + "torch.help.supplyExhausted.title": "Supply Exhausted", + "torch.help.supplyExhausted.body": "

Your light source is consumable and your quantity has dropped to zero. Increase the quantity of the item to light a fresh one.

", + "torch.help.setupSources.title": "Setting Up Light Sources", + "torch.help.setupSources.body": "

Your character currently has no light sources in their inventory, either as items or as spells.

For recognized systems, the light sources offered are based on inventory items - by name. Placing known light sources in your inventory will make them available to you.

Some light sources are consumable, like candles and torches. For these, using a light source decreases its quantity by one.

For systems that have no inventory-based light sources configured, you can configure light sources through module settings. In this case, all actors get the same light source.

You can make a system recognized by supplying a JSON file of light sources, as described in the README.md.

If you have multiple light sources in your inventory, you can choose among them by right-clicking the Torch button on the HUD when you do not have a light source lit.

" } diff --git a/lang/de.json b/lang/de.json index fa56607..f2283ce 100644 --- a/lang/de.json +++ b/lang/de.json @@ -19,5 +19,9 @@ "torch.gameLightSources.name": "Zusätzliche Lichtquellen", "torch.gameLightSources.hint": "JSON Datei mit zusätzlichen Lichtquellen, die über die mitgelieferten hinaus verwendet werden sollen", "torch.brightRadius.name": "Radius des hellen Licht", - "torch.dimRadius.name": "Radius des gedämpften Licht" + "torch.dimRadius.name": "Radius des gedämpften Licht", + "torch.help.supplyExhausted.title": "Supply Exhausted", + "torch.help.supplyExhausted.body": "

Your light source is consumable and your quantity has dropped to zero. Increase the quantity of the item to light a fresh one.

", + "torch.help.setupSources.title": "Setting Up Light Sources", + "torch.help.setupSources.body": "

Your character currently has no light sources in their inventory, either as items or as spells.

For recognized systems, the light sources offered are based on inventory items - by name. Placing known light sources in your inventory will make them available to you.

Some light sources are consumable, like candles and torches. For these, using a light source decreases its quantity by one.

For systems that have no inventory-based light sources configured, you can configure light sources through module settings. In this case, all actors get the same light source.

You can make a system recognized by supplying a JSON file of light sources, as described in the README.md.

If you have multiple light sources in your inventory, you can choose among them by right-clicking the Torch button on the HUD when you do not have a light source lit.

" } \ No newline at end of file diff --git a/lang/en.json b/lang/en.json index c0eb9e4..111a809 100644 --- a/lang/en.json +++ b/lang/en.json @@ -19,5 +19,9 @@ "torch.gameLightSources.name": "Additional Light Sources", "torch.gameLightSources.hint": "JSON file containing additional light sources to use beyond those supplied", "torch.brightRadius.name": "Bright Light Radius", - "torch.dimRadius.name": "Dim Light Radius" + "torch.dimRadius.name": "Dim Light Radius", + "torch.help.supplyExhausted.title": "Supply Exhausted", + "torch.help.supplyExhausted.body": "

Your light source is consumable and your quantity has dropped to zero. Increase the quantity of the item to light a fresh one.

", + "torch.help.setupSources.title": "Setting Up Light Sources", + "torch.help.setupSources.body": "

Your character currently has no light sources in their inventory, either as items or as spells.

For recognized systems, the light sources offered are based on inventory items - by name. Placing known light sources in your inventory will make them available to you.

Some light sources are consumable, like candles and torches. For these, using a light source decreases its quantity by one.

For systems that have no inventory-based light sources configured, you can configure light sources through module settings. In this case, all actors get the same light source.

You can make a system recognized by supplying a JSON file of light sources, as described in the README.md.

If you have multiple light sources in your inventory, you can choose among them by right-clicking the Torch button on the HUD when you do not have a light source lit.

" } diff --git a/lang/es.json b/lang/es.json index 6f37afd..f60fe3e 100644 --- a/lang/es.json +++ b/lang/es.json @@ -19,5 +19,9 @@ "torch.gameLightSources.name": "Additional Light Sources", "torch.gameLightSources.hint": "JSON file containing additional light sources to use beyond those supplied", "torch.brightRadius.name": "Bright Light Radius", - "torch.dimRadius.name": "Dim Light Radius" + "torch.dimRadius.name": "Dim Light Radius", + "torch.help.supplyExhausted.title": "Supply Exhausted", + "torch.help.supplyExhausted.body": "

Your light source is consumable and your quantity has dropped to zero. Increase the quantity of the item to light a fresh one.

", + "torch.help.setupSources.title": "Setting Up Light Sources", + "torch.help.setupSources.body": "

Your character currently has no light sources in their inventory, either as items or as spells.

For recognized systems, the light sources offered are based on inventory items - by name. Placing known light sources in your inventory will make them available to you.

Some light sources are consumable, like candles and torches. For these, using a light source decreases its quantity by one.

For systems that have no inventory-based light sources configured, you can configure light sources through module settings. In this case, all actors get the same light source.

You can make a system recognized by supplying a JSON file of light sources, as described in the README.md.

If you have multiple light sources in your inventory, you can choose among them by right-clicking the Torch button on the HUD when you do not have a light source lit.

" } diff --git a/lang/fr.json b/lang/fr.json index c2779e4..07bfc7a 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -19,5 +19,9 @@ "torch.gameLightSources.name": "Sources de lumière additionnelles", "torch.gameLightSources.hint": "Fichier JSON contenant des sources de lumière supplémentaires à utiliser en plus de celles fournies", "torch.brightRadius.name": "Étendue lumière vive", - "torch.dimRadius.name": "Étendue lumière faible" + "torch.dimRadius.name": "Étendue lumière faible", + "torch.help.supplyExhausted.title": "Supply Exhausted", + "torch.help.supplyExhausted.body": "

Your light source is consumable and your quantity has dropped to zero. Increase the quantity of the item to light a fresh one.

", + "torch.help.setupSources.title": "Setting Up Light Sources", + "torch.help.setupSources.body": "

Your character currently has no light sources in their inventory, either as items or as spells.

For recognized systems, the light sources offered are based on inventory items - by name. Placing known light sources in your inventory will make them available to you.

Some light sources are consumable, like candles and torches. For these, using a light source decreases its quantity by one.

For systems that have no inventory-based light sources configured, you can configure light sources through module settings. In this case, all actors get the same light source.

You can make a system recognized by supplying a JSON file of light sources, as described in the README.md.

If you have multiple light sources in your inventory, you can choose among them by right-clicking the Torch button on the HUD when you do not have a light source lit.

" } \ No newline at end of file diff --git a/lang/pt-BR.json b/lang/pt-BR.json index e4fb12d..1813c69 100644 --- a/lang/pt-BR.json +++ b/lang/pt-BR.json @@ -19,5 +19,9 @@ "torch.gameLightSources.name": "Additional Light Sources", "torch.gameLightSources.hint": "JSON file containing additional light sources to use beyond those supplied", "torch.brightRadius.name": "Bright Light Radius", - "torch.dimRadius.name": "Dim Light Radius" + "torch.dimRadius.name": "Dim Light Radius", + "torch.help.supplyExhausted.title": "Supply Exhausted", + "torch.help.supplyExhausted.body": "

Your light source is consumable and your quantity has dropped to zero. Increase the quantity of the item to light a fresh one.

", + "torch.help.setupSources.title": "Setting Up Light Sources", + "torch.help.setupSources.body": "

Your character currently has no light sources in their inventory, either as items or as spells.

For recognized systems, the light sources offered are based on inventory items - by name. Placing known light sources in your inventory will make them available to you.

Some light sources are consumable, like candles and torches. For these, using a light source decreases its quantity by one.

For systems that have no inventory-based light sources configured, you can configure light sources through module settings. In this case, all actors get the same light source.

You can make a system recognized by supplying a JSON file of light sources, as described in the README.md.

If you have multiple light sources in your inventory, you can choose among them by right-clicking the Torch button on the HUD when you do not have a light source lit.

" } diff --git a/lang/zh-TW.json b/lang/zh-TW.json index 8181469..585d2cd 100644 --- a/lang/zh-TW.json +++ b/lang/zh-TW.json @@ -19,5 +19,9 @@ "torch.gameLightSources.name": "Additional Light Sources", "torch.gameLightSources.hint": "JSON file containing additional light sources to use beyond those supplied", "torch.brightRadius.name": "Bright Light Radius", - "torch.dimRadius.name": "Dim Light Radius" + "torch.dimRadius.name": "Dim Light Radius", + "torch.help.supplyExhausted.title": "Supply Exhausted", + "torch.help.supplyExhausted.body": "

Your light source is consumable and your quantity has dropped to zero. Increase the quantity of the item to light a fresh one.

", + "torch.help.setupSources.title": "Setting Up Light Sources", + "torch.help.setupSources.body": "

Your character currently has no light sources in their inventory, either as items or as spells.

For recognized systems, the light sources offered are based on inventory items - by name. Placing known light sources in your inventory will make them available to you.

Some light sources are consumable, like candles and torches. For these, using a light source decreases its quantity by one.

For systems that have no inventory-based light sources configured, you can configure light sources through module settings. In this case, all actors get the same light source.

You can make a system recognized by supplying a JSON file of light sources, as described in the README.md.

If you have multiple light sources in your inventory, you can choose among them by right-clicking the Torch button on the HUD when you do not have a light source lit.

" } diff --git a/module.json b/module.json index 2daad3f..68cf373 100644 --- a/module.json +++ b/module.json @@ -2,7 +2,7 @@ "id": "torch", "title": "Torch", "description": "Torch HUD Controls", - "version": "2.7.0", + "version": "2.8.0", "authors": [ { "name": "Deuce", @@ -69,7 +69,7 @@ "url": "https://github.com/League-of-Foundry-Developers/torch", "compatibility": { "minimum": "10", - "verified": "11.299", + "verified": "11.306", "maximum": "11" } } \ No newline at end of file diff --git a/sources.json b/sources.json index 1f7533c..83512c8 100644 --- a/sources.json +++ b/sources.json @@ -519,7 +519,7 @@ "topology": "standard", "quantity": "quantity.value", "sources": { - "Torch": { + "Torches": { "type": "item", "consumable": true, "light": [ @@ -559,6 +559,207 @@ } } }, + "reclaim-the-wild": { + "system": "reclaim-the-wild", + "topology": "standard", + "quantity" : "quantity", + "aliases": { + }, + "sources": { + "Candle": { + "name": "Candle", + "type": "equipment", + "consumable": true, + "states": 2, + "light": [ + { + "bright": 0, "dim": 1, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Firewood": { + "name": "Firewood", + "type": "equipment", + "consumable": true, + "states": 2, + "light": [ + { + "bright": 2, "dim": 8, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Lantern (1h, R0)": { + "name": "Lantern (1h, R0)", + "type": "equipment", + "consumable": false, + "states": 3, + "light": [ + { + "bright": 2, "dim": 0, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + }, + { + "bright": 5, "dim": 0, "angle": 85, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Lantern (1h, R1)": { + "name": "Lantern (1h, R1)", + "type": "equipment", + "consumable": false, + "states": 3, + "light": [ + { + "bright": 2, "dim": 3, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + }, + { + "bright": 6, "dim": 0, "angle": 85, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Lantern (1h, R2)": { + "name": "Lantern (1h, R2)", + "type": "equipment", + "consumable": false, + "states": 3, + "light": [ + { + "bright": 3, "dim": 0, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + }, + { + "bright": 7, "dim": 0, "angle": 85, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Lantern (1h, R3)": { + "name": "Lantern (1h, R3)", + "type": "equipment", + "consumable": false, + "states": 3, + "light": [ + { + "bright": 3, "dim": 4, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + }, + { + "bright": 8, "dim": 0, "angle": 85, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Lantern (1h, R4)": { + "name": "Lantern (1h, R4)", + "type": "equipment", + "consumable": false, + "states": 3, + "light": [ + { + "bright": 4, "dim": 0, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + }, + { + "bright": 9, "dim": 0, "angle": 85, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Lantern (1h, R5)": { + "name": "Lantern (1h, R5)", + "type": "equipment", + "consumable": false, + "states": 3, + "light": [ + { + "bright": 4, "dim": 5, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + }, + { + "bright": 10, "dim": 0, "angle": 85, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Torch (1h, R0)": { + "name": "Torch (1h, R0)", + "type": "equipment", + "consumable": false, + "states": 2, + "light": [ + { + "bright": 4, "dim": 0, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Torch (1h, R1)": { + "name": "Torch (1h, R1)", + "type": "equipment", + "consumable": false, + "states": 2, + "light": [ + { + "bright": 4, "dim": 5, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Torch (1h, R2)": { + "name": "Torch (1h, R2)", + "type": "equipment", + "consumable": false, + "states": 2, + "light": [ + { + "bright": 5, "dim": 0, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Torch (1h, R3)": { + "name": "Torch (1h, R3)", + "type": "equipment", + "consumable": false, + "states": 2, + "light": [ + { + "bright": 5, "dim": 6, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Torch (1h, R4)": { + "name": "Torch (1h, R4)", + "type": "equipment", + "consumable": false, + "states": 2, + "light": [ + { + "bright": 6, "dim": 0, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + }, + "Torch (1h, R5)": { + "name": "Torch (1h, R5)", + "type": "equipment", + "consumable": false, + "states": 2, + "light": [ + { + "bright": 6, "dim": 7, "angle": 360, "color": "#ff9329", "alpha": 0.5, + "animation": { "type": "torch", "speed": 5, "intensity": 5, "reverse": false } + } + ] + } + } + }, "default": { "system": "default", "topology": "none", diff --git a/token.js b/token.js index 2449855..c7aa858 100644 --- a/token.js +++ b/token.js @@ -78,6 +78,15 @@ export default class TorchToken { return false; } + getInventory(source) { + let sourceObj = this._library.getLightSource(source); + if (sourceObj && sourceObj.consumable) { + return this._library.getInventory(this._token.actor, source); + } else if (sourceObj) { + return -1; + } + } + /* Orchestrate State Management */ async forceStateOff() { diff --git a/torch.js b/torch.js index d18d3f8..bbb9e0d 100644 --- a/torch.js +++ b/torch.js @@ -2,6 +2,7 @@ import Settings from "./settings.js"; import TorchSocket from "./socket.js"; import TokenHUD from "./hud.js"; import TorchToken from "./token.js"; +import TorchApi from './api.js'; import SourceLibrary from "./library.js"; /* @@ -25,32 +26,35 @@ class Torch { * Add a torch button to the Token HUD - called from TokenHUD render hook */ static async addTorchButton(hud, hudHtml, hudData) { + let actor = game.actors.get(hud.object.document.actorId); let library = await SourceLibrary.load( game.system.id, Settings.lightRadii.bright, Settings.lightRadii.dim, Settings.inventoryItemName, Settings.gameLightSources, - hud.object.actor.prototypeToken.light, + actor.prototypeToken.light, ); let token = new TorchToken(hud.object.document, library); let lightSources = token.ownedLightSources; // Don't let the tokens we create for light sources have or use their own // light sources recursively. - if (hud.object.document.name in lightSources) return; - if (!game.user.isGM && !Settings.playerTorches) return; - if (!token.currentLightSource) return; - - /* Manage torch state */ - TokenHUD.addFlameButton( - token, - hudHtml, - Torch.forceSourceOff, - Torch.toggleLightSource, - Torch.toggleLightHeld, - Torch.changeLightSource - ); + if (hud.object.document.name in lightSources) return; + if (!game.user.isGM && !Settings.playerTorches) return; + if (!token.currentLightSource) { + TokenHUD.addQueryButton(token, hudHtml) + return; + } + /* Manage torch state */ + TokenHUD.addFlameButton( + token, + hudHtml, + Torch.forceSourceOff, + Torch.toggleLightSource, + Torch.toggleLightHeld, + Torch.changeLightSource + ); } static async toggleLightSource(token) { @@ -106,6 +110,7 @@ Hooks.once("init", () => { Torch.setupQuenchTesting(); } Settings.register(); + game.Torch = new TorchApi(); }); console.log("Torch | --- Module loaded"); diff --git a/torch.zip b/torch.zip index b9b3e4281fc967d5ab2fdf54a93676e253e22bb7..a540588def73dd7aa397f6123084eff9e955645f 100644 GIT binary patch delta 26761 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