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

Add attribute API?

I've heard that there are add attribute scripts out there. However, the ones I have found are part of larger scripts and as a code illiterate person I don't know how to make them work. Anyone point me at a script that works, and how to use it? I need to add 4 attributes, with different text values, to all of my npcs and pcs and that is a pain in the butt to do manually
1432915926

Edited 1432916548
Invincible Spleen
Pro
Sheet Author
Hi Kunguru! I've written something along those lines for a specific game I'm running, but it didn't take long to make it a little more system-neutral: var DefaultAttributes = DefaultAttributes || (function () { 'use strict'; // Attributes all characters should have var attributeHash = { "Attribute1": { "current": "Some text", }, "Attribute2": { "current": "Blah", }, "Attribute3": { "current": "Words words words", }, "Attribute4": { "current": "asdasdf", } }, // Function which adds missing attributes to a character addAttributes = function(characterID, attributeHash) { for (var key in attributeHash) { if (attributeHash.hasOwnProperty(key)) { var foundAttribute = findObjs({ _characterid: characterID, name: key })[0]; if (!foundAttribute) { log("Attribute " + key + " not found for character ID " + characterID + " Creating."); createObj("attribute", { name: key, current: attributeHash[key]["current"], characterid: characterID }); } } } }, // Add all missing attributes to a character initCharacterAttributes = function(char){ addAttributes(char.id, attributeHash); }, // Manually add missing attributes to all existing characters handleInput = function(msg) { if(msg.type == "api" && msg.content == "!initattributes") { log("Initializing attributes for all existing characters."); var allCharacters = findObjs({ _type: "character" }); _.each(allCharacters, function(char) { initCharacterAttributes(char); }); } }, // Event triggers registerEventHandlers = function() { on("add:character", initCharacterAttributes); on("chat:message", handleInput); }; return { RegisterEventHandlers: registerEventHandlers }; })(); on("ready", function() { 'use strict'; DefaultAttributes.RegisterEventHandlers(); }); You can change the attributes in attributeHash to what you want to see on every character. By default, this will only affect newly created characters, but if you use the !initattributes command, it will add the attributes to all preexisting characters.
Doesn't seem to be working. When I create a new character sheet it isn't added to attributes, and the !initattributes doesn't add them either. It doesn't throw an error or a message in to chat.
Tested and working for me... Leave your API Script Editor page open in its own tab and check if there's any funny output on the Output Console when you add characters or run !initattributes. You should post what you changed attributeHash to contain too, since that's probably the only part of the code you changed.
Here is what I changed the attribute hash to // Attributes all characters should have var attributeHash = { "Token_Title": { "current": "the", }, "Token_Subj": { "current": "he", }, "Token_Obj": { "current": "him", }, "Token_Poss": { "current": "his", } }, the only thing that pops up in the api is the following: "msg.content: !initattributes" that is when I type in !initattributes. When i create a character nothing happens. Here is the newly created character:
Not sure what the issue could be... Works fine for me with your changes. Dumb question: did you save the script? If so, are you running other scripts? I'm testing this on a fresh campaign with nothing else going on script-wise.
Will this script work to modify existing Attribute values that are already on a character sheet?
Kunguru said: Here is what I changed the attribute hash to // Attributes all characters should have var attributeHash = { "Token_Title": { "current": "the", }, "Token_Subj": { "current": "he", }, "Token_Obj": { "current": "him", }, "Token_Poss": { "current": "his", } }, the only thing that pops up in the api is the following: "msg.content: !initattributes" that is when I type in !initattributes. When i create a character nothing happens. Here is the newly created character: I think you should open a bug report on this... I was getting the same thing (meaning "msg.content: <api command>" appearing in the api console) attempting to run api commands in a friends campaign. It was baffling...
1432924135

