Last active
August 29, 2015 14:05
-
-
Save Cazra/2378ab5a8a0ec3c208bf to your computer and use it in GitHub Desktop.
roll20 follow v2
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
/** | |
* A script with a command for specifying tokens to follow other tokens. | |
* Simply select the tokens in the marching order and enter the "!follow" | |
* commandwith either a direction for the marching order of the selected tokens | |
* or the name of a token for the selected tokens to follow behind. | |
* | |
* E.G. "!follow west" will make the selected tokens follow each other in order | |
* from east to west, with the westmost token being the leader and the eastmost | |
* token being the caboose. | |
* Alternatively if we want the selected tokens to follow a character named | |
* "Drizt", enter the command "!follow Drizt". | |
* | |
* !follow [north|south|east|west|name of leader token] | |
* | |
* To make a token stop following the token in front of it, just manually move | |
* the token anywhere. | |
*/ | |
/** Helper function: Makes one token follow another token. */ | |
var _followCmd = function(leader, follower) { | |
if(!leader || !follower) { | |
return; | |
} | |
// unbind all of cur's following links. | |
_unfollowCmd(follower); | |
var prevFollower = leader.follower; | |
follower.leader = leader; | |
follower.follower = prevFollower; | |
leader.follower = follower; | |
if(prevFollower) { | |
prevFollower.leader = follower; | |
} | |
} | |
/** | |
* Helper method for making a character token stop following another token | |
* and stopped being followed by another token. | |
*/ | |
var _unfollowCmd = function(token) { | |
if(token.leader) { | |
token.leader.follower = token.follower; | |
} | |
if(token.follower) { | |
token.follower.leader = token.leader; | |
} | |
token.leader = null; | |
token.follower = null; | |
} | |
/** Interpret the chat commands. */ | |
on("chat:message", function(msg) { | |
var cmdName; | |
var msgTxt; | |
if(!msg.selected || msg.selected.length == 0) { | |
return; | |
} | |
cmdName = "!follow"; | |
msgTxt = msg.content; | |
if(msg.type == "api" && msgTxt.indexOf(cmdName) !== -1) { | |
var curPageID = Campaign().get("playerpageid"); | |
// A direction can be given for the marching order since | |
// the msg.selected array is in no particular order. | |
var direction; | |
if(msgTxt.indexOf("north") !== -1) { | |
direction = "north"; | |
} | |
else if(msgTxt.indexOf("south") !== -1) { | |
direction = "south"; | |
} | |
else if(msgTxt.indexOf("west") !== -1) { | |
direction = "west"; | |
} | |
else if(msgTxt.indexOf("east") !== -1) { | |
direction = "east"; | |
} | |
// Get the tokens for the selected objects. | |
var selected = msg.selected; | |
var marchingOrder = []; | |
for(var i=0; i<selected.length; i++) { | |
var token = findObjs({ | |
_id: selected[i]._id, | |
_pageid: curPageID | |
})[0]; | |
marchingOrder.push(token); | |
} | |
// Sort the marching order in the specified direction. | |
if(direction !== undefined) { | |
marchingOrder.sort(function(a,b) { | |
var aX = parseFloat(a.get("left")); | |
var bX = parseFloat(b.get("left")); | |
var aY = parseFloat(a.get("top")); | |
var bY = parseFloat(b.get("top")); | |
if(direction === "north") { | |
return (aY - bY); | |
} | |
else if(direction === "south") { | |
return (bY - aY); | |
} | |
else if(direction === "west") { | |
return (aX - bX); | |
} | |
else { | |
return (bX - aX); | |
} | |
}); | |
} | |
// Alternatively, we can tell the tokens to follow a character given | |
// by name. | |
else { | |
var leader = findObjs({ | |
name: msgTxt.substr(cmdName.length+1), | |
_pageid: curPageID | |
})[0]; | |
if(leader === undefined) { | |
var playerName = msg.who; | |
if(playerName.indexOf(" ") !== -1) { | |
playerName = playerName.substring(0, playerName.indexOf(" ")); | |
} | |
sendChat("A mysterious voice", "/w " + playerName + " Invalid " + | |
"command. After the command enter either north, south," + | |
" east, or west for the direction of the marching order, " + | |
"or the name of a character to follow."); | |
return; | |
} | |
else { | |
marchingOrder.unshift(leader); | |
} | |
} | |
// Set up the marching order from leader to caboose. | |
for(var i=0; i<marchingOrder.length - 1; i++) { | |
var leader = marchingOrder[i]; | |
var follower = marchingOrder[i+1]; | |
sendChat("", follower.get("name") + " is following " + leader.get("name")); | |
_followCmd(leader, follower); | |
} | |
} | |
}); | |
/** Do the marching order effect when the leader tokens move! */ | |
on("change:graphic", function(obj, prev) { | |
var leader = obj; | |
var follower = leader.follower; | |
leader.prevLeft = prev["left"]; | |
leader.prevTop = prev["top"]; | |
leader.prevRotation = prev["rotation"]; | |
// Only move the followers if there was a change in either the leader's | |
// left or top attributes. | |
if(leader.get("left") == leader.prevLeft && leader.get("top") == leader.prevTop) { | |
return; | |
} | |
// We stepped out of line. Stop following the guy in front of us. | |
if(leader.leader) { | |
_unfollowCmd(leader); | |
} | |
// move everyone to the previous position of the token in front of them. | |
while(follower) { | |
follower.prevLeft = follower.get("left"); | |
follower.prevTop = follower.get("top"); | |
follower.prevRotation = follower.get("rotation") | |
follower.set("left",leader.prevLeft); | |
follower.set("top",leader.prevTop); | |
follower.set("rotation", leader.prevRotation); | |
leader = follower; | |
follower = follower.follower; | |
// avoid cycles. | |
if(follower == obj) { | |
return; | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment