'use strict';
/* global on log playerIsGM findObjs getObj getAttrByName sendChat globalconfig */ // eslint-disable-line no-unused-vars
/*
GMSheet 0.1.3
A quick GM Cheatsheet for the D&D 5e OGL sheets on roll20.net.
Please use `!gmsheet` for inline help and examples.
arthurbauer@me.com
*/
on('ready', function () {
var v = '0.1.3'; // version number
var scname = 'GMSheet'; // script name
log(scname + ' v' + v + ' online. Select one or more party members, then use `!gmsheet -h`');
var output = '';
var collectedAttributes = '';
var wantedAttributes = void 0;
var columnjumper = 0;
var myoutput = '';
var resourceName = '';
var resolveAttr = function resolveAttr(cid, name) {
return {
name: name,
current: getAttrByName(cid, name),
max: getAttrByName(cid, name, 'max')
};
};
var getCharMainAtt = function getCharMainAtt(cid2) {
//! Main attributes
output = '
';
var cid = cid2.id;
wantedAttributes = ['strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma'];
wantedAttributes.forEach(function (myAtt) {
collectedAttributes = resolveAttr(cid, myAtt);
output += '| ' + collectedAttributes.name.slice(0, 3).toUpperCase() + ': | ' + (resolveAttr(cid, myAtt + '_mod').current > 0 ? '+' + resolveAttr(cid, myAtt + '_mod').current : resolveAttr(cid, myAtt + '_mod').current) + ' | (' + collectedAttributes.current + ') | | ';
if (columnjumper === 1) {
output += '
';
columnjumper = 0;
} else {
columnjumper = 1;
}
});
output += '
';
return output;
};
var getCharOtherAtt = function getCharOtherAtt(cid2) {
//! Other Attributes
output = '';
var cid = cid2.id;
var hp = parseInt(resolveAttr(cid, 'hp').current, 10);
var maxhp = parseInt(resolveAttr(cid, 'hp').max, 10);
var hpdown = maxhp - hp;
var hppercentage = Math.floor(100 * hp / maxhp / 5) * 5;
output = '
' + resolveAttr(cid, 'race').current + ' Lvl ' + resolveAttr(cid, 'level').current + ' ' + resolveAttr(cid, 'class').current + '';
output += resolveAttr(cid, 'inspiration').current === 'on' ? " 🌟" : '';
output += '
HP: ' + hp + '/' + maxhp + ' ';
output += hp < maxhp ? ' 🤕 ' + hppercentage + '% (-' + hpdown + ' HP) ' : '';
output += parseInt(resolveAttr(cid, 'hp_temp').current, 10) > 0 ? ' + ' + resolveAttr(cid, 'hp_temp').current + ' TMP' : '';
output += '
AC: ' + resolveAttr(cid, 'ac').current;
output += '
Speed: ' + resolveAttr(cid, 'speed').current + ' ft, Passive Perception: ' + resolveAttr(cid, 'passive_wisdom').current + '
Initiative bonus: ' + (resolveAttr(cid, 'initiative_bonus').current > 0 ? '+' + resolveAttr(cid, 'initiative_bonus').current : resolveAttr(cid, 'initiative_bonus').current) + ', Proficiency ' + (resolveAttr(cid, 'pb').current > 0 ? '+' + resolveAttr(cid, 'pb').current : resolveAttr(cid, 'pb').current);
output += '
';
return output;
};
var getSpellSlots = function getSpellSlots(cid2) {
//! Spell slots
output = '';
var cid = cid2.id;
output = '
Spell slots
';
var i = 1;
var spellLevelTotal = 0;
var spellLevelEx = 0;
var spellcount = 0;
while (i < 10) {
spellLevelTotal = resolveAttr(cid, 'lvl' + parseInt(i, 10) + '_slots_total').current;
spellLevelEx = resolveAttr(cid, 'lvl' + parseInt(i, 10) + '_slots_expended').current;
if (spellLevelTotal > 0) {
spellcount += 1;
if (spellLevelEx / spellLevelTotal <= 0.25) spellLevelEx = '' + spellLevelEx + '';else if (spellLevelEx / spellLevelTotal <= 0.5) spellLevelEx = '' + spellLevelEx + '';else if (spellLevelEx / spellLevelTotal <= 0.75) spellLevelEx = '' + spellLevelEx + '';else spellLevelEx = '' + spellLevelEx + '';
output += 'Level ' + i + ': ' + spellLevelEx + ' / ' + spellLevelTotal + '
';
}
i += 1;
}
if (spellcount < 1) output = '';
// start with sorcerer points here...
// check which attribute to get.
if (resolveAttr(cid, 'class').current === 'Sorcerer') {
resourceName = 'Sorcerer points';
} else if (resolveAttr(cid, 'class').current === 'Barbarian') {
resourceName = 'Rage';
} else if (resolveAttr(cid, 'class').current === 'Bard') {
resourceName = 'Bardic Inspiration';
} else if (resolveAttr(cid, 'class').current === 'Cleric' || resolveAttr(cid, 'class').current === 'Paladin') {
resourceName = 'Channel Divinity';
} else if (resolveAttr(cid, 'class').current === 'Druid') {
resourceName = 'Wild Shape';
} else if (resolveAttr(cid, 'class').current === 'Fighter') {
resourceName = 'Second Wind';
} else if (resolveAttr(cid, 'class').current === 'Monk') {
resourceName = 'KI';
} else if (resolveAttr(cid, 'class').current === 'Warlock') {
resourceName = 'Spell Slots';
}
var classResourceTotal = resolveAttr(cid, 'class_resource').max;
var classResourceCurrent = resolveAttr(cid, 'class_resource').current;
if (resourceName) output += '
' + resourceName + ': ' + classResourceCurrent + '/' + classResourceTotal;
resourceName = '';
return output;
};
on('chat:message', function (msg) {
if (msg.type !== 'api' && !playerIsGM(msg.playerid)) return;
if (msg.content.startsWith('!gmsheet') !== true) return;
if (msg.content.includes('-help') || msg.content.includes('-h')) {
//! Help
sendChat(scname, '/w gm Roll20-GMSheet
Version 0.1.3
A quick GM Cheatsheet for the D&D 5e OGL sheets on Roll20.Please use !gmsheet -h for inline help and examples.
The script currently shows
- name, race, level and class, including the character's avatar
- inspiration!
- HP, also indicating temporary hitpoints and injuries
- speed, passive perception, initiative bonus
- main abilities + modifiers
- available spell slots
Usage
- Select one or several tokens
- Type
!gmsheet in chat
'); // eslint-disable-line quotes
} else if (msg.selected == null) {
sendChat(scname, '/w gm **ERROR:** You need to select at least one character.');
/* will add a routine to save/load characters later */
} else {
msg.selected.forEach(function (obj) {
//! Output
var token = getObj('graphic', obj._id); // eslint-disable-line no-underscore-dangle
var character = void 0;
if (token) {
character = getObj('character', token.get('represents'));
}
if (character) {
/* get the attributes and assemble the output */
var charname = character.get('name');
var charicon = character.get('avatar');
if (myoutput.length > 0) myoutput += '
';
myoutput += '
' + charname + '
' + getCharOtherAtt(character) + getCharMainAtt(character) + getSpellSlots(character);
}
});
sendChat(scname, '/w gm ' + myoutput + '
'); // eslint-disable-line quotes
myoutput = '';
}
});
});