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

Deck Object from Hand Object

Hi all! I'm working on getting my Savage Rifts (Savage Worlds) game set up and I've created a deck of cards to represent bennies (1 card in deck, infinite deals, back and card face are identical images of a poker chip). Adding a bennie to a player's hand is working great, I have it putting the card count in the green status area of the character token to reflect the number of bennies.  The problem I'm having though, is to make sure that it's the proper deck, I'm checking the card name "Bennie", but if they use their last bennie or they're recalled then there's no way to check that. So, is there a way to find out what deck a player's hand belongs to when their hand has no cards? I would think there'd be a way to link the id of the hand back to the id of the deck? I've named the deck "Bennies".
1492440971
The Aaron
Pro
API Scripter
Hand is a collection of cards, only cards belong to decks. If you have cards in hand from multiple decks, they would all just be listed in the currenthand attribute. If you want to know how many cards of which deck, you'd need to grab the card ids out of currenthand and then load the card objects for each one, then check which deck they each belong to.
Interesting, and bummer! I would have thought since a player's hand can be sorted by deck, then there must be some link between the hand and the deck since the hand itself doesn't go away when it's empty... I guess I'll have to find a way to keep up with all of the player's bennie hand ids to validate that it's that hand that I am looking at when the hand is empty...or be lazy since for right now it's the only hand they'll have. Would just be nice to have that validation in there "just in case".
1492442652
The Aaron
Pro
API Scripter
Something like this: let handByDeck = _.chain(hand.get('currenthand').split(/,/)) .map((i)=>getObj('card',i)) .reject(_.isUndefined) .reduce((m,c)=>{ let deckid=c.get('deckid'); m[deckid]=m[deckid]||[]; m[deckid].push(c); return m; },{}) .reduce((m,cs,deckid)=>{ let deck=getObj('deck',deckid); if(deck){ m[deck.get('name')]={ deck: deck, cards: cs }; } return m; },{}) .value(); I haven't tested this code, but if you have the hand object in a variable named hand, it will give you a variable named handByDeck that is keyed by the names of the decks and contains an object with the deck and an array of all the currently held cards.
Oh nice! This certainly gives me something to work with. Thanks for the sample!
1492449277

Edited 1492449847
Here is the script I ended up making, if anyone else has a situation similar: on('ready', function(){     on('change:hand',function(obj,prev){         var playerId = obj.get('_parentid');         if(isGM(playerId)){ return; }                  var handid = obj.get('_id');         var hand = obj.get('_currentHand');                  var hdx = _.indexOf(playerBennieHands, handid);         var cards = hand.split(',');         var ccount = (hand !== '' ? cards.length : 0);         if(ccount > 0){             var card = getObj('card', cards[0]);              if(isBennie(card)){                 if(hdx === -1){ playerBennieHands.push(handid); }                                 setBennieCount(playerId, cards.length);             }         }else{ if(hdx > -1){ setBennieCount(playerId, 0); } }     }); }); var playerBennieHands = []; function isBennie(card){     if(card){ return (card.get('name') === 'Bennie'); }     else{ return false; } } function setBennieCount(playerId, bennies){     var character = findObjs({ type: 'character', controlledby: playerId })[0];     if(character){         var playerToken = findObjs({ type: 'graphic', represents: character.get('_id') })[0];         if(playerToken){             playerToken.set('bar1_value', bennies);             // Green Benny Bar             if(bennies > 0){ playerToken.set('status_green',parseInt(bennies)); }             else{ playerToken.set('status_green',false); }         }     } } I exit the function if the hand belongs to the GM as the GM doesn't have specific tokens to place bennies on.
1492451355
The Aaron
Pro
API Scripter
I might suggest a minor reorganization: on('ready', function(){   var playerBennieHands = [];   function isBennie(card){     if(card){ return (card.get('name') === 'Bennie'); }     else{ return false; }   }   function setBennieCount(playerId, bennies){     var character = findObjs({ type: 'character', controlledby: playerId })[0];     if(character){       var playerToken = findObjs({ type: 'graphic', represents: character.get('_id') })[0];       if(playerToken){         playerToken.set('bar1_value', bennies);         // Green Benny Bar         if(bennies > 0){ playerToken.set('status_green',parseInt(bennies)); }         else{ playerToken.set('status_green',false); }       }     }   }   on('change:hand',function(obj,prev){     var playerId = obj.get('_parentid');     if(isGM(playerId)){ return; }     var handid = obj.get('_id');     var hand = obj.get('_currentHand');     var hdx = _.indexOf(playerBennieHands, handid);     var cards = hand.split(',');     var ccount = (hand !== '' ? cards.length : 0);     if(ccount > 0){       var card = getObj('card', cards[0]);        if(isBennie(card)){         if(hdx === -1){ playerBennieHands.push(handid); }                         setBennieCount(playerId, cards.length);       }     }else{ if(hdx > -1){ setBennieCount(playerId, 0); } }   }); }); Moving that variable and those functions inside the on('ready',...) leaves them accessible to your handler function, but keeps them from polluting the global namespace (All scripts are concatenated together).
1492451457

Edited 1492451585
The Aaron
Pro
API Scripter
Also, you should use if( playerIsGM (playerId)){ return; } playerIsGM() is a built in function.  isGM() is a function I wrote several years ago because there wasn't a function.  This way, you won't require my isGM script, which just calls playerIsGM() in the modern version anyway. Something you might not know, you can use .id to get the id of a Roll20 object: var handid = obj.id; Also, you can leave the _ off on read only properties: var playerId = obj.get('parentid'); Looks like a nice script!
Awesome! Thanks for the heads up on all that Aaron! I'm still learning the caveats! Time to update :D