Created
December 7, 2016 06:42
-
-
Save Lithl/993b9bc4fac029e9dd180d4530635946 to your computer and use it in GitHub Desktop.
Unfinished sample of a Roll20 API script for rolling Armello-style dice. The main takeaway is from the `orderFaces` function, which changes the order of the six die faces (sword, shield, sun, moon, wyld, rot) and sets an explode point based on which of those faces should explode.
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 bshields = bshields || {}; | |
bshields.armello = (function() { | |
'use strict'; | |
var version = 0.1, | |
commands = { | |
armello: function(args, msg) { | |
var flags = processFlags(args); | |
resolveCombat({pool:flags.pool[0],explodesword:flags.explodesword[0],explodesun:flags.explodesun[0],explodemoon:flags.explodemoon[0]}, | |
{pool:flags.pool[1],explodesword:flags.explodesword[0],explodesun:flags.explodesun[0],explodemoon:flags.explodemoon[0]}); | |
}, | |
armelloattack: function(args, msg) { | |
var flags = processFlags(args); | |
}, | |
armellodefend: function(args, msg) { | |
var flags = processFlags(args); | |
}, | |
help: function(command, args, msg) { | |
if (_.isFunction(commands[`help_${command}`])) { | |
commands[`help_${command}`](args, msg); | |
} | |
} | |
}; | |
function resolveCombat(attack, defend, isDay) { | |
var attackFaces = orderFaces(attack), | |
defendFaces = orderFaces(defend), | |
attackExplodePoint = attackFaces.explodePoint, | |
defendExplodePoint = defendFaces.explodePoint; | |
attackFaces = attackFaces.faces; | |
defendFaces = defendFaces.faces; | |
sendChat('', `/r ${attack.pool}d6!>${attackExplodePoint}`, function(ops) { | |
var rollresult = JSON.parse(ops[0].content).rolls[0].results, | |
attackResult = calcHitsBlocks(rollresult, attackFaces, isDay, attack.corrupted); | |
log(`Attack hits: ${attackResult.hits}`); | |
log(`Attack blocks: ${attackResult.blocks}`); | |
sendChat('', `/r ${defend.pool}d6!>${defendExplodePoint}`, function(ops) { | |
var rollresult = JSON.parse(ops[0].content).rolls[0].results, | |
defendResult = calcHitsBlocks(rollresult, defendFaces, isDay, defend.corrupted); | |
log(`Defend hits: ${defendResult.hits}`); | |
log(`Defend blocks: ${defendResult.blocks}`); | |
}); | |
}); | |
} | |
function calcHitsBlocks(rollresult, faces, isDay, isCorrupted) { | |
var hits = 0, | |
blocks = 0; | |
_.each(rollresult, function(die) { | |
var face = faces[die.v - 1]; | |
switch (face) { | |
case 'Sword': | |
hits++; | |
break; | |
case 'Shield': | |
blocks++; | |
break; | |
case 'Sun': | |
if (isDay) hits++; | |
break; | |
case 'Moon': | |
if (!isDay) hits++; | |
break; | |
case 'Wyld': | |
if (!isCorrupted) hits++; | |
break; | |
case 'Rot': | |
if (isCorrupted) hits++; | |
break; | |
} | |
}); | |
return { | |
hits: hits, | |
blocks: blocks | |
}; | |
} | |
function orderFaces(flags) { | |
var faces = ['Shield'], | |
explodePoint = 3; | |
if (flags.corrupted) { | |
faces.push('Rot'); | |
faces.unshift('Wyld'); | |
} else { | |
faces.push('Wyld'); | |
faces.unshift('Rot'); | |
} | |
if (flags.ruby || flags.explodesword) { | |
faces.push('Sword'); | |
} else { | |
faces.unshift('Sword'); | |
explodePoint++; | |
} | |
if (flags.aflame || flags.explodesun) { | |
faces.push('Sun'); | |
} else { | |
faces.unshift('Sun'); | |
explodePoint++; | |
} | |
if (flags.moonscythe || flags.explodemoon) { | |
faces.push('Moon'); | |
} else { | |
faces.unshift('Moon'); | |
explodePoint++; | |
} | |
return { | |
faces: faces, | |
explodePoint: explodePoint | |
}; | |
} | |
function processFlags(args) { | |
var flags = { noFlag: [] }, | |
tmp = null; | |
_.each(args, function(arg) { | |
if (arg.indexOf('--') === 0) { | |
if (tmp !== null) { | |
if (flags[tmp]) flags[tmp].push('true'); | |
else flags[tmp] = ['true']; | |
} | |
tmp = arg.substring(2).toLowerCase(); | |
} else { | |
if (tmp === null) { | |
flags.noFlag.push(arg); | |
} else { | |
if (flags[tmp]) flags[tmp].push(arg); | |
else flags[tmp] = [arg]; | |
} | |
tmp = null; | |
} | |
}); | |
if (tmp !== null) { | |
if (flags[tmp]) flags[tmp].push('true'); | |
else flags[tmp] = ['true']; | |
} | |
_.each(flags, function(f, k, o) { | |
o[k] = _.map(f, (s) => s.toLowerCase() === 'true' ? true : s.toLowerCase() === 'false' ? false : s); | |
}); | |
return flags; | |
} | |
function processInlinerolls(msg) { | |
if (_.has(msg, 'inlinerolls')) { | |
return _.chain(msg.inlinerolls) | |
.reduce(function(m, v, k) { | |
var ti = _.reduce(v.results.rolls, function(m2, v2) { | |
if(_.has(v2, 'table')) { | |
m2.push(_.reduce(v2.results, function(m3, v3) { | |
m3.push(v3.tableItem.name); | |
return m3; | |
}, []).join(', ')); | |
} | |
return m2; | |
}, []).join(', '); | |
m['$[['+k+']]'] = (ti.length && ti) || v.results.total || 0; | |
return m; | |
}, {}) | |
.reduce(function(m, v, k) { | |
return m.replace(k,v); | |
}, msg.content) | |
.value(); | |
} else { | |
return msg.content; | |
} | |
} | |
function handleInput(msg) { | |
var isApi = msg.type === 'api', | |
args = processInlinerolls(msg).trim().splitArgs(), | |
command, arg0, isHelp; | |
if (isApi) { | |
command = args.shift().substring(1).toLowerCase(); | |
arg0 = args.shift() || ''; | |
isHelp = arg0.toLowerCase() === 'help' || arg0.toLowerCase() === 'h' || command === 'help'; | |
if (!isHelp) { | |
if (arg0 && arg0.length > 0) { | |
args.unshift(arg0); | |
} | |
if (_.isFunction(commands[command])) { | |
commands[command](args, msg); | |
} | |
} else if (_.isFunction(commands.help)) { | |
commands.help(command === 'help' ? arg0 : command, args, msg); | |
} | |
} else if (_.isFunction(commands[`msg_${msg.type}`])) { | |
commands[`msg_${msg.type}`](args, msg); | |
} | |
} | |
function checkInstall() { | |
if (!state.bshields || | |
!state.bshields.armello || | |
!state.bshields.armello.version || | |
state.bshields.armello.version !== version) { | |
state.bshields = state.bshields || {}; | |
state.bshields.armello = { | |
version: version, | |
gcUpdated: 0, | |
config: {} | |
}; | |
} | |
checkGlobalConfig(); | |
} | |
function checkGlobalConfig() { | |
var gc = globalconfig && globalconfig['armellodice'], | |
st = state.bshields.armello; | |
if (gc && gc.lastsaved && gc.lastsaved > st.gcUpdated) { | |
st.gcUpdated = gc.lastsaved; | |
} | |
} | |
function registerEventHandlers() { | |
on('chat:message', handleInput); | |
} | |
return { | |
registerEventHandlers: registerEventHandlers, | |
checkInstall: checkInstall | |
}; | |
}()); | |
on('ready', function() { | |
'use strict'; | |
bshields.armello.checkInstall(); | |
bshields.armello.registerEventHandlers(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment