This repository has been archived on 2023-04-01. You can view files and clone it, but cannot push or open issues or pull requests.
foundrybackup_james_archive_1/worlds/der-fluch-der-verlorenen-stadt/data/macros.db
2023-03-29 09:56:24 +02:00

6 lines
48 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"name":"Active Aura Only (Generic)","type":"script","img":"icons/svg/dice-target.svg","scope":"global","command":"if(!game.modules.get(\"ActiveAuras\")?.active) {\n ui.notifications.error(\"ActiveAuras is not enabled\");\n return;\n}\n\nconst lastArg = args[args.length - 1];\n\nasync function wait(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); }\n\nasync function attemptRemoval(targetToken, condition, item) {\n if (game.dfreds.effectInterface.hasEffectApplied(condition, targetToken.document.uuid)) {\n new Dialog({\n title: `Use action to attempt to remove ${condition}?`,\n buttons: {\n one: {\n label: \"Yes\",\n callback: async () => {\n const caster = item.parent;\n const saveDc = caster.system.attributes.spelldc;\n const removalCheck = item.flags.ddbimporter.effect.removalCheck;\n const removalSave = item.flags.ddbimporter.effect.removalSave;\n const ability = removalCheck ? removalCheck : removalSave;\n const type = removalCheck ? \"check\" : \"save\";\n const flavor = `${condition} (via ${item.name}) : ${CONFIG.DND5E.abilities[ability]} ${type} vs DC${saveDc}`;\n const rollResult = removalCheck\n ? (await targetToken.actor.rollAbilityTest(ability, { flavor })).total\n : (await targetToken.actor.rollAbilitySave(ability, { flavor })).total;\n\n if (rollResult >= saveDc) {\n game.dfreds.effectInterface.removeEffect({ effectName: condition, uuid: targetToken.document.uuid });\n } else {\n if (rollResult < saveDc) ChatMessage.create({ content: `${targetToken.name} fails the ${type} for ${item.name}, still has the ${condition} condition.` });\n }\n },\n },\n two: {\n label: \"No\",\n callback: () => {},\n },\n },\n }).render(true);\n }\n}\n\nasync function applyCondition(condition, targetToken, item, itemLevel) {\n if (!game.dfreds.effectInterface.hasEffectApplied(condition, targetToken.document.uuid)) {\n const caster = item.parent;\n const workflowItemData = duplicate(item.data);\n workflowItemData.system.target = { value: 1, units: \"\", type: \"creature\" };\n workflowItemData.system.save.ability = item.flags.ddbimporter.effect.save;\n workflowItemData.system.components.concentration = false;\n workflowItemData.system.level = itemLevel;\n workflowItemData.system.duration = { value: null, units: \"inst\" };\n workflowItemData.system.target = { value: null, width: null, units: \"\", type: \"creature\" };\n workflowItemData.system.preparation.mode = \"atwill\";\n setProperty(workflowItemData, \"flags.itemacro\", {});\n setProperty(workflowItemData, \"flags.midi-qol\", {});\n setProperty(workflowItemData, \"flags.dae\", {});\n setProperty(workflowItemData, \"effects\", []);\n delete workflowItemData._id;\n workflowItemData.name = `${workflowItemData.name}: ${item.name} Condition save`;\n // console.warn(\"workflowItemData\", workflowItemData);\n\n const saveTargets = [...game.user?.targets].map((t )=> t.id);\n game.user.updateTokenTargets([targetToken.id]);\n const saveItem = new CONFIG.Item.documentClass(workflowItemData, { parent: caster });\n const options = { showFullCard: false, createWorkflow: true, configureDialog: true };\n const result = await MidiQOL.completeItemRoll(saveItem, options);\n\n game.user.updateTokenTargets(saveTargets);\n const failedSaves = [...result.failedSaves];\n if (failedSaves.length > 0) {\n await game.dfreds.effectInterface.addEffect({ effectName: condition, uuid: failedSaves[0].document.uuid });\n }\n\n return result;\n }\n}\n\nasync function attachSequencerFileToTemplate(templateUuid, sequencerFile, originUuid) {\n if (game.modules.get(\"sequencer\")?.active) {\n if (Sequencer.Database.entryExists(sequencerFile)) {\n console.debug(`Trying to apply sequencer effect (${sequencerFile}) to ${templateUuid} from ${originUuid}`, sequencerFile);\n const template = await fromUuid(templateUuid);\n new Sequence()\n .effect()\n .file(Sequencer.Database.entryExists(sequencerFile))\n .size({\n width: canvas.grid.size * (template.data.width / canvas.dimensions.distance),\n height: canvas.grid.size * (template.data.width / canvas.dimensions.distance),\n })\n .persist(true)\n .origin(originUuid)\n .belowTokens()\n .opacity(0.5)\n .attachTo(template, { followRotation: true })\n .stretchTo(template, { attachTo: true})\n .play();\n }\n }\n}\n\nif (args[0].tag === \"OnUse\" && args[0].macroPass === \"preActiveEffects\") {\n const safeName = lastArg.itemData.name.replace(/\\s|'|\\.|/g, \"_\");\n const dataTracker = {\n randomId: randomID(),\n targetUuids: lastArg.targetUuids,\n startRound: game.combat.round,\n startTurn: game.combat.turn,\n spellLevel: lastArg.spellLevel,\n };\n\n const item = await fromUuid(lastArg.itemUuid);\n // await item.update(dataTracker);\n await DAE.unsetFlag(item, `${safeName}Tracker`);\n await DAE.setFlag(item, `${safeName}Tracker`, dataTracker);\n\n const sequencerFile = lastArg.item.flags.ddbimporter?.effect?.sequencerFile;\n if (sequencerFile) {\n attachSequencerFileToTemplate(lastArg.templateUuid, sequencerFile, lastArg.itemUuid)\n }\n\n if (lastArg.item.flags.ddbimporter?.effect?.applyImmediate) {\n await wait(500);\n const condition = lastArg.item.flags.ddbimporter.effect.condition;\n for (const token of lastArg.failedSaves) {\n if (!game.dfreds.effectInterface.hasEffectApplied(condition, token.actor.uuid)) {\n console.debug(`Applying ${condition} to ${token.name}`);\n await game.dfreds.effectInterface.addEffect({ effectName: condition, uuid: token.actor.uuid });\n }\n };\n }\n\n return await AAhelpers.applyTemplate(args);\n\n} else if (args[0].tag === \"OnUse\" && args[0].macroPass === \"postActiveEffects\") {\n if (lastArg.item.flags.ddbimporter?.effect?.applyImmediate) {\n const condition = lastArg.item.flags.ddbimporter.effect.condition;\n for (const token of lastArg.failedSaves) {\n if (!game.dfreds.effectInterface.hasEffectApplied(condition, token.actor.uuid)) {\n console.debug(`Applying ${condition} to ${token.name}`);\n await game.dfreds.effectInterface.addEffect({ effectName: condition, uuid: token.actor.uuid });\n }\n };\n }\n} else if (args[0] == \"on\" || args[0] == \"each\") {\n const safeName = lastArg.efData.label.replace(/\\s|'|\\.|/g, \"_\");\n const item = await fromUuid(lastArg.efData.origin);\n // sometimes the round info has not updated, so we pause a bit\n if (args[0] == \"each\") await wait(500);\n const targetItemTracker = DAE.getFlag(item.parent, `${safeName}Tracker`);\n const originalTarget = targetItemTracker.targetUuids.includes(lastArg.tokenUuid);\n const target = canvas.tokens.get(lastArg.tokenId);\n const targetTokenTrackerFlag = DAE.getFlag(target, `${safeName}Tracker`);\n const targetedThisCombat = targetTokenTrackerFlag && targetItemTracker.randomId === targetTokenTrackerFlag.randomId;\n const targetTokenTracker = targetedThisCombat\n ? targetTokenTrackerFlag\n : {\n randomId: targetItemTracker.randomId,\n round: game.combat.round,\n turn: game.combat.turn,\n hasLeft: false,\n condition: item.flags.ddbimporter.effect.condition,\n };\n\n const castTurn = targetItemTracker.startRound === game.combat.round && targetItemTracker.startTurn === game.combat.turn;\n const isLaterTurn = game.combat.round > targetTokenTracker.round || game.combat.turn > targetTokenTracker.turn;\n const everyEntry = hasProperty(item.data, \"flags.ddbimporter.effect.everyEntry\")\n ? item.flags.ddbimporter.effect.everyEntry\n : false;\n\n // if:\n // not cast turn, and not part of the original target\n // AND one of the following\n // not original template and have not yet had this effect applied this combat OR\n // has been targeted this combat, left and re-entered effect, and is a later turn\n\n if (castTurn && originalTarget) {\n console.debug(`Token ${target.name} is part of the original target for ${item.name}`);\n } else if (everyEntry || !targetedThisCombat || (targetedThisCombat && isLaterTurn)) {\n console.debug(`Token ${target.name} is targeted for immediate save vs condition with ${item.name}, using the following factors`, { originalTarget, castTurn, targetedThisCombat, targetTokenTracker, isLaterTurn });\n targetTokenTracker.hasLeft = false;\n await applyCondition(targetTokenTracker.condition, target, item, targetItemTracker.spellLevel);\n }\n await DAE.setFlag(target, `${safeName}Tracker`, targetTokenTracker);\n const allowVsRemoveCondition = item.flags.ddbimporter.effect.allowVsRemoveCondition;\n const effectApplied = game.dfreds.effectInterface.hasEffectApplied(targetTokenTracker.condition, target.document.uuid);\n const currentTokenCombatTurn = game.combat.current.tokenId === lastArg.tokenId;\n if (currentTokenCombatTurn && allowVsRemoveCondition && effectApplied) {\n console.warn(`Removing ${targetTokenTracker.condition}`);\n await attemptRemoval(target, targetTokenTracker.condition, item);\n }\n} else if (args[0] == \"off\") {\n const safeName = lastArg.efData.label.replace(/\\s|'|\\.|/g, \"_\");\n const targetToken = await fromUuid(lastArg.tokenUuid);\n const targetTokenTracker = await DAE.getFlag(targetToken, `${safeName}Tracker`);\n const removeOnOff = hasProperty(lastArg, \"efData.flags.ddbimporter.effect.removeOnOff\")\n ? lastArg.efData.flags.ddbimporter.effect.removeOnOff\n : true;\n\n if (targetTokenTracker?.condition && removeOnOff && game.dfreds.effectInterface.hasEffectApplied(targetTokenTracker.condition, lastArg.tokenUuid)) {\n console.debug(`Removing ${targetTokenTracker.condition} from ${targetToken.name}`);\n game.dfreds.effectInterface.removeEffect({ effectName: targetTokenTracker.condition, uuid: lastArg.tokenUuid });\n }\n\n if (targetTokenTracker) {\n targetTokenTracker.hasLeft = true;\n targetTokenTracker.turn = game.combat.turn;\n targetTokenTracker.round = game.combat.round;\n await DAE.setFlag(targetToken, `${safeName}Tracker`, targetTokenTracker);\n }\n}","folder":"Xnvpa6bGFYi4yoqK","flags":{"advanced-macros":{"runAsGM":false}},"author":"xOFiqDVDAkPwiqtI","sort":0,"ownership":{"default":0,"xOFiqDVDAkPwiqtI":3},"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.291","createdTime":1672646160256,"modifiedTime":1672646160256,"lastModifiedBy":"xOFiqDVDAkPwiqtI"},"_id":"8ewUgzM0IbTcfc2J"}
{"name":"Active Aura Damage On Entry (Generic)","type":"script","img":"icons/svg/dice-target.svg","scope":"global","command":"if(!game.modules.get(\"ActiveAuras\")?.active) {\n ui.notifications.error(\"ActiveAuras is not enabled\");\n return;\n}\n\nconsole.warn(args)\n\nconst lastArg = args[args.length - 1];\n\nfunction getCantripDice(actor) {\n const level = actor.type === \"character\" ? actor.system.details.level : actor.system.details.cr;\n return 1 + Math.floor((level + 1) / 6);\n}\n\nasync function rollItemDamage(targetToken, itemUuid, itemLevel) {\n const item = await fromUuid(itemUuid);\n const caster = item.parent;\n const ddbEffectFlags = item.flags.ddbimporter.effect;\n const isCantrip = ddbEffectFlags.isCantrip;\n const damageDice = ddbEffectFlags.dice;\n const damageType = ddbEffectFlags.damageType;\n const saveAbility = ddbEffectFlags.save;\n const casterToken = canvas.tokens.placeables.find((t) => t.actor?.uuid === caster.uuid);\n const scalingDiceArray = item.system.scaling.formula.split(\"d\");\n const scalingDiceNumber = itemLevel - item.system.level;\n const upscaledDamage = isCantrip\n ? `${getCantripDice(caster.data)}d${scalingDiceArray[1]}[${damageType}]`\n : scalingDiceNumber > 0 ? `${scalingDiceNumber}d${scalingDiceArray[1]}[${damageType}] + ${damageDice}` : damageDice;\n\n const workflowItemData = duplicate(item.data);\n workflowItemData.system.target = { value: 1, units: \"\", type: \"creature\" };\n workflowItemData.system.save.ability = saveAbility;\n workflowItemData.system.components.concentration = false;\n workflowItemData.system.level = itemLevel;\n workflowItemData.system.duration = { value: null, units: \"inst\" };\n workflowItemData.system.target = { value: null, width: null, units: \"\", type: \"creature\" };\n\n setProperty(workflowItemData, \"flags.itemacro\", {});\n setProperty(workflowItemData, \"flags.midi-qol\", {});\n setProperty(workflowItemData, \"flags.dae\", {});\n setProperty(workflowItemData, \"effects\", []);\n delete workflowItemData._id;\n\n const saveOnEntry = ddbEffectFlags.saveOnEntry;\n console.warn(\"saveOnEntry\", {ddbEffectFlags, saveOnEntry});\n if (saveOnEntry) {\n const entryItem = new CONFIG.Item.documentClass(workflowItemData, { parent: caster });\n console.warn(\"Saving item on entry\", {entryItem, targetToken});\n const options = {\n showFullCard: false,\n createWorkflow: true,\n targetUuids: [targetToken.document.uuid],\n configureDialog: false,\n versatile: false,\n consumeResource: false,\n consumeSlot: false,\n };\n await MidiQOL.completeItemRoll(entryItem, options);\n } else {\n const damageRoll = await new Roll(upscaledDamage).evaluate({ async: true });\n if (game.dice3d) game.dice3d.showForRoll(damageRoll);\n\n workflowItemData.name = `${workflowItemData.name}: Turn Entry Damage`;\n // console.warn(\"workflowItemData\", workflowItemData);\n\n await new MidiQOL.DamageOnlyWorkflow(\n caster,\n casterToken,\n damageRoll.total,\n damageType,\n [targetToken],\n damageRoll,\n {\n flavor: `(${CONFIG.DND5E.damageTypes[damageType]})`,\n itemCardId: \"new\",\n itemData: workflowItemData,\n isCritical: false,\n }\n );\n }\n\n}\n\nasync function attachSequencerFileToTemplate(templateUuid, sequencerFile, originUuid) {\n if (game.modules.get(\"sequencer\")?.active) {\n if (Sequencer.Database.entryExists(sequencerFile)) {\n console.debug(\"Trying to apply sequencer effect\", {sequencerFile, templateUuid});\n const template = await fromUuid(templateUuid);\n new Sequence()\n .effect()\n .file(Sequencer.Database.entryExists(sequencerFile))\n .size({\n width: canvas.grid.size * (template.data.width / canvas.dimensions.distance),\n height: canvas.grid.size * (template.data.width / canvas.dimensions.distance),\n })\n .persist(true)\n .origin(originUuid)\n .belowTokens()\n .opacity(0.5)\n .attachTo(template, { followRotation: true })\n .stretchTo(template, { attachTo: true})\n .play();\n }\n }\n}\n\nif (args[0].tag === \"OnUse\" && args[0].macroPass === \"preActiveEffects\") {\n const safeName = lastArg.itemData.name.replace(/\\s|'|\\.|/g, \"_\");\n const dataTracker = {\n randomId: randomID(),\n targetUuids: lastArg.targetUuids,\n startRound: game.combat.round,\n startTurn: game.combat.turn,\n spellLevel: lastArg.spellLevel,\n };\n\n const item = await fromUuid(lastArg.itemUuid);\n await DAE.unsetFlag(item, `${safeName}Tracker`);\n await DAE.setFlag(item, `${safeName}Tracker`, dataTracker);\n\n const ddbEffectFlags = lastArg.item.flags.ddbimporter?.effect;\n\n if (ddbEffectFlags) {\n const sequencerFile = ddbEffectFlags.sequencerFile;\n if (sequencerFile) {\n attachSequencerFileToTemplate(lastArg.templateUuid, sequencerFile, lastArg.itemUuid)\n }\n if (ddbEffectFlags.isCantrip) {\n const cantripDice = getCantripDice(lastArg.actor);\n args[0].spellLevel = cantripDice;\n ddbEffectFlags.cantripDice = cantripDice;\n let newEffects = args[0].item.effects.map((effect) => {\n effect.changes = effect.changes.map((change) => {\n change.value = change.value.replace(\"@cantripDice\", cantripDice)\n return change;\n });\n return effect;\n });\n args[0].item.effects = duplicate(newEffects);\n args[0].itemData.effects = duplicate(newEffects);\n }\n const template = await fromUuid(lastArg.templateUuid);\n await template.update({\"flags.effect\": ddbEffectFlags});\n }\n\n return await AAhelpers.applyTemplate(args);\n\n} else if (args[0] == \"on\") {\n const safeName = lastArg.efData.label.replace(/\\s|'|\\.|/g, \"_\");\n const item = await fromUuid(lastArg.efData.origin);\n const targetItemTracker = DAE.getFlag(item.parent, `${safeName}Tracker`);\n const originalTarget = targetItemTracker.targetUuids.includes(lastArg.tokenUuid);\n const target = canvas.tokens.get(lastArg.tokenId);\n const targetTokenTrackerFlag = DAE.getFlag(target, `${safeName}Tracker`);\n const targetedThisCombat = targetTokenTrackerFlag && targetItemTracker.randomId === targetTokenTrackerFlag.randomId;\n const targetTokenTracker = targetedThisCombat\n ? targetTokenTrackerFlag\n : {\n randomId: targetItemTracker.randomId,\n round: game.combat.round,\n turn: game.combat.turn,\n hasLeft: false,\n };\n\n const castTurn = targetItemTracker.startRound === game.combat.round && targetItemTracker.startTurn === game.combat.turn;\n const isLaterTurn = game.combat.round > targetTokenTracker.round || game.combat.turn > targetTokenTracker.turn;\n\n // if:\n // not cast turn, and not part of the original target\n // AND one of the following\n // not original template and have not yet had this effect applied this combat OR\n // has been targeted this combat, left and re-entered effect, and is a later turn\n if (castTurn && originalTarget) {\n console.debug(`Token ${target.name} is part of the original target for ${item.name}`);\n } else if (!targetedThisCombat || (targetedThisCombat && targetTokenTracker.hasLeft && isLaterTurn)){\n console.debug(`Token ${target.name} is targeted for immediate damage with ${item.name}, using the following factors`, { originalTarget, castTurn, targetedThisCombat, targetTokenTracker, isLaterTurn });\n targetTokenTracker.hasLeft = false;\n await rollItemDamage(target, lastArg.efData.origin, targetItemTracker.spellLevel);\n }\n await DAE.setFlag(target, `${safeName}Tracker`, targetTokenTracker);\n} else if (args[0] == \"off\") {\n const safeName = lastArg.efData.label.replace(/\\s|'|\\.|/g, \"_\");\n const target = canvas.tokens.get(lastArg.tokenId);\n const targetTokenTracker = DAE.getFlag(target, `${safeName}Tracker`);\n\n if (targetTokenTracker) {\n targetTokenTracker.hasLeft = true;\n targetTokenTracker.turn = game.combat.turn;\n targetTokenTracker.round = game.combat.round;\n await DAE.setFlag(target, `${safeName}Tracker`, targetTokenTracker);\n }\n}","folder":"Xnvpa6bGFYi4yoqK","flags":{"advanced-macros":{"runAsGM":false}},"author":"xOFiqDVDAkPwiqtI","sort":0,"ownership":{"default":0,"xOFiqDVDAkPwiqtI":3},"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.291","createdTime":1672646161120,"modifiedTime":1672646161120,"lastModifiedBy":"xOFiqDVDAkPwiqtI"},"_id":"IfxT63Ay2HWaSmWC"}
{"name":"Active Aura Damage and Condition On Entry (Generic)","type":"script","img":"icons/svg/dice-target.svg","scope":"global","command":"if(!game.modules.get(\"ActiveAuras\")?.active) {\n ui.notifications.error(\"ActiveAuras is not enabled\");\n return;\n}\n\nconst lastArg = args[args.length - 1];\n\nasync function wait(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); }\n\nfunction getHighestAbility(actor, abilities) {\n if (typeof abilities === \"string\") {\n return abilities;\n } else if (Array.isArray(abilities)) {\n return abilities.reduce((prv, current) => {\n if (actor.system.abilities[current].value > actor.system.abilities[prv].value) return current;\n else return prv;\n }, abilities[0]);\n }\n}\n\nfunction getCantripDice(actor) {\n const level = actor.type === \"character\" ? actor.system.details.level : actor.system.details.cr;\n return 1 + Math.floor((level + 1) / 6);\n}\n\n\nasync function attemptRemoval(targetToken, condition, item) {\n if (game.dfreds.effectInterface.hasEffectApplied(condition, targetToken.document.uuid)) {\n new Dialog({\n title: `Use action to attempt to remove ${condition}?`,\n buttons: {\n one: {\n label: \"Yes\",\n callback: async () => {\n const caster = item.parent;\n const saveDc = caster.system.attributes.spelldc;\n const removalCheck = item.system.flags.ddbimporter.effect.removalCheck;\n const removalSave = item.system.flags.ddbimporter.effect.removalSave;\n const ability = removalCheck ? getHighestAbility(targetToken.actor.data, removalCheck) : getHighestAbility(targetToken.actor.data, removalSave);\n const type = removalCheck ? \"check\" : \"save\";\n const flavor = `${condition} (via ${item.name}) : ${CONFIG.DND5E.abilities[ability]} ${type} vs DC${saveDc}`;\n const rollResult = removalCheck\n ? (await targetToken.actor.rollAbilityTest(ability, { flavor })).total\n : (await targetToken.actor.rollAbilitySave(ability, { flavor })).total;\n\n if (rollResult >= saveDc) {\n game.dfreds.effectInterface.removeEffect({ effectName: condition, uuid: targetToken.document.uuid });\n } else {\n if (rollResult < saveDc) ChatMessage.create({ content: `${targetToken.name} fails the ${type} for ${item.name}, still has the ${condition} condition.` });\n }\n },\n },\n two: {\n label: \"No\",\n callback: () => {},\n },\n },\n }).render(true);\n }\n}\n\nasync function applyCondition(condition, targetToken, item, itemLevel) {\n if (!game.dfreds.effectInterface.hasEffectApplied(condition, targetToken.document.uuid)) {\n const caster = item.parent;\n const workflowItemData = duplicate(item.data);\n workflowItemData.system.target = { value: 1, units: \"\", type: \"creature\" };\n workflowItemData.system.save.ability = item.flags.ddbimporter.effect.save;\n workflowItemData.system.components.concentration = false;\n workflowItemData.system.level = itemLevel;\n workflowItemData.system.duration = { value: null, units: \"inst\" };\n workflowItemData.system.target = { value: null, width: null, units: \"\", type: \"creature\" };\n workflowItemData.system.preparation.mode = \"atwill\";\n setProperty(workflowItemData, \"flags.itemacro\", {});\n setProperty(workflowItemData, \"flags.midi-qol\", {});\n setProperty(workflowItemData, \"flags.dae\", {});\n setProperty(workflowItemData, \"effects\", []);\n delete workflowItemData._id;\n workflowItemData.name = `${workflowItemData.name}: ${item.name} Condition save`;\n // console.warn(\"workflowItemData\", workflowItemData);\n\n const saveTargets = [...game.user?.targets].map((t )=> t.id);\n game.user.updateTokenTargets([targetToken.id]);\n const saveItem = new CONFIG.Item.documentClass(workflowItemData, { parent: caster });\n const options = { showFullCard: false, createWorkflow: true, configureDialog: true };\n const result = await MidiQOL.completeItemRoll(saveItem, options);\n\n game.user.updateTokenTargets(saveTargets);\n const failedSaves = [...result.failedSaves];\n if (failedSaves.length > 0) {\n await game.dfreds.effectInterface.addEffect({ effectName: condition, uuid: failedSaves[0].document.uuid });\n }\n\n return result;\n }\n}\n\nasync function attachSequencerFileToTemplate(templateUuid, sequencerFile, originUuid) {\n if (game.modules.get(\"sequencer\")?.active) {\n if (Sequencer.Database.entryExists(sequencerFile)) {\n console.debug(`Trying to apply sequencer effect (${sequencerFile}) to ${templateUuid} from ${originUuid}`, sequencerFile);\n const template = await fromUuid(templateUuid);\n new Sequence()\n .effect()\n .file(Sequencer.Database.entryExists(sequencerFile))\n .size({\n width: canvas.grid.size * (template.data.width / canvas.dimensions.distance),\n height: canvas.grid.size * (template.data.width / canvas.dimensions.distance),\n })\n .persist(true)\n .origin(originUuid)\n .belowTokens()\n .opacity(0.5)\n .attachTo(template, { followRotation: true })\n .stretchTo(template, { attachTo: true})\n .play();\n }\n }\n}\n\n\nasync function rollItemDamage(targetToken, itemUuid, itemLevel) {\n const item = await fromUuid(itemUuid);\n const caster = item.parent;\n const isCantrip = item.flags.ddbimporter.effect.isCantrip;\n const damageDice = item.flags.ddbimporter.effect.dice;\n const damageType = item.flags.ddbimporter.effect.damageType;\n const saveAbility = item.flags.ddbimporter.effect.save;\n const casterToken = canvas.tokens.placeables.find((t) => t.actor?.uuid === caster.uuid);\n const scalingDiceArray = item.system.scaling.formula.split(\"d\");\n const scalingDiceNumber = itemLevel - item.system.level;\n const upscaledDamage = isCantrip\n ? `${getCantripDice(caster.data)}d${scalingDiceArray[1]}[${damageType}]`\n : scalingDiceNumber > 0 ? `${scalingDiceNumber}d${scalingDiceArray[1]}[${damageType}] + ${damageDice}` : damageDice;\n const damageRoll = await new Roll(upscaledDamage).evaluate({ async: true });\n if (game.dice3d) game.dice3d.showForRoll(damageRoll);\n const workflowItemData = duplicate(item.data);\n workflowItemData.system.target = { value: 1, units: \"\", type: \"creature\" };\n workflowItemData.system.save.ability = saveAbility;\n workflowItemData.system.components.concentration = false;\n workflowItemData.system.level = itemLevel;\n workflowItemData.system.duration = { value: null, units: \"inst\" };\n workflowItemData.system.target = { value: null, width: null, units: \"\", type: \"creature\" };\n\n setProperty(workflowItemData, \"flags.itemacro\", {});\n setProperty(workflowItemData, \"flags.midi-qol\", {});\n setProperty(workflowItemData, \"flags.dae\", {});\n setProperty(workflowItemData, \"effects\", []);\n delete workflowItemData._id;\n workflowItemData.name = `${workflowItemData.name}: Turn Entry Damage`;\n // console.warn(\"workflowItemData\", workflowItemData);\n\n await new MidiQOL.DamageOnlyWorkflow(\n caster,\n casterToken,\n damageRoll.total,\n damageType,\n [targetToken],\n damageRoll,\n {\n flavor: `(${CONFIG.DND5E.damageTypes[damageType]})`,\n itemCardId: \"new\",\n itemData: workflowItemData,\n isCritical: false,\n }\n );\n}\n\nif (args[0].tag === \"OnUse\" && args[0].macroPass === \"preActiveEffects\") {\n const safeName = lastArg.itemData.name.replace(/\\s|'|\\.|/g, \"_\");\n const dataTracker = {\n randomId: randomID(),\n targetUuids: lastArg.targetUuids,\n startRound: game.combat.round,\n startTurn: game.combat.turn,\n spellLevel: lastArg.spellLevel,\n };\n\n const item = await fromUuid(lastArg.itemUuid);\n // await item.update(dataTracker);\n await DAE.unsetFlag(item, `${safeName}Tracker`);\n await DAE.setFlag(item, `${safeName}Tracker`, dataTracker);\n\n const ddbEffectFlags = lastArg.item.flags.ddbimporter?.effect;\n if (ddbEffectFlags) {\n const sequencerFile = ddbEffectFlags.sequencerFile;\n if (sequencerFile) {\n await attachSequencerFileToTemplate(lastArg.templateUuid, sequencerFile, lastArg.itemUuid)\n }\n if (ddbEffectFlags.isCantrip) {\n const cantripDice = getCantripDice(lastArg.actor);\n args[0].spellLevel = cantripDice;\n ddbEffectFlags.cantripDice = cantripDice;\n let newEffects = args[0].item.effects.map((effect) => {\n effect.changes = effect.changes.map((change) => {\n change.value = change.value.replace(\"@cantripDice\", cantripDice)\n return change;\n });\n return effect;\n });\n args[0].item.effects = duplicate(newEffects);\n args[0].itemData.effects = duplicate(newEffects);\n }\n const template = await fromUuid(lastArg.templateUuid);\n await template.update({\"flags.effect\": ddbEffectFlags});\n\n if (ddbEffectFlags.applyImmediate) {\n console.debug(\"Applying immediate effect\");\n await wait(500);\n const condition = ddbEffectFlags.condition;\n for (const token of lastArg.failedSaves) {\n if (!game.dfreds.effectInterface.hasEffectApplied(condition, token.actor.uuid)) {\n console.debug(`Applying ${condition} to ${token.name}`);\n await game.dfreds.effectInterface.addEffect({ effectName: condition, uuid: token.actor.uuid });\n }\n };\n }\n }\n\n console.debug(\"ItemMacro: Pre-apply finised, applying effect to template\")\n\n return await AAhelpers.applyTemplate(args);\n\n} else if (args[0].tag === \"OnUse\" && args[0].macroPass === \"postActiveEffects\") {\n if (lastArg.item.flags.ddbimporter?.effect?.applyImmediate) {\n const condition = lastArg.item.flags.ddbimporter.effect.condition;\n for (const token of lastArg.failedSaves) {\n if (!game.dfreds.effectInterface.hasEffectApplied(condition, token.actor.uuid)) {\n console.debug(`Applying ${condition} to ${token.name}`);\n await game.dfreds.effectInterface.addEffect({ effectName: condition, uuid: token.actor.uuid });\n }\n };\n }\n} else if (args[0] == \"on\" || args[0] == \"each\") {\n const safeName = lastArg.efData.label.replace(/\\s|'|\\.|/g, \"_\");\n const item = await fromUuid(lastArg.efData.origin);\n const ddbEffectFlags = item.flags.ddbimporter.effect;\n // sometimes the round info has not updated, so we pause a bit\n if (args[0] == \"each\") await wait(500);\n const targetItemTracker = DAE.getFlag(item.parent, `${safeName}Tracker`);\n const originalTarget = targetItemTracker.targetUuids.includes(lastArg.tokenUuid);\n const target = canvas.tokens.get(lastArg.tokenId);\n const targetTokenTrackerFlag = DAE.getFlag(target, `${safeName}Tracker`);\n const targetedThisCombat = targetTokenTrackerFlag && targetItemTracker.randomId === targetTokenTrackerFlag.randomId;\n const targetTokenTracker = targetedThisCombat\n ? targetTokenTrackerFlag\n : {\n randomId: targetItemTracker.randomId,\n round: game.combat.round,\n turn: game.combat.turn,\n hasLeft: false,\n condition: ddbEffectFlags.condition,\n };\n\n const castTurn = targetItemTracker.startRound === game.combat.round && targetItemTracker.startTurn === game.combat.turn;\n const isLaterTurn = game.combat.round > targetTokenTracker.round || game.combat.turn > targetTokenTracker.turn;\n const everyEntry = hasProperty(item.data, \"flags.ddbimporter.effect.everyEntry\")\n ? item.flags.ddbimporter.effect.everyEntry\n : false;\n\n // if:\n // not cast turn, and not part of the original target\n // AND one of the following\n // not original template and have not yet had this effect applied this combat OR\n // has been targeted this combat, left and re-entered effect, and is a later turn\n\n const autoDamageIfCondition = hasProperty(ddbEffectFlags, \"autoDamageIfCondition\") ? ddbEffectFlags.autoDamageIfCondition : false;\n const hasConditionStart = game.dfreds.effectInterface.hasEffectApplied(targetTokenTracker.condition, target.actor.uuid);\n const applyAutoConditionDamage = autoDamageIfCondition && hasConditionStart;\n\n if (ddbEffectFlags.conditionEffect && !hasConditionStart) {\n if (castTurn && originalTarget) {\n console.debug(`Token ${target.name} is part of the original target for ${item.name}`);\n } else if (everyEntry || !targetedThisCombat || (targetedThisCombat && isLaterTurn)) {\n console.debug(`Token ${target.name} is targeted for immediate save vs condition with ${item.name}, using the following factors`, { originalTarget, castTurn, targetedThisCombat, targetTokenTracker, isLaterTurn });\n targetTokenTracker.hasLeft = false;\n await applyCondition(targetTokenTracker.condition, target, item, targetItemTracker.spellLevel);\n } else {\n console.debug(`Token ${target.name} has not evaluated for condition application`);\n }\n }\n if (ddbEffectFlags.damageEffect) {\n if (castTurn && originalTarget) {\n console.debug(`Token ${target.name} is part of the original target for ${item.name}`);\n } else if ((!targetedThisCombat && !autoDamageIfCondition) || //if auto damage applied by conditional save\n (targetedThisCombat && ((targetTokenTracker.hasLeft && isLaterTurn) || (applyAutoConditionDamage && isLaterTurn)))\n ) {\n console.debug(`Token ${target.name} is targeted for immediate damage with ${item.name}, using the following factors`, { originalTarget, castTurn, targetedThisCombat, targetTokenTracker, isLaterTurn });\n targetTokenTracker.hasLeft = false;\n await rollItemDamage(target, lastArg.efData.origin, targetItemTracker.spellLevel);\n } else {\n console.debug(`Token ${target.name} has not evaluated for damage application`);\n }\n }\n\n targetTokenTracker.turn = game.combat.turn;\n targetTokenTracker.round = game.combat.round;\n await DAE.setFlag(target, `${safeName}Tracker`, targetTokenTracker);\n const allowVsRemoveCondition = item.flags.ddbimporter.effect.allowVsRemoveCondition;\n const hasConditionAppliedEnd = game.dfreds.effectInterface.hasEffectApplied(targetTokenTracker.condition, target.document.uuid);\n const currentTokenCombatTurn = game.combat.current.tokenId === lastArg.tokenId;\n if (currentTokenCombatTurn && allowVsRemoveCondition && hasConditionAppliedEnd) {\n console.warn(`Asking ${target.name} wants to remove ${targetTokenTracker.condition}`);\n await attemptRemoval(target, targetTokenTracker.condition, item);\n }\n} else if (args[0] == \"off\") {\n const safeName = lastArg.efData.label.replace(/\\s|'|\\.|/g, \"_\");\n const targetToken = await fromUuid(lastArg.tokenUuid);\n const targetTokenTracker = await DAE.getFlag(targetToken, `${safeName}Tracker`);\n const removeOnOff = hasProperty(lastArg, \"efData.flags.ddbimporter.effect.removeOnOff\")\n ? lastArg.efData.flags.ddbimporter.effect.removeOnOff\n : true;\n\n if (targetTokenTracker?.condition && removeOnOff && game.dfreds.effectInterface.hasEffectApplied(targetTokenTracker.condition, lastArg.tokenUuid)) {\n console.debug(`Removing ${targetTokenTracker.condition} from ${targetToken.name}`);\n game.dfreds.effectInterface.removeEffect({ effectName: targetTokenTracker.condition, uuid: lastArg.tokenUuid });\n }\n\n if (targetTokenTracker) {\n targetTokenTracker.hasLeft = true;\n await DAE.setFlag(targetToken, `${safeName}Tracker`, targetTokenTracker);\n }\n}","folder":"Xnvpa6bGFYi4yoqK","flags":{"advanced-macros":{"runAsGM":false}},"author":"xOFiqDVDAkPwiqtI","sort":0,"ownership":{"default":0,"xOFiqDVDAkPwiqtI":3},"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.291","createdTime":1672646160477,"modifiedTime":1672646160477,"lastModifiedBy":"xOFiqDVDAkPwiqtI"},"_id":"WGHcYsxRUkvg0dR1"}
{"name":"Darkness (DDB - GM)","type":"script","img":"icons/magic/unholy/orb-glowing-yellow-purple.webp","scope":"global","command":"// This Macro is called by the Darkness spell so players can place walls and lights.\n\nconst darknessParams = args[args.length - 1];\n\nfunction circleWall(cx, cy, radius) {\n let walls = [];\n const step = 30;\n for (let i = step; i <= 360; i += step) {\n let theta0 = Math.toRadians(i - step);\n let theta1 = Math.toRadians(i);\n\n let lastX = Math.floor(radius * Math.cos(theta0) + cx);\n let lastY = Math.floor(radius * Math.sin(theta0) + cy);\n let newX = Math.floor(radius * Math.cos(theta1) + cx);\n let newY = Math.floor(radius * Math.sin(theta1) + cy);\n\n walls.push({\n c: [lastX, lastY, newX, newY],\n move: CONST.WALL_MOVEMENT_TYPES.NONE,\n light: CONST.WALL_SENSE_TYPES.NORMAL,\n sight: CONST.WALL_SENSE_TYPES.NORMAL,\n sound: CONST.WALL_SENSE_TYPES.NONE,\n dir: CONST.WALL_DIRECTIONS.BOTH,\n door: CONST.WALL_DOOR_TYPES.NONE,\n ds: CONST.WALL_DOOR_STATES.CLOSED,\n flags: {\n spellEffects: {\n Darkness: {\n ActorId: darknessParams.targetActorId,\n },\n },\n },\n });\n }\n\n canvas.scene.createEmbeddedDocuments(\"Wall\", walls);\n}\n\nfunction darknessLight(cx, cy, radius) {\n const lightTemplate = {\n x: cx,\n y: cy,\n rotation: 0,\n walls: false,\n vision: false,\n config: {\n alpha: 0.5,\n angle: 0,\n bright: radius,\n coloration: 1,\n dim: 0,\n gradual: false,\n luminosity: -1,\n saturation: 0,\n contrast: 0,\n shadows: 0,\n animation: {\n speed: 5,\n intensity: 5,\n reverse: false,\n },\n darkness: {\n min: 0,\n max: 1,\n },\n color: null,\n },\n hidden: false,\n flags: {\n spellEffects: {\n Darkness: {\n ActorId: darknessParams.targetActorId,\n },\n },\n \"perfect-vision\": {\n sightLimit: 0,\n },\n },\n };\n canvas.scene.createEmbeddedDocuments(\"AmbientLight\", [lightTemplate]);\n}\n\nif (args[0] == \"on\") {\n if (!game.modules.get(\"perfect-vision\")?.active) circleWall(darknessParams.x, darknessParams.y, darknessParams.radius);\n darknessLight(darknessParams.x, darknessParams.y, darknessParams.distance);\n}\n\nif (args[0] == \"off\") {\n const darkWalls = canvas.walls.placeables.filter((w) => w.data.flags?.spellEffects?.Darkness?.ActorId === darknessParams.targetActorId);\n const wallArray = darkWalls.map((w) => w.id);\n const darkLights = canvas.lighting.placeables.filter((w) => w.data.flags?.spellEffects?.Darkness?.ActorId === darknessParams.targetActorId);\n const lightArray = darkLights.map((w) => w.id);\n await canvas.scene.deleteEmbeddedDocuments(\"Wall\", wallArray);\n await canvas.scene.deleteEmbeddedDocuments(\"AmbientLight\", lightArray);\n}","folder":"Xnvpa6bGFYi4yoqK","flags":{"advanced-macros":{"runAsGM":true}},"author":"xOFiqDVDAkPwiqtI","sort":0,"ownership":{"default":0,"xOFiqDVDAkPwiqtI":3},"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.291","createdTime":1672646161288,"modifiedTime":1672646161288,"lastModifiedBy":"xOFiqDVDAkPwiqtI"},"_id":"aiZPfEnPWSiwDzD8"}
{"name":"Active Aura Condition On Entry (Generic)","type":"script","img":"icons/svg/dice-target.svg","scope":"global","command":"if(!game.modules.get(\"ActiveAuras\")?.active) {\n ui.notifications.error(\"ActiveAuras is not enabled\");\n return;\n}\n\nconst lastArg = args[args.length - 1];\n\nasync function wait(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); }\n\nasync function attemptRemoval(targetToken, condition, item) {\n if (game.dfreds.effectInterface.hasEffectApplied(condition, targetToken.document.uuid)) {\n new Dialog({\n title: `Use action to attempt to remove ${condition}?`,\n buttons: {\n one: {\n label: \"Yes\",\n callback: async () => {\n const caster = item.parent;\n const saveDc = caster.system.attributes.spelldc;\n const removalCheck = item.flags.ddbimporter.effect.removalCheck;\n const removalSave = item.flags.ddbimporter.effect.removalSave;\n const ability = removalCheck ? removalCheck : removalSave;\n const type = removalCheck ? \"check\" : \"save\";\n const flavor = `${condition} (via ${item.name}) : ${CONFIG.DND5E.abilities[ability]} ${type} vs DC${saveDc}`;\n const rollResult = removalCheck\n ? (await targetToken.actor.rollAbilityTest(ability, { flavor })).total\n : (await targetToken.actor.rollAbilitySave(ability, { flavor })).total;\n\n if (rollResult >= saveDc) {\n game.dfreds.effectInterface.removeEffect({ effectName: condition, uuid: targetToken.document.uuid });\n } else {\n if (rollResult < saveDc) ChatMessage.create({ content: `${targetToken.name} fails the ${type} for ${item.name}, still has the ${condition} condition.` });\n }\n },\n },\n two: {\n label: \"No\",\n callback: () => {},\n },\n },\n }).render(true);\n }\n}\n\nasync function applyCondition(condition, targetToken, item, itemLevel) {\n if (!game.dfreds.effectInterface.hasEffectApplied(condition, targetToken.document.uuid)) {\n const caster = item.parent;\n const workflowItemData = duplicate(item.data);\n workflowItemData.system.target = { value: 1, units: \"\", type: \"creature\" };\n workflowItemData.system.save.ability = item.flags.ddbimporter.effect.save;\n workflowItemData.system.components.concentration = false;\n workflowItemData.system.level = itemLevel;\n workflowItemData.system.duration = { value: null, units: \"inst\" };\n workflowItemData.system.target = { value: null, width: null, units: \"\", type: \"creature\" };\n workflowItemData.system.preparation.mode = \"atwill\";\n setProperty(workflowItemData, \"flags.itemacro\", {});\n setProperty(workflowItemData, \"flags.midi-qol\", {});\n setProperty(workflowItemData, \"flags.dae\", {});\n setProperty(workflowItemData, \"effects\", []);\n delete workflowItemData._id;\n workflowItemData.name = `${workflowItemData.name}: ${item.name} Condition save`;\n // console.warn(\"workflowItemData\", workflowItemData);\n\n const saveTargets = [...game.user?.targets].map((t )=> t.id);\n game.user.updateTokenTargets([targetToken.id]);\n const saveItem = new CONFIG.Item.documentClass(workflowItemData, { parent: caster });\n const options = { showFullCard: false, createWorkflow: true, configureDialog: true };\n const result = await MidiQOL.completeItemRoll(saveItem, options);\n\n game.user.updateTokenTargets(saveTargets);\n const failedSaves = [...result.failedSaves];\n if (failedSaves.length > 0) {\n await game.dfreds.effectInterface.addEffect({ effectName: condition, uuid: failedSaves[0].document.uuid });\n }\n\n return result;\n }\n}\n\nasync function attachSequencerFileToTemplate(templateUuid, sequencerFile, originUuid) {\n if (game.modules.get(\"sequencer\")?.active) {\n if (Sequencer.Database.entryExists(sequencerFile)) {\n console.debug(`Trying to apply sequencer effect (${sequencerFile}) to ${templateUuid} from ${originUuid}`, sequencerFile);\n const template = await fromUuid(templateUuid);\n new Sequence()\n .effect()\n .file(Sequencer.Database.entryExists(sequencerFile))\n .size({\n width: canvas.grid.size * (template.data.width / canvas.dimensions.distance),\n height: canvas.grid.size * (template.data.width / canvas.dimensions.distance),\n })\n .persist(true)\n .origin(originUuid)\n .belowTokens()\n .opacity(0.5)\n .attachTo(template, { followRotation: true })\n .stretchTo(template, { attachTo: true})\n .play();\n }\n }\n}\n\nif (args[0].tag === \"OnUse\" && args[0].macroPass === \"preActiveEffects\") {\n const safeName = lastArg.itemData.name.replace(/\\s|'|\\.|/g, \"_\");\n const dataTracker = {\n randomId: randomID(),\n targetUuids: lastArg.targetUuids,\n startRound: game.combat.round,\n startTurn: game.combat.turn,\n spellLevel: lastArg.spellLevel,\n };\n\n const item = await fromUuid(lastArg.itemUuid);\n // await item.update(dataTracker);\n await DAE.unsetFlag(item, `${safeName}Tracker`);\n await DAE.setFlag(item, `${safeName}Tracker`, dataTracker);\n\n const sequencerFile = lastArg.item.flags.ddbimporter?.effect?.sequencerFile;\n if (sequencerFile) {\n attachSequencerFileToTemplate(lastArg.templateUuid, sequencerFile, lastArg.itemUuid)\n }\n\n if (lastArg.item.flags.ddbimporter?.effect?.applyImmediate) {\n await wait(500);\n const condition = lastArg.item.flags.ddbimporter.effect.condition;\n for (const token of lastArg.failedSaves) {\n if (!game.dfreds.effectInterface.hasEffectApplied(condition, token.actor.uuid)) {\n console.debug(`Applying ${condition} to ${token.name}`);\n await game.dfreds.effectInterface.addEffect({ effectName: condition, uuid: token.actor.uuid });\n }\n };\n }\n\n return await AAhelpers.applyTemplate(args);\n\n} else if (args[0].tag === \"OnUse\" && args[0].macroPass === \"postActiveEffects\") {\n if (lastArg.item.flags.ddbimporter?.effect?.applyImmediate) {\n const condition = lastArg.item.flags.ddbimporter.effect.condition;\n for (const token of lastArg.failedSaves) {\n if (!game.dfreds.effectInterface.hasEffectApplied(condition, token.actor.uuid)) {\n console.debug(`Applying ${condition} to ${token.name}`);\n await game.dfreds.effectInterface.addEffect({ effectName: condition, uuid: token.actor.uuid });\n }\n };\n }\n} else if (args[0] == \"on\" || args[0] == \"each\") {\n const safeName = lastArg.efData.label.replace(/\\s|'|\\.|/g, \"_\");\n const item = await fromUuid(lastArg.efData.origin);\n // sometimes the round info has not updated, so we pause a bit\n if (args[0] == \"each\") await wait(500);\n const targetItemTracker = DAE.getFlag(item.parent, `${safeName}Tracker`);\n const originalTarget = targetItemTracker.targetUuids.includes(lastArg.tokenUuid);\n const target = canvas.tokens.get(lastArg.tokenId);\n const targetTokenTrackerFlag = DAE.getFlag(target, `${safeName}Tracker`);\n const targetedThisCombat = targetTokenTrackerFlag && targetItemTracker.randomId === targetTokenTrackerFlag.randomId;\n const targetTokenTracker = targetedThisCombat\n ? targetTokenTrackerFlag\n : {\n randomId: targetItemTracker.randomId,\n round: game.combat.round,\n turn: game.combat.turn,\n hasLeft: false,\n condition: item.flags.ddbimporter.effect.condition,\n };\n\n const castTurn = targetItemTracker.startRound === game.combat.round && targetItemTracker.startTurn === game.combat.turn;\n const isLaterTurn = game.combat.round > targetTokenTracker.round || game.combat.turn > targetTokenTracker.turn;\n const everyEntry = hasProperty(item.data, \"flags.ddbimporter.effect.everyEntry\")\n ? item.flags.ddbimporter.effect.everyEntry\n : false;\n\n // if:\n // not cast turn, and not part of the original target\n // AND one of the following\n // not original template and have not yet had this effect applied this combat OR\n // has been targeted this combat, left and re-entered effect, and is a later turn\n\n if (castTurn && originalTarget) {\n console.debug(`Token ${target.name} is part of the original target for ${item.name}`);\n } else if (everyEntry || !targetedThisCombat || (targetedThisCombat && isLaterTurn)) {\n console.debug(`Token ${target.name} is targeted for immediate save vs condition with ${item.name}, using the following factors`, { originalTarget, castTurn, targetedThisCombat, targetTokenTracker, isLaterTurn });\n targetTokenTracker.hasLeft = false;\n await applyCondition(targetTokenTracker.condition, target, item, targetItemTracker.spellLevel);\n }\n await DAE.setFlag(target, `${safeName}Tracker`, targetTokenTracker);\n const allowVsRemoveCondition = item.flags.ddbimporter.effect.allowVsRemoveCondition;\n const effectApplied = game.dfreds.effectInterface.hasEffectApplied(targetTokenTracker.condition, target.document.uuid);\n const currentTokenCombatTurn = game.combat.current.tokenId === lastArg.tokenId;\n if (currentTokenCombatTurn && allowVsRemoveCondition && effectApplied) {\n console.warn(`Removing ${targetTokenTracker.condition}`);\n await attemptRemoval(target, targetTokenTracker.condition, item);\n }\n} else if (args[0] == \"off\") {\n const safeName = lastArg.efData.label.replace(/\\s|'|\\.|/g, \"_\");\n const targetToken = await fromUuid(lastArg.tokenUuid);\n const targetTokenTracker = await DAE.getFlag(targetToken, `${safeName}Tracker`);\n const removeOnOff = hasProperty(lastArg, \"efData.flags.ddbimporter.effect.removeOnOff\")\n ? lastArg.efData.flags.ddbimporter.effect.removeOnOff\n : true;\n\n if (targetTokenTracker?.condition && removeOnOff && game.dfreds.effectInterface.hasEffectApplied(targetTokenTracker.condition, lastArg.tokenUuid)) {\n console.debug(`Removing ${targetTokenTracker.condition} from ${targetToken.name}`);\n game.dfreds.effectInterface.removeEffect({ effectName: targetTokenTracker.condition, uuid: lastArg.tokenUuid });\n }\n\n if (targetTokenTracker) {\n targetTokenTracker.hasLeft = true;\n targetTokenTracker.turn = game.combat.turn;\n targetTokenTracker.round = game.combat.round;\n await DAE.setFlag(targetToken, `${safeName}Tracker`, targetTokenTracker);\n }\n}","folder":"Xnvpa6bGFYi4yoqK","flags":{"advanced-macros":{"runAsGM":false}},"author":"xOFiqDVDAkPwiqtI","sort":0,"ownership":{"default":0,"xOFiqDVDAkPwiqtI":3},"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.291","createdTime":1672646160590,"modifiedTime":1672646160590,"lastModifiedBy":"xOFiqDVDAkPwiqtI"},"_id":"joyyEVZhl9n6atWK"}