Macro to Change Token/Character Art

Type: Macro Short Description: A Macro that changes Token Art and Character Art Long Description: I run Delta Green, and I want a macro to change both the token art and the character art to a secondary piece of token/character art (it will be a visual indicator that the character is insane). Executing the macro again will switch the token to the original art. I actually have the macro mostly done (it's only about 20 lines) - but I lack the knowledge to complete it. Budget: Should be the easiest $30 you'll make today
33 Replies
enso
enso•14mo ago
can you post what you have so far?
Craftzero
CraftzeroOP•14mo ago
Sure, this macro is specific to one person ("Zahra") - but I want a macro that returns the name of the current token and goes to that path, if that makes sense. if (!token) return ui.notifications.error("No token is selected.") let notTransformed = 'zahra/zahra1.png'; let transformed = 'Zahra/Zahra2.png'; let img = token.document.texture.src === notTransformed ? transformed : notTransformed; new Sequence() .sound("Zahra/evil2.ogg") .effect() .file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm") .atLocation(token) .scaleToObject(2) .randomRotation() .wait(1500) .thenDo(() => { token.document.update({ img }); }) .play()
enso
enso•14mo ago
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;

const notTransformed = tokenName + '/' + tokenName + '1.png';
const transformed = tokenName + '/' + tokenName + '2.png';
const img = token.document.texture.src === notTransformed ? transformed : notTransformed;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(() => {
token.document.update({ img });
})
.play()
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;

const notTransformed = tokenName + '/' + tokenName + '1.png';
const transformed = tokenName + '/' + tokenName + '2.png';
const img = token.document.texture.src === notTransformed ? transformed : notTransformed;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(() => {
token.document.update({ img });
})
.play()
I assumed the folder would be the same as the token name
Craftzero
CraftzeroOP•14mo ago
Looks about right, but how would I change the character art as well?
enso
enso•14mo ago
I think that should be done by this part of the Sequencer chain:
.thenDo(() => {
token.document.update({ img });
})
.thenDo(() => {
token.document.update({ img });
})
Craftzero
CraftzeroOP•14mo ago
Hmm, does it? Let me check how that works right now, 1 min
Craftzero
CraftzeroOP•14mo ago
No, it doesn't, unfortunately.
No description
Craftzero
CraftzeroOP•14mo ago
You can see the art changed to the "horned" token, but the character art doesn't change.
enso
enso•14mo ago
oh you want the art on the character sheet to change as well?
Craftzero
CraftzeroOP•14mo ago
Yes
enso
enso•14mo ago
ah my bad, one sec should the character art be the same as the token art?
Craftzero
CraftzeroOP•14mo ago
Umm, err. Good question. It can, sure.
enso
enso•14mo ago
let's see if this works
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;
const notTransformed = tokenName + '/' + tokenName + '1.png';
const transformed = tokenName + '/' + tokenName + '2.png';
const img = token.document.texture.src === notTransformed ? transformed : notTransformed;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(async () => {
await token.document.update({ img });
await token.actor.update({ img });
})
.play()
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;
const notTransformed = tokenName + '/' + tokenName + '1.png';
const transformed = tokenName + '/' + tokenName + '2.png';
const img = token.document.texture.src === notTransformed ? transformed : notTransformed;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(async () => {
await token.document.update({ img });
await token.actor.update({ img });
})
.play()
Craftzero
CraftzeroOP•14mo ago
Give me a bit to put that in there and make sure the images are there, give me... 5 mins plz
enso
enso•14mo ago
as is, this will make the token art and the character art the same, but you can have different art for the character sheet if you would prefer, it would just require you to set up the image file paths
Craftzero
CraftzeroOP•14mo ago
How do I post this as code, what command is that?
enso
enso•14mo ago
No description
Craftzero
CraftzeroOP•14mo ago
js Test
js Test
Okay, so first here is the folder structure and what's in it:
Craftzero
CraftzeroOP•14mo ago
No description
Craftzero
CraftzeroOP•14mo ago
Here is the code, I changed the names to reflect .webp
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;
const notTransformed = tokenName + '/' + tokenName + 'Normal.webp';
const transformed = tokenName + '/' + tokenName + 'Scared.webp';
const img = token.document.texture.src === notTransformed ? transformed : notTransformed;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(async () => {
await token.document.update({ img });
await token.actor.update({ img });
})
.play()
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;
const notTransformed = tokenName + '/' + tokenName + 'Normal.webp';
const transformed = tokenName + '/' + tokenName + 'Scared.webp';
const img = token.document.texture.src === notTransformed ? transformed : notTransformed;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(async () => {
await token.document.update({ img });
await token.actor.update({ img });
})
.play()
The sound works, the jb2a animation fires... but the token changes to the mystery man token And that's it. Clearly I screwed something up. 🙂
Zhell
Zhell•14mo ago
Tokens have texture.src, not img. Also your webp files above have a dot that the jpg images do not
Craftzero
CraftzeroOP•14mo ago
Yup, saw that!! Now it appears to be fixed, at least as far as going back and forth for the token (Thanks @Zhell !)
Leo The League Lion
Leo The League Lion•14mo ago
@Craftzero gave :vote: LeaguePoints™ to @Zhell (#45 • 62)
Craftzero
CraftzeroOP•14mo ago
@enso the token is now switching, thank you. But it's showing the token art, rather than the character art, what would I need to do to change that?
Craftzero
CraftzeroOP•14mo ago
No description
Zhell
Zhell•14mo ago
Point to the correct file?
Craftzero
CraftzeroOP•14mo ago
Hmm, What in the code points to the correct character art file?
js
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;
const notTransformed = tokenName + '/' + tokenName + 'Normal.webp';
const transformed = tokenName + '/' + tokenName + 'Scared.webp';
const img = token.document.texture.src === notTransformed ? transformed : notTransformed;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(async () => {
await token.document.update({ img });
await token.actor.update({ img });
})
.play()
js
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;
const notTransformed = tokenName + '/' + tokenName + 'Normal.webp';
const transformed = tokenName + '/' + tokenName + 'Scared.webp';
const img = token.document.texture.src === notTransformed ? transformed : notTransformed;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(async () => {
await token.document.update({ img });
await token.actor.update({ img });
})
.play()
enso
enso•14mo ago
one sec
Zhell
Zhell•14mo ago
The actor art is the two on the left, right? And the tokens the two on the right?
Craftzero
CraftzeroOP•14mo ago
Correct Although I removed the extra period as per Enso's suggestion
enso
enso•14mo ago
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;
const notTransformed = tokenName + '/' + tokenName + 'Normal.webp';
const transformed = tokenName + '/' + tokenName + 'Scared.webp';
const tokenImg = token.document.texture.src === notTransformed ? transformed : notTransformed;

const notTransformedCharacter = tokenName + '/' + tokenName + 'Normal.jpg';
const transformedCharacter = tokenName + '/' + tokenName + 'Scared.jpg';
const characterImg = token.document.texture.src === notTransformed ? transformedCharacter : notTransformedCharacter;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(async () => {
await token.document.update({ 'texture.src': tokenImg });
await token.actor.update({ img: characterImg });
})
.play()
if (!token) return ui.notifications.error("No token is selected.")

const tokenName = token.name;
const notTransformed = tokenName + '/' + tokenName + 'Normal.webp';
const transformed = tokenName + '/' + tokenName + 'Scared.webp';
const tokenImg = token.document.texture.src === notTransformed ? transformed : notTransformed;

const notTransformedCharacter = tokenName + '/' + tokenName + 'Normal.jpg';
const transformedCharacter = tokenName + '/' + tokenName + 'Scared.jpg';
const characterImg = token.document.texture.src === notTransformed ? transformedCharacter : notTransformedCharacter;

new Sequence()
.sound(`${tokenName}/evil2.ogg`)
.effect()
.file("modules/jb2a_patreon/Library/2nd_Level/Divine_Smite/DivineSmite_01_Dark_Purple_Caster_400x400.webm")
.atLocation(token)
.scaleToObject(2)
.randomRotation()
.wait(1500)
.thenDo(async () => {
await token.document.update({ 'texture.src': tokenImg });
await token.actor.update({ img: characterImg });
})
.play()
Craftzero
CraftzeroOP•14mo ago
Works Perfectly! Can you message me your venmo, Enso? Closing this, thanks @enso
Leo The League Lion
Leo The League Lion•14mo ago
@Craftzero gave :vote: LeaguePoints™ to @enso (#20 • 156)

Did you find this page helpful?