Edited 1432924970
Invincible Spleen
Pro
Sheet Author
Hi Nyghtmare. This one just creates attributes that don't exist yet. If you want to modify existing values things have to be a little more complicated. For example, below where it says: if (!foundAttribute) { log("Attribute " + key + " not found for character ID " + characterID + " Creating."); createObj("attribute", { name: key, current: attributeHash[key]["current"], characterid: characterID }); } You could add: else { log("Attribute " + key + " found for character ID " + characterID + ". Overwriting."); _.each(foundAttribute, function(attr) { attr.set("current", attributeHash[key]["current"]); }); } This would overwrite existing attributes with the default values you configured in attributeHash.
Yeah, a bug report is probably a good idea. I can't seem to reproduce the issue.
Thanks invincible. I will do that.
Working now, weird. Thanks!
Glad it's working for you!
1433284819
Sam
Sheet Author
Hey Invincible Spleen nice job on this api. Any chance you would be willing to modify it to accept a !setAttribute command were we could tell it on the fly a new attribute to create if it doesn't exists or update if it does? I would love to use this to keep track of my burn and nonlethal values in a game and I've been looking for something to do just that. I would also love an ability to take the value of the attribute if it exists and then add a new value to it. For example this would be my macro !setAttribute burn +1 !setAttribute nonlethal-damage +[[@{level}]]
1433435183

Edited 1433436096
Invincible Spleen
Pro
Sheet Author
Samuel T. said: Hey Invincible Spleen nice job on this api. Any chance you would be willing to modify it to accept a !setAttribute command were we could tell it on the fly a new attribute to create if it doesn't exists or update if it does? I would love to use this to keep track of my burn and nonlethal values in a game and I've been looking for something to do just that. I would also love an ability to take the value of the attribute if it exists and then add a new value to it. For example this would be my macro !setAttribute burn +1 !setAttribute nonlethal-damage +[[@{level}]] This is starting to get pretty robust, but there are likely still ways you can creatively break it. var DefaultAttributes = DefaultAttributes || (function () { 'use strict'; // Attributes all characters should have var attributeHash = { "Attribute1": { "current": "Some text" }, "Attribute2": { "current": "Blah" }, "Attribute3": { "current": "Words words words" }, "Attribute4": { "current": "asdasdf" } }, // Set an attribute's value, or create it if it does not exist setAttribute = function(characterID, attributeName, newValue, operator) { var mod_newValue = { "+": function (num) { return num; }, "-": function (num) { return -num; } }, foundAttribute = findObjs({ _characterid: characterID, _type: "attribute", name: attributeName })[0]; if (!foundAttribute) { if (typeof operator !== 'undefined' && !isNaN(newValue)) { log (newValue + " is a number."); newValue = mod_newValue[operator](newValue); } log("DefaultAttributes: Initializing " + attributeName + " on character ID " + characterID + " with a value of " + newValue + "."); sendChat("DefaultAttributes:", "/w GM Initializing " + attributeName + " on character ID " + characterID + " with a value of " + newValue + "."); createObj("attribute", { name: attributeName, current: newValue, characterid: characterID }); } else { if (typeof operator !== 'undefined' && !isNaN(newValue) && !isNaN(foundAttribute.get("current"))) { newValue = parseFloat(foundAttribute.get("current")) + parseFloat(mod_newValue[operator](newValue)); } log("DefaultAttributes: Setting " + attributeName + " on character ID " + characterID + " to a value of " + newValue + "."); sendChat("DefaultAttributes:", "/w GM Setting " + attributeName + " on character ID " + characterID + " to a value of " + newValue + "."); foundAttribute.set("current", newValue); } }, // Add missing attributes and restore exiting ones to their default values initCharacterAttributes = function(char){ log("DefaultAttributes: Initializing default attributes for character ID " + char.id + "."); sendChat("DefaultAttributes:", "/w GM Initializing default attributes for character ID " + char.id + "."); for (var key in attributeHash) { if (attributeHash.hasOwnProperty(key)) { setAttribute(char.id, key, attributeHash[key]["current"]); } } }, showHelp = function () { sendChat("DefaultAttributes:", "/w GM Syntax is !setattribute <i>Attribute</i> [+/-] <i>Value</i>"); }, handleInput = function(msg) { if(msg.type == "api" && isGM(msg.playerid)) { var args = msg.content.split(/\s+/); switch(args[0]) { case '!initattributes': log("DefaultAttributes: Initializing default attributes for all existing characters."); sendChat("DefaultAttributes:", "/w GM Initializing default attributes for all existing characters."); var allCharacters = findObjs({ _type: "character" }); _.each(allCharacters, function(char) { initCharacterAttributes(char); }); break; case '!setattribute': if (args.length < 3 || args.length > 4) { return showHelp(); } var foundCharacter = findObjs({ _type: "character", name: msg.who })[0]; if (foundCharacter) { if (args[2] == "+" || args[2] == "-") { setAttribute(foundCharacter.id, args[1], args[3], args[2]); } else { setAttribute(foundCharacter.id, args[1], args[2]); } } else { log("DefaultAttributes: No character associated with " + msg.who); sendChat("DefaultAttributes:", "/w GM No character associated with " + msg.who); } break; } } }, // Event triggers registerEventHandlers = function() { on("add:character", initCharacterAttributes); on("chat:message", handleInput); }; return { RegisterEventHandlers: registerEventHandlers }; })(); on("ready", function() { 'use strict'; DefaultAttributes.RegisterEventHandlers(); }); Note that the IsGM script is required now. We probably don't want players resetting every character's attributes to their default values...
1433436030
Sam
Sheet Author
Will the isGM script allow me to set the attribute values of a character I do control even if I'm not a GM?
1433436487

Edited 1433436512
Invincible Spleen
Pro
Sheet Author
Samuel T. said: Will the isGM script allow me to set the attribute values of a character I do control even if I'm not a GM? Quick fix to allow that is to replace the handleInput function with: handleInput = function(msg) { if(msg.type == "api") { var args = msg.content.split(/\s+/); switch(args[0]) { case '!initattributes': if(isGM(msg.playerid)) { log("DefaultAttributes: Initializing default attributes for all existing characters."); sendChat("DefaultAttributes:", "/w GM Initializing default attributes for all existing characters."); var allCharacters = findObjs({ _type: "character" }); _.each(allCharacters, function(char) { initCharacterAttributes(char); }); } break; case '!setattribute': if (args.length < 3 || args.length > 4) { return showHelp(); } var foundCharacter = findObjs({ _type: "character", name: msg.who })[0]; if (foundCharacter) { if (args[2] == "+" || args[2] == "-") { setAttribute(foundCharacter.id, args[1], args[3], args[2]); } else { setAttribute(foundCharacter.id, args[1], args[2]); } } else { log("DefaultAttributes: No character associated with " + msg.who); sendChat("DefaultAttributes:", "/w GM No character associated with " + msg.who); } break; } } }, Feedback messages are all still going to the GM, though, so you'll want to redirect those. Functionality is all there, though!
1433451927
Gen Kitty
Forum Champion
The isGM script was replaced with a builtin function a few updates ago, but I can't remember the syntax of it. Hopefully a coder will stop by and grant us the needed knowledge.
GenKitty said: The isGM script was replaced with a builtin function a few updates ago, but I can't remember the syntax of it. Hopefully a coder will stop by and grant us the needed knowledge. Thanks for pointing this out! I didn't realize that was a built-in thing'. Fixing the script so it's no longer dependent on external scripts is as simple as changing the line: if (isGM(msg.playerid)) { to: if (playerIsGM(msg.playerid)) {
1433470115
Sam
Sheet Author
Do you know of that will allow a non gm player to adjust a sheet they own?
Samuel T. said: Do you know of that will allow a non gm player to adjust a sheet they own? Yes, it will. The script only checks if you're the GM if you try to use the !initattributes command to set all characters' attributes to the defaults you set up.
1433514794
Sam
Sheet Author
Awesome work, I'll be sure to try it out, thanks so much