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

Simple question: Listing cards in Player hands and on Map

1503426674
Pktome
Pro
Sheet Author
Can you see on the Deck (GM) which cards have been removed and which ones are in the hands of each player? Even if the player is out of the room.
1503435089
The Aaron
Pro
API Scripter
Not in the basic interface.  You can with an API script, though I'm not aware of one written for that purpose.
1503494075
Pktome
Pro
Sheet Author
The Aaron said: Not in the basic interface.  You can with an API script, though I'm not aware of one written for that purpose. Thank you. Usually when I update the plug and some points of my system I create a new room (like copy of the old one). But the cards are not drawn, do you have any light of how I should create this script?
1503498920
The Aaron
Pro
API Scripter
"Room" is a Game/Campaign? The capabilities of the script you want are: Able to show the GM what cards a player has in hand Able to show the GM what cards remain in the deck If that's the case, I think I have 90% of that script written.  I certainly have the 2nd part and all the wiring to add the 1st.
1503518265
Pktome
Pro
Sheet Author
The Aaron said: "Room" is a Game/Campaign? The capabilities of the script you want are: Able to show the GM what cards a player has in hand Able to show the GM what cards remain in the deck If that's the case, I think I have 90% of that script written.  I certainly have the 2nd part and all the wiring to add the 1st. I think so. anyway: 1) GM see cards that are out of the deck (not considering infinity). 1) GM see cards that are still in the deck. 2) GM see cards that are in a player's hand (even if they are offline). 3) GM see cards that are on the table (even if the scenario is archived) I see that a simple message would suffice, just like: GM, Deck XXX has 42/50 cards, being: 3 on the table: Card 1 • Scenery YYY Card 2 • Scenery YYY Card 3 • Scenery YYY 5 on hand: Card 1 • Player 1 Card 2 • Player 1 Card 3 • Player 2 Card 4 • Player 3 Card 5 • Player 5
1503519353
The Aaron
Pro
API Scripter
In this case, "Scenery YYY" is the name of a Map/Page ?
1503519872
Pktome
Pro
Sheet Author
The Aaron said: In this case, "Scenery YYY" is the name of a Map/Page ? Yes.
1503522860
The Aaron
Pro
API Scripter
Do you want to know which cards are in the deck, and what order?  Do you care about the order that cards are in a player's hand?
1503522949

Edited 1503522974
The Aaron
Pro
API Scripter
And I assume this is deck-centric, so you do something like !deck-state Commodities and it would only tell you the state of the Commodities deck?  Wouldn't list other deck's cards in their hand, etc
1503523781
Pktome
Pro
Sheet Author
The Aaron said: And I assume this is deck-centric, so you do something like !deck-state Commodities and it would only tell you the state of the Commodities deck?  Wouldn't list other deck's cards in their hand, etc I did not understand very well, but, the order is not important. Going random (and not knowing what will come) is an advantage in this case. "The cards I use are not conventional cards, they were created to shape the adventure itself, but if the player is offline, I can not create the background because I can not see the card he has taken."
1503524067
The Aaron
Pro
API Scripter
I mean that there is only one deck you are concerned with at a time, that you don't need to know about cards from other decks, just one deck which you specify.
1503529423
Pktome
Pro
Sheet Author
Yes, only one deck (or type of deck, Since this same deck is present on three tables.)
1504303107

Edited 1504317043
The Aaron
Pro
API Scripter
Sorry for the delay, see if this works for you: !deck-state <Deck Name> You can use the minimum matching name for the deck. Help: !deck-state Examples: Help: Multiple matching decks: Output with cards on the table in in multiple hands: Code: (function(){     "use strict";     const          esRE = function (s) {           var escapeForRegexp = /(\\|\/|\[|\]|\(|\)|\{|\}|\?|\+|\*|\||\.|\^|\$)/g;           return s.replace(escapeForRegexp,"\\$1");         },         HE = (function(){           var entities={                   //' ' : '&'+'nbsp'+';',                   '<' : '&'+'lt'+';',                   '>' : '&'+'gt'+';',                   "'" : '&'+'#39'+';',                   '@' : '&'+'#64'+';',                   '{' : '&'+'#123'+';',                   '|' : '&'+'#124'+';',                   '}' : '&'+'#125'+';',                   '[' : '&'+'#91'+';',                   ']' : '&'+'#93'+';',                   '"' : '&'+'quot'+';'               },               re=new RegExp('('+_.map(_.keys(entities),esRE).join('|')+')','g');           return function(s){             return s.replace(re, function(c){ return entities[c] || c; });           };         }()),         ch = function (c) {             var entities = {                 '<' : 'lt',                 '>' : 'gt',                 "'" : '#39',                 '@' : '#64',                 '{' : '#123',                 '|' : '#124',                 '}' : '#125',                 '[' : '#91',                 ']' : '#93',                 '"' : 'quot',                 '-' : 'mdash',                 ' ' : 'nbsp'             };             if(_.has(entities,c) ){                 return ('&'+entities[c]+';');             }             return '';         },                  keyFormat = (s)=>s.toLowerCase().replace(/[^a-z0-9]/,''),         showHelp = function(who){             sendChat('',`/w "${who}" `+             `<div>`+                 `<div>`+                     `<code>!deck-state ${ch('<')}Deck name${ch('>')}</code>`+                 `</div>`+                 `<h4>Deck Name</h4>`+                 `<p>Wherever you specify a deck name, you can use the minimal matching part of the name.  Case is ignored, as are spaces and any punctuation.  ${ch('"')}Bob - the - builder!${ch('"')} would be matched by ${ch('"')}bob${ch('"')} or ${ch('"')}thebui${ch('"')} or a similar substring.</p>`+             `</div>`             );         },                  getDecks = function(name){             let deckKey=keyFormat(name||'');             return deckKey ?                 _.filter(findObjs({ type: 'deck' }), (d)=> -1 !== keyFormat(d.get('name')).indexOf(deckKey)) :                 [];         },         showDeckOptions = function(who,msg,decks,deckName){             let notFound = (decks.length ? '' : `<div style="color:red;font-weight:bold;">No deck found for <code>${deckName}</code></div>`),                 deckOpt = (decks.length ? decks : findObjs({type:'deck'}));             sendChat('',`/w "${who}" `+                 `<div>`+                     notFound+                     `<div><div>Possible options:</div><ul>`+                         _.map(deckOpt,(d)=>{                             return `<li><a href="!deck-state ${HE(d.get('name'))}">${d.get('name')}</a></li>`;                         }).join('')+                     `</ul></div>`+                 `</div>`             );                      },         getLookup = (obj) => _.reduce(findObjs(obj),(m,o)=>{             m[o.id]=o;             return m;         },{}),         deckState = function(deck){             // get cards              let cards = getLookup({                 type: 'card',                 deckid: deck.id             });             let hands = getLookup({                 type: 'hand'             });             let players = getLookup({                 type: 'player'             });             let pages = getLookup({                 type: 'page'             });             let remaining=_.keys(cards);             // for each player, which cards do they have             // map of [playerid] -> array of [card ids]             let inHand = _.reduce(hands,(m,h)=>{                 let cids = _.intersection(h.get('currentHand').split(/,/),remaining);                 if(cids.length){                     m[h.get('parentid')]=_.map(cids,(id)=>cards[id].get('name'));                     remaining=_.difference(remaining,cids);                 }                 return m;             },{});             // for each played card, what map is it on             // map of [pageid] -> array of [card ids]             let played = _.chain(findObjs({                     type: 'graphic',                     subtype: 'card'                 }))                 .filter((c)=>_.contains(remaining,c.get('cardid')))                 .reduce((m,c)=>{                     let pageid=c.get('pageid');                     m[pageid] = (m[pageid]||[]);                     m[pageid].push(cards[c.get('cardid')].get('name'));                     return m;                 },{})                 .value();             remaining = _.map(remaining,(id)=>cards[id].get('name'));             const cf = (t) =>`<span style="display: inline-block;border:1px solid #ccc;border-radius:5px;background-color:white;padding:.1em .5em;">${t}</span>`;             return `<div style="border: 1px solid #666; border-radius: 5px; padding: .25em; background-color: #efefff;">`+                 `<div style="border-bottom: 1px solid #666;font-size: 1.2em;font-weight: bold;">`+                     `Deck ${cf(deck.get('name'))} has <b>${remaining.length}/${_.keys(cards).length}</b> cards.`+                 `</div>`+                 `<div>`+                     `<div style="font-weight: bold;">${_.keys(played).length} table${_.keys(played).length===1 ?' has':'s have'} cards:</div>`+                     `<div><ul>${_.map(played,(cs,pid)=>`<li><b>${pages[pid].get('name')}</b><ul>${_.map(cs.sort(),(c)=>`<li>${cf(c)}</li>`).join('')}</ul></li>`).join('')}</ul></div>`+                     `<div></div>`+                 `</div>`+                 `<div>`+                     `<div style="font-weight: bold;">${_.keys(inHand).length} player${_.keys(inHand).length===1 ?' has' :'s have'} cards:</div>`+                     `<div><ul>${_.map(inHand,(cs,pid)=>`<li><b>${(players[pid]||{get:()=>'[DELETED]'}).get('displayname')}</b><ul>${_.map(cs.sort(),(c)=>`<li>${cf(c)}</li>`).join('')}</ul></li>`).join('')}</ul></div>`+                     `<div></div>`+                 `</div>`+             `</div>`;              };     on('ready',function(){                  on('chat:message',function(msg){             if(msg.type !== 'api' || !playerIsGM(msg.playerid)){                 return;             }             if(msg.content.match(/^!deck-state/)){                 let who=(getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname'),                     deckname = msg.content.replace(/^!deck-state\s*/,''),                     decks = getDecks(deckname);                 if(!deckname.length){                     showHelp(who);                     return;                 }                 if(1 !== decks.length){                     showDeckOptions(who,msg.content,decks,deckname);                     return;                 }                 // show                 _.each(decks, (d)=>{                     sendChat('',`/w "${who}" ${deckState(d)}`);                 });              }         });     }); })();
1504312780
Pktome
Pro
Sheet Author
Hi Aeron, you are the Greater, But, i dont know the problem what happys when i digit other name if not "i" This error: Your scripts are currently disabled due to an error that was detected. Please make appropriate changes to your scripts and click the "Save Script" button and we'll attempt to start running them again. More info... For reference, the error message generated was: TypeError: Cannot read property 'get' of undefined TypeError: Cannot read property 'get' of undefined at _.map (apiscript.js:3026:78) at Function._.map._.collect (/home/node/d20-api-server/node_modules/underscore/underscore.js:172:24) at deckState (apiscript.js:3026:35) at _.each (apiscript.js:3054:48) at Function._.each._.forEach (/home/node/d20-api-server/node_modules/underscore/underscore.js:153:9) at apiscript.js:3053:19 at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:146:1), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:146:1), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1510:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 on my campaing, i have two decks, Playing Cards (default) and "Arkana Deck"
1504316672
The Aaron
Pro
API Scripter
hmmm... want to PM me an invite and GM me?
1504317088
The Aaron
Pro
API Scripter
Actually, think i know the issue.  I updated the script above, try it again?
1504360724
Pktome
Pro
Sheet Author
The Aaron said: Actually, think i know the issue.  I updated the script above, try it again? yeah! is fine XD If I find any bug I will let you know Thx man
1504365531
The Aaron
Pro
API Scripter
Great!