
The upcoming version of D&D is likely to institute a popular alternative to the standard exhaustion rules. Each level of exhaustion simply subtracts -1 from all d20 rolls. There are other proposed penalties, such as a -1 to spell save DC and -5 ft. of movement, but the d20 test is all this script addresses. The other stuff is more messy to implement on the D&D 5th Edition by Roll20 Sheet.
Every time you change the exhaustion level on a PC, it will modify the core die roll to add an exhaustion penalty. Changing the exhaustion level to 0 will remove all modifications and restore the core roll to "1d20". The script recognizes changes made by ChatSetAttr
There are some limitations:
- This only affects the core 1d20 roll used for attacks, ability checks and saving throws. Movement, spell DC or other proposed changes are not covered.
- It only affects the first roll. If you have always roll advantage turned on, the second roll does not suffer the penalty. I can't do anything about this, that second roll is created by the roll template as far as I can tell
- This script only manages PCs and unique NPCs. NPCs use a statblock that has no visible for exhaustion. You can set it on an NPC using the ChatSetAttr script, but keep in mind that if you have one sheet representing multiple creatures (ex. a horde of goblins), ALL tokens represented by that sheet will share exhaustion level. The script is best used on PCs, or NPC statblocks that only represent a unique creature.
- Toggle the sheet setting that allows for exhaustion tracking. This allows players to easily track their own exhaustion. They can ignore the standard exhaustion listing on the sheet if you use this script.
The Code:
on('ready', () => { const registerWithCSA = () => { setTimeout(() => { if (typeof(ChatSetAttr) === 'object') { ChatSetAttr.registerObserver('change', onChangeAttribute); } else { // notify GM that CSA changes won't work } }, 100); } registerWithCSA(); function setExhaustion(obj) { let cID = obj.get("_characterid"); let exhaustionLevel = parseInt(obj.get('current')); let rollString = { core_die: "1d20" }; if (exhaustionLevel > 0) { rollString = { core_die: "-" + exhaustionLevel + "[Exhaustion]+1d20" }; } setAttrs(cID, rollString); } const onChangeAttribute = function(obj, prev) { if (obj.get('name') === 'exhaustion_level') { setExhaustion(obj); } }; on("change:attribute", onChangeAttribute); });
Sample ChatSetAttr macro:
!setattr --sel --exhaustion_level|?{Choose Exhaustion Level}
Disclaimer: As always with one of my scripts, test carefully. The only thing this script should be able to change is the "core_die" attribute. If anything needs to be reset manually, you can change this on the Attributes and Abilities tab of the character journal. The default value is "1d20".