Created
March 24, 2014 15:55
-
-
Save Parmeisan/9743076 to your computer and use it in GitHub Desktop.
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
"Page id: -JIjGqeZev9HB5rcJjv4" | |
"Comparing arrays:" | |
["-JHmkUEVLtCKu6vCFxtT"] | |
["-JHmkUEVLtCKu6vCFxtT","-JIjGi-23xpbsUXQMkhw"] | |
"New:-JIjGi-23xpbsUXQMkhw" | |
"Moving -JIjGi-23xpbsUXQMkhw to hand." | |
{"name":"Angreal - Well","avatar":"https://s3.amazonaws.com/files.d20.io/images/3499705/HEPFrdn2JGgMwycqu8bTqw/med.png?1395584000","_deckid":"-JIjDXFy-WlTpDfC1Ggu","_type":"card","_id":"-JIjGi-23xpbsUXQMkhw"} | |
"Creating card-token--JIjGi-23xpbsUXQMkhw-id" | |
"https://s3.amazonaws.com/files.d20.io/images/3499705/HEPFrdn2JGgMwycqu8bTqw/med.png?1395584000" | |
"Moving -JIjGi-23xpbsUXQMkhw to table." | |
"Found card-token--JIjGi-23xpbsUXQMkhw-id" | |
"last_change to_table" | |
"Comparing arrays:" | |
["-JHmkUEVLtCKu6vCFxtT"] | |
["-JHmkUEVLtCKu6vCFxtT","-JIjGi-23xpbsUXQMkhw"] | |
"New:-JIjGi-23xpbsUXQMkhw" | |
"is -JIjGi-23xpbsUXQMkhw?" | |
"Deleting from hand." | |
"Loading" | |
"Copying" | |
"Completed copy" | |
{"_id":"-JIog7FNFPMgrV3IrzLN","_pageid":"-JIjGqeZev9HB5rcJjv4","left":657,"top":529,"width":70,"height":70,"rotation":0,"layer":"objects","isdrawing":false,"flipv":false,"fliph":false,"imgsrc":"https://s3.amazonaws.com/files.d20.io/images/3499705/HEPFrdn2JGgMwycqu8bTqw/med.png?1395584000","name":"","gmnotes":"","controlledby":"","bar1_value":"","bar1_max":"","bar1_link":"","bar2_value":"","bar2_max":"","bar2_link":"","bar3_value":"","bar3_max":"","bar3_link":"","represents":"","aura1_radius":"","aura1_color":"#FFFF99","aura1_square":false,"aura2_radius":"","aura2_color":"#59E594","aura2_square":false,"tint_color":"transparent","statusmarkers":"","showname":false,"showplayers_name":false,"showplayers_bar1":false,"showplayers_bar2":false,"showplayers_bar3":false,"showplayers_aura1":false,"showplayers_aura2":false,"playersedit_name":true,"playersedit_bar1":true,"playersedit_bar2":true,"playersedit_bar3":true,"playersedit_aura1":true,"playersedit_aura2":true,"light_radius":"","light_dimradius":"","light_otherplayers":false,"light_hassight":false,"light_angle":"","light_losangle":"","sides":"","currentSide":0,"lastmove":"","_type":"graphic","_subtype":"card","_cardid":"-JIjGi-23xpbsUXQMkhw"} | |
"Comparing arrays:" | |
["-JHmkUEVLtCKu6vCFxtT"] | |
["-JHmkUEVLtCKu6vCFxtT","-JIjGi-23xpbsUXQMkhw"] | |
"New:-JIjGi-23xpbsUXQMkhw" | |
"Moving -JIjGi-23xpbsUXQMkhw to hand." | |
"Found card-token--JIjGi-23xpbsUXQMkhw-id" | |
"Deleting from table." | |
"Saving" | |
"Copying" | |
"Completed copy" | |
{"_id":"-JIog0mXaWgC_gQZTBKg","_pageid":"-JIjGqeZev9HB5rcJjv4","left":105,"top":105,"width":70,"height":70,"rotation":0,"layer":"objects","isdrawing":false,"flipv":false,"fliph":false,"imgsrc":"https://s3.amazonaws.com/files.d20.io/images/3499705/HEPFrdn2JGgMwycqu8bTqw/thumb.png?1395584000","name":"card-token--JIjGi-23xpbsUXQMkhw-id","gmnotes":"","controlledby":"","bar1_value":"1","bar1_max":"1","bar1_link":"","bar2_value":"","bar2_max":"","bar2_link":"","bar3_value":"","bar3_max":"","bar3_link":"","represents":"","aura1_radius":"","aura1_color":"#FFFF99","aura1_square":false,"aura2_radius":"","aura2_color":"#59E594","aura2_square":false,"tint_color":"transparent","statusmarkers":"","showname":false,"showplayers_name":false,"showplayers_bar1":false,"showplayers_bar2":false,"showplayers_bar3":false,"showplayers_aura1":false,"showplayers_aura2":false,"playersedit_name":true,"playersedit_bar1":true,"playersedit_bar2":true,"playersedit_bar3":true,"playersedit_aura1":true,"playersedit_aura2":true,"light_radius":"","light_dimradius":"","light_otherplayers":false,"light_hassight":false,"light_angle":"","light_losangle":"","sides":"","currentSide":0,"lastmove":"","_type":"graphic","_subtype":"token","_cardid":""} | |
"And back to you." | |
/home/symbly/www/d20-api-server/node_modules/firebase/lib/firebase-node.js:1 | |
orts, require, module, __filename, __dirname) { function f(a){throw a;}var j=v | |
^ | |
Error: Firebase.child failed: First argument must be a non-empty string and can't contain ".", "#", "$", "[", or "]". | |
at Error (<anonymous>) | |
at Ha (/home/symbly/www/d20-api-server/node_modules/firebase/lib/firebase-node.js:12:204) | |
at G.W.H (/home/symbly/www/d20-api-server/node_modules/firebase/lib/firebase-node.js:126:213) | |
at TrackedObj._doSave ( |
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 debugging = true;//false;// | |
var speak_as = "Inventory-Extension"; | |
var pg_id; | |
// When a card is dragged to the tabletop, it first triggers add:graphic and then change:hand. | |
// When the card is taken from the tabletop, it frist triggers change:hand and then destroy:graphic. | |
// (In other words, it's always copied before it's deleted.) However, any of these can be called | |
// independently of either situation, and I only want to react when both are called. | |
// Much of the code that follows deals with that... skip ahead to assertTokenInfo for the meat of the extension. | |
var last_change = new Array(); | |
on("ready", function () | |
{ | |
last_change["time"] = 0; // I may want to add a check for how long ago this happened. | |
last_change["id"] = 0; | |
last_change["obj"]; | |
last_change["type"] = ""; | |
// Also, various checks to see if this script is viable: | |
var script_viable = false; | |
var script_errmsg = ""; | |
var pg_obj = findObjs({ _type: "page", _name: "Inventory" }); | |
if (pg_obj.length == 1) | |
{ | |
pg_id = pg_obj[0].get("_id"); | |
debug("Page id: " + pg_id); | |
} | |
else | |
{ | |
script_errmsg += " * Requires exactly one page called 'Inventory'."; | |
} | |
script_viable = (script_errmsg.length == 0); | |
if (!script_viable) | |
{ | |
script_errmsg = "Script requirements not met." + script_errmsg; | |
debug(script_errmsg); | |
error(script_errmsg); | |
} | |
else | |
{ | |
on("change:hand", function(obj, prev) | |
{ | |
var old_hand = prev["_currentHand"].split(","); | |
var new_hand = obj.get("_currentHand").split(","); | |
if (old_hand.length > new_hand.length) | |
{ | |
debug("last_change " + last_change["type"]); | |
// Do the quick checks first, then compare card id, and *then* we can react. | |
if (last_change["type"] == "to_table" && isRecent(last_change["time"])) | |
{ | |
var card_id = whatsNew(new_hand, old_hand); | |
debug("is " + last_change["id"] + "?"); | |
if (card_id == last_change["id"]) | |
{ | |
debug("Deleting from hand."); | |
loadTokenInfo(); | |
} | |
} | |
} | |
else if (old_hand.length < new_hand.length) | |
{ | |
// Save this data so we can check it later | |
last_change["time"] = new Date(); | |
last_change["id"] = whatsNew(old_hand, new_hand); | |
last_change["obj"] = getObj("card", last_change["id"]); | |
last_change["type"] = "to_hand"; | |
debug("Moving " + last_change["id"] + " to hand."); | |
assertTokenInfo(); // We'll need it later. | |
} | |
else { last_change["type"] == "other"; } | |
}); | |
on("add:graphic", function(obj) | |
{ | |
var card_id = obj.get("_cardid"); | |
if (!isnull(card_id)) | |
{ | |
// Save this data so we can check it later | |
last_change["time"] = new Date(); | |
last_change["id"] = card_id; | |
last_change["obj"] = obj; | |
last_change["type"] = "to_table"; | |
debug("Moving " + last_change["id"] + " to table."); | |
assertTokenInfo(); // We'll need it later. | |
} | |
}); | |
on("destroy:graphic", function(obj) | |
{ | |
// Do the quick checks first, then compare card id, and *then* we can react. | |
var card_id = obj.get("_cardid"); | |
{ | |
if (!isnull(card_id)) | |
if (last_change["type"] == "to_hand" && isRecent(last_change["time"])) | |
{ | |
if ((card_id == last_change["id"])) | |
{ | |
debug("Deleting from table."); | |
// Update "obj" to be the newly created object first, we'll be needing that. | |
last_change["obj"] = obj; | |
saveTokenInfo(); | |
} | |
} | |
} | |
debug("And back to you."); | |
}); | |
} | |
}); | |
// Takes two arrays, sorts them, and returns the first value in b that doesn't match a. | |
// If you already know that they are equal except for one added value, then this tells you what's new. | |
function whatsNew(a, b) | |
{ | |
debug("Comparing arrays:"); | |
// I don't know why, but sometimes there's a blank elements here and sometimes they don't even align | |
a = _.without(a.sort(), ""); | |
b = _.without(b.sort(), ""); | |
debug(a); | |
debug(b); | |
var found = false; | |
for (var i = 0; i < b.length; i++) | |
{ | |
found = (a[i] !== b[i]); | |
if (found) break; | |
} | |
debug("New:" + b[i]); | |
return b[i]; | |
} | |
// Checks if a time is "recent". The exact definition is arbitrary, but this is used to | |
// guess whether two functions were called one after the after. | |
function isRecent(t) | |
{ | |
var now = new Date(); | |
var milli = now - t.getTime(); | |
return (milli < 5000); // 5 seconds | |
} | |
// ----------------------------------------------------------------------------------------------- | |
// And finally, the meat of this script! Saving and loading all your token info. | |
// ----------------------------------------------------------------------------------------------- | |
function assertTokenInfo() | |
{ | |
// Check to see if this object exists yet, and if not, create it. | |
// This should happen in a separate call from actually doing anything with it, | |
// to give Roll20 a chance to actually save this data. | |
var chk_obj = findInventoryToken(); | |
if (isnull(chk_obj)) | |
{ | |
var o = last_change["obj"]; | |
debug(o); | |
if (!isnull(o)) | |
{ | |
debug("Creating " + getID()); | |
var img_src; // Required, and must be exactly right | |
if (o.get("_type") == "card") img_src = o.get("avatar"); | |
else img_src = o.get("imgsrc"); | |
debug(img_src); | |
img_src = img_src.replace("med.png", "thumb.png"); | |
chk_obj = createObj("graphic", { | |
pageid: pg_id, layer: "objects", name: getID(), | |
imgsrc: img_src, left: 105, top: 105, width: 70, height: 70 | |
}); | |
} | |
else | |
{ | |
error("Could not create the inventory token object."); | |
} | |
} | |
else | |
{ | |
debug("Found " + chk_obj.get("name")); | |
} | |
} | |
function saveTokenInfo() | |
{ | |
debug("Saving"); | |
var copy_src = last_change["obj"]; | |
var copy_dest = findInventoryToken();//findOrCreate(); | |
if (isnull(copy_dest)) | |
error("Inventory token object not found."); | |
else | |
copyTokenInfo(copy_src, copy_dest); | |
} | |
function loadTokenInfo() | |
{ | |
debug("Loading"); | |
var copy_src = findInventoryToken();//findOrCreate(); | |
var copy_dest = last_change["obj"]; | |
if (isnull(copy_src)) | |
error("Inventory token object not found."); | |
else | |
copyTokenInfo(copy_src, copy_dest); | |
} | |
function copyTokenInfo(copy_src, copy_dest) | |
{ | |
debug("Copying"); | |
if (!isnull(copy_src)) | |
{ | |
_.each(copy_src.attributes, function (value, key) | |
{ | |
// Save everything that's not read-only or specially-flagged | |
var dont_save = Array("layer", "imgsrc", "left", "top", "name"); | |
if (key.indexOf("_") != 0 && _.indexOf(dont_save, key) == -1) | |
{ | |
//debug("saving: " + key + " -> " + value); | |
copy_dest.set(key, value); | |
} | |
//if (key == "gmnotes") copy_dest.set(key, saveGMNotes(value)); | |
}); | |
} | |
else | |
{ | |
error("Found nothing to copy."); | |
} | |
debug("Completed copy"); | |
debug(copy_dest); | |
} | |
function getID() | |
{ | |
return "card-token-" + last_change["id"] + "-id"; | |
} | |
// The Inventory version is identified the card ID in the name field. | |
function findInventoryToken() | |
{ | |
return findObjs({ _type: "graphic", name: getID() })[0]; | |
} | |
// My function library | |
function debug(s) { if (debugging) log(s); } | |
function error(s) { sendChat(speak_as, "Error: " + s); } | |
function nvl(o, v) { return isnull(o) ? v : o; } | |
function isnull(o) { return typeof o == 'undefined' || o == null || o.length == 0; } |
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
"Page id: -JIjGqeZev9HB5rcJjv4" | |
"Comparing arrays:" | |
["-JHmkUEVLtCKu6vCFxtT"] | |
["-JHmkUEVLtCKu6vCFxtT","-JIjGi-23xpbsUXQMkhw"] | |
"New:-JIjGi-23xpbsUXQMkhw" | |
"Moving -JIjGi-23xpbsUXQMkhw to hand." | |
{"name":"Angreal - Well","avatar":"https://s3.amazonaws.com/files.d20.io/images/3499705/HEPFrdn2JGgMwycqu8bTqw/med.png?1395584000","_deckid":"-JIjDXFy-WlTpDfC1Ggu","_type":"card","_id":"-JIjGi-23xpbsUXQMkhw"} | |
"Creating card-token--JIjGi-23xpbsUXQMkhw-id" | |
"https://s3.amazonaws.com/files.d20.io/images/3499705/HEPFrdn2JGgMwycqu8bTqw/med.png?1395584000" | |
"Moving -JIjGi-23xpbsUXQMkhw to table." | |
"Found card-token--JIjGi-23xpbsUXQMkhw-id" | |
"last_change to_table" | |
"Comparing arrays:" | |
["-JHmkUEVLtCKu6vCFxtT"] | |
["-JHmkUEVLtCKu6vCFxtT","-JIjGi-23xpbsUXQMkhw"] | |
"New:-JIjGi-23xpbsUXQMkhw" | |
"is -JIjGi-23xpbsUXQMkhw?" | |
"Deleting from hand." | |
"Loading" | |
"Copying" | |
"Completed copy" | |
{"_id":"-JIofxi30qU4hexRSWNG","_pageid":"-JIjGqeZev9HB5rcJjv4","left":657,"top":519,"width":70,"height":70,"rotation":0,"layer":"objects","isdrawing":false,"flipv":false,"fliph":false,"imgsrc":"https://s3.amazonaws.com/files.d20.io/images/3499705/HEPFrdn2JGgMwycqu8bTqw/med.png?1395584000","name":"","gmnotes":"","controlledby":"","bar1_value":"","bar1_max":"","bar1_link":"","bar2_value":"","bar2_max":"","bar2_link":"","bar3_value":"","bar3_max":"","bar3_link":"","represents":"","aura1_radius":"","aura1_color":"#FFFF99","aura1_square":false,"aura2_radius":"","aura2_color":"#59E594","aura2_square":false,"tint_color":"transparent","statusmarkers":"","showname":false,"showplayers_name":false,"showplayers_bar1":false,"showplayers_bar2":false,"showplayers_bar3":false,"showplayers_aura1":false,"showplayers_aura2":false,"playersedit_name":true,"playersedit_bar1":true,"playersedit_bar2":true,"playersedit_bar3":true,"playersedit_aura1":true,"playersedit_aura2":true,"light_radius":"","light_dimradius":"","light_otherplayers":false,"light_hassight":false,"light_angle":"","light_losangle":"","sides":"","currentSide":0,"lastmove":"","_type":"graphic","_subtype":"card","_cardid":"-JIjGi-23xpbsUXQMkhw"} | |
Restarting sandbox due to script changes... | |
Spinning up new sandbox... | |
"Page id: -JIjGqeZev9HB5rcJjv4" | |
"Comparing arrays:" | |
["-JHmkUEVLtCKu6vCFxtT"] | |
["-JHmkUEVLtCKu6vCFxtT","-JIjGi-23xpbsUXQMkhw"] | |
"New:-JIjGi-23xpbsUXQMkhw" | |
"Moving -JIjGi-23xpbsUXQMkhw to hand." | |
"Found card-token--JIjGi-23xpbsUXQMkhw-id" | |
"Deleting from table." | |
"Saving" | |
"Copying" | |
"Completed copy" | |
{"_id":"-JIofqMe9lJuu6k3Z9WB","_pageid":"-JIjGqeZev9HB5rcJjv4","left":105,"top":105,"width":70,"height":70,"rotation":0,"layer":"objects","isdrawing":false,"flipv":false,"fliph":false,"imgsrc":"https://s3.amazonaws.com/files.d20.io/images/3499705/HEPFrdn2JGgMwycqu8bTqw/thumb.png?1395584000","name":"card-token--JIjGi-23xpbsUXQMkhw-id","gmnotes":"","controlledby":"","bar1_value":"1","bar1_max":"1","bar1_link":"","bar2_value":"","bar2_max":"","bar2_link":"","bar3_value":"","bar3_max":"","bar3_link":"","represents":"","aura1_radius":"","aura1_color":"#FFFF99","aura1_square":false,"aura2_radius":"","aura2_color":"#59E594","aura2_square":false,"tint_color":"transparent","statusmarkers":"","showname":false,"showplayers_name":false,"showplayers_bar1":false,"showplayers_bar2":false,"showplayers_bar3":false,"showplayers_aura1":false,"showplayers_aura2":false,"playersedit_name":true,"playersedit_bar1":true,"playersedit_bar2":true,"playersedit_bar3":true,"playersedit_aura1":true,"playersedit_aura2":true,"light_radius":"","light_dimradius":"","light_otherplayers":false,"light_hassight":false,"light_angle":"","light_losangle":"","sides":"","currentSide":0,"lastmove":"","_type":"graphic","_subtype":"token","_cardid":""} | |
"And back to you." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment