Closed the-real-orson closed 2 years ago
So it doesn't work if you ONLY target the linked token, right?
To be honest, this doesn't really seem like an issue on my end. You can definitely apply effects to linked tokens using the regular API from this module. It seems likely that the issue is somewhere else.... can you try using macro.execute.GM
? That requires dae 0.9.02 or higher.
It always works for the linked token, whether it is single target or part of target array.
It never works for the unlinked token, whether it is single target or part of target array.
Not sure how to implement maco.execute.GM. Happy to try it if you give me a little more direction.
I didn't know if it was an issue on your end, just started here since this kind of issue tends to get me a "it's a module issue" when I ask in #macro-polo. I was told in that channel before that unlinked tokens will respond to all the same actor methods as linked tokens, so I'm confused as to why they are behaving differently.
The reason I'm trying to do this is because I want to apply the blinded condition only if the target does not have tremor/blind/true sight/sense.
Looking for some direction or suggestions if you have any.
So the first step you provided was this:
Setup dFreds effect with name: "Darkness", Effect: Macro Execute (*) CUSTOM "Darkness Effects"
Macro Execute puts in the effect as macro.execute
. Change it to macro.execute.GM
No difference when executed as GM.
The invisible effect is being applied to the unlinked token....it just somehow then isn't there. According to the chat log Invisible is applied first, then the dFreds effect Darkness (that is calling the macro) is applied, but then only Darkness remains on the unlinked token.
Console shows it being applied but does not show it being removed.
If you suspect it's a midi issue I can inquire on that GitH
Someone else had this issue in the past, but they resolved it by working with tposney, the developer of midi and DAE. It was something around asynchronous functions... I'll see if I can find what the solution was and I'll post it here if I do. Otherwise, you'll have to ask him.
Relevant messages from tposney: https://cdn.discordapp.com/attachments/938550435474726954/944556702248890428/unknown.png https://media.discordapp.net/attachments/938550435474726954/944556897938337812/unknown.png
Also, here is a working example from someone who asked tposney about it. You can save this as a .json and import it into a sample item in Foundry by right-clicking the item and choosing 'Import'.
{
"name": "Tasha's Hideous Laughter",
"type": "spell",
"img": "icons/creatures/unholy/demon-fire-horned-mask.webp",
"data": {
"description": {
"value": "<p>A creature of your choice that you can see within range perceives everything as hilariously funny and falls into fits of laughter if this spell affects it. The target must succeed on a Wisdom saving throw or fall prone, becoming Incapacitated and unable to stand up for the Duration. A creature with an Intelligence score of 4 or less isn't affected.</p><p>At the end of each of its turns, and each time it takes damage, the target can make another Wisdom saving throw. The target has advantage on the saving throw if it's triggered by damage. On a success, the spell ends.</p>",
"chat": "",
"unidentified": ""
},
"source": "",
"activation": {
"type": "action",
"cost": 1,
"condition": ""
},
"duration": {
"value": 1,
"units": "minute"
},
"target": {
"value": 1,
"width": null,
"units": "",
"type": "creature"
},
"range": {
"value": 30,
"long": 0,
"units": "ft"
},
"uses": {
"value": 0,
"max": "0",
"per": ""
},
"consume": {
"type": "",
"target": "",
"amount": null
},
"ability": "",
"actionType": "save",
"attackBonus": 0,
"chatFlavor": "",
"critical": {
"threshold": null,
"damage": ""
},
"damage": {
"parts": [],
"versatile": "",
"value": ""
},
"formula": "",
"save": {
"ability": "wis",
"dc": 13,
"scaling": "spell"
},
"level": 1,
"school": "enc",
"components": {
"value": "",
"vocal": true,
"somatic": true,
"material": true,
"ritual": false,
"concentration": true
},
"materials": {
"value": "Tiny tarts and a feather that is waved in the air",
"consumed": false,
"cost": 0,
"supply": 0
},
"preparation": {
"mode": "prepared",
"prepared": false
},
"scaling": {
"mode": "none",
"formula": ""
},
"attunement": 0
},
"effects": [
{
"_id": "2uNNhG0teoyGCX2W",
"changes": [
{
"key": "flags.midi-qol.OverTime",
"mode": 5,
"value": "turn=end,saveAbility=wis,saveDC=@attributes.spelldc,label=Tashas Hideous Laughter",
"priority": "20"
},
{
"key": "macro.itemMacro",
"mode": 0,
"value": "",
"priority": "20"
}
],
"disabled": false,
"duration": {
"startTime": null
},
"icon": "icons/creatures/unholy/demon-fire-horned-mask.webp",
"label": "Tasha's Hideous Laughter",
"transfer": false,
"flags": {
"core": {
"statusId": ""
},
"dae": {
"stackable": "none",
"macroRepeat": "none",
"specialDuration": [],
"transfer": false,
"durationExpression": ""
},
"dnd5e-helpers": {
"rest-effect": "Ignore"
},
"ActiveAuras": {
"isAura": false,
"aura": "None",
"radius": null,
"alignment": "",
"type": "",
"ignoreSelf": false,
"height": false,
"hidden": false,
"displayTemp": false,
"hostile": false,
"onlyOnce": false
}
},
"tint": "#000000",
"selectedKey": [
"flags.midi-qol.OverTime",
"macro.itemMacro"
]
}
],
"flags": {
"midi-qol": {
"effectActivation": false,
"onUseMacroName": "[postActiveEffects]ItemMacro"
},
"core": {
"sourceId": "Item.Nyl9SSFSG5lloLF0"
},
"itemacro": {
"macro": {
"data": {
"_id": null,
"name": "Tasha's Hideous Laughter (TPosney)",
"type": "script",
"author": "Xv8kOpT0YuRo8rso",
"img": "icons/svg/dice-target.svg",
"scope": "global",
"command": "async function wait(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); }\n\nif (args[0].tag === \"OnUse\") {\n let checkProne;\n for (let targetUuid of args[0].failedSaveUuids) {\n checkProne = await game.dfreds.effectInterface.hasEffectApplied('Prone', targetUuid);\n if (!checkProne) {\n await game.dfreds.effectInterface.addEffect({ effectName: 'Prone', uuid: targetUuid});\n }\n }\n return;\n}\n\nconst lastArg = args[args.length - 1];\nconst tokenD = canvas.tokens.get(lastArg.tokenId);\nconst actorD = canvas.tokens.get(lastArg.tokenId).actor;\nconst itemD = lastArg.efData.flags.dae.itemData;\nconst origin = lastArg.origin;\nconst itemUuid = await fromUuid(origin);\nconst caster = itemUuid.actor;\nconst gameRound = game.combat ? game.combat.round : 0;\nconst tokenUuid = canvas.tokens.get(lastArg.tokenId).actor.uuid;\n\nasync function damageCheck(workflow) {\n console.warn(\"args inside damageCheck: \", args)\n let effectData = [{\n label: \"Damage Save\",\n icon: \"icons/skills/wounds/injury-triple-slash-bleed.webp\",\n origin: origin,\n disabled: false,\n flags: { dae: { specialDuration: [\"isDamaged\"] } },\n duration: { rounds: 10, seconds: 60, startRound: gameRound, startTime: game.time.worldTime },\n changes: [{ key: `flags.midi-qol.advantage.ability.save.all`, mode: 2, value: 1, priority: 20 }]\n }];\n let damageSave = actorD.effects.find(i => i.data.label === \"Damage Save\");\n if (!damageSave) await MidiQOL.socket().executeAsGM(\"createEffects\", { actorUuid: lastArg.actorUuid, effects: effectData });\n await wait(600);\n let attackWorkflow = workflow.damageList.map((i) => ({ tokenId: i?.tokenId, totalDamage: i?.totalDamage })).filter(i => i.tokenId === tokenD.id);\n let lastAttack = attackWorkflow[attackWorkflow.length - 1];\n if (lastAttack?.totalDamage > 0) {\n let workflow = await MidiQOL.Workflow.getWorkflow(origin);\n workflow.advantage = true;\n let itemCard = await MidiQOL.showItemCard.bind(workflow.item)(false, workflow, false);\n workflow.itemCardId = await itemCard.id;\n await workflow.checkSaves(false);\n await workflow.displaySaves(false, true);\n let save = await workflow.saveResults[0];\n let DC = workflow.item.data.data.save.dc;\n game.dice3d?.showForRoll(save);\n await ui.chat.scrollBottom();\n if (save.total >= DC) {\n let removeConc = caster.effects.find(i => i.data.label === \"Concentrating\");\n if (removeConc) await MidiQOL.socket().executeAsGM(\"removeEffects\", { actorUuid: caster.uuid, effects: [removeConc.id] });\n } else {\n ChatMessage.create({\n user: game.user._id,\n speaker: ChatMessage.getSpeaker({ token: tokenD.document }),\n content: `${tokenD.name} laughs maniacally`,\n type: CONST.CHAT_MESSAGE_TYPES.EMOTE\n });\n }\n }\n}\n\nif (args[0] === \"on\") {\n let hookId = await Hooks.on(\"midi-qol.DamageRollComplete\", damageCheck);\n await DAE.setFlag(actorD, \"hLaughter\", hookId);\n if (!(game.modules.get(\"jb2a_patreon\")?.active || game.modules.get(\"JB2A_DnD5e\")?.active)) return {};\n if (!(game.modules.get(\"sequencer\")?.active)) return {};\n console.warn(\"tokenD\", tokenD);\n new Sequence()\n .effect()\n .file(\"jb2a.toll_the_dead.purple.skull_smoke\")\n .atLocation(tokenD)\n .scaleToObject(1.5)\n .waitUntilFinished(-500)\n .play()\n}\n\nif (args[0] === \"off\") {\n let hookId = await DAE.getFlag(actorD, \"hLaughter\");\n await Hooks.off(\"midi-qol.DamageRollComplete\", hookId);\n await DAE.unsetFlag(actorD, \"hLaughter\");\n let conc = caster.effects.find(i => i.data.label === \"Concentration\");\n if (conc) await MidiQOL.socket().executeAsGM(\"removeEffects\", { actorUuid: caster.uuid, effects: [conc.id] });\n}",
"folder": null,
"sort": 0,
"permission": {
"default": 0
},
"flags": {}
}
}
},
"exportSource": {
"world": "tesira",
"system": "dnd5e",
"coreVersion": "9.249",
"systemVersion": "1.5.7"
},
"scene-packer": {
"hash": "1eb7e56d5929032bc6d02692d6f045850fda3f8f",
"sourceId": "Item.ntH9EDjGoPzrzoTq"
},
"betterRolls5e": {
"quickOther": {
"context": "",
"value": true,
"altValue": true
},
"quickDamage": {
"context": {
"0": ""
}
},
"quickDesc": {
"value": true,
"altValue": true
},
"quickSave": {
"value": true,
"altValue": true
},
"quickProperties": {
"value": true,
"altValue": true
},
"quickVersatile": {
"value": false,
"altValue": false
},
"quickFlavor": {
"value": true,
"altValue": true
}
}
}
}
Finally spun back around to this, missed the alert email...
Thanks for looking into this!
Describe the bug If targets are unlinked tokens, macro applies effect using addEffect (according to the console) but the effect doesn't show up on the targeted token. midi-qol and dae are both active
To Reproduce Steps to reproduce the behavior:
Expected behavior All tokens have "Darkness" and "Invisible"
Screenshots
Additional context