Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[Script] Bloodied Reminder

1663468262

Edited 1663469181
Liam
Pro
In order to make monster fights more interesting in D&D 5e games, I often find myself adding "bloodied" conditions to the monsters. A monster being "bloodied" essentially means that it has just lost enough hit points to take it below half its max amount. Personally, I find this is a great way to make combat a bit more dynamic and turn a boring encounter into one that evolves as the fight goes on, allowing a monster who is losing a fight to act in a different way than if it were fresh in a fight. This often has one (or more) of several effects on the monster's stat block, completely differently depending on the creature and what its tactics are: They may unlock extra actions they can use that weren't previously available It may gain new reactions, so it can react differently to the situation than before Sometimes it gives them a way to flee the fight or do some extra damage Sometimes it gives them new passive abilities, like acid leaking out of a black dragon's wounds that do damage to anyone who gets close Sometimes being "bloodied" is detrimental to the monster itself, like having its natural armor chipped away and lowering its AC Once my monster is set up, I have one main problem: I forget when it gets bloodied! That's what this little script solves. What is Bloodied Reminder? This script sends the GM a reminder note whenever your monsters first go below half their max HP in a fight, AND if they have anything (eg. traits/actions/bonus actions/reactions/legendary actions) on their stat block with the word "Bloodied" in the title (this way it doesn't remind you even on monsters without bloodied conditions). What might a bloodied creature do? Consider an Ancient Red Dragon, an above-average-intellect creature, who has just realised they might be losing the fight: Perhaps they will use a new action, replacing their claw attacks with an attempt to fling their enemies away, causing bludgeoning damage if they are knocked into a solid object. This will let the dragon make a clean escape without taking opportunity attacks. They muster up all their strength to use their breath weapon again (immediately recharging any expended uses whenever they are first knocked below half HP in the fight) in order to use their most powerful attack once again at their foes. Maybe they decide they need to fight more, and regain any uses of their legendary actions this round. Maybe they just want to play mind games with their opponent, and will use its reaction when an attack misses it to make a jest, or retaliate with an attack of its own Here's the script: on('ready',()=>{ var hpBar = 'bar1'; /** Check if a character sheet has any actions/bonus actions/reactions/traits with the phrase "bloodied" in the name */ function hasBloodiedConditions(characterSheetId) { let attributes = findObjs({ type: 'attribute', characterid: characterSheetId }) .filter(attribute => /^repeating_([^_]*?)_([^_]*?)_name$/g.test(attribute.get('name'))) .filter(attribute => attribute.get('current').toLowerCase().includes('bloodied')); return attributes.length > 0; } on(`change:graphic:${hpBar}_value`, function(obj, prev) { var hasMaxHp = obj.get(`${hpBar}_max`) !== ''; if (!hasMaxHp) return; var isAlreadyBloodied = prev[`${hpBar}_value`] <= prev[`${hpBar}_max`] / 2; var isNewlyBloodied = obj.get(`${hpBar}_value`) <= obj.get(`${hpBar}_max`) / 2; var isRepresentingCharacterSheet = obj.get('represents') !== ''; var isControlledByPlayer = getObj('character', obj.get('represents')).get('controlledby') !== ''; if(!isAlreadyBloodied && isNewlyBloodied && isRepresentingCharacterSheet && !isControlledByPlayer) { if (!hasBloodiedConditions(obj.get('represents'))) return; var name = obj.get('name'); sendChat('Bloodied', `/w gm ${name} has been bloodied!`); } }); });
1663468789

Edited 1663468874
The Aaron
Roll20 Production Team
API Scripter
Nice little addition!  I'd suggest wrapping the whole script in on('ready',()=>{ /*code here*/ });  to avoid collisions in the global scope (all scripts are concatenated at execution).  It might be cool to list out the abilities that activate on bloodied in the chat. You can use html in your sendChat(), so maybe an <ul> element. =D
Thanks for the reminder for the on-ready, forgot that! Yeah I considered adding some things to the chat message, but considering they can come in many forms (eg. new passive traits, actions, bonus actions, reaction options or an immediate reaction upon being bloodied), I wasn't sure how best to display that compared to the character sheet itself. I'll play around with that and see what I can come up with.