Last active
July 29, 2016 02:16
-
-
Save Kurohyou/b6d8022c70b133ac408f272d5faac690 to your computer and use it in GitHub Desktop.
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
// Github: https://github.com/shdwjk/Roll20API/blob/master/RecursiveTable/RecursiveTable.js | |
// By: The Aaron, Arcane Scriptomancer | |
// Contact: https://app.roll20.net/users/104025/the-aaron | |
var RecursiveTable = RecursiveTable || (function() { | |
'use strict'; | |
var version = '0.1.2', | |
lastUpdate = 1453302547, | |
schemaVersion = 0.1, | |
maxParseSec = 50, | |
checkInstall = function() { | |
log('-=> RecursiveTable v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); | |
if( ! _.has(state,'RecursiveTable') || state.RecursiveTable.version !== schemaVersion) { | |
log(' > Updating Schema to v'+schemaVersion+' <'); | |
state.RecursiveTable = { | |
version: schemaVersion | |
}; | |
} | |
}, | |
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 ''; | |
}, | |
showHelp = function(who) { | |
sendChat('','/w "'+who+'" ' | |
+'<div style="border: 1px solid black; background-color: white; padding: 3px 3px;">' | |
+'<div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;">' | |
+'RecursiveTable v'+version | |
+'</div>' | |
+'<div style="padding-left:10px;margin-bottom:3px;">' | |
+'<p>RecursiveTable provides a way to expand the results of Rollable Tables which have inline rolls within them.</p>' | |
+'</div>' | |
+'<b>Commands</b>' | |
+'<div style="padding-left:10px;">' | |
+'<b><span style="font-family: serif;">!rt [--help| ... ]</span></b>' | |
+'<div style="padding-left: 10px;padding-right:20px">' | |
+'<p>Performs all inline rolls, then continues to expand inline rolls (to a maximum depth of around 10).</p>' | |
+'<ul>' | |
+'<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">' | |
+'<b><span style="font-family: serif;">--help</span></b> '+ch('-')+' Shows the Help screen' | |
+'</li> ' | |
+'<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">' | |
+'<b><span style="font-family: serif;">...</span></b> '+ch('-')+' Anything following !rt will be expanded, then sent to to the chat. Tables can be rolled ' | |
+'with a modifier by calling the table like this: '+ch('[')+ch('[')+'1t'+ch('[')+'tableName'+ch(']')+'+3'+ch(']')+ch(']')+'. The roll mod can be a' | |
+'number or an inline dice roll' | |
+'</li> ' | |
+'</ul>' | |
+'</div>' | |
+'</div>' | |
+'</div>' | |
); | |
}, | |
extractInlineRolls = function(str){ | |
"use strict"; | |
let rolls=[], | |
bracketCount=0, | |
rollStart=0, | |
accumulator=''; | |
for(let position = 0; position < str.length; ++position) { | |
if('[' === str[position]) { | |
if(bracketCount){ | |
accumulator='['; | |
rollStart=position-1; | |
while(bracketCount>0 && position<str.length){ | |
switch(str[position]){ | |
case '[': ++bracketCount; break; | |
case ']': --bracketCount; break; | |
} | |
accumulator+=str[position]; | |
++position; | |
} | |
if(!bracketCount){ | |
rolls.push(accumulator); | |
} | |
} else { | |
++bracketCount; | |
} | |
} else { | |
bracketCount=0; | |
} | |
} | |
return rolls; | |
}, | |
getTableItem = function(tableName,currentRoll,mod){ | |
var table = findObjs({ | |
type:'rollabletable', | |
name: tableName | |
})[0], | |
items, | |
weight, | |
list =[], | |
text = '', | |
rollMod; | |
items = findObjs({ | |
type:'tableitem', | |
rollabletableid: table.id | |
}); | |
_.each(items,function(obj){ | |
weight = parseInt(obj.get('weight')); | |
for(var i = 0; i < weight; i++){ | |
list.push(obj.get('name')); | |
}; | |
}); | |
_.each(currentRoll,function(r){ | |
rollMod = eval(mod)+r.tableidx; | |
if(rollMod>(list.length - 1)){ | |
text += list[list.length- 1] + ' '; | |
}else if(rollMod<0){ | |
text += list[0] + ' '; | |
}else{ | |
text += list[rollMod] + ' '; | |
}; | |
}); | |
return text; | |
}, | |
rollChat = function(toChat){ | |
return new Promise(function(resolve,reject){ | |
sendChat('',toChat,function(obj){ | |
resolve(parseMessage(obj[0])); | |
}); | |
}); | |
}, | |
recursiveParse = function(iRoll){ | |
var table, | |
result, | |
inlines, | |
rollResult = []; | |
if(_.has(iRoll.results.rolls[0],'table')){ | |
if(iRoll.results.rolls.length>1){ | |
result = getTableItem(iRoll.results.rolls[0].table, iRoll.results.rolls[0].results, iRoll.results.rolls[1].expr); | |
}else{//this needs to be dynamic based on number of calls. | |
result = getTableItem(iRoll.results.rolls[0].table, iRoll.results.rolls[0].results, '+0'); | |
}; | |
result = result.replace(/\[\[\[/g, "[[ ["); | |
inlines = extractInlineRolls(result); | |
for(var i = 0; i < inlines.length; i++){ | |
result = result.replace(inlines[i],'$||'+i+'||'); | |
}; | |
}else{ | |
result = iRoll.results.total; | |
}; | |
if(inlines){ | |
return Promise.all(inlines.map(rollChat)).then(function(text){ | |
for(var i = 0;i<text.length;i++){ | |
result = result.replace('$||'+i+'||',text[i]); | |
}; | |
return (result); | |
}); | |
}else{ | |
return result; | |
}; | |
}, | |
parseMessage = function(msg){ | |
return Promise.all(msg.inlinerolls.map(recursiveParse)).then(function(rolltext){ | |
for(var i = 0;i<rolltext.length;i++){ | |
msg.content = msg.content.replace('$[['+i+']]',rolltext[i]); | |
}; | |
return msg.content; | |
}) | |
}, | |
handleInput = function(msg_orig) { | |
var msg = _.clone(msg_orig), | |
args, who; | |
if (msg.type !== "api") { | |
return; | |
} | |
who=getObj('player',msg.playerid).get('_displayname'); | |
args = msg.content.split(/\s+/); | |
switch(args[0]) { | |
case '!rt': | |
if('--help' === args[1]){ | |
showHelp(who); | |
} else { | |
msg.content = msg.content.replace(/^!rt\s+/,'').replace(/\{\{/,'&{template:'+msg.rolltemplate+'} {{'); | |
parseMessage(msg).then(function(chat){ | |
sendChat(msg.who,chat); | |
},function(err){ | |
sendChat(msg.who,'/w "'+msg.who+'" '+err); | |
}).catch(function(oErr){ | |
log('An unanticiapted error occurred:'); | |
log(oErr); | |
}); | |
}; | |
break; | |
} | |
}, | |
registerEventHandlers = function() { | |
on('chat:message', handleInput); | |
}; | |
return { | |
CheckInstall: checkInstall, | |
RegisterEventHandlers: registerEventHandlers | |
}; | |
}()); | |
on('ready',function() { | |
'use strict'; | |
RecursiveTable.CheckInstall(); | |
RecursiveTable.RegisterEventHandlers(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment