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 b9b3e42..a540588 100644 Binary files a/torch.zip and b/torch.zip differ