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

Update global variable inside function.

May 29 (10 years ago)

Edited May 29 (10 years ago)
DXWarlock
Sheet Author
API Scripter
I seem to be stuck, Im trying to update a variable inside a function..but it only ever returns the blank var I set at the top of the script.
Even when logging it RIGHT after the function.

I had a similar problem before, and seemed to get it solved by declaring as a var foo = ' ' ; at the top of the script, and then later just doing foo = foo + whatever...but now its not. doing a log(tLOOT); always returns a " ", any ideas?
To help give an idea what Im trying to do. Im trying to make a variable that equals all the loot they find, and instead of sending EACH loot as a chat message itself, causing a lot of "(From soandso)" for each chat..save it all as tLOOT = tLOOT + (Something) into one long var THEN send it.

My variable is
var tLOOT = '' ;

and for example inside a:
sendChat('', "/roll 1t[MiscItems]", function (ops) {

I have:
tLOOT = tLOOT + fPart + "background-color:#A8A142;'>ITEM: " + lootE + "";

which I assume should take tLOOT as nothing add that to it, and repeat for the loop. Only if I log it inside the function itself..then its right, outside it its not it never returns anything other than tLOOT = ' '; if its done inside a function. the only one that works is the money one, since it doesnt use a function (ops)




function myrolls(loota) {
  for(var i = 0; i < loota.length; i++) {
    var ii = (loota[i].indexOf("[[") != -1);
    if(ii == true) {
      var num = loota[i].replace(/[^0-9]/g, '');
      var res1 = num.substr(0, 1);
      var res2 = num.substr(1, 4);
      var i = 1;
      var tot = 0;
      while(i <= res1) {
        var tot = tot + randomInteger(res2);
        i++
      }
      return tot;
    }
  }
}
//--------------
on("chat:message", function (msg) {
  var cmdName = "!loot";
  var tLOOT = '';
  var msgTxt = msg.content;
  if(msg.type == "api" && msgTxt.indexOf(cmdName) !== -1) {
    var msgWho = msg.who;
    var msgFormula = msgTxt.split(" ");
    //---------check if allowed
    var croll = findObjs({_type: 'character',name: 'Z-Mike'})[0];
    var oCanRoll = findObjs({name: "Rolls",_type: "attribute",_characterid: croll.id}, {caseInsensitive: true})[0];
    var rollallow = parseInt(oCanRoll.get("current"));
    if(rollallow != 1) {
      sendChat(msgWho, '/desc Rolling disallowed');
      return;
    }
    //---------catch non players
    var cWho = findObjs({_type: 'character',name: msg.who})[0];
    if(cWho == undefined) {
      var aLooterr = fPart+"background-color:##FF0000;'>" + msg.who + ": roll as your character name</div>";
      sendChat('', "/direct " + aLooterr);
    }
    //do rolls---------------------------------
    if(cWho != undefined) {
      var aLoottext = fPart +"background-color:##0B3B0B;'>" + msg.who + " Looks for loot..</div>";
      sendChat('', "/direct " + aLoottext);
      //set times to run----------------------
      var x = 0;
      var times = msgFormula[1];
      if(times > 10) {
        times = 10;
      }
      while(x < times || x < 1) {
        //---------set cash or loot
        var loots = randomInteger(100);
        if(loots <= 0) {
          //Set Cash Value---------------------------------
          var cWhol = findObjs({_type: 'character',name: msgWho})[0];
          var oLevel = findObjs({name: "Level",_type: "attribute",_characterid: cWhol.id}, {caseInsensitive: true})[0];
          if(oLevel == undefined) oLevel == 1;
          var level = parseInt(oLevel.get("current"));
          var cR1 = randomInteger(1000);
          var T = Math.floor(cR1 / 10);
          var H = Math.floor(cR1 / 100);
          var C = Math.floor(cR1 / 250);
          //---set big payout
          var BigMoney = randomInteger(100);
          var BigM = '';
          if(BigMoney <= 10) {
            var BigM = ('BIG');
            T = (T * 20) + (100 * level);
          }
          var V = randomInteger(10);
          var cR = Math.floor(((T + H + C) * (level / 2)) + V);
          //give money-------------------------
          var cWho = findObjs({_type: 'character',name: msg.who})[0];
          var oC = findObjs({name: "Credits",_type: "attribute",characterid: cWho.id}, {caseInsensitive: true})[0];
          if(oC == undefined || oC.length == 0) {
            sendChat(msgWho, '/direct No Credits Found, please set!');
            return;
          }
          else {
            var credits = parseInt(oC.get("current"));
            var total = credits + cR;
            oC.set('current', total);
          }
          //tell money-------------------------
          var lootE = BigM + '  MONEY:' + cR + ' credits, total: ' + total
          tLOOT = tLOOT + fPart + "background-color:#4D995B;'>MONEY: " + lootE + "</div>";
        }
        else {
          //set loot-------------------------
          var guns = randomInteger(100);
          if(guns >= 2) {
            //mundane loot-------------------------
            sendChat('', "/roll 1t[MiscItems]", function (ops) {
              var loot = JSON.parse(ops[0].content).rolls[0].results[0].tableItem.name;
              var loot1 = loot.split(" ");
              var a = myrolls(loot1);
              var lootE = loot.replace(/\[.*?\]\]/g, a);
              tLOOT = tLOOT + fPart + "background-color:#A8A142;'>ITEM: " + lootE + "</div>";
            });
          }
          else {
            //weapon loot-------------------------
            sendChat('', "/roll 1t[WeaponItems]", function (ops) {
              var loot = JSON.parse(ops[0].content).rolls[0].results[0].tableItem.name;
              var loot1 = loot.split(" ");
              var a = myrolls(loot1);
              var lootE = loot.replace(/\[.*?\]\]/g, a);
              tLOOT = tLOOT + fPart + "background-color:#9E2F2F;'>WEAPON: " + lootE + "</div>";
            });
          }
        }
      log(tLOOT);
      sendChat(msgWho, '/w gm ' + tLOOT);
      sendChat(msgWho, "/w " + msgWho + ' ' + tLOOT);
        x++;
      }
    };
  }
});
May 29 (10 years ago)
Riley D.
Roll20 Team
Once you go inside of the sendChat callback function, you are now dealing with "asynchronous" code. Synchronous means that everything executes in-order from top-to-bottom. Asynchronous means you have to start considering when the code will actually execute, not just what order it appears on the screen. Basically, all of the other code from top-to-bottom is getting executed (including your final sendChat() where you send the loot), then after that your callback functions are getting executed, but it's already "too late." If you sprinkle some log() functions throughout you can see it happening (e.g. you would see the log() by the final sendChat() fire before the log() for inside the callback function.

The easiest thing would just be to send individual sendChats() for each result. If you really just want to send one message once it's all calculated, you can provide you have to keep track of how many functions haven't yet completed, and then only send the final message once they're all done. Here's some more reading on that:

http://tech.pro/blog/1402/five-patterns-to-help-yo...
May 29 (10 years ago)

Edited May 29 (10 years ago)
DXWarlock
Sheet Author
API Scripter
ah..that sneaky Asynchronous screwing with me again :)
is there a way to lookup in a rollable table in API without the sendchat? that might help me without overcomplicating it into learning to track them all and send it after.
May 29 (10 years ago)

Edited May 29 (10 years ago)
Riley D.
Roll20 Team
Well, you can fetch an array of all the rollable table items:

var items = findObjs({_type: "tableitem", _rollabletableid: XXXX});

And then just get a random entry from the array yourself:

var chosen = items[randomInteger(items.length) - 1];

That's basically all the sendChat() is doing anyway.
May 29 (10 years ago)
DXWarlock
Sheet Author
API Scripter
Ah that works, they are all weight 1 anyway.
What would we do without you Riley?