Last active
November 18, 2017 04:12
-
-
Save Parmeisan/9864305 to your computer and use it in GitHub Desktop.
Roll20 - Deck Utilities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var parm_deck_util = parm_deck_util || {}; | |
parm_deck_util.debugging = false;//true;// | |
parm_deck_util.speak_as = "Deck-Util"; | |
parm_deck_util.whisper = ""; | |
parm_deck_util.deck; | |
parm_deck_util.rtable; | |
on("chat:message", function(msg) | |
{ | |
var ns = parm_deck_util; | |
var words = msg.content.split(" "); | |
var w = 0; | |
if(msg.type == "api" && words[w++] == "!deck-util") | |
{ | |
// You must include one or both of a Deck name or a Rollable Table name | |
// If the Deck is "none" or invalid, then it uses the Rollable Table. | |
// If you leave out the Rollable Table, it checks for one with the same | |
// name as the Deck. If that's "none" or invalid, it uses weights all at 1. | |
var deck_name = words[w++]; | |
var rtable_name; | |
if (words[w].indexOf("!") == 0) rtable_name = deck_name; | |
else rtable_name = words[w++]; | |
ns.deck = findObjs({ _type: "deck", name: deck_name })[0]; | |
ns.rtable = findObjs({ _type: "rollabletable", name: rtable_name })[0]; | |
// Check to see whether to to randomly pick one (the default) or to return everything. | |
var listing = (_.indexOf(words, "!all") >= 0); | |
// Check whether to create a token or not. At some point, this will deal from the | |
// deck when a valid deck is given, but right now all it can do is create new | |
// tokens objects, so I'll just use the rollable table image or card images. | |
var make_token = (_.indexOf(words, "!token") >= 0); | |
// Check to see who to reply to (everyone by default) | |
ns.whisper = (_.indexOf(words, "!w") >= 0) ? "/w " + msg.who + " " : ""; | |
// If the input contains !filter, parse from that to the end (or the next !) | |
// All the words in this section should begin and end with quotes. | |
// Words with no operator must be in the results. | |
// Words beginning with ^ must not be in the results. | |
var filters = []; | |
for (var i = _.indexOf(words, "!filter") + 1; 0 < i && i < words.length; i++) | |
{ | |
if (words[i].indexOf("!") == 0) break; | |
else | |
{ | |
// Technically, all words and word groups must be surrounded with quotes. | |
// In practice, I'm going to add all words that don't start with a quote | |
// to the preceding word, and ignore all other quotes. | |
// Except the first word - it should still be treated as the first word. | |
var trimmed = ns.replaceAll(words[i], "\"", ""); | |
if (words[i].indexOf("\"") == 0) | |
filters[filters.length] = trimmed; | |
else | |
{ | |
var pos = _.max([0 , filters.length - 1]); | |
filters[pos] = filters[pos] + " " + trimmed; | |
} | |
} | |
} | |
// Anything that isn't expected is ignored. | |
// Now... *rubs hands* | |
ns.debug("Deck: " + deck_name); | |
ns.debug("RTable: " + rtable_name); | |
ns.debug("Filters: " + filters); | |
// Load up an array with the Rollable Table values that match | |
var rt = []; | |
if (ns.isnull(ns.rtable)) {} // Fill from deck instead | |
else | |
{ | |
var rt_items = findObjs({ _type: "tableitem", _rollabletableid: ns.rtable.get("id") }); | |
ns.debug("Found " + rt_items.length); | |
_.each(rt_items, function (item, key) | |
{ | |
var desc = item.get("name"); | |
var weight = item.get("weight"); | |
if (ns.matches(desc, filters)) | |
{ | |
// Include once if listing, once per weight if picking randomly | |
if (listing) rt[rt.length] = desc; | |
else for (var i = 0; i < weight; i++) rt[rt.length] = desc; | |
} | |
}); | |
} | |
// Report the reults | |
ns.debug("rt: " + rt); | |
if (ns.isnull(rt)) ns.info("No matches.") | |
else | |
{ | |
ns.info("Matches:"); | |
if (listing) | |
{ | |
// Output them all | |
_.each(rt, function (item, key) { ns.result(item, make_token); }); | |
} | |
else | |
{ | |
// Now randomly choose one. | |
var r = Math.floor(Math.random() * rt.length); | |
ns.result(rt[r], make_token); | |
} | |
} | |
} | |
}); | |
// Outputs the result of the query, create a token if needed | |
parm_deck_util.result = function(i_name, make_token) | |
{ | |
var ns = parm_deck_util; | |
ns.info(i_name); | |
if (make_token) | |
{ | |
// The image URL is very important, it must be exactly right | |
var img_src; | |
var img_w = 70; // FIXME: Grid size... or *something* | |
var img_h = 70; | |
if (!ns.isnull(ns.rtable)) | |
{ | |
// Try the rollable table... | |
var tbl_item = findObjs({ _type: "tableitem", _rollabletableid: ns.rtable.get("id"), name: i_name })[0]; | |
ns.debug(tbl_item); | |
img_src = tbl_item.get("avatar"); | |
} | |
if (ns.isnull(img_src) && !ns.isnull(ns.deck)) | |
{ | |
// Try the deck... | |
ns.debug("Deck: " + ns.deck); | |
img_w = ns.deck.get("defaultwidth"); | |
img_h = ns.deck.get("defaultheight"); | |
var card = findObjs({ _type: "card", _deckid: ns.deck.get("id"), name: i_name })[0]; | |
img_src = card.get("avatar"); | |
} | |
// If it's still null, too bad, we can't do this. Otherwise... | |
if (!ns.isnull(img_src)) | |
{ | |
var pos1 = img_src.lastIndexOf("/"); | |
var pos2 = img_src.lastIndexOf("?"); | |
img_src = img_src.substring(0, pos1 + 1) + "thumb.png" + img_src.substring(pos2); | |
ns.debug(img_src); | |
o = createObj("graphic", { | |
pageid: Campaign().get("playerpageid"), layer: "objects", | |
imgsrc: img_src, left: 105, top: 105, width: img_w, height: img_h //width: 70, height: 70 | |
}); | |
} | |
//var grid_size = 70; // FIXME: Actually find this. | |
//var img_w = nvl(o.get("width")); | |
//var img_h = nvl(o.get("height")); | |
} | |
} | |
// Takes a string and an array describing match conditions. | |
// Returns a boolean indicating whether or not the string passed. | |
parm_deck_util.matches = function(desc, filters) | |
{ | |
var ns = parm_deck_util; | |
var passed = true; | |
_.each(filters, function (condition, key) | |
{ | |
// The first letter may indicate something. | |
var indicator = condition[0]; | |
if (indicator != "/" && indicator != "^") indicator = ""; | |
// Remove the indicator from the string if one was found. | |
var s = condition.substring(indicator.length); | |
// Now for our tests... | |
if (passed) | |
{ | |
if (indicator == "/") | |
{ | |
// Regular expression | |
var regex = new RegExp(s); | |
passed = regex.test(desc); | |
} | |
else | |
{ | |
// Filter with (the default) or without (^ indicator) this word | |
var wanted = (indicator != "^"); | |
var contains = (desc.indexOf(s) >= 0); | |
passed = (contains == wanted); | |
} | |
//debug(desc + (passed ? " meets ": " fails ") + s); | |
} | |
//if (!passed) break; // Can't break out of _each, consider switching to _find | |
}); | |
ns.debug(desc + (passed ? " passes.": " fails.")); | |
return passed; | |
}; | |
// My function library | |
parm_deck_util.debug = function(s) { if (parm_deck_util.debugging) log(s); }; | |
parm_deck_util.error = function(s) { sendChat(parm_deck_util.speak_as, parm_deck_util.whisper + "Error: " + s); }; | |
parm_deck_util.info = function(s) { sendChat(parm_deck_util.speak_as, parm_deck_util.whisper + s); }; | |
parm_deck_util.nvl = function(o, v) { return parm_deck_util.isnull(o) ? v : o; }; | |
parm_deck_util.isnull = function(o) { return typeof o == 'undefined' || o == null || o.length == 0; }; | |
parm_deck_util.replaceAll = function(s, a, b) { return s.split(a).join(b); }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment