-
-
Save birdbrainiac/3c8c2122aa2545b8a78d58dcce31d027 to your computer and use it in GitHub Desktop.
Turn Counter
This file contains hidden or 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
/* --------------------------------------------------------------------------------------------------- */ | |
// Initiative Script | |
// | |
// Usage: Select the tokens you want the initiative to be rolled for and use the command "!initiative" | |
// This command rolls a die of the type specified using the "initiativeDie" variable, adds | |
// the result to the attribute specified using the "initiativeAttribute" variable (for each | |
// token), then sorts the tokens by the total achieved (higher to lower) and puts them into | |
// the Turn Tracker. Use the command "!nextround" to move to the next round and increase the | |
// counter. | |
// | |
// Notes: Tokens must have a linked character sheet that contains the attribute used for the | |
// initiative (see variable "initiativeAttribute") | |
// You can add further tokens at any time selecting them and using the command "!addtokens" | |
// This will re-sort the list of tokens, so it is best used at the beginning o a Round. | |
// You can reset the round counter to 1 using the command "!restart" | |
// The command "!restart reroll" will reset the round counter to 1 and reroll for the tokens | |
// already present in the Turn Tracker, sorting them by their total score | |
// The script also visualizes the round counter on a token named "Round 1", if any, and if the | |
// variable useTokenCounter is set to true (default). | |
// | |
// Warning: Changing manually the order of the tokens in the Turn Tracker is possible (and the changes | |
// will be kept) but if the command "!nextround" is given while the "ROUND x" item is not the | |
// topmost item in the Turn Tracker, the order of the tokens in the next round will be different | |
// than the order chosen - it will be a "snapshot" of the Turn Tracker WITHOUT the "ROUND x" item: | |
// | |
// Having a Turn Order like this, manually adjusted: | |
// | |
// ROUND x | |
// Token 1 | |
// Token 3 | |
// Token 2 | |
// | |
// Then cycling two times will show this: | |
// | |
// Token 3 | |
// Token 2 | |
// ROUND x | |
// Token 1 | |
// | |
// Once you issue the !nextround command, the order of the tokens will be this one: | |
// | |
// ROUND x | |
// Token 3 | |
// Token 2 | |
// Token 1 | |
// | |
// So if you manually adjusted the order of the tokens in the Turn Tracker ALWAYS have your | |
// "ROUND x" counter as the topmost item before using the !nextround command if you want to | |
// keep your custom order between rounds | |
/* --------------------------------------------------------------------------------------------------- */ | |
var initiativeDie = 20; // Type of die to roll for initiative | |
var initiativeAttribute = "Initiative"; // Attribute to add to the roll. Change it to whatever attribute you use for initiative - i.e. Dex or Dexterity, etc. | |
var useTokenCounter = false; // Put it to true if you also want a token in the page to show Round number - it has to be named "Round 1". | |
var allowDuplicateTokens = false; // If set to true, a token can be added more than once in the Turn Tracker | |
state.iTurn = state.iTurn || 0; | |
state.turnOrder = state.turnOrder || {}; | |
state.aChars = state.aChars || {}; | |
var aChars; | |
var iTurn; | |
var turnorder; | |
var adding = false; | |
var duplicate = false; | |
on("ready", function() { | |
if(state.iTurn != 0) | |
{ | |
aChars = state.aChars; | |
iTurn = state.iTurn; | |
if(iTurn == 0) iTurn = 1; | |
turnorder = state.turnOrder; | |
} | |
else | |
{ | |
aChars = new Array(); | |
iTurn = 1; | |
if(Campaign().get("turnorder") == "") | |
turnorder = []; | |
else | |
turnorder = JSON.parse(Campaign().get("turnorder")); | |
state.aChars = aChars; | |
state.iTurn = iTurn; | |
state.turnOrder = turnorder; | |
} | |
}); | |
on("change:campaign:turnorder", function(obj) { | |
if(state.turnOrder!="") | |
{ | |
var tempTO = JSON.parse(obj.get("turnorder")).shift(); | |
if(tempTO != undefined) | |
if(tempTO.custom == "") // We have a token | |
{ | |
var tempTok = getObj("graphic", tempTO.id); | |
sendPing(tempTok.get("left"), tempTok.get("top"), Campaign().get('playerpageid'), null, true); | |
} | |
} | |
}); | |
on('chat:message', function(msg) { | |
var command = msg.content.toLowerCase(); | |
if (msg.type == "api" && command == "!initiative"){ | |
if(command == "!initiative"){ | |
var selected = msg.selected; | |
aChars.length = 0; | |
createArray(selected, false); | |
if(aChars.length>0) {sendChat("GM", "/desc Combat begins!");} | |
else{sendChat("Script", "/w GM No tokens selected!");} | |
rollandsort(false); | |
} | |
if(iTurn != 1 && useTokenCounter) updateTurnToken(iTurn); | |
iTurn = 1; | |
fillTracker(iTurn); | |
} | |
if (msg.type == "api" && command.indexOf("!restart") >= 0){ | |
currTurn = 1; | |
if(useTokenCounter) updateTurnToken(currTurn); | |
iTurn = 1; | |
if(command.split(" ").pop() == "reroll") rollandsort(false); | |
fillTracker(iTurn); | |
} | |
if (msg.type == "api" && command.indexOf("!addtokens") >= 0){ | |
var selected = msg.selected; | |
adding = true; | |
createArray(selected, true); | |
if(duplicate) | |
{ | |
sendChat("Initiative script", "/w gm Duplicate token detected."); | |
duplicate = false; | |
} | |
else | |
{ | |
rollandsort(true); | |
fillTracker(iTurn); | |
} | |
adding = false; | |
} | |
if (msg.type == "api" && command.indexOf("!nextround") >= 0){ | |
nextRound(iTurn); | |
} | |
}); | |
function rollandsort(addtokens) | |
{ | |
var dieRolled; | |
var chatMsg = "/direct Initiative rolled:<br>"; | |
for (var a = 0; a < aChars.length; a++) | |
{ | |
dieRolled = randomInteger(initiativeDie); | |
if(addtokens) | |
{ | |
if(aChars[a][1] == "") | |
{ | |
aChars[a][1] = aChars[a][2] + dieRolled; | |
chatMsg += aChars[a][3] + ": " + dieRolled + "<br>"; | |
} | |
} | |
else | |
{ | |
aChars[a][1] = aChars[a][2] + dieRolled; | |
chatMsg += aChars[a][3] + ": " + dieRolled + "<br>"; | |
} | |
} | |
sendChat("GM", chatMsg); | |
aChars = aChars.sort(function(a,b) { // sorts characters by initiative | |
if (a[1] < b[1]) return 1; | |
if (a[1] > b[1]) return -1; | |
return 0; | |
}); | |
state.aChars = aChars; | |
} | |
function updateTurnToken(currTurn) | |
{ | |
if(iTurn==1) tokName = "Round 1"; | |
else tokName = "Round " + (iTurn-1); | |
var curName = "Round " + currTurn; | |
oToken = findObjs({ | |
_pageid: Campaign().get("playerpageid"), | |
_type: "graphic", | |
name: tokName, | |
}); | |
if(oToken == "") | |
sendChat("Script", "/w GM No Round token present!"); | |
else | |
oToken[0].set("name", curName); | |
} | |
function fillTracker(currTurn) | |
{ | |
turnorder.length = 0; | |
if(aChars.length>0 && !adding) | |
{ | |
sendChat("GM", "/desc Round " + currTurn + " begins!"); | |
turnorder.push({ | |
id: "-1", | |
pr: " ", | |
custom: "ROUND " + currTurn | |
}); | |
} | |
if(adding) | |
{ | |
var actualTurn = currTurn-1; | |
turnorder.push({ | |
id: "-1", | |
pr: " ", | |
custom: "ROUND " + actualTurn, | |
}); | |
} | |
for (var a = 0; a < aChars.length; a++) | |
{ | |
turnorder.push({ | |
id: aChars[a][0], | |
pr: aChars[a][1], | |
custom: "" | |
}); | |
} | |
state.turnOrder = turnorder; | |
Campaign().set("turnorder", JSON.stringify(turnorder)); | |
} | |
function createArray(ob, newtokens) | |
{ | |
var nCount = 0; | |
if(newtokens) | |
nCount = aChars.length; | |
_.each(ob, function(obj) | |
{ | |
if(!allowDuplicateTokens && newtokens) | |
{ | |
if(JSON.stringify(aChars).indexOf(obj._id) >=0) | |
{ | |
duplicate = true; | |
return; | |
} | |
} | |
if(obj._type != 'graphic') return; | |
var token = getObj("graphic", obj._id); | |
var oCharacter = getObj("character", token.get("represents")); | |
if (oCharacter != "") | |
{ | |
aChars[nCount] = new Array(4); | |
aChars[nCount][0] = token.get('_id'); | |
aChars[nCount][3] = token.get('name'); | |
var oInitiative = findObjs({name: initiativeAttribute, _type: "attribute", _characterid: oCharacter.id}, {caseInsensitive: true})[0]; | |
if (oInitiative) | |
{ | |
aChars[nCount][1] = ""; | |
aChars[nCount][2] = parseInt(oInitiative.get('current')); | |
} | |
else{sendChat("Initiative script", "/w gm No " + initiativeAttribute + " attribute for character " + token.get('name')); return;} | |
nCount++; | |
} | |
}); | |
} | |
function deleteToken(currentTurnOrder) | |
{ | |
for(var i=0;i<aChars.length;i++) | |
{ | |
for(var a=0;a<currentTurnOrder.length;a++) | |
{ | |
var found = false; | |
var curToken = currentTurnOrder.shift(); | |
if(aChars[i][0] == curToken.id) | |
found = true; | |
} | |
if(!found) | |
aChars.splice(i,1); | |
} | |
state.aChars = aChars; | |
} | |
function saveTurnOrder() | |
{ | |
var aTemp = new Array(); | |
for(var t=0; t<turnorder.length;t++) | |
{ | |
for(var a=0; a<aChars.length;a++) | |
{ | |
if(turnorder[t].id == aChars[a][0]) | |
{ | |
aTemp[t] = new Array(4); | |
aTemp[t][0] = turnorder[t].id; | |
aTemp[t][1] = aChars[a][1]; | |
aTemp[t][2] = aChars[a][2]; | |
aTemp[t][3] = aChars[a][3]; | |
} | |
} | |
} | |
aChars = aTemp.slice(0); | |
state.aChars = aChars; | |
} | |
function nextRound(round) | |
{ | |
if(Campaign().get("turnorder") == "") | |
turnorder = state.turnOrder; | |
else | |
turnorder = JSON.parse(Campaign().get("turnorder")); | |
if(turnorder.length < aChars.length) | |
{ | |
deleteToken(turnorder); | |
return; | |
} | |
if(round == 1) round++; | |
for(var n=0;n<turnorder.length;n++) | |
{ | |
if(turnorder[n].id == "-1" && round > 1 && !adding) | |
{ | |
sendChat("GM", "/desc Round " + round + " begins!"); | |
turnorder.splice(n,1); | |
saveTurnOrder(); | |
turnorder.unshift({ | |
id: "-1", | |
pr: " ", | |
custom: "ROUND " + round | |
}); | |
Campaign().set("turnorder", JSON.stringify(turnorder)); | |
state.turnOrder = turnorder; | |
if(useTokenCounter) updateTurnToken(round); | |
round++; | |
state.iTurn = round; | |
iTurn = round; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment