From d85ee766f332b55cc9029812f9ac88aea7cd3800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Tue, 12 Oct 2021 15:26:50 +0200 Subject: [PATCH 1/9] actually use better rolltables if enabled --- scripts/populateLoot.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/scripts/populateLoot.js b/scripts/populateLoot.js index c5a7c8f..120c894 100644 --- a/scripts/populateLoot.js +++ b/scripts/populateLoot.js @@ -13,18 +13,18 @@ export class LootPopulator { this.token = token; this.actor = this.token.actor; - this.shopQtyFormula = this.actor.getFlag(ls5e_moduleNamespace, "shopQty") || this._getSetting("fallbackShopQty") || "1"; - this.itemQtyFormula = this.actor.getFlag(ls5e_moduleNamespace, "itemQty") || this._getSetting("fallbackItemQty") || "1"; - this.itemQtyLimit = this.actor.getFlag(ls5e_moduleNamespace, "itemQtyLimit") || this._getSetting("fallbackItemQtyLimit") || "0"; - this.itemOnlyOnce = this.actor.getFlag(ls5e_moduleNamespace, "itemOnlyOnce") || false; - this.reducedVerbosity = this._getSetting("reduceUpdateVerbosity") || true; - if (this._getSetting("creatureTypeFallbacks") && (this._getSetting("creaturetype_default_" + creatureType + '_table') != 0)) { this.rolltableName = this.actor.getFlag(ls5e_moduleNamespace, "rolltable") || this._getSetting("creaturetype_default_" + creatureType + '_table'); } else { this.rolltableName = this.actor.getFlag(ls5e_moduleNamespace, "rolltable") || this._getSetting("fallbackRolltable"); } + this.shopQtyFormula = this.actor.getFlag(ls5e_moduleNamespace, "shopQty") || this._getSetting("fallbackShopQty") || "1"; + this.itemQtyFormula = this.actor.getFlag(ls5e_moduleNamespace, "itemQty") || this._getSetting("fallbackItemQty") || "1"; + this.itemQtyLimit = this.actor.getFlag(ls5e_moduleNamespace, "itemQtyLimit") || this._getSetting("fallbackItemQtyLimit") || "0"; + this.itemOnlyOnce = this.actor.getFlag(ls5e_moduleNamespace, "itemOnlyOnce") || false; + this.reducedVerbosity = this._getSetting("reduceUpdateVerbosity") || true; + return this; } @@ -36,17 +36,21 @@ export class LootPopulator { async populateToken() { if (!this.rolltableName) return; - - let shopQtyRoll = new Roll(this.shopQtyFormula); - - shopQtyRoll.roll(); - let rolltable = await tableHelper._getRolltable(this.rolltableName); if (!rolltable) { return ui.notifications.error(moduleNamespace + `: No Rollable Table found with name "${this.rolltableName}".`); } + if (this._getSetting("useBetterRolltables") && rolltable.getFlag('better-rolltables', 'table-type')) { + game.betterTables.addLootToSelectedToken(rolltable, this.token); + return; + } + + let shopQtyRoll = new Roll(this.shopQtyFormula); + + shopQtyRoll.roll(); + if (this.itemOnlyOnce) { if (rolltable.results.length < shopQtyRoll.total) { return ui.notifications.error(moduleNamespace + `: Cannot create a loot with ${shopQtyRoll.total} unqiue entries if the rolltable only contains ${rolltable.results.length} items`); From 299b3ded4c2cbec5de1bf5d3cd90cd8f0932bad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Sun, 17 Oct 2021 16:34:02 +0200 Subject: [PATCH 2/9] add a macro compendium to the module --- module.json | 22 ++++++++++++++++++++-- packs/macros.db | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 packs/macros.db diff --git a/module.json b/module.json index 968667e..00ceb6f 100644 --- a/module.json +++ b/module.json @@ -2,11 +2,20 @@ "name": "lootpopulatornpc5e", "title": "Loot populater NPC | 5e", "description": "A module to automatically populate loot on monsters and npcs when placed on the map.", - "version": "0.2.2", + "version": "0.3.0", "minimumCoreVersion": "0.8.5", - "compatibleCoreVersion": "0.8.8", + "compatibleCoreVersion": "0.8.9", "author": "Daniel Böttner", "systems": ["dnd5e"], + "dependencies": [ + { + "name": "dnd5e", + "type": "system" + }, + { + "name": "lootsheetnpc5e" + } + ], "includes": [ "./hooks/**", "./scripts/**" @@ -16,6 +25,15 @@ ], "styles": [], "socket": false, + "packs": [ + { + "name": "loot-populator-macros", + "label": "Loot Populator Macros", + "system": "dnd5e", + "path": "./packs/macros.db", + "entity": "Macro" + } + ], "url": "https://github.com/DanielBoettner/fvtt-loot-populator-npc-5e", "manifest": "https://raw.githubusercontent.com/DanielBoettner/fvtt-loot-populator-npc-5e/master/module.json", "download": "https://github.com/DanielBoettner/fvtt-loot-populator-npc-5e/archive/master.zip" diff --git a/packs/macros.db b/packs/macros.db new file mode 100644 index 0000000..a4b08d5 --- /dev/null +++ b/packs/macros.db @@ -0,0 +1 @@ +{"name":"toggle auto population","type":"script","author":"rKaPA9z0omV5p2Qt","img":"icons/commodities/tech/lever.webp","scope":"global","command":"let module = 'lootpopulatornpc5e',\n key = 'autoPopulateTokens';\n \ngame.settings.set(module,key,!game.settings.get(module,key));\nui.notifications.info('The setting ' + key + ' was changed to: ' + game.settings.get(module,key) + '');","folder":null,"sort":0,"permission":{"default":0,"rKaPA9z0omV5p2Qt":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.KnGdlkChHPPNClhx"}},"_id":"94Ut6QAo4GsOslMl"} From 8438cef4c5e44ad098cc9b5b75589f94e0ccf41b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Sun, 17 Oct 2021 17:01:25 +0200 Subject: [PATCH 3/9] Add light switch macro to compendium --- packs/macros.db | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packs/macros.db b/packs/macros.db index a4b08d5..c5d734b 100644 --- a/packs/macros.db +++ b/packs/macros.db @@ -1 +1,2 @@ -{"name":"toggle auto population","type":"script","author":"rKaPA9z0omV5p2Qt","img":"icons/commodities/tech/lever.webp","scope":"global","command":"let module = 'lootpopulatornpc5e',\n key = 'autoPopulateTokens';\n \ngame.settings.set(module,key,!game.settings.get(module,key));\nui.notifications.info('The setting ' + key + ' was changed to: ' + game.settings.get(module,key) + '');","folder":null,"sort":0,"permission":{"default":0,"rKaPA9z0omV5p2Qt":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.KnGdlkChHPPNClhx"}},"_id":"94Ut6QAo4GsOslMl"} +{"name":"toggle auto population","type":"script","author":"rKaPA9z0omV5p2Qt","img":"icons/commodities/tech/lever.webp","scope":"global","command":"/**\n * Simple Macro to toggle the state of a boolean setting.\n **/\nlet module = 'lootpopulatornpc5e',\n key = 'autoPopulateTokens';\n \ngame.settings.set(module,key,!game.settings.get(module,key));\nui.notifications.info('The setting ' + key + ' was changed to: ' + !game.settings.get(module,key) + '');","folder":null,"sort":0,"permission":{"default":0,"rKaPA9z0omV5p2Qt":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.KnGdlkChHPPNClhx"}},"_id":"tIGp2puPIBWOW8Wc"} +{"name":"Set light on tokens","type":"script","author":"rKaPA9z0omV5p2Qt","img":"icons/commodities/tech/levers-colored.webp","scope":"global","command":"let presets = {\n darkvision: {\n vision: true,\n dimSight: 60,\n brightSight: 0,\n dimLight: 0,\n brightLight: 0,\n lightAngle: 360,\n lockRotation: false,\n lightColor: \"\",\n lightAlpha: 0.2,\n },\n light_cantrip: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 40,\n brightLight: 20,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"torch\", intensity: 1, speed: 1},\n lightColor: \"#bbbbff\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_spotlight: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 120,\n brightLight: 60,\n lightAngle: 55,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_narrow: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 90,\n brightLight: 45,\n lightAngle: 100,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_wide: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 60,\n brightLight: 30,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_dim: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 30,\n brightLight: 15,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n torch: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 20,\n brightLight: 10,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"torch\", intensity: 5, speed: 5},\n lightColor: \"#ffbb33\",\n lightAlpha: 0.2,\n },\n normal_vision: {\n vision: true,\n dimSight: 5,\n brightSight: 0,\n dimLight: 0,\n brightLight: 0,\n lightAngle: 360,\n lockRotation: false,\n lightColor: \"\",\n lightAlpha: 0.2,\n },\n no_vision: {\n vision: false,\n }\n};\n\nlet vision_buttons = [];\nfor (let key in presets) {\n vision_buttons.push({\n label: key.replaceAll('_',' '),\n callback: async function() {\n updateTokens(presets[key]);\n }\n });\n}\n\nnew Dialog({\n title: `Select a vision option`,\n content: ``,\n buttons: vision_buttons,\n //default: \"yes\",\n close: html => {}\n}).render(true);\n\nasync function updateTokens(preset){\n const updates = canvas.tokens.controlled.map(t => mergeObject({_id: t.id}, preset));\n await canvas.scene.updateEmbeddedDocuments(\"Token\", updates);\n}","folder":null,"sort":0,"permission":{"default":0,"rKaPA9z0omV5p2Qt":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.PBzvJUvRseFBUDAL"}},"_id":"5oCVwuyikEpuWdH8"} From bc81157660bac3c15d5a6b583bf3247000fd057f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Tue, 19 Oct 2021 23:07:15 +0200 Subject: [PATCH 4/9] made the module available to the game object --- hooks/onCreateToken.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hooks/onCreateToken.js b/hooks/onCreateToken.js index 18c552e..634f447 100644 --- a/hooks/onCreateToken.js +++ b/hooks/onCreateToken.js @@ -1,8 +1,10 @@ import { LootPopulator } from '../scripts/populateLoot.js'; export let initHooks = () => { - Hooks.on('createToken', (token, createData, options, userId) => { + + game.LootPopulator = new LootPopulator(); + Hooks.on('createToken', (token, createData, options, userId) => { // only act on tokens dropped by the GM if (!game.user.isGM) return token; if (!game.settings.get("lootpopulatornpc5e", "autoPopulateTokens")) return token; @@ -19,7 +21,6 @@ export let initHooks = () => { return token; } - let lootPopulator = new LootPopulator(token); - lootPopulator.populateToken(); + game.LootPopulator.populate(token); }); }; From 36577566aaa798921585b08cc86a4721c4921b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Tue, 19 Oct 2021 23:09:50 +0200 Subject: [PATCH 5/9] version bump, changed from author to authors --- module.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/module.json b/module.json index 00ceb6f..e3d842c 100644 --- a/module.json +++ b/module.json @@ -2,10 +2,15 @@ "name": "lootpopulatornpc5e", "title": "Loot populater NPC | 5e", "description": "A module to automatically populate loot on monsters and npcs when placed on the map.", - "version": "0.3.0", + "version": "0.3.1", "minimumCoreVersion": "0.8.5", "compatibleCoreVersion": "0.8.9", - "author": "Daniel Böttner", + "authors":[ + { + "name": "Daniel Böttner | JackPrince#0494", + "url": "https://github.com/DanielBoettner/" + } + ], "systems": ["dnd5e"], "dependencies": [ { From 998c3d31937786b9a930c64490cf0a34209c60fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Tue, 19 Oct 2021 23:10:25 +0200 Subject: [PATCH 6/9] added a game pack with macros --- packs/macros.db | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packs/macros.db b/packs/macros.db index c5d734b..813d8f8 100644 --- a/packs/macros.db +++ b/packs/macros.db @@ -1,2 +1,3 @@ -{"name":"toggle auto population","type":"script","author":"rKaPA9z0omV5p2Qt","img":"icons/commodities/tech/lever.webp","scope":"global","command":"/**\n * Simple Macro to toggle the state of a boolean setting.\n **/\nlet module = 'lootpopulatornpc5e',\n key = 'autoPopulateTokens';\n \ngame.settings.set(module,key,!game.settings.get(module,key));\nui.notifications.info('The setting ' + key + ' was changed to: ' + !game.settings.get(module,key) + '');","folder":null,"sort":0,"permission":{"default":0,"rKaPA9z0omV5p2Qt":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.KnGdlkChHPPNClhx"}},"_id":"tIGp2puPIBWOW8Wc"} -{"name":"Set light on tokens","type":"script","author":"rKaPA9z0omV5p2Qt","img":"icons/commodities/tech/levers-colored.webp","scope":"global","command":"let presets = {\n darkvision: {\n vision: true,\n dimSight: 60,\n brightSight: 0,\n dimLight: 0,\n brightLight: 0,\n lightAngle: 360,\n lockRotation: false,\n lightColor: \"\",\n lightAlpha: 0.2,\n },\n light_cantrip: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 40,\n brightLight: 20,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"torch\", intensity: 1, speed: 1},\n lightColor: \"#bbbbff\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_spotlight: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 120,\n brightLight: 60,\n lightAngle: 55,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_narrow: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 90,\n brightLight: 45,\n lightAngle: 100,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_wide: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 60,\n brightLight: 30,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_dim: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 30,\n brightLight: 15,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n torch: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 20,\n brightLight: 10,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"torch\", intensity: 5, speed: 5},\n lightColor: \"#ffbb33\",\n lightAlpha: 0.2,\n },\n normal_vision: {\n vision: true,\n dimSight: 5,\n brightSight: 0,\n dimLight: 0,\n brightLight: 0,\n lightAngle: 360,\n lockRotation: false,\n lightColor: \"\",\n lightAlpha: 0.2,\n },\n no_vision: {\n vision: false,\n }\n};\n\nlet vision_buttons = [];\nfor (let key in presets) {\n vision_buttons.push({\n label: key.replaceAll('_',' '),\n callback: async function() {\n updateTokens(presets[key]);\n }\n });\n}\n\nnew Dialog({\n title: `Select a vision option`,\n content: ``,\n buttons: vision_buttons,\n //default: \"yes\",\n close: html => {}\n}).render(true);\n\nasync function updateTokens(preset){\n const updates = canvas.tokens.controlled.map(t => mergeObject({_id: t.id}, preset));\n await canvas.scene.updateEmbeddedDocuments(\"Token\", updates);\n}","folder":null,"sort":0,"permission":{"default":0,"rKaPA9z0omV5p2Qt":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.PBzvJUvRseFBUDAL"}},"_id":"5oCVwuyikEpuWdH8"} +{"name":"toggleTokenAutoPopulation","type":"script","author":"rKaPA9z0omV5p2Qt","img":"icons/commodities/tech/lever.webp","scope":"global","command":"/**\n * Simple Macro to toggle the state of a boolean setting.\n **/\nlet module = 'lootpopulatornpc5e',\n key = 'autoPopulateTokens';\n \ngame.settings.set(module,key,!game.settings.get(module,key));\nui.notifications.info('The setting ' + key + ' was changed to: ' + !game.settings.get(module,key) + '');","folder":null,"sort":0,"permission":{"default":0,"rKaPA9z0omV5p2Qt":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.KnGdlkChHPPNClhx"}},"_id":"IfSKfuB5qqPUiTaf"} +{"name":"populateLoot","type":"script","author":"rKaPA9z0omV5p2Qt","img":"icons/skills/trades/farming-plant-seeds-gray.webp","scope":"global","command":"// no token given defaults to currently selected tokens\ngame.LootPopulator.populate();","folder":null,"sort":0,"permission":{"default":0,"rKaPA9z0omV5p2Qt":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.xAhxp90zTM54uT9z"}},"_id":"Ab23KwPq9VD4C2yn"} +{"name":"setLightOnTokens","type":"script","author":"rKaPA9z0omV5p2Qt","img":"icons/commodities/tech/levers-colored.webp","scope":"global","command":"let presets = {\n darkvision: {\n vision: true,\n dimSight: 60,\n brightSight: 0,\n dimLight: 0,\n brightLight: 0,\n lightAngle: 360,\n lockRotation: false,\n lightColor: \"\",\n lightAlpha: 0.2,\n },\n light_cantrip: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 40,\n brightLight: 20,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"torch\", intensity: 1, speed: 1},\n lightColor: \"#bbbbff\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_spotlight: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 120,\n brightLight: 60,\n lightAngle: 55,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_narrow: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 90,\n brightLight: 45,\n lightAngle: 100,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_wide: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 60,\n brightLight: 30,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n acetylene_lantern_dim: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 30,\n brightLight: 15,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"pulse\", intensity: 2, speed: 3},\n lightColor: \"#ffee99\",\n lightAlpha: 0.2,\n },\n torch: {\n vision: true,\n dimSight: 1,\n brightSight: 0,\n dimLight: 20,\n brightLight: 10,\n lightAngle: 360,\n lockRotation: false,\n lightAnimation: {type: \"torch\", intensity: 5, speed: 5},\n lightColor: \"#ffbb33\",\n lightAlpha: 0.2,\n },\n normal_vision: {\n vision: true,\n dimSight: 5,\n brightSight: 0,\n dimLight: 0,\n brightLight: 0,\n lightAngle: 360,\n lockRotation: false,\n lightColor: \"\",\n lightAlpha: 0.2,\n },\n no_vision: {\n vision: false,\n }\n};\n\nlet vision_buttons = [];\nfor (let key in presets) {\n vision_buttons.push({\n label: key.replaceAll('_',' '),\n callback: async function() {\n updateTokens(presets[key]);\n }\n });\n}\n\nnew Dialog({\n title: `Select a vision option`,\n content: ``,\n buttons: vision_buttons,\n //default: \"yes\",\n close: html => {}\n}).render(true);\n\nasync function updateTokens(preset){\n const updates = canvas.tokens.controlled.map(t => mergeObject({_id: t.id}, preset));\n await canvas.scene.updateEmbeddedDocuments(\"Token\", updates);\n}","folder":null,"sort":0,"permission":{"default":0,"rKaPA9z0omV5p2Qt":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.PBzvJUvRseFBUDAL"}},"_id":"ZWRIblJrmgW5qv9l"} From 85a0792df301e859b6df6612c42922ec1baa4388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Tue, 19 Oct 2021 23:11:00 +0200 Subject: [PATCH 7/9] bugfixing and refactoring --- .github/release.yml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/release.yml diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..032ba01 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,38 @@ +on: + push: + # Sequence of patterns matched against refs/tags + tags: + - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 + +name: Upload Release Asset + +jobs: + build: + name: Upload Release Asset + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Zip files + run: | + zip -r compendium-browser ./dist/ * -x "img/*" ".github/*" ".idea/*" "tsconfig.json" + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false + - name: Upload Release Asset + id: upload-release-asset + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./compendium-browser.zip + asset_name: compendium-browser.zip + asset_content_type: application/zip From f0f0a6155f464face4a4d340aac8e31aa0a39a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Tue, 19 Oct 2021 23:11:43 +0200 Subject: [PATCH 8/9] bugfixing and refactoring --- scripts/modules/currency.mjs | 44 ++-- scripts/populateLoot.js | 389 ++++++++++++++++++----------------- 2 files changed, 233 insertions(+), 200 deletions(-) diff --git a/scripts/modules/currency.mjs b/scripts/modules/currency.mjs index 21d4189..637b6f3 100644 --- a/scripts/modules/currency.mjs +++ b/scripts/modules/currency.mjs @@ -10,18 +10,25 @@ class Currency { * @param useBTR */ static async _handleCurrency( - actor, + token, flags ) { if (flags.generateCurrency && flags.lootCurrencyDefault) { let lootCurrencyString = flags.lootCurrencyDefault; - if (flags.useBetterRolltables) { - lootCurrencyString = flags.brt_rt_tcs || lootCurrencyString; - } + /** + * If we use betterRolltable and the currencyString of BRT is not empty + * the currency was already populated. + */ + if ( + flags.useBetterRolltables && + (flags.brt_rt_tcs || flags.brt_rt_tcs.length > 0 ) + ){ + return; + } - await Currency.addCurrenciesToActor( - actor, + await Currency.addCurrenciesToToken( + token, Currency._generateCurrency(lootCurrencyString), flags.adjustCurrency ); @@ -58,28 +65,33 @@ class Currency { /** * Expects and actor and an array - * @param {Actor} actor + * @param {Actor} token * @param {Array|string} lootCurrency * @param {boolean} adjutsByCR */ - static async addCurrenciesToActor(actor, lootCurrency, adjutsByCR = false) { - let currencyData = duplicate(actor.data.data.currency), - cr = actor.data.data.details.cr || 0, - amount = 0; + static async addCurrenciesToToken(token, lootCurrency, adjutsByCR = false) { + const currencyDataInitial = {cp: 0, ep: 0, gp: 0, pp: 0,sp: 0}; + let currencyData = currencyDataInitial, + amount = 0; + + if (token.data.actorData.data?.currency) { + currencyData = duplicate(token.data.actorData.data.currency); + } - for (var key in lootCurrency) { + for (let key in lootCurrency) { if (currencyData.hasOwnProperty(key)) { if(adjutsByCR){ - amount = Number(currencyData[key].value || 0) + Math.ceil(cr) + Number(lootCurrency[key]); + let cr = game.actors.find(actor => actor._id === token.data.actorId).data.data.details.cr || 0; + amount = Number(currencyData[key] || 0) + Number(Math.ceil(cr * lootCurrency[key])); } else { - amount = Number(currencyData[key].value || 0) + Number(lootCurrency[key]); + amount = Number(currencyData[key] || 0) + Number(lootCurrency[key]); } - currencyData[key] = {"value": amount.toString()}; + currencyData[key] = amount; } } - await actor.update({"data.currency": currencyData}); + await token.update({ 'actorData.data.currency': currencyData }); } /** diff --git a/scripts/populateLoot.js b/scripts/populateLoot.js index 120c894..41e5e6b 100644 --- a/scripts/populateLoot.js +++ b/scripts/populateLoot.js @@ -5,214 +5,235 @@ import tableHelper from "./modules/tableHelper.mjs"; const moduleNamespace = "lootpopulatornpc5e"; export class LootPopulator { - constructor(token) { + /** + * Populate given token(s) with items from rolltables. + * + * @returns + */ + async populate(token = null) { //support for LootSheetNPC5e - let ls5e_moduleNamespace = "lootsheetnpc5e"; - let creatureType = token.actor.data.data.details.type.value; - - this.token = token; - this.actor = this.token.actor; - - if (this._getSetting("creatureTypeFallbacks") && (this._getSetting("creaturetype_default_" + creatureType + '_table') != 0)) { - this.rolltableName = this.actor.getFlag(ls5e_moduleNamespace, "rolltable") || this._getSetting("creaturetype_default_" + creatureType + '_table'); - } else { - this.rolltableName = this.actor.getFlag(ls5e_moduleNamespace, "rolltable") || this._getSetting("fallbackRolltable"); - } + const ls5e_moduleNamespace = "lootsheetnpc5e", + reducedVerbosity = this._getSetting("reduceUpdateVerbosity") || true, + tokenstack = (token) ? (token.length >= 0) ? token : [token] : canvas.tokens.controlled; + + for (const currentToken of tokenstack) { + const tokenActor = currentToken.actor, + creatureType = tokenActor.data.data.details.type.value; + let rolltableName = null; + + //skip linked tokens + if (!currentToken.actor || currentToken.data.actorLink) continue; + + if (this._getSetting("creatureTypeFallbacks") && (this._getSetting("creaturetype_default_" + creatureType + '_table') != 0)) { + rolltableName = tokenActor.getFlag(ls5e_moduleNamespace, "rolltable") || this._getSetting("creaturetype_default_" + creatureType + '_table'); + } else { + rolltableName = tokenActor.getFlag(ls5e_moduleNamespace, "rolltable") || this._getSetting("fallbackRolltable"); + } - this.shopQtyFormula = this.actor.getFlag(ls5e_moduleNamespace, "shopQty") || this._getSetting("fallbackShopQty") || "1"; - this.itemQtyFormula = this.actor.getFlag(ls5e_moduleNamespace, "itemQty") || this._getSetting("fallbackItemQty") || "1"; - this.itemQtyLimit = this.actor.getFlag(ls5e_moduleNamespace, "itemQtyLimit") || this._getSetting("fallbackItemQtyLimit") || "0"; - this.itemOnlyOnce = this.actor.getFlag(ls5e_moduleNamespace, "itemOnlyOnce") || false; - this.reducedVerbosity = this._getSetting("reduceUpdateVerbosity") || true; + if (!rolltableName) return ui.notifications.error(moduleNamespace + `: No Rolltable name was found on the actor or in the module defaults.`); - return this; + let rolltable = await tableHelper._getRolltable(rolltableName); + + if (!rolltable) { + return ui.notifications.error(moduleNamespace + `: No Rollable Table found with name "${rolltableName}".`); + } + + // if we use betterRolltables, let it handle the loot + if (this._getSetting("useBetterRolltables") && rolltable.getFlag('better-rolltables', 'table-type')) { + game.betterTables.addLootToSelectedToken(rolltable, currentToken); + } else { + await this._populateToken(rolltable, currentToken, reducedVerbosity); + } + + let currencyFlags = { + "generateCurrency": this._getSetting('generateCurrency'), + "lootCurrencyDefault": this._getSetting('lootCurrencyDefault'), + "useBetterRolltables": this._getSetting("useBetterRolltables"), + "brt_rt_tcs": rolltable.getFlag('better-rolltables', 'table-currency-string'), + "adjustCurrency": this._getSetting("adjustCurrencyWithCR") + }; + + await Currency._handleCurrency(currentToken,currencyFlags); + } } /** - * Populate given token with items from rolltables. * + * @param {RollTableDocument} rolltable + * @param {TokenDocument} token + * * @returns */ - async populateToken() { - - if (!this.rolltableName) return; - let rolltable = await tableHelper._getRolltable(this.rolltableName); - - if (!rolltable) { - return ui.notifications.error(moduleNamespace + `: No Rollable Table found with name "${this.rolltableName}".`); - } - - if (this._getSetting("useBetterRolltables") && rolltable.getFlag('better-rolltables', 'table-type')) { - game.betterTables.addLootToSelectedToken(rolltable, this.token); - return; - } - - let shopQtyRoll = new Roll(this.shopQtyFormula); + async _populateToken(rolltable, token, reducedVerbosity) { + const ls5e_moduleNamespace = "lootsheetnpc5e", + tokenActor = token.actor, + shopQtyFormula = tokenActor.getFlag(ls5e_moduleNamespace, "shopQty") || this._getSetting("fallbackShopQty") || "1", + itemQtyFormula = tokenActor.getFlag(ls5e_moduleNamespace, "itemQty") || this._getSetting("fallbackItemQty") || "1", + itemQtyLimit = tokenActor.getFlag(ls5e_moduleNamespace, "itemQtyLimit") || this._getSetting("fallbackItemQtyLimit") || "0", + itemOnlyOnce = tokenActor.getFlag(ls5e_moduleNamespace, "itemOnlyOnce") || false; + + let shopQtyRoll = new Roll(shopQtyFormula); - shopQtyRoll.roll(); - - if (this.itemOnlyOnce) { - if (rolltable.results.length < shopQtyRoll.total) { - return ui.notifications.error(moduleNamespace + `: Cannot create a loot with ${shopQtyRoll.total} unqiue entries if the rolltable only contains ${rolltable.results.length} items`); - } - } - - if (!this.itemOnlyOnce) { - for (let i = 0; i < shopQtyRoll.total; i++) { - const rollResult = await rolltable.roll(); - let newItem = null; - - if (rollResult.results[0].collection === "Item") { - newItem = game.items.get(rollResult.results[0].data.resultId); - } else { - const items = game.packs.get(rollResult.results[0].data.collection); - newItem = await items.getDocument(rollResult.results[0].data.resultId); + shopQtyRoll.roll(); + + if (itemOnlyOnce) { + if (rolltable.results.length < shopQtyRoll.total) { + return ui.notifications.error(moduleNamespace + `: Cannot create loot with ${shopQtyRoll.total} unqiue entries if the rolltable only contains ${rolltable.results.length} items`); } - - newItem = await tableHelper._rollSubTables(newItem); - - if (!newItem || newItem === null) { - return; - } - - if (newItem.type === "spell") { - newItem = await Item5e.createScrollFromSpell(newItem); - } - - let itemQtyRoll = new Roll(this.itemQtyFormula); - itemQtyRoll.roll(); - - console.log(moduleNamespace + `: Adding ${itemQtyRoll.total} x ${newItem.name}`); - - let existingItem = this.actor.items.find(item => item.data.name == newItem.name); - - if (existingItem === undefined) { - await this.actor.createEmbeddedDocuments("Item", [newItem.toObject()]); - //console.log(moduleNamespace + `: ${newItem.name} does not exist.`); - existingItem = await this.actor.items.find(item => item.data.name == newItem.name); - - if (this.itemQtyLimit > 0 && Number(this.itemQtyLimit) < Number(itemQtyRoll.total)) { - await existingItem.update({ "data.quantity": this.itemQtyLimit }); - if (!this.reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added new ${this.itemQtyLimit} x ${newItem.name}.`); + } + + if (!itemOnlyOnce) { + for (let i = 0; i < shopQtyRoll.total; i++) { + const rollResult = await rolltable.roll(); + let newItem = null; + + if (rollResult.results[0].collection === "Item") { + newItem = game.items.get(rollResult.results[0].data.resultId); } else { - await existingItem.update({ "data.quantity": itemQtyRoll.total }); - if (!this.reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added new ${itemQtyRoll.total} x ${newItem.name}.`); + const items = game.packs.get(rollResult.results[0].data.collection); + newItem = await items.getDocument(rollResult.results[0].data.resultId); } - } else { - console.log(moduleNamespace + `: Item ${newItem.name} exists.`); - - let newQty = Number(existingItem.data.data.quantity) + Number(itemQtyRoll.total); - - if (itemQtyLimit > 0 && Number(itemQtyLimit) === Number(existingItem.data.data.quantity)) { - if (!this.reducedVerbosity) ui.notifications.info(moduleNamespace + `: ${newItem.name} already at maximum quantity (${this.itemQtyLimit}).`); + + newItem = await tableHelper._rollSubTables(newItem); + + if (!newItem || newItem === null) { + return; } - else if (this.itemQtyLimit > 0 && Number(this.itemQtyLimit) < Number(newQty)) { - //console.log("Exceeds existing quantity, limiting"); - await existingItem.update({ "data.quantity": this.itemQtyLimit }); - - if (!this.reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added additional quantity to ${newItem.name} to the specified maximum of ${this.itemQtyLimit}.`); + + if (newItem.type === "spell") { + newItem = await Item5e.createScrollFromSpell(newItem); + } + + let itemQtyRoll = new Roll(itemQtyFormula); + itemQtyRoll.roll(); + + if (!reducedVerbosity) console.log(moduleNamespace + `: Adding ${itemQtyRoll.total} x ${newItem.name}`); + + let existingItem = tokenActor.items.find(item => item.data.name == newItem.name); + + if (existingItem === undefined) { + await tokenActor.createEmbeddedDocuments("Item", [newItem.toObject()]); + //console.log(moduleNamespace + `: ${newItem.name} does not exist.`); + existingItem = await tokenActor.items.find(item => item.data.name == newItem.name); + + if (itemQtyLimit > 0 && Number(itemQtyLimit) < Number(itemQtyRoll.total)) { + await existingItem.update({ "data.quantity": itemQtyLimit }); + if (!reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added new ${itemQtyLimit} x ${newItem.name}.`); + } else { + await existingItem.update({ "data.quantity": itemQtyRoll.total }); + if (!reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added new ${itemQtyRoll.total} x ${newItem.name}.`); + } } else { - await existingItem.update({ "data.quantity": newQty }); - if (!this.reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added additional ${itemQtyRoll.total} quantity to ${newItem.name}.`); + if (!reducedVerbosity) console.log(moduleNamespace + `: Item ${newItem.name} exists.`); + + let newQty = Number(existingItem.data.data.quantity) + Number(itemQtyRoll.total); + + if (itemQtyLimit > 0 && Number(itemQtyLimit) === Number(existingItem.data.data.quantity)) { + if (!reducedVerbosity) ui.notifications.info(moduleNamespace + `: ${newItem.name} already at maximum quantity (${itemQtyLimit}).`); + } + else if (itemQtyLimit > 0 && Number(itemQtyLimit) < Number(newQty)) { + //console.log("Exceeds existing quantity, limiting"); + await existingItem.update({ "data.quantity": itemQtyLimit }); + + if (!reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added additional quantity to ${newItem.name} to the specified maximum of ${itemQtyLimit}.`); + } else { + await existingItem.update({ "data.quantity": newQty }); + if (!reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added additional ${itemQtyRoll.total} quantity to ${newItem.name}.`); + } } } - } - } else { - // Get a list which contains indexes of all possible results - const rolltableIndexes = []; - - // Add one entry for each weight an item has - for (let index in [...Array(rolltable.results.length).keys()]) { - let numberOfEntries = rolltable.data.results[index].weight; - for (let i = 0; i < numberOfEntries; i++) { - rolltableIndexes.push(index); - } - } - - // Shuffle the list of indexes - var currentIndex = rolltableIndexes.length, temporaryValue, randomIndex; - - // While there remain elements to shuffle... - while (0 !== currentIndex) { - - // Pick a remaining element... - randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex -= 1; - - // And swap it with the current element. - temporaryValue = rolltableIndexes[currentIndex]; - rolltableIndexes[currentIndex] = rolltableIndexes[randomIndex]; - rolltableIndexes[randomIndex] = temporaryValue; - } - - // console.log(`Rollables: ${rolltableIndexes}`) - - let indexesToUse = []; - let numberOfAdditionalItems = 0; - // Get the first N entries from our shuffled list. Those are the indexes of the items in the roll table we want to add - // But because we added multiple entries per index to account for weighting, we need to increase our list length until we got enough unique items - while (true) { - let usedEntries = rolltableIndexes.slice(0, shopQtyRoll.total + numberOfAdditionalItems); - // console.log(`Distinct: ${usedEntries}`); - let distinctEntries = [...new Set(usedEntries)]; - - if (distinctEntries.length < shopQtyRoll.total) { - numberOfAdditionalItems++; - continue; - } - - indexesToUse = distinctEntries; - break; - } - - for (const index of indexesToUse) { - let itemQtyRoll = new Roll(this.itemQtyFormula); - itemQtyRoll.roll(); - - let newItem = null; - - if (rolltable.results[index].collection === "Item") { - newItem = game.items.get(rolltable.results[index].resultId); - } else { - //Try to find it in the compendium - const items = game.packs.get(rolltable.results[index].data.collection); - newItem = await items.getDocument(rollResult.results[0].data.resultId); + } else { + // Get a list which contains indexes of all possible results + const rolltableIndexes = []; + + // Add one entry for each weight an item has + for (let index in [...Array(rolltable.results.length).keys()]) { + let numberOfEntries = rolltable.data.results[index].weight; + for (let i = 0; i < numberOfEntries; i++) { + rolltableIndexes.push(index); + } } - - newItem = await tableHelper._rollSubTables(newItem, index); - - if (!newItem || newItem === null) { - return ui.notifications.error(moduleNamespace + `: No item found "${rolltable.results[index].resultId}".`); + + // Shuffle the list of indexes + var currentIndex = rolltableIndexes.length, temporaryValue, randomIndex; + + // While there remain elements to shuffle... + while (0 !== currentIndex) { + + // Pick a remaining element... + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + + // And swap it with the current element. + temporaryValue = rolltableIndexes[currentIndex]; + rolltableIndexes[currentIndex] = rolltableIndexes[randomIndex]; + rolltableIndexes[randomIndex] = temporaryValue; } - - if (newItem.type === "spell") { - newItem = await Item5e.createScrollFromSpell(newItem); + + // console.log(`Rollables: ${rolltableIndexes}`) + + let indexesToUse = []; + let numberOfAdditionalItems = 0; + // Get the first N entries from our shuffled list. Those are the indexes of the items in the roll table we want to add + // But because we added multiple entries per index to account for weighting, we need to increase our list length until we got enough unique items + while (true) { + let usedEntries = rolltableIndexes.slice(0, shopQtyRoll.total + numberOfAdditionalItems); + // console.log(`Distinct: ${usedEntries}`); + let distinctEntries = [...new Set(usedEntries)]; + + if (distinctEntries.length < shopQtyRoll.total) { + numberOfAdditionalItems++; + continue; + } + + indexesToUse = distinctEntries; + break; } - - await item.createEmbeddedDocuments("Item", [newItem.toObject()]); - let existingItem = this.actor.items.find(item => item.data.name == newItem.name); - - if (this.itemQtyLimit > 0 && Number(this.itemQtyLimit) < Number(itemQtyRoll.total)) { - await existingItem.update({ "data.quantity": this.itemQtyLimit }); - if (!this.reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added new ${this.itemQtyLimit} x ${newItem.name}.`); - } else { - await existingItem.update({ "data.quantity": itemQtyRoll.total }); - if (!this.reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added new ${itemQtyRoll.total} x ${newItem.name}.`); + + for (const index of indexesToUse) { + let itemQtyRoll = new Roll(itemQtyFormula); + itemQtyRoll.roll(); + + let newItem = null; + + if (rolltable.results[index].collection === "Item") { + newItem = game.items.get(rolltable.results[index].resultId); + } else { + //Try to find it in the compendium + const items = game.packs.get(rolltable.results[index].data.collection); + newItem = await items.getDocument(rollResult.results[0].data.resultId); + } + + newItem = await tableHelper._rollSubTables(newItem, index); + + if (!newItem || newItem === null) { + return ui.notifications.error(moduleNamespace + `: No item found "${rolltable.results[index].resultId}".`); + } + + if (newItem.type === "spell") { + newItem = await Item5e.createScrollFromSpell(newItem); + } + + await item.createEmbeddedDocuments("Item", [newItem.toObject()]); + let existingItem = tokenActor.items.find(item => item.data.name == newItem.name); + + if (itemQtyLimit > 0 && Number(itemQtyLimit) < Number(itemQtyRoll.total)) { + await existingItem.update({ "data.quantity": itemQtyLimit }); + if (!reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added new ${itemQtyLimit} x ${newItem.name}.`); + } else { + await existingItem.update({ "data.quantity": itemQtyRoll.total }); + if (!reducedVerbosity) ui.notifications.info(moduleNamespace + `: Added new ${itemQtyRoll.total} x ${newItem.name}.`); + } } } - } - - let currencyFlags = { - "generateCurrency": this._getSetting('generateCurrency'), - "lootCurrencyDefault": this._getSetting('lootCurrencyDefault'), - "useBetterRolltables": this._getSetting("useBetterRolltables"), - "brt_rt_tcs": rolltable.getFlag('better-rolltables', 'table-currency-string'), - "adjustCurrency": this._getSetting("adjustCurrencyWithCR") - }; - - await Currency._handleCurrency(this.actor,currencyFlags); } + /** + * + * @param {string} setting + * + * @returns {*} Setting + */ _getSetting(setting) { return game.settings.get(moduleNamespace, setting); } From 74661bb74705b942c02e40857558ba2c98e85ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Tue, 19 Oct 2021 23:14:05 +0200 Subject: [PATCH 9/9] deleted release yml --- .github/release.yml | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 .github/release.yml diff --git a/.github/release.yml b/.github/release.yml deleted file mode 100644 index 032ba01..0000000 --- a/.github/release.yml +++ /dev/null @@ -1,38 +0,0 @@ -on: - push: - # Sequence of patterns matched against refs/tags - tags: - - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 - -name: Upload Release Asset - -jobs: - build: - name: Upload Release Asset - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - name: Zip files - run: | - zip -r compendium-browser ./dist/ * -x "img/*" ".github/*" ".idea/*" "tsconfig.json" - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} - draft: false - prerelease: false - - name: Upload Release Asset - id: upload-release-asset - uses: actions/upload-release-asset@v1.0.2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./compendium-browser.zip - asset_name: compendium-browser.zip - asset_content_type: application/zip