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

[Script] Augh!!!! To many macro buttons!!!! I know I will add some more! That will fix it! (Scrolling Macro bar)

December 01 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter









Need to sort through a way to organize these.... but it can be done and seems to work great!

scrollleft = function(msg) {
var macro1name = findObjs({ _type: "macro", _id: "-J9fiY13CHFalnrnFmzn"})[0].get("name");
var macro1action = findObjs({ _type: "macro", _id: "-J9fiY13CHFalnrnFmzn"})[0].get("action");
var macro2name = findObjs({ _type: "macro", _id: "-J9fidotpUxCzVbZZtOV"})[0].get("name");
var macro2action = findObjs({ _type: "macro", _id: "-J9fidotpUxCzVbZZtOV"})[0].get("action");
var macro3name = findObjs({ _type: "macro", _id: "-J9filI9RbRQc-vhufYN"})[0].get("name");
var macro3action = findObjs({ _type: "macro", _id: "-J9filI9RbRQc-vhufYN"})[0].get("action");
findObjs({ _type: "macro", _id: "-J9fiY13CHFalnrnFmzn"})[0].set({name: macro2name});
findObjs({ _type: "macro", _id: "-J9fiY13CHFalnrnFmzn"})[0].set({action: macro2action});
findObjs({ _type: "macro", _id: "-J9fidotpUxCzVbZZtOV"})[0].set({name: macro3name});
findObjs({ _type: "macro", _id: "-J9fidotpUxCzVbZZtOV"})[0].set({action: macro3action});
findObjs({ _type: "macro", _id: "-J9filI9RbRQc-vhufYN"})[0].set({name: macro1name});
findObjs({ _type: "macro", _id: "-J9filI9RbRQc-vhufYN"})[0].set({action: macro1action});
};
scrollright = function(msg) {
var macro1name = findObjs({ _type: "macro", _id: "-J9fiY13CHFalnrnFmzn"})[0].get("name");
var macro1action = findObjs({ _type: "macro", _id: "-J9fiY13CHFalnrnFmzn"})[0].get("action");
var macro2name = findObjs({ _type: "macro", _id: "-J9fidotpUxCzVbZZtOV"})[0].get("name");
var macro2action = findObjs({ _type: "macro", _id: "-J9fidotpUxCzVbZZtOV"})[0].get("action");
var macro3name = findObjs({ _type: "macro", _id: "-J9filI9RbRQc-vhufYN"})[0].get("name");
var macro3action = findObjs({ _type: "macro", _id: "-J9filI9RbRQc-vhufYN"})[0].get("action");
findObjs({ _type: "macro", _id: "-J9fiY13CHFalnrnFmzn"})[0].set({name: macro3name});
findObjs({ _type: "macro", _id: "-J9fiY13CHFalnrnFmzn"})[0].set({action: macro3action});
findObjs({ _type: "macro", _id: "-J9fidotpUxCzVbZZtOV"})[0].set({name: macro1name});
findObjs({ _type: "macro", _id: "-J9fidotpUxCzVbZZtOV"})[0].set({action: macro1action});
findObjs({ _type: "macro", _id: "-J9filI9RbRQc-vhufYN"})[0].set({name: macro2name});
findObjs({ _type: "macro", _id: "-J9filI9RbRQc-vhufYN"})[0].set({action: macro2action});
};

You need to add your brand of API parsing and point your "left" "right" macros to the functions.... and of course get your marco _id's..
... and shift in an array would be better...


December 01 (11 years ago)
This is cool, your code crazy man! Good Stuff you are putting out!
December 01 (11 years ago)
Lithl
Pro
Sheet Author
API Scripter
Neat idea, though hardcoding that ID makes me cringe.
December 01 (11 years ago)

Edited December 01 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
You only need hard code the _ids (or even have macros that actually exist) for the the number of macros you want to see across the bottom. (plus two for the arrows) and it doesn't matter what they are called or what they do.

After that all your macros exist in an array....

{name: "Slay Big Mike", action: "/me hits Big Mike for [[1d1000]] points of damage."]]},
{name: "Poison Big Mike", action: "/me pours Big Mike a ice cold beer."]]}.
{name: "Push Big Mike", action: "/me shoves Big Mike off the edge."]]}

December 01 (11 years ago)

Edited December 01 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
[<<] [<] [Button1] [Button2] [Button3] [Button4] [Button5] [Button6] [>] [>>] [Add] [Remove][Find]
This would even be better....

December 01 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter


[<<] [<] [Button0001] [Button0002] [Button0003] [Button0004] [>] [>>] [Add] [Remove] [Find] [Button00000005]
"Buttons 1-4" Scroll..... "Button 5" is the last macro used... "add/remove" will add (if not already in the array) or remove the last last macro used from the list...

And !macroids (or something like it) creates a sheet with the array code needed to be added to the script:

var buttonIds = new Array();
buttonIds[0] = "-J9i7S7fX-KbcZAvnOmx"
buttonIds[1] = "-J9i7dcZvuooiiur7b7l"
buttonIds[2] = "-J9i7l_FYolAA1G1A3Dg"
buttonIds[3] = "-J9i7n3xb70-gXCGXRhS"
buttonIds[4] = "-J9iAq9bGulEFXecE9Dd"
A "set" will be created for each player (or new player)
December 01 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
????

createObj({
_type: "macro",
name: "<<",
action: "<<",
visibleto: playid,
});

Gives me....

"ERROR: Tried to create an invlid object type. See the API Documentation for valid types."

Wiki:

createObj(type, attributes)
Note: currently you can create 'graphic', 'text', 'path', 'character', 'ability', 'attribute', 'handout', 'rollabletable', 'tableitem', and 'macro' objects.

Have I not had enough coffee? What am I missing here?


December 01 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
https://app.roll20.net/forum/post/142856/new-api-update-5-slash-2-and-5-slash-3-create-objects#post-144003

So.... the wiki is incorrect?

:/
December 02 (11 years ago)
dev or main
December 02 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
main
December 02 (11 years ago)

Stephen S. said:

You only need hard code the _ids (or even have macros that actually exist) for the the number of macros you want to see across the bottom. (plus two for the arrows) and it doesn't matter what they are called or what they do.

After that all your macros exist in an array....

{name: "Slay Big Mike", action: "/me hits Big Mike for [[1d1000]] points of damage."]]},
{name: "Poison Big Mike", action: "/me pours Big Mike a ice cold beer."]]}.
{name: "Push Big Mike", action: "/me shoves Big Mike off the edge."]]}


I really need to be careful!!
December 02 (11 years ago)

Edited December 02 (11 years ago)
as far as I understand, you can't create macros on main yet, its in the rugged reroll update which doesnt hit the main servers until the 16th.
best to write and test your scripts and have them ready on the Dev server, and port them over when they reach functionality on main.
December 02 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
There is good news and there is bad news....

First the good news... the left right arrows:



Can be used by anyone (they just trigger a API script which comes with msg.playerid so you know who's macro buttons to move left and right.



The sort of bad news is the the buttons that scroll have to be build by the player themselves so they carry the "create" _playerid so the left right arrows can be related to them easily.

After that is where things get bad.... it gets tricky when you start thinking about mixing macros and abilities in the bar (especially from multiple characters. It seems to me you have to give something up here..... OR.. you have to hold an array in the state object all this... and way to "build and remove" abilities/macros into and out of that state array.

This doesn't seem worth it to me.... This is looking more like a "suggestion" then an API script.
December 03 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Would still be nice for API commands.... small wrap around for them.. you have to code for those anyhow.
December 03 (11 years ago)
Lithl
Pro
Sheet Author
API Scripter

Stephen S. said:

https://app.roll20.net/forum/post/142856/new-api-update-5-slash-2-and-5-slash-3-create-objects#post-144003

So.... the wiki is incorrect?

:/
Riley has been updating the wiki preemptively. =)

December 03 (11 years ago)

Edited December 03 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter

Ha! In spite of his efforts to confuse and confound me... I have managed to eke out a win of sorts...


var macroScroll = macroScroll || {};


on("chat:message", function(msg) {
    if(msg.type == "api"){
        if(msg.content.indexOf(' ') == -1){
            var msgMessage = null;
            var msgApiCommand = msg.content.substr(1, msg.content.length);
        }else{
            var msgMessage = msg.content.substr(msg.content.indexOf(' ') + 1);
            var msgApiCommand = msg.content.substr(1, msg.content.indexOf(' ')-1);
        };
        macroScroll.Playerid = msg.playerid;


        if(msgApiCommand == "macroids"){
            macroScroll.utilityScroll = "API_Utility_Scrolling_Macro_Bar";
            macroids();
        };


        if(msgApiCommand == "macroleftone"){
            macroleft(1);
            macroupdate();
        }; 
        if(msgApiCommand == "macrorightone"){
            macroright(1);
            macroupdate();
        };
        if(msgApiCommand == "macroleftmany"){
            macroleft(3);
            macroupdate();
        };
        if(msgApiCommand == "macrorightmany"){
            macroright(3);
            macroupdate();
        };
    };
});


macroids = function(msg) {
    var findPlayers = findObjs({_type: "player",});
    var findMacros = findObjs({_type: "macro",});
    var playerCode = "<code>"
    playerCode = playerCode + "Refresh using \"!macroids\""
    playerCode = playerCode + "</code><br><br>"
    _.each(findMacros, function(loopMacros) {
        if(loopMacros.get("action").length == 0){
            var createrid = loopMacros.get("_playerid")
            var createrR20id = "Unknown";
            var createrDname = "Unknown";
            _.each(findPlayers, function(loopPlayer) {
                if(loopPlayer.get("_id") == createrid){
                    createrDname = loopPlayer.get("_displayname");
                    createrR20id = loopPlayer.get("_id");
                }
            });
            playerCode = playerCode + "<code>"
            playerCode = playerCode + loopMacros.get("name") + " _id = " + loopMacros.get("_id") + "<br>";
            playerCode = playerCode + createrDname + " _id = " + createrR20id + "<br>";
            playerCode = playerCode + "</code></br><br>"
        };
    });
    if(findObjs({ _type: "handout", name: macroScroll.utilityScroll }).length == 0){
        createObj("handout", {
            name: macroScroll.utilityScroll,
        });        
    };
    APIPlayerCode = findObjs({ _type: "handout", name: macroScroll.utilityScroll })
    APIPlayerCode[0].set("notes", playerCode);
};    
    
macroleft = function(repeat) {
    var characterid = undefined;
    var findCharacter = findObjs({_type: "character", name: macroScroll.Playerid});
    var characterid = findCharacter[0].get("_id");
    if(characterid !== undefined){
        var findAbility = findObjs({_type: "ability", _characterid: characterid});
        var nameArray = [];
        var actnArray = [];
        for (var abilityCount = 0;abilityCount<findAbility.length;abilityCount++){ 
            nameArray[abilityCount] = findAbility[abilityCount].get("name");
            actnArray[abilityCount] = findAbility[abilityCount].get("name");
        };
        var i = 0;
        while (i < repeat) {
            nameArray.push(nameArray.shift());
            actnArray.push(actnArray.shift());
            i++;
        };
        for (var abilityCount = 0;abilityCount<findAbility.length;abilityCount++){
            findAbility[abilityCount].set({name: nameArray[abilityCount]});
            findAbility[abilityCount].set({name: actnArray[abilityCount]});
        };   
    };
};


macroright = function(repeat) {
    var characterid = undefined;
    var findCharacter = findObjs({_type: "character", name: macroScroll.Playerid});
    var characterid = findCharacter[0].get("_id");
    if(characterid !== undefined){
        var findAbility = findObjs({_type: "ability", _characterid: characterid});
        var nameArray = [];
        var actnArray = [];
        for (var abilityCount = 0;abilityCount<findAbility.length;abilityCount++){ 
            nameArray[abilityCount] = findAbility[abilityCount].get("name");
            actnArray[abilityCount] = findAbility[abilityCount].get("name");
        };
        nameArray.reverse()
        actnArray.reverse()
        var i = 0;
        while (i < repeat) {
            nameArray.push(nameArray.shift());
            actnArray.push(actnArray.shift());
            i++;
        };
        nameArray.reverse()
        actnArray.reverse()
        for (var abilityCount = 0;abilityCount<findAbility.length;abilityCount++){
            findAbility[abilityCount].set({name: nameArray[abilityCount]});
            findAbility[abilityCount].set({name: actnArray[abilityCount]});
        };   
    };
};


macroupdate = function() {
    var characterid = undefined;
    var findCharacter = findObjs({_type: "character",name: macroScroll.Playerid});
    var characterid = findCharacter[0].get("_id");
    var findAbility = findObjs({_type: "ability", _characterid: characterid});
    if(characterid !== undefined){
        var findAttribute = findObjs({_type: "attribute", _characterid: characterid});
        var buttonidArray = [];
        for (var attributeCount = 0;attributeCount<findAttribute.length;attributeCount++){ 
            buttonidArray[attributeCount] = findAttribute[attributeCount].get("current");
        };
    };
    for (var buttonCount = 0;buttonCount<buttonidArray.length;buttonCount++){ 
            findObjs({_type: "macro", _id: buttonidArray[buttonCount]})[0].set({name: findAbility[buttonCount].get("name")});
            findObjs({_type: "macro", _id: buttonidArray[buttonCount]})[0].set({action: findAbility[buttonCount].get("action")});
        };
};



Step1) Make these buttons usable by all (share these)



[<<] action is !macroleftmany
[<] action is !macroleftone
[>] action is !macrorightone
[>>] action is !macrorightmany

Step2) makes these buttons usable only (do not share these and should be made by the player who will own them.)



THE ACTION FOR THESE MUST BE BLANK

Step3) enter the API command !macroids and look for hand out called API_Utility_Scrolling_Macro_Bar



This gives you all the button ids and user id (this is why the action needs to be blank so they can be found from any others)

Step4) Make a character sheet where the name is the player ID



The attributes is the array of button ids.... once set you never have to change or edit the API!!! Easy to add other players.

The abilities are now the macro array.... just build whatever you want here.... add or remove...

The [<<] [<] [>] [>>] scrolls these up and down too!!!

Here is how it looks at the start and stepped through....



Very little hard coding and its really to add the character sheets with a utility aid....

Just repeats steps 2, 3 4 for each player (players should build the buttons in step 2.)

Character creations APIs could be used to makes dozens of macros to scroll through.... and you still have room and can have non-scolling buttons...
December 03 (11 years ago)
Sweet! Way to go!
December 09 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter



This trick I am using in "Trader Joe" could be used to make a menu for API commands.. and reduce the number of macro buttons you need.
December 21 (11 years ago)
After step 2, when I execute !macroids:

API_Utility_Scrolling_Macro_Bar is created but is empty

I get "ERROR: You cannot set the imgsrc or avatar of an object unless you use an image that is in your Roll20 Library. See the API documentation for more info." in the API output console.
December 21 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
It shouldn't be trying to set an imgscrc.

I haven't reworked this since the update however....
December 21 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
And really if we can now create Macros this should be rewritten.
December 22 (11 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Something like this...

scrollingMacros = function() {
	var excludeMacros = ["<<","<",">",">>"]
	state.macroArray = undefined;  
	roll20API.macroArray = [
		{id: "",  name: "<<", action: "!leftthree"},
		{id: "",  name: "<", action: "!leftone"},
		{id: "",  name: "a", action: "!a"},         
		{id: "",  name: "b", action: "!b"},
		{id: "",  name: "c", action: "!c"},
		{id: "",  name: "d", action: "!d"},
		{id: "",  name: "e", action: "!e"},
		{id: "",  name: "f", action: "!f"},
		{id: "",  name: ">", action: "!rightone"},
		{id: "",  name: ">>", action: "!rightThree"},
	];
	state.macroArray = [];
	_.each(roll20API.macroArray, function(indexMacro) {
		createObj("macro", {
			name: indexMacro.name,
			action: indexMacro.action,
			_playerid: roll20API.playerSentId
		});
		if(indexMacro.name(excludeMacros) == -1){
			state.macroArray.push({
				id: findObjs({ _type: "macro", name: indexMacro.name })[0].get("_id"), 
				name: indexMacro.name, 
				action: indexMacro.action
			});
		};
	});    
};

Then the array of macros is in stored in "state."

What would be really nice is the ability to "DELETE" objects <-HINT-HINT