Hello,
I got this script from someone I don't remember the name (sorry :( )
I did try to reach him some months ago but never get answered.
This script autopopulate token actions for npc (which send repeating actions from the 5e ogl sheet to the gm) BUT often get twice the repeating action in the chat... don't know why since I'm no good with API scripts :D
Anyone? Pleaseeee :)
function getCharacterObj(obj) { "use strict"; //send any object and returns the associated character object //returns character object for attribute, token/graphic, and ability, and... character var objType = obj._type, att, characterObj, tok; if ((objType !== "attribute") && (objType !== "graphic") && (objType !== "character")) { sendChat("API"," cannot be associated with a character."); return; } if ((objType === "attribute") || (objType === "ability")) { att = getObj(objType, obj._id); if (att.get("_characterid") !== "") { characterObj = getObj("character", att.get("_characterid")); } } if (objType === "graphic") { tok = getObj("graphic", obj._id); if (tok.get("represents") !== "") { characterObj = getObj("character", tok.get("represents")); } else { sendChat("API"," Selected token does not represent a character."); return; } } if (objType === "character") { characterObj = getObj("character", obj._id); } return characterObj; } on("chat:message", function(msg) { "use strict"; var msg, selected, Parameters, statusName, aName, ids, attributeName, newValue, characterObj, attributeObjArray, tok; if (msg.type === "api" && msg.content.indexOf("!generate-spellbook") !== -1 ) { selected = msg.selected; var parameters = msg.content.split(" "); // Set filter for what spell class to generate a spellbook for // Defaults to -1 for no filter var spellClass = -1; if (parameters.length > 1) spellClass = parameters[1]; // Set the name of the ability the macro will be put into // Defaults to "Spells" var abilityName = "Spells"; if (parameters.length > 2) abilityName = parameters[2]; // Set the title to use in the template header // Defaults to "Spells" var title = "Spells"; if (parameters.length > 3) title = parameters[3]; //loop through selected tokens _.each(selected, function(obj) { tok = getObj("graphic", obj._id); // Get the character token represents characterObj = getCharacterObj(obj); if ( ! characterObj) { return; } var characterName = characterObj.get("name"); var rowIDs = new Array(); // Create array for repeating spell attribute names getAllObjs().forEach(function(obj) { // Filter down to just attribute objects belonging to the character, whose name indicates it's a spell if (obj.get("type") !== "attribute") return; if (obj.get("_characterid") !== characterObj.get("_id")) return; if (obj.get("name").indexOf("repeating_spell-") === -1) return; // If this is a name attribute, use that to add the base repeating attribute name to the array if (obj.get("name").indexOf("_spellname") !== -1) rowIDs.push(obj.get("name").substr(0,obj.get("name").indexOf("_spellname"))); }); // Create arrays for individual spell levels var lvl0 = new Array(); var lvl1 = new Array(); var lvl2 = new Array(); var lvl3 = new Array(); var lvl4 = new Array(); var lvl5 = new Array(); var lvl6 = new Array(); var lvl7 = new Array(); var lvl8 = new Array(); var lvl9 = new Array(); var npc = new Array(); // Sort rowIDs into spell levels rowIDs.forEach(function(entry){ // Grab the spell level from attribute name repeating_spell-1 var lvl = entry.substr(16,1); if(entry.indexOf("cantrip") >= 0){ lvl = "cantrip"; } if(entry.indexOf("npc") >= 0){ lvl = "npc"; } // Put spell into the correct spell level switch (lvl) { case "cantrip": lvl0.push(entry); break; case "1": lvl1.push(entry); break; case "2": lvl2.push(entry); break; case "3": lvl3.push(entry); break; case "4": lvl4.push(entry); break; case "5": lvl5.push(entry); break; case "6": lvl6.push(entry); break; case "7": lvl7.push(entry); break; case "8": lvl8.push(entry); break; case "9": lvl9.push(entry); break; case "npc": npc.push(entry); break; } }); var macroText = "/w @{character_name} @{selected|wtype}&{template:atk} {{rname=Spell List}} {{desc=SPELL LIST:\n\n"; // Base macro text // Add spells to macro by spell level var addSpells = function(spells, title){ if (spells.length > 0) { var lvlText = ""; spells.forEach(function(entry) { // Check for spell name attribute; was having orphaned row_id attributes creating buttons for repeating rows that didn't actually exist if (_.isUndefined(getAttrByName(characterObj.get("_id"), entry + "_spellname"))) return; if(lvlText){ lvlText += ", "; } lvlText = lvlText + "[@{"+entry+"_spellname}](~"+characterName+"|"+entry+"_spell) "; }); if (lvlText !== "") macroText = macroText+title+": "+ lvlText+"\n\n"; } } addSpells(lvl0, "Cantrips"); addSpells(lvl1, "Level 1"); addSpells(lvl2, "Level 2"); addSpells(lvl3, "Level 3"); addSpells(lvl4, "Level 4"); addSpells(lvl5, "Level 5"); addSpells(lvl6, "Level 6"); addSpells(lvl7, "Level 7"); addSpells(lvl8, "Level 8"); addSpells(lvl9, "Level 9"); addSpells(npc, "NPC"); macroText += "}}" // Check for existing ability with chosen ability name var abil = findObjs({ _type: "ability", _characterid: characterObj.get("_id"), name: abilityName }); if (abil.length === 0){ createObj("ability", { name: abilityName, characterid: characterObj.get("_id"), action: macroText, istokenaction: true }); }else{ abil[0].set("action", macroText); } }); } }); on("chat:message", function(msg) { "use strict"; var msg, selected, Parameters, statusName, aName, ids, attributeName, newValue, characterObj, attributeObjArray, tok; if (msg.type === "api" && msg.content.indexOf("!generate-attackbook") !== -1 ) { selected = msg.selected; var parameters = msg.content.split(" "); // Set filter for what spell class to generate a spellbook for // Defaults to -1 for no filter var spellClass = -1; if (parameters.length > 1) spellClass = parameters[1]; // Set the name of the ability the macro will be put into // Defaults to "Spells" var abilityName = "Attacks"; if (parameters.length > 2) abilityName = parameters[2]; // Set the title to use in the template header // Defaults to "Spells" var title = "Attacks"; if (parameters.length > 3) title = parameters[3]; //loop through selected tokens _.each(selected, function(obj) { tok = getObj("graphic", obj._id); // Get the character token represents characterObj = getCharacterObj(obj); if ( ! characterObj) { return; } var characterName = characterObj.get("name"); var attackIds = new Array(); // Create array for repeating spell attribute names var npcActionIds = new Array(); // Create array for repeating spell attribute names var npcReactionIds = new Array(); // Create array for repeating spell attribute names var npcTraitIds = new Array(); // Create array for repeating spell attribute names var legendaryActionIds = new Array(); // Create array for repeating spell attribute names getAllObjs().forEach(function(obj) { // Filter down to just attribute objects belonging to the character, whose name indicates it's a spell if (obj.get("type") !== "attribute") return; if (obj.get("_characterid") !== characterObj.get("_id")) return; if (obj.get("name").indexOf("repeating_attack") === -1 && obj.get("name").indexOf("repeating_npcaction") === -1 && obj.get("name").indexOf("repeating_npcreaction") === -1 && obj.get("name").indexOf("repeating_npctrait") === -1) return; // If this is a name attribute, use that to add the base repeating attribute name to the array if (obj.get("name").indexOf("_atkname") !== -1) attackIds.push(obj.get("name").substr(0,obj.get("name").indexOf("_atkname"))); if (obj.get("name").indexOf("npcaction_") !== -1 && obj.get("name").indexOf("_name") !== -1){ npcActionIds.push(obj.get("name").substr(0,obj.get("name").indexOf("_name"))); } if (obj.get("name").indexOf("npcreaction_") !== -1 && obj.get("name").indexOf("_name") !== -1){ npcReactionIds.push(obj.get("name").substr(0,obj.get("name").indexOf("_name"))); } if (obj.get("name").indexOf("npctrait_") !== -1 && obj.get("name").indexOf("_name") !== -1){ npcTraitIds.push(obj.get("name").substr(0,obj.get("name").indexOf("_name"))); } if (obj.get("name").indexOf("npcaction-l_") !== -1 && obj.get("name").indexOf("_name") !== -1){ legendaryActionIds.push(obj.get("name").substr(0,obj.get("name").indexOf("_name"))); } }); var macroText = "/w @{character_name} @{selected|wtype}&{template:atk} {{rname=Attack List}} {{desc= ATTACK LIST\n"; // Base macro text // Add spells to macro by spell level if (attackIds.length > 0) { var lvlText = ""; attackIds.forEach(function(entry) { // Check for spell name attribute; was having orphaned row_id attributes creating buttons for repeating rows that didn't actually exist if (_.isUndefined(getAttrByName(characterObj.get("_id"), entry + "_atkname"))) return; lvlText = lvlText + "\n[@{"+entry+"_atkname}](~"+characterName+"|"+entry+"_attack) "; }); if (lvlText !== "") macroText = macroText+"Attacks: "+ lvlText+"\n\n"; } if (npcActionIds.length > 0) { var lvlText = ""; npcActionIds.forEach(function(entry) { // Check for spell name attribute; was having orphaned row_id attributes creating buttons for repeating rows that didn't actually exist if (_.isUndefined(getAttrByName(characterObj.get("_id"), entry + "_name"))) return; lvlText = lvlText + "\n[@{"+entry+"_name}](~"+characterName+"|"+entry+"_npc_action) "; }); if (lvlText !== "") macroText = macroText+"Actions: "+ lvlText+"\n\n"; } if (legendaryActionIds.length > 0) { var lvlText = ""; legendaryActionIds.forEach(function(entry) { // Check for spell name attribute; was having orphaned row_id attributes creating buttons for repeating rows that didn't actually exist if (_.isUndefined(getAttrByName(characterObj.get("_id"), entry + "_name"))) return; lvlText = lvlText + "\n[@{"+entry+"_name}](~"+characterName+"|"+entry+"_npc_action) "; }); if (lvlText !== "") macroText = macroText+"Legendary Actions: "+ lvlText+"\n\n"; } macroText += "}}" // Check for existing ability with chosen ability name var abil = findObjs({ _type: "ability", _characterid: characterObj.get("_id"), name: abilityName }); if (abil.length === 0){ createObj("ability", { name: abilityName, characterid: characterObj.get("_id"), action: macroText, istokenaction: true }); }else{ abil[0].set("action", macroText); } }); } }); on("chat:message", function(msg) { "use strict"; var msg, selected, Parameters, statusName, aName, ids, attributeName, newValue, characterObj, attributeObjArray, tok; if (msg.type === "api" && msg.content.indexOf("!generate-checkbook") !== -1 ) { selected = msg.selected; var parameters = msg.content.split(" "); // Set the name of the ability the macro will be put into // Defaults to "Spells" var abilityName = "Other"; // Set the title to use in the template header // Defaults to "Spells" var title = "Other"; //loop through selected tokens _.each(selected, function(obj) { tok = getObj("graphic", obj._id); // Get the character token represents characterObj = getCharacterObj(obj); if ( ! characterObj) { return; } var characterName = characterObj.get("name"); var macroText = "/w @{character_name} @{selected|wtype}&{template:atk} {{rname=Other}} {{desc="; // Base macro text if(getAttrByName(characterObj.get("_id"), "npc") == 1){ macroText += "Checks: \n" macroText += "[Str](~"+characterName+"|npc_str) "; macroText += ", [Dex](~"+characterName+"|npc_dex) "; macroText += ", [Con](~"+characterName+"|npc_con) "; macroText += ", [Wis](~"+characterName+"|npc_wis) "; macroText += ", [Int](~"+characterName+"|npc_int) "; macroText += ", [Cha](~"+characterName+"|npc_cha) "; macroText += "\n\n[Acrobatics](~"+characterName+"|npc_Acrobatics) "; macroText += ", [Animal Handling](~"+characterName+"|npc_Animal_Handling) "; macroText += ", [Arcana](~"+characterName+"|npc_Arcana) "; macroText += ", [Athletics](~"+characterName+"|npc_Athletics) "; macroText += ", [Deception](~"+characterName+"|npc_Deception) "; macroText += ", [History](~"+characterName+"|npc_History) "; macroText += ", [Insight](~"+characterName+"|npc_Insight) "; macroText += ", [Intimidation](~"+characterName+"|npc_Intimidation) "; macroText += ", [Investigation](~"+characterName+"|npc_Investigation) "; macroText += ", [Medicine](~"+characterName+"|npc_Medicine) "; macroText += ", [Nature](~"+characterName+"|npc_Nature) "; macroText += ", [Perception](~"+characterName+"|npc_Perception) "; macroText += ", [Performance](~"+characterName+"|npc_Performance) "; macroText += ", [Persuasion](~"+characterName+"|npc_Persuasion) "; macroText += ", [Religion](~"+characterName+"|npc_Religion) "; macroText += ", [Sleight of Hand](~"+characterName+"|npc_Sleight_of_Hand) "; macroText += ", [Stealth](~"+characterName+"|npc_Stealth) "; macroText += ", [Survival](~"+characterName+"|npc_Survival) "; macroText += "\n\nSaves: \n" macroText += "[Str](~"+characterName+"|npc_str_save) "; macroText += ", [Dex](~"+characterName+"|npc_dex_save) "; macroText += ", [Con](~"+characterName+"|npc_con_save) "; macroText += ", [Wis](~"+characterName+"|npc_wis_save) "; macroText += ", [Int](~"+characterName+"|npc_int_save) "; macroText += ", [Cha](~"+characterName+"|npc_cha_save) "; } else { macroText += "Checks: \n" macroText += "[Str](~"+characterName+"|strength) "; macroText += ", [Dex](~"+characterName+"|dexterity) "; macroText += ", [Con](~"+characterName+"|constitution) "; macroText += ", [Wis](~"+characterName+"|wisdom) "; macroText += ", [Int](~"+characterName+"|intelligence) "; macroText += ", [Cha](~"+characterName+"|charisma) "; macroText += "\n\n[Acrobatics](~"+characterName+"|Acrobatics) "; macroText += ", [Animal Handling](~"+characterName+"|Animal_Handling) "; macroText += ", [Arcana](~"+characterName+"|Arcana) "; macroText += ", [Athletics](~"+characterName+"|Athletics) "; macroText += ", [Deception](~"+characterName+"|Deception) "; macroText += ", [History](~"+characterName+"|History) "; macroText += ", [Insight](~"+characterName+"|Insight) "; macroText += ", [Intimidation](~"+characterName+"|Intimidation) "; macroText += ", [Investigation](~"+characterName+"|Investigation) "; macroText += ", [Medicine](~"+characterName+"|Medicine) "; macroText += ", [Nature](~"+characterName+"|Nature) "; macroText += ", [Perception](~"+characterName+"|Perception) "; macroText += ", [Performance](~"+characterName+"|Performance) "; macroText += ", [Persuasion](~"+characterName+"|Persuasion) "; macroText += ", [Religion](~"+characterName+"|Religion) "; macroText += ", [Sleight of Hand](~"+characterName+"|Sleight_of_Hand) "; macroText += ", [Stealth](~"+characterName+"|Stealth) "; macroText += ", [Survival](~"+characterName+"|Survival) "; macroText += "\n\nSaves: \n" macroText += "[Str](~"+characterName+"|strength_save) "; macroText += ", [Dex](~"+characterName+"|dexterity_save) "; macroText += ", [Con](~"+characterName+"|constitution_save) "; macroText += ", [Wis](~"+characterName+"|wisdom_save) "; macroText += ", [Int](~"+characterName+"|intelligence_save) "; macroText += ", [Cha](~"+characterName+"|charisma_save) "; } macroText += "}}" // Check for existing ability with chosen ability name var abil = findObjs({ _type: "ability", _characterid: characterObj.get("_id"), name: abilityName }); if (abil.length === 0){ createObj("ability", { name: abilityName, characterid: characterObj.get("_id"), action: macroText, istokenaction: true }); }else{ abil[0].set("action", macroText); } }); } });