Skip to content

Instantly share code, notes, and snippets.

@VoltCruelerz
Created September 19, 2018 23:39
Show Gist options
  • Select an option

  • Save VoltCruelerz/74c61c7bcf4c72ae73f2fb258981b340 to your computer and use it in GitHub Desktop.

Select an option

Save VoltCruelerz/74c61c7bcf4c72ae73f2fb258981b340 to your computer and use it in GitHub Desktop.
Alteration to The Aaron's Spell Menu script
on('ready',()=>{
const range = (n) => [...Array(n).keys()];
const spellAbilityName = 'Spells';
const spellProps = ['cantrip','1','2','3','4','5','6','7','8','9'];
const spellLevelNames = {
cantrip: "Cantrips",
1: "1st Level",
2: "2nd Level",
3: "3rd Level",
4: "4th Level",
5: "5th Level",
6: "6th Level",
7: "7th Level",
8: "8th Level",
9: "9th Level"
};
const displayOnlyPrepared = true;
const isSpellSlot = /^lvl(\d)_slots_total$/;
const isSpell = /^repeating_spell-([^_]*)_(.*)_spellname/;
const isPrepared = /^repeating_spell-([^_]*)_(.*)_spellprepared/;
const makeButton = (l,n) => `[@{selected|repeating_spell-${l}_$${n}_spellname}](~selected|repeating_spell-${l}_$${n}_spell)`;
const makeLevel = (s,l,n) => `{{${spellLevelNames[l]}${s?` (${s} slot${s!==1?'s':''})`:''}=${range(n).map(nn=>makeButton(l,nn)).join('')}}}`; // eslint-disable-line no-irregular-whitespace
const makeSpellSheet = (c) => {
let cn = getAttrByName(c.id, 'character_name');
if(!cn) cn = getAttrByName(c.id, 'npc_name');
const isNpc = getAttrByName(c.id, 'npc') || 0;
const counts = {};
const slots = {};
const preparedSpells = [];
// find all prepared entries
if(displayOnlyPrepared && isNpc == 0){
findObjs({
type: 'attribute',
characterid: c.id
}).forEach(p=>{
let pn = p.get('name');
if(isPrepared.test(pn)){
let pp = p.get('current') || 0;
if(pp > 0){
preparedSpells.push(pn.match(isPrepared)[2]);
}
}
let pm = pn.match(isPrepared);
});
}
// find all spells
findObjs({
type: 'attribute',
characterid: c.id
})
.forEach(a=>{
let n = a.get('name');
if(isSpellSlot.test(n)){
let m = n.match(isSpellSlot);
slots[m[1]]=parseInt(a.get('current'));
} else if(isSpell.test(n)){
let m = n.match(isSpell);
// If showing only prepared, do not check cantrips or npcs
if(displayOnlyPrepared && m[1] !== spellProps[0] && isNpc == 0) {
if(preparedSpells.includes(m[2])){
counts[m[1]]=(counts[m[1]]||0)+1;
}
} else {
counts[m[1]]=(counts[m[1]]||0)+1;
}
}
});
let parts = [];
if(Object.keys(counts).length){
spellProps.forEach(k=>{
if(counts.hasOwnProperty(k)){
parts.push(makeLevel(slots[k],k,counts[k]));
}
});
let ability = (findObjs({
type: 'ability',
characterid: c.id,
name: spellAbilityName
})[0] || createObj('ability',{
characterid: c.id,
name: spellAbilityName
}));
ability.set({
action: `/w "${cn}" @{selected|wtype}&{template:default}{{name=${cn} Spells}}${parts.join('')}`,
istokenaction: true
});
}
};
const updateAll = () => {
let queue = findObjs({
type: 'character'
});
const burndownQueue = () => {
if(queue.length){
makeSpellSheet(queue.shift());
setTimeout(burndownQueue,0);
} else {
log('Done Updating Spells Ability');
}
};
log(`Considering ${spellAbilityName} Ability on ${queue.length} character${queue.length!==1?'s':''}`);
setTimeout(burndownQueue,100);
}
updateAll();
on('chat:message', (msg) => {
log('msg: ' + msg.content);
if (msg.type !== 'api') return;
if (msg.content === '!spellMenu'){
updateAll();
sendChat('Spell Menu', `Refreshing Spell Menus`);
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment