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,Snippet] RetrieveTokens -- get graphics that are off the page

December 23 (5 years ago)
The Aaron
Roll20 Production Team
API Scripter

Kind of situational, but here's a little script that will move tokens that are off the page onto the closest edge.

Just run:

!retrieve-tokens

And any tokens that have gotten moved off the bounds of the page will be pulled to overlap the edge by half.

Script:

on('ready',()=>{

  const EPSILON = 5;

  const getPageForPlayer = (playerid) => {
    let player = getObj('player',playerid);
    if(playerIsGM(playerid)){
      return player.get('lastpage');
    }

    let psp = Campaign().get('playerspecificpages');
    if(psp[playerid]){
      return psp[playerid];
    }

    return Campaign().get('playerpageid');
  };


  on('chat:message', (msg) => {
    if('api'===msg.type && playerIsGM(msg.playerid) && /^!retr(ie|ei)ve(\b|$)-tokens/i.test(msg.content)){
      let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname');

      let pid = getPageForPlayer(msg.playerid);
      let page = getObj('page',pid);
      let pHeight=page.get('height')*70;
      let pWidth=page.get('width')*70;

      const outside = (t) => {
        let hw = (t.get('width')/2)-EPSILON;
        let hh = (t.get('height')/2)-EPSILON;

        let offU = (t.get('top')+hh)<0;
        let offL = (t.get('left')+hw)<0;
        let offD = (t.get('top')-hh)>pHeight;
        let offR = (t.get('left')-hw)>pWidth;

        return offL || offR || offU ||offD;
      };

      const moveOn = (t) => {
        let opts = {};
        let x = t.get('left');
        let y = t.get('top');

        if(x < 0){
          opts.left = 0;
        }
        if(x > pWidth){
          opts.left = pWidth;
        }
        if(y < 0){
          opts.top = 0;
        }
        if(y > pHeight){
          opts.top = pHeight;
        }

        t.set(opts);
      };

      let tokens = findObjs({
        type: 'graphic',
        pageid: pid
      }).filter(outside);

      tokens.forEach(moveOn);

      let fixed= tokens.length;

      sendChat('RetrieveTokens',`/w "${who}" <div>Fixed ${fixed} tokens.</div>`);

    }
  });
});


December 23 (5 years ago)
keithcurtis
Forum Champion
Marketplace Creator
API Scripter

This happens when I copy all the tokens from a large map and am not careful when pasting them to another. Nice!

December 23 (5 years ago)
The Aaron
Roll20 Production Team
API Scripter

I've had it happen when I resized a page without thinking about it, and also when I've selected a bunch of things to move and didn't realize I had one near the edge. 

December 23 (5 years ago)
vÍnce
Pro
Sheet Author

Another solution to a problem I didn't even know I had.  ;-P

Thanks Aaron

Awesome! I wonder how many lost tokens will turn up with this :p

December 23 (5 years ago)
The Aaron
Roll20 Production Team
API Scripter

Yup. 

Cleaning out the Roll20 Couch Cushions since 2019!