8 lines
50 KiB
Plaintext
8 lines
50 KiB
Plaintext
|
{"_id":"0INTT5ceHhZDyqHn","name":"Active Aura Condition On Entry (Generic)","type":"script","author":"DXpvV8G3PxeQ79Hd","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 ap
|
||
|
{"_id":"A2zMF5wEWV5zxBhS","name":"Active Aura Damage and Condition On Entry (Generic)","type":"script","author":"DXpvV8G3PxeQ79Hd","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 = {
|
||
|
{"name":"Verspielt Effekt hinzufügen","type":"script","author":"PXCx7EbGRFUpVVbT","img":"icons/svg/dice-target.svg","scope":"global","command":"const uuid = canvas.tokens.controlled[0].actor.uuid;\nconst hasEffectApplied = await game.dfreds.effectInterface.hasEffectApplied('Verspielt', uuid);\n\nif (!hasEffectApplied) {\n game.dfreds.effectInterface.addEffect({ effectName: 'Verspielt', uuid });\n}","flags":{"core":{"sourceId":"Macro.dRKN6lkyWvkUtPcQ"},"advanced-macros":{"runAsGM":false}},"ownership":{"default":0,"PXCx7EbGRFUpVVbT":3},"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.287","createdTime":1665557700885,"modifiedTime":1665557745976,"lastModifiedBy":"PXCx7EbGRFUpVVbT"},"folder":null,"sort":0,"_id":"d8RNAjXs73hjKBzW"}
|
||
|
{"name":"Choose Random Target","type":"script","author":"PXCx7EbGRFUpVVbT","img":"modules/random-target/assets/icons/random-target.svg","scope":"global","command":"game.randomTarget.run();","folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.random-target.random-target-macros.oIVhNA8Po9HpYdJc"}},"ownership":{"default":0,"PXCx7EbGRFUpVVbT":3},"_stats":{"systemId":"dnd5e","systemVersion":"2.0.3","coreVersion":"10.287","createdTime":1665512069004,"modifiedTime":1665512069004,"lastModifiedBy":"PXCx7EbGRFUpVVbT"},"_id":"g7uYghogwYhma6LX"}
|
||
|
{"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":"prIQ7vvvClaSGgsC","flags":{"advanced-macros":{"runAsGM":true}},"author":"PXCx7EbGRFUpVVbT","sort":0,"ownership":{"default":0,"PXCx7EbGRFUpVVbT":3},"_stats":{"systemId":"dnd5e","systemVersion":"2.0.2","coreVersion":"10.284","createdTime":1662449020474,"modifiedTime":1662449020474,"lastModifiedBy":"PXCx7EbGRFUpVVbT"},"_id":"gv17eZiP7BdN5kfD"}
|
||
|
{"_id":"vyFk1U0ElQBHw1GL","name":"Active Aura Only (Generic)","type":"script","author":"DXpvV8G3PxeQ79Hd","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
|
||
|
{"_id":"xMXVwq0le6PEbB33","name":"Active Aura Damage On Entry (Generic)","type":"script","author":"DXpvV8G3PxeQ79Hd","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\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.data,\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
|