Skip to content

Instantly share code, notes, and snippets.

@SplenectomY
Last active November 21, 2017 17:55
Show Gist options
  • Save SplenectomY/5bef7f65e1d13eab70f81fe4e9fd2455 to your computer and use it in GitHub Desktop.
Save SplenectomY/5bef7f65e1d13eab70f81fe4e9fd2455 to your computer and use it in GitHub Desktop.
Creates abilities for each character based on the repeating_action sections of the 5th Edition OGL character sheet
// SET CONFIG FIRST, THEN CHANGE "RUN" TO TRUE
// Create a button to roll HP for a selected NPC token. Requires TokenMod
var doHP = false,
// If you're done with all the config, set this to true and save the script.
// Be careful and make sure you're 100 percent ready. This script is going
// to make macro buttons for EVERY CHARACTER YOU HAVE. It will take a moment.
// These actions are not easily undone. Consider copying your campaign
// to test it first.
run = false,
// END CONFIG
CharAbilities = {}
const getRepeatingSectionAttrs = function (charid, prefix)
{
const repeatingAttrs = {},
regExp = new RegExp(`^${prefix}_(-[-A-Za-z0-9]+?|\\d+)_`);
let repOrder;
// Get attributes
findObjs({
_type: 'attribute',
_characterid: charid
}).forEach(o => {
const attrName = o.get('name');
if (attrName.search(regExp) === 0) repeatingAttrs[attrName] = o;
else if (attrName === `_reporder_${prefix}`) repOrder = o.get('current').split(',');
});
if (!repOrder) repOrder = [];
// Get list of repeating row ids by prefix from repeatingAttrs
const unorderedIds = [...new Set(Object.keys(repeatingAttrs)
.map(n => n.match(regExp))
.filter(x => !!x)
.map(a => a[1]))];
const repRowIds = [...new Set(repOrder.filter(x => unorderedIds.includes(x)).concat(unorderedIds))];
return [repRowIds, repeatingAttrs];
},
removeSplenAbils = function()
{
var abilities = filterObjs(function(o)
{
if(o.get("_type") == "ability" && o.get("description") === "SplenRepeatingAbil")
{
log("Removing ability '" + o.get("name") + "' from " + o.get("_characterid"))
o.remove()
}
})
}
var wasAnythingCreated = false
const createAbil = function(n, act, char)
{
var makeAction = true
if(CharAbilities[char.id][n]) makeAction = false
createObj("ability", {
name: n,
action: act,
istokenaction: makeAction,
characterid: char.id,
description: "SplenRepeatingAbil"
})
wasAnythingCreated = true
CharAbilities[char.id][n] = true
log("Created ability button '" + n + "' for character '" + char.get("name") + "'")
},
abilExists = function(a, char) {return findObjs({action: a, _type: "ability", _characterid: char.id}).length},
process = function()
{
removeSplenAbils()
CharAbilities = {}
var prefixes =
[
"npcaction",
"npcaction-l",
"attack",
"spell-npc",
"spell-cantrip"
],
suffixes = [],
names = []
for (f = 1; f < 15; f++)
{
if(f<3) names.push("_name")
else if(f<4) names.push("_atkname")
else names.push("_spellname")
if(f<4) suffixes.push("rollbase")
else if(f<6) suffixes.push("rollcontent")
else
{
prefixes.push("spell-" + String(f - 5))
suffixes.push("rollcontent")
}
}
log("Finding repeating actions for characters...")
var chars = findObjs({_type: "character"})
var makeAbils = function(o)
{
CharAbilities[o.id] = CharAbilities[o.id] || {}
var isNPC = parseInt(getAttrByName(o.id, "npc"))
//Handle utility buttons
if(isNPC && doHP)
{
var a = "!token-mod --set bar3|[[@{npc_hpformula}]]"
if(!abilExists(a,o)) createAbil(".HP", a, o)
}
a = "@{wtype}&{template:simple} {{rname=^{init-u}}} {{mod=@{initiative_bonus}}} {{r1=[[@{initiative_style}+@{initiative_bonus}@{pbd_safe}[INIT] &{tracker}]]}} {{normal=1}} @{charname_output}"
if(isNPC) a = "@{wtype}&{template:npc} @{npc_name_flag} {{rname=^{init}}} {{mod=[[[[@{initiative_bonus}]][DEX]]]}} {{r1=[[@{d20}+[[@{initiative_bonus}]][DEX] &{tracker}]]}} {{normal=1}} {{type=Initiative}}"
if(!abilExists(a,o))
{
if(isNPC) createAbil(".INIT", a, o)
else createAbil(".INIT", a, o)
}
a = "!SplenSave ?{Which attribute?|STR|DEX|CON|INT|WIS|CHA}"
if(!abilExists(a,o)) createAbil(".SAVE", a, o)
a = "!SplenDoor"
if(!abilExists(a,o)) createAbil(".DOOR", a, o)
//Handle repeating actions
_.each(prefixes, function(p,k)
{
RepActions = getRepeatingSectionAttrs(o.id,"repeating_" + p)
_.each(RepActions[0], function(g)
{
if(RepActions[0].length)
{
var a = "@{repeating_" + p + "_" + g + "_" + suffixes[k] + "}"
var j = RepActions[1]["repeating_" + p + "_" + g + names[k]].get("current")
if(j === "") j = p + "_" + g
createAbil(j, a, o)
}
})
})
}
_.each(chars, function(o)
{
_.delay(makeAbils, 50, o)
})
}
on('ready',function()
{
if(run) process()
})
var getAttr = function(a)
{
return {
"STR" : "strength",
"DEX" : "dexterity",
"CON" : "constitution",
"INT" : "intelligence",
"WIS" : "wisdom",
"CHA" : "charisma"
}[a]
}
on("chat:message", function(msg)
{
if(msg.type == "api")
{
if(msg.content.indexOf("!SplenSave ") !== -1 && msg.selected)
{
var a = msg.content.replace("!SplenSave ", "")
var b = getAttr(a)
var char = getObj(msg.selected[0]._type, msg.selected[0]._id)
var c = getObj("character", char.get("represents")).get("name")
var isNPC = parseInt(getAttrByName(char.get("represents"), "npc"))
if(isNPC) sendChat(msg.who, "@{" + c + "|wtype}&{template:npc} @{" + c + "|npc_name_flag} {{rname=^{" + b + "}}} {{mod=[[[[@{" + c + "|" + b + "_mod}]]]]}} {{r1=[[@{" + c + "|d20}+[[@{" + c + "|" + b + "_mod}]]]]}} @{" + c + "|rtype}+[[@{" + c + "|" + b + "_mod}]]]]}} {{type=Ability}}")
else sendChat(msg.who, "@{" + c + "|wtype}&{template:simple} {{rname=^{" + b + "-save-u}}} {{mod=@{" + c + "|" + b + "_save_bonus}}} {{r1=[[@{" + c + "|d20}+@{" + c + "|" + b + "_save_bonus}@{" + c + "|pbd_safe}]]}} @{" + c + "|rtype}+@{" + c + "|" + b + "_save_bonus}@{" + c + "|pbd_safe}]]}} @{" + c + "|global_save_mod} @{" + c + "|charname_output}")
}
else if(msg.content.indexOf("!SplenFlushAbils") !== -1)
{
var isGM = playerIsGM(msg.playerid)
if(isGM)
{
removeSplenAbils()
sendChat("System", "/w " + msg.who + "All repeating ability buttons have been removed.")
}
else sendChat("System", "/w " + msg.who + "You must be a GM to use that command.")
}
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment