From 60638392ddd7b45bd6887d7aba2c3d9f95a9bc7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93dor=20Levente?= <70817607+Levente007@users.noreply.github.com> Date: Sat, 11 May 2024 00:02:18 +0200 Subject: [PATCH 1/2] Added Paladin's Sacred Weapon macro --- 5e/paladin_sacred_weapon.js | 126 ++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 5e/paladin_sacred_weapon.js diff --git a/5e/paladin_sacred_weapon.js b/5e/paladin_sacred_weapon.js new file mode 100644 index 0000000..81f73b6 --- /dev/null +++ b/5e/paladin_sacred_weapon.js @@ -0,0 +1,126 @@ +/* This macro is meant to automate the Sacred Weapon paladin Channel Divinity feature. +* This means that you get to decide which weapon from your inventory you want to buff. +* The macro automatically adds your Charisma modifier to the attackBonus field of the weapon. +* Also removes a Channel Divinity slot. If you have no slots you can't use the macro! +* (there is an option to not expend any slots also) +* If the effect is already on your weapon executing the macro a second time reverts the changes to the weapon. +* +* This macro uses the Warpgate modul!!! Whitout this modul the macro DOESN'T WORK! +* Make sure to install it from: https://foundryvtt.com/packages/warpgate +* This module is "closed" as of 2024/05/07 (yyyy/MM/dd) since the author quit, so if foundry changes something that ruins the module it means that this macro will no longer work. +* +* This macro uses the old data structure still not used from V10. +* The macro still works tho (V11 b315) +* +* Levente Ódor 2024/05/10 (yyyy/MM/dd) +* Discord: thecringeone +* Github: Levente007 +* Have fun slaying them dragons in them dungeons! +*/ + +// VARIABLES +let actor = canvas.tokens.controlled[0]?.actor || game.user.character; +let cha = token.document.actor.system.abilities.cha.mod; +const mutName = "Sacred Weapon"; + +// ON SECOND CLICK REMOVE BUFF +if (!!warpgate.mutationStack(token.document).getName(mutName)) { + await warpgate.revert(token.document, mutName); + return; +} + + +//VALIDATIONS +// check if the actor has this ability or not +if (actor?.data.items.find(i => i.name === "Channel Divinity: Sacred Weapon") === undefined){ + return ui.notifications.error(`No actor selected has the "Sacred Weapon" feature`); +} +// check if the actor has Channel Divinity charges left +if (actor?.data.items.find(i => i.name === "Channel Divinity").system.uses.value <= 0) { + return ui.notifications.error(`The selected actor has no more Channel Divinity charges left`); +} + +//LOGIC +// Create a Dialog box to select the weapon to buff +let optionsText = ""; // all weapons to choose from +let allWeapons = actor?.data.items.filter(entry => entry.type === "weapon"); +let i = 0 +for (; i < allWeapons.length; i++) { + optionsText += ``; +} +let confirmed = false; +new Dialog({ + title: "Sacred Weapon: Usage Configuration", + content: ` +
+ `, + buttons: { + one: { + icon: '', + label: "Buff", + callback: () => confirmed = true + }, + two: { + icon: '', + label: "Cancel", + callback: () => confirmed = false + } + }, + default: "Cancel", + close: html => { + if (confirmed) { + //remove Channel Divinity Slot + if(html.find('[name=consumeCheckbox]')[0].checked) { + const changedValue = actor?.data.items.find(i => i.name === "Channel Divinity").system.uses.value - 1; + const updates = { + embedded: { + Item: { + "Channel Divinity": { + "system": { + "uses": { + "value": changedValue + } + } + } + } + } + } + warpgate.mutate(token.document, updates, {}, {permanent: true}); + } + + weapon = allWeapons[parseInt(html.find('[name=weaponToBuff]')[0].value)]; + const originaAtckBonus = weapon.system.attack.bonus; + const updates = { + embedded: { + Item: { + [weapon.name]: { + "system": { + "attack": { + "bonus": (originaAtckBonus == 0 ? "" : originaAtckBonus + "+") + cha + } + } + } + } + } + } + warpgate.mutate(token.document, updates, {}, {name: mutName}); + } + } +}).render(true); \ No newline at end of file From 41aca4b9a46f7438e3767d052f6ca7064a5597b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93dor=20Levente?= <70817607+Levente007@users.noreply.github.com> Date: Tue, 12 Nov 2024 23:37:25 +0100 Subject: [PATCH 2/2] paladin sacred weapon v1.0 --- 5e/paladin_sacred_weapon.js | 104 ++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/5e/paladin_sacred_weapon.js b/5e/paladin_sacred_weapon.js index 81f73b6..da32386 100644 --- a/5e/paladin_sacred_weapon.js +++ b/5e/paladin_sacred_weapon.js @@ -1,51 +1,67 @@ /* This macro is meant to automate the Sacred Weapon paladin Channel Divinity feature. * This means that you get to decide which weapon from your inventory you want to buff. * The macro automatically adds your Charisma modifier to the attackBonus field of the weapon. -* Also removes a Channel Divinity slot. If you have no slots you can't use the macro! +* Also removes a Channel Divinity slot. If you have no slots left you can still use the macro, but it will drop an error. * (there is an option to not expend any slots also) * If the effect is already on your weapon executing the macro a second time reverts the changes to the weapon. + + +* Levente Ódor 2024/11/12 (yyyy/MM/dd) v1.0 +* Discord: thecringeone +* Github: Levente007 +* Dropped support for the old data structure. The macro now uses the new one. +* No longer using wapgate module. The macro is now standalone. * -* This macro uses the Warpgate modul!!! Whitout this modul the macro DOESN'T WORK! -* Make sure to install it from: https://foundryvtt.com/packages/warpgate -* This module is "closed" as of 2024/05/07 (yyyy/MM/dd) since the author quit, so if foundry changes something that ruins the module it means that this macro will no longer work. -* -* This macro uses the old data structure still not used from V10. -* The macro still works tho (V11 b315) * -* Levente Ódor 2024/05/10 (yyyy/MM/dd) +* Levente Ódor 2024/05/10 (yyyy/MM/dd) v0.1 * Discord: thecringeone * Github: Levente007 -* Have fun slaying them dragons in them dungeons! +* +* Have fun slaying them dragons in them dungeons! */ // VARIABLES -let actor = canvas.tokens.controlled[0]?.actor || game.user.character; +let actor = canvas.tokens.controlled[0]?.actor || game.user.character; let cha = token.document.actor.system.abilities.cha.mod; -const mutName = "Sacred Weapon"; // ON SECOND CLICK REMOVE BUFF -if (!!warpgate.mutationStack(token.document).getName(mutName)) { - await warpgate.revert(token.document, mutName); +if (actor?.flags.scweapon.active == true) { + // remove buffs + let weapon = actor?.items.get(actor?.flags.scweapon.weaponId); + weapon.update({"system.attack.bonus": actor?.flags.scweapon.originaAtckBonus}); + if (!actor?.flags.scweapon.wasMgc) { + let properties = weapon.system.properties; + properties.delete('mgc'); + weapon.update({"system.properties": properties}); + } + //remove flag + actor?.update({'flags.scweapon': {'active': false, 'weaponId': '', 'originaAtckBonus': '', 'wasMgc': ''}}); return; } - //VALIDATIONS // check if the actor has this ability or not -if (actor?.data.items.find(i => i.name === "Channel Divinity: Sacred Weapon") === undefined){ +function find(findName, map) { + for (let [key, value] of map) { + if (value.name === findName && value.system.activation.type != '') { // paladin gets 2 features named 'Channel Divinity' for this reason we must find the one that has an action which is the real one + return value; + } + } + return undefined; +} +if (find("Sacred Weapon", actor?.sourcedItems.entries()) === undefined) { return ui.notifications.error(`No actor selected has the "Sacred Weapon" feature`); } // check if the actor has Channel Divinity charges left -if (actor?.data.items.find(i => i.name === "Channel Divinity").system.uses.value <= 0) { - return ui.notifications.error(`The selected actor has no more Channel Divinity charges left`); +else if (find("Channel Divinity", actor?.sourcedItems.entries()).system.uses.value <= 0) { + ui.notifications.error(`The selected actor has no more Channel Divinity charges left`); } //LOGIC // Create a Dialog box to select the weapon to buff let optionsText = ""; // all weapons to choose from -let allWeapons = actor?.data.items.filter(entry => entry.type === "weapon"); -let i = 0 -for (; i < allWeapons.length; i++) { +let allWeapons = actor?.items.filter(entry => entry.type === "weapon"); +for (let i = 0; i < allWeapons.length; i++) { optionsText += ``; } let confirmed = false; @@ -86,41 +102,23 @@ new Dialog({ default: "Cancel", close: html => { if (confirmed) { - //remove Channel Divinity Slot - if(html.find('[name=consumeCheckbox]')[0].checked) { - const changedValue = actor?.data.items.find(i => i.name === "Channel Divinity").system.uses.value - 1; - const updates = { - embedded: { - Item: { - "Channel Divinity": { - "system": { - "uses": { - "value": changedValue - } - } - } - } - } - } - warpgate.mutate(token.document, updates, {}, {permanent: true}); - } - + // remove Channel Divinity Slot + const changedValue = find("Channel Divinity", actor?.sourcedItems.entries()).system.uses.value - 1; + find("Channel Divinity", actor?.sourcedItems.entries()).update({"system.uses.value": changedValue}); + // add cha to selected weapon weapon = allWeapons[parseInt(html.find('[name=weaponToBuff]')[0].value)]; const originaAtckBonus = weapon.system.attack.bonus; - const updates = { - embedded: { - Item: { - [weapon.name]: { - "system": { - "attack": { - "bonus": (originaAtckBonus == 0 ? "" : originaAtckBonus + "+") + cha - } - } - } - } - } + weapon.update({"system.attack.bonus": (originaAtckBonus == 0 ? "" : originaAtckBonus + "+") + cha}); + // add the magical propertie if not already there + let wasMgc = true; + if (find('mgc', weapon.system.properties) === undefined) { + wasMgc = false; + let properties = weapon.system.properties; + properties.add('mgc'); + weapon.update({"system.properties": properties}); } - warpgate.mutate(token.document, updates, {}, {name: mutName}); - } + //add flag hat effect is active + actor?.update({'flags.scweapon': {'active': true, 'weaponId': weapon.id, 'originaAtckBonus': originaAtckBonus, 'wasMgc': wasMgc}}); + } } }).render(true); \ No newline at end of file