Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Name not defined in reworked SpawnFx script

Hey folks, I'm having trouble with a script for spawning custom FX alongside the base attack roll.  The idea is that each weapon in the repeating section has a linked FX, usually custom, so you have to go through a rigamarole to make the right FX spawn on command.  I've actually solved this issue in the past her e, but now it's giving me trouble with what should be a simpler script.  The crash tells me "name" is undefined, but my logs tell me "name" is being found accurately.   All of the args look like exactly what I need the script to find. I'm seeing a lot of variance as to where my logs stop.  It often stops after logging "name" and "main," but sometimes it gets past the token name and "dr".  Either way, I'm not sure what I'm doing wrong, because I thought I just copied a script that was already working. Here's the button command and script: “!fxattack2 --@{character_id} --@{target|character_id} --{weapon} --@{damagedie} --@{weaponfx} --@{selected|token_id} --@{target|token_id}" // wait till the ready event before registering a chat handler on('ready', () => {     // create a function to return attribute value, given character id and attribute name.     const getLocation = function(id, choice) {         let location = parseInt((findObjs({             type: 'attribute',             characterid: id,             name: choice         })[0] || {             get: () => -1         }).get('current'));         return location;     }; on('chat:message', (msg) => {         if ('api' === msg.type && /^!fxattack2\b/i.test(msg.content)) {           const args = msg.content.split(/\s+--/);           log(args);             let c = getObj('character',args[1]);             log(c);             // verify we got a character             if(c){                          let name = getAttrByName(c.id, "character_name");     let main = getAttrByName(c.id, "main");     let ar = getAttrByName(c.id, "ar");     log(name);     log(main);     log(ar);             }                        let t = getObj('character',args[2]);              if (t) {                                     let tname = getAttrByName(t.id, "character_name");     let dr = getAttrByName(t.id, "dr");     let av = getAttrByName(t.id, "av");                 log(tname); log(dr); log(av);              }             const weapon = args[3] ; const damagedie = args[4];              const fx = args[5];             log(fx);             const ctoken = args[6];             const ttoken = args[7];                          let fxid = findObjs({_type: "custfx", name: fx})[0].id;             log(fxid);                          const tokenCenter = (id) => {        const token = getObj('graphic', id);    log(token);    return {     x: Math.round(token.get('left')),      y: Math.round(token.get('top'))    } }; log(tokenCenter); let output = `?{Roll Type| Standard, 2d10m| Benefit, 3d10k2m| Hindrance, 3d10dh1m} &{template:default} {{name= ${name}: ${weapon} Attack }} {{STATS= ${main} ${ar} | Bonus ?{Core Path Points| 0} }} {{TARGET= ${tname} | DR ${dr} | AV ${av} }} {{RESULT= [[?{Roll Type} + ${ar} + ?{Core Path Points| 0}]] }} {{DAMAGE= [[${damagedie}+ ${ar} - ${av}]] }}`;             sendChat('', output);             if (fx == "sword" ||fx == "melee" ||fx == "hammer" ||fx == "stab") {             let p = tokenCenter(ttoken);             spawnFx(p.x, p.y, fxid)             } else {             spawnFxBetweenPoints(tokenCenter(ctoken), tokenCenter(ttoken), fxid);             log(tokenCenter(ttoken));             }           }     });  });      
1583754500
The Aaron
Roll20 Production Team
API Scripter
Hmm. I don't use getattrbyname() usually. I just get the attribute object. That's probably because that function didn't exist when I started writing API scripts, so I really only think of it when I am trying to resolve character sheet formulas. You might try switching to getting attributes and see if you get a better error message. 
Hi Aaron, I actually played with it throughout the day and I I realized it was a combination of misplaced brackets, queries that were being handled too late, and the fact that the API can't really process the "m" suffice for dice rolls that were screwing me over.  I can now get this script to fire the template properly with no error message... but still no FX.  Kind of like the issue I had in the previous link.  I can see it properly logging coordinates, plus the FX and id, but it's shooting blanks.  I tested the nearly identical script from my old campaign and it still works perfectly. Current button input:  "!fxattack2 --@{character_id} --@{target|character_id} --@{weapon} --@{damagedie} --@{weaponfx} --@{selected|token_id} --@{target|token_id} --?{Roll Type| Standard,2d10| Benefit,3d10k2| Hindrance,3d10dh1} --?{Core Path Points|0}"             Current script:  // wait till the ready event before registering a chat handler on('ready', () => {     // create a function to return attribute value, given character id and attribute name.     const getLocation = function(id, choice) {         let location = parseInt((findObjs({             type: 'attribute',             characterid: id,             name: choice         })[0] || {             get: () => -1         }).get('current'));         return location;     }; on('chat:message', (msg) => {         // make sure the message is an api command, then verify it starts with !infdice          if ('api' === msg.type && /^!fxattack2\b/i.test(msg.content)) {           const args = msg.content.split(/\s+--/);           log(args);             let c = getObj('character',args[1]);                      // verify we got a character             if(c){                          let name = getAttrByName(c.id, "character_name");     let main = getAttrByName(c.id, "main");     let ar = getAttrByName(c.id, "ar");     let skillAttr = findObjs({type:'attribute',characterid:args[1]})     log(name);     log(main);     log(ar);                let t = getObj('character',args[2]);              if (t) {                                     let tname = getAttrByName(t.id, "character_name");             let dr = getAttrByName(t.id, "dr");             let av = getAttrByName(t.id, "av");                 log(tname); log(dr); log(av);                                const weapon = args[3];             const damagedie = args[4];              const fx = args[5];             log(fx);             const ctoken = args[6];             const ttoken = args[7];             const rolltype = args[8];             const core = args[9];                          let fxid = findObjs({_type: "custfx", name: fx})[0].id;             log(fxid);                          const tokenCenter = (id) => {                 const token = getObj('graphic', id);               return {                x: Math.round(token.get('left')),                 y: Math.round(token.get('top'))           }         }; let output = `&{template:default} {{name= ${name}: ${weapon} Attack }} {{STATS= ${main} ${ar} | Bonus ${core} }} {{TARGET= ${tname} | DR ${dr} | AV ${av} }} {{RESULT= [[${rolltype} + ${ar} + ${core}]] }} {{DAMAGE= [[${damagedie} + ${ar} - ${av}]] }}`;             sendChat('', output);             if (c) {             spawnFxBetweenPoints(tokenCenter(ctoken), tokenCenter(ttoken), fxid);             log(tokenCenter(ctoken));             log(tokenCenter(ttoken));             }              }           }         }     });  });       I tested replacing "fxid" with just "beam-acid" to see if there was some issue with the custom fx.  Same problem.  Also tried sending it with no conditional, plus with a few alternate conditionals - no change.
Does anyone have any clues for this?  I am stumped unfortunately...
Hey all, my script finally worked without me changing anything! So... problem solved? I just need to fix one thing in this.  When I run the script on an attack with no defined "fx" attribute, it crashes because the field is undefined.  Is there a quick snippet I can add to this script to help me avoid that badness?  
1585273423
The Aaron
Roll20 Production Team
API Scripter
Change: let fxid = findObjs({_type: "custfx", name: fx})[0].id; to let fxid = (findObjs({_type: "custfx", name: fx})[0]||{id:undefined}).id;
Hmmm, ok, now I am getting " TypeError: Cannot read property 'indexOf' of undefined".
1585279478
The Aaron
Roll20 Production Team
API Scripter
Hmm... You don't even call indexOf()...
I sure don't!  I'm still stumped on this one : (