Created
May 15, 2025 16:38
-
-
Save keithcurtis1/432a1ca92ac1cecf742d56df07169033 to your computer and use it in GitHub Desktop.
Looks for keywords in chat to give buttons for assigning and defining
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var API_Meta = API_Meta || {}; //eslint-disable-line no-var | |
API_Meta.Condefinition = { | |
offset: Number.MAX_SAFE_INTEGER, | |
lineCount: -1 | |
}; { | |
try { | |
throw new Error(''); | |
} catch (e) { | |
API_Meta.Condefinition.offset = (parseInt(e.stack.split(/\n/)[1].replace(/^.*:(\d+):.*$/, '$1'), 10) - (7)); | |
} | |
} | |
/* globals libTokenMarkers, TokenMod, SmartAoE */ | |
on('ready', () => { | |
let applyDamageIsInstalled = false; | |
//check for dependencies | |
if (typeof ApplyDamage !== "undefined") { | |
applyDamageIsInstalled = true; | |
} | |
let groupCheckIsInstalled = false; | |
if (typeof GroupCheck !== "undefined") { | |
groupCheckIsInstalled = true; | |
} | |
const version = '0.0.0b12'; | |
log('Condefinitions v' + version + ' is ready! --offset ' + API_Meta.Condefinition.offset + ' for the D&D 5th Edition by Roll20 Sheet.'); | |
const buttonstyle = `"background-color:#702c91; border-style:none;border-radius:0px 0px 0px 0px; margin:3px 2px 3px 0px; text-decoration:none;display:inline-block;color:#e6e6e6; font-family:Arial; font-size:13px; padding:0px 7px"`; | |
const publicButtonStyle = `"background-color:#702c91; border-style:none;border-radius:10px 0px 0px 10px; margin:3px 2px 3px 3px; text-decoration:none;display:inline-block;color:#e6e6e6; font-family:Arial; font-size:13px; padding:0px 3px"`; | |
const markerButtonStyle = `"background-color:#702c91; border-style:none;border-radius:0px 10px 10px 0px; margin:3px 3px 3px 0px; text-decoration:none;display:inline-block;color:#e6e6e6; font-family:Arial; font-size:13px; padding:0px 3px"`; | |
const saveButtonstyle = `"background-color:#ce0f69; border-width:0px;border-radius:13px; margin:3px; text-transform:capitalize;text-decoration:none;display:inline-block;color:#fff; font-family:Arial; font-size:13px; padding:0px 7px"`; | |
const groupSaveButtonstyle = `"background-color:#ce0f69; border-width:0px;border-radius:13px 0px 0px 13px; margin:3px 1px 3px 3px; text-transform:capitalize;text-decoration:none;display:inline-block;color:#fff; font-family:Arial; font-size:13px; padding:0px 7px"`; | |
const applyDamageButtonstyle = `"background-color:#ce0f69; border-width:0px;border-radius:0px 13px 13px 0px; margin:3px 3px 3px 1px; text-transform:capitalize;text-decoration:none;display:inline-block;color:#fff; font-family:Arial; font-size:13px; padding:0px 7px"`; | |
const conditionnamestyle = `"background-color:#702c91; border-style:none;border-radius:6px 6px 0px 0px; margin:-8px -8px 3px -8px; font-weight:bold;text-transform:capitalize;text-decoration:none;display:block;text-align:center;color:#e6e6e6; font-family:Arial; font-size:13px; padding:0px 7px"`; | |
const reportstyle = `"display: block; position:relative;left: -5px; top: -30px; margin-bottom: -34px; background-color:#aaa; border-radius:6px; text-decoration:none;color:#000; font-family:Arial; font-size:13px; padding: 8px;"`; | |
const preportstyle = `"display: block; background-color:#aaa; border-radius:6px; text-decoration:none;color:#000; font-family:Arial; font-size:13px; padding: 8px;"`; | |
const regexForTitles = /<a style='background-color: transparent;padding: 0px;color: #702c91;display: inline-block;border: none;' href='!condef incapacitated'>incapacitated<\/a>/; | |
const buttonbox = `<div style='position:relative;left: -5px; top: -30px; margin-bottom: -34px; min-height:30px; border: solid 1px #444; border-radius:4px; background-color:#000;display:block'>`; | |
const buttonboxUnshifted = `<div style='position:relative;left: -5px; top: min-height:30px; border: solid 1px #444; border-radius:4px; background-color:#000;display:block'>`; | |
const printChar = '<span style="font-family: pictos">w</a>'; | |
// SET STATUS CONDITIONS OR TOKEN MARKERS HERE | |
const ConcentrationMarker = "Concentrating" | |
const condefConcentrationMarker = "status_" + ConcentrationMarker; | |
// Double colons in Custom Token Marker names must use double semicolons | |
const conditionsArray = [ | |
["concentrating", | |
/concentration check|concentration=1/i, | |
"Some spells and other effects require Concentration to remain active, as specified in their descriptions. If the effect’s creator loses Concentration, the effect ends. If the effect has a maximum duration, the effect’s description specifies how long the creator can concentrate on it: up to 1 minute, 1 hour, or some other duration. The creator can end Concentration at any time (no action required). The following factors break Concentration.<BR>Another Concentration Effect. You lose Concentration on an effect the moment you start casting a spell that requires Concentration or activate another effect that requires Concentration.<BR>Damage. If you take damage, you must succeed on a Constitution saving throw to maintain Concentration. The DC equals 10 or half the damage taken (round down), whichever number is higher, up to a maximum DC of 30.<BR>Incapacitated or Dead. Your Concentration ends if you have the Incapacitated condition or you die.", | |
// `death-zone` | |
`Concentrating` | |
], | |
["blinded", | |
/(be|and|is|magically|become|becomes|is either) blinded|blinded condition/i, | |
"While you have the Blinded condition, you experience the following effects.<BR><b>Can’t See.</b> You can’t see and automatically fail any ability check that requires sight.<BR><b>Attacks Affected.</b> Attack rolls against you have Advantage, and your attack rolls have Disadvantage.", | |
// `bleeding-eye` | |
`Blinded` | |
], | |
[ | |
"charmed", | |
/(be|and|is|magically|become|becomes) charmed|charmed condition/i, | |
"While you have the Charmed condition, you experience the following effects.<BR><BR><b>Can’t Harm the Charmer.</b> You can’t attack the charmer or target the charmer with damaging abilities or magical effects.<BR><BR><b>Social Advantage.</b> The charmer has Advantage on any ability check to interact with you socially.", | |
// `chained-heart` | |
`Charmed` | |
], | |
[ | |
"deafened", | |
/(be|and|is|magically|become|becomes) deafened|deafened condition/i, | |
"While you have the Deafened condition, you experience the following effect.<BR><BR><b>Can’t Hear.</b> You can’t hear and automatically fail any ability check that requires hearing.", | |
// `overdrive` | |
`Deafened` | |
], | |
[ | |
"exhaustion", | |
/(be|and|is|magically|become|becomes) exhausted|(of|magical) exhaustion|exhausted condition/i, | |
"While you have the Exhaustion condition, you experience the following effects.<BR><BR><b>Exhaustion Levels.</b> This condition is cumulative. Each time you receive it, you gain 1 Exhaustion level. You die if your Exhaustion level is 6.<BR><BR><b>D20 Tests Affected.</b> When you make a D20 Test, the roll is reduced by 2 times your Exhaustion level.<BR><BR><b>Speed Reduced.</b> Your Speed is reduced by a number of feet equal to 5 times your Exhaustion level.<BR><BR><b>Removing Exhaustion Levels.</b> Finishing a Long Rest removes 1 of your Exhaustion levels. When your Exhaustion level reaches 0, the condition ends.", | |
// `half-haze` | |
`Exhaustion1;;30991` | |
], | |
[ | |
"frightened", | |
/(be|and|is|magically|become|becomes) frightened|frightened condition/i, | |
"While you have the Frightened condition, you experience the following effects.<BR><BR><b>Ability Checks and Attacks Affected.</b> You have Disadvantage on ability checks and attack rolls while the source of fear is within line of sight.<BR><BR><b>Can’t Approach.</b> You can’t willingly move closer to the source of fear.", | |
// `screaming` | |
`Frightened;;31005` | |
], | |
[ | |
"grappled", | |
/(be|and|is|magically|becomes|considered) grappled|grappled condition/i, | |
"While you have the Grappled condition, you experience the following effects.<BR><BR><b>Speed 0.</b> Your Speed is 0 and can’t increase.<BR><BR><b>Attacks Affected.</b> You have Disadvantage on attack rolls against any target other than the grappler.<BR><BR><b>Movable.</b> The grappler can drag or carry you when it moves, but every foot of movement costs it 1 extra foot unless you are Tiny or two or more sizes smaller than it.", | |
// `grab` | |
`Grappled;;31007` | |
], | |
[ | |
"incapacitated", | |
/(be|and|is|magically|become|becomes) incapacitated|incapacitated condition/i, | |
"While you have the Incapacitated condition, you experience the following effects.<BR><BR><b>Inactive.</b> You can’t take any action, Bonus Action, or Reaction.<BR><BR><b>No Concentration.</b> Your Concentration is broken.<BR><BR><b>Speechless.</b> You can’t speak.<BR><BR><b>Surprised.</b> If you’re Incapacitated when you roll Initiative, you have Disadvantage on the roll.", | |
// `interdiction` | |
`Incapacitated;;31018` | |
], | |
[ | |
"invisible", | |
/(be|and|is|magically|become|becomes) invisible|invisible condition/i, | |
"While you have the Invisible condition, you experience the following effects.<BR><BR><b>Surprise.</b> If you’re Invisible when you roll Initiative, you have Advantage on the roll.<BR><BR><b>Concealed.</b> You aren’t affected by any effect that requires its target to be seen unless the effect’s creator can somehow see you. Any equipment you are wearing or carrying is also concealed.<BR><BR><b>Attacks Affected.</b> Attack rolls against you have Disadvantage, and your attack rolls have Advantage. If a creature can somehow see you, you don’t gain this benefit against that creature.", | |
// `ninja-mask` | |
`Invisible;;31021` | |
], | |
[ | |
"paralyzed", | |
/(be|and|is|magically|become|becomes) paralyzed|paralyzed condition/i, | |
"While you have the Paralyzed condition, you experience the following effects.<BR><BR><b>Incapacitated.</b> You have the <a style='background-color: transparent;padding: 0px;color: #702c91;display: inline-block;border: none;' href='!condef incapacitated'>Incapacitated</a> condition.<BR><BR><b>Speed 0.</b> Your Speed is 0 and can’t increase.<BR><BR><b>Saving Throws Affected.</b> You automatically fail Strength and Dexterity saving throws.<BR><BR><b>Attacks Affected.</b> Attack rolls against you have Advantage.<BR><BR><b>Automatic Critical Hits.</b> Any attack roll that hits you is a Critical Hit if the attacker is within 5 feet of you.", | |
// `aura` | |
`Paralyzed;;31028` | |
], | |
[ | |
"petrified", | |
/(be|and|is|magically|become|becomes|becoming) petrified|(turns to|turning to) stone|petrified condition/i, | |
"While you have the Petrified condition, you experience the following effects.<BR><BR><b>Turned to Inanimate Substance.</b> You are transformed, along with any nonmagical objects you are wearing and carrying, into a solid inanimate substance (usually stone). Your weight increases by a factor of ten, and you cease aging.<BR><BR><b>Incapacitated.</b> You have the <a style='background-color: transparent;padding: 0px;color: #702c91;display: inline-block;border: none;' href='!condef incapacitated'>Incapacitated</a> condition.<BR><BR><b>Speed 0.</b> Your Speed is 0 and can’t increase.<BR><BR><b>Attacks Affected.</b> Attack rolls against you have Advantage.<BR><BR><b>Saving Throws Affected.</b> You automatically fail Strength and Dexterity saving throws.<BR><BR><b>Resist Damage.</b> You have Resistance to all damage.<BR><BR><b>Poison Immunity.</b> You have Immunity to the Poisoned condition.", | |
// `chemical-bolt` | |
`Petrified;;31029` | |
], | |
[ | |
"poisoned", | |
/(be|and|is|magically|become|becomes) poisoned|poisoned condition/i, | |
"While you have the Poisoned condition, you experience the following effect.<BR><BR><b>Ability Checks and Attacks Affected.</b> You have Disadvantage on attack rolls and ability checks.", | |
// `skull` | |
'Poisoned;;31030' | |
], | |
[ | |
"prone", | |
/(be|and|is|magically|become|becomes|knocked|fall|falls) prone|prone condition/i, | |
"While you have the Prone condition, you experience the following effects.<BR><BR><b>Restricted Movement.</b> Your only movement options are to crawl or to spend an amount of movement equal to half your Speed (round down) to right yourself and thereby end the condition. If your Speed is 0, you can’t right yourself.<BR><BR><b>Attacks Affected.</b> You have Disadvantage on attack rolls. An attack roll against you has Advantage if the attacker is within 5 feet of you. Otherwise, that attack roll has Disadvantage.", | |
// `back-pain` | |
`Prone;;31031` | |
], | |
[ | |
"restrained", | |
/(be|and|is|magically|become|becomes) restrained|restrained condition/i, | |
"While you have the Restrained condition, you experience the following effects.<BR><BR><b>Speed 0.</b> Your Speed is 0 and can’t increase.<BR><BR><b>Attacks Affected.</b> Attack rolls against you have Advantage, and your attack rolls have Disadvantage.<BR><BR><b>Saving Throws Affected.</b> You have Disadvantage on Dexterity saving throws.", | |
// `cobweb` | |
`Restrained;;31033` | |
], | |
[ | |
"stunned", | |
/(be|and|is|magically|become|becomes) stunned|stunned condition/i, | |
"While you have the Stunned condition, you experience the following effects.<BR><BR><b>Incapacitated.</b> You have the <a style='background-color: transparent;padding: 0px;color: #702c91;display: inline-block;border: none;' href='!condef incapacitated'>Incapacitated</a> condition.<BR><BR><b>Saving Throws Affected.</b> You automatically fail Strength and Dexterity saving throws.<BR><BR><b>Attacks Affected.</b> Attack rolls against you have Advantage.", | |
// `broken-skull` | |
`Stunned;;31035` | |
], | |
[ | |
"unconscious", | |
/(be|and|is|magically|become|becomes) unconscious|unconscious condition/i, | |
"While you have the Unconscious condition, you experience the following effects.<BR><BR><b>Inert.</b> You have the <a style='background-color: transparent;padding: 0px;color: #702c91;display: inline-block;border: none;' href='!condef incapacitated'>Incapacitated</a> and <a style='background-color: transparent;padding: 0px;color: #702c91;display: inline-block;border: none;' href='!condef prone'>Prone</a> conditions, and you drop whatever you’re holding. When this condition ends, you remain Prone.<BR><BR><b>Speed 0.</b> Your Speed is 0 and can’t increase.<BR><BR><b>Attacks Affected.</b> Attack rolls against you have Advantage.<BR><BR><b>Saving Throws Affected.</b> You automatically fail Strength and Dexterity saving throws.<BR><BR><b>Automatic Critical Hits.</b> Any attack roll that hits you is a Critical Hit if the attacker is within 5 feet of you.<BR><BR><b>Unaware.</b> You’re unaware of your surroundings.", | |
// `death-zone` | |
`Unconscious;;31039` | |
], | |
[ | |
"dead", | |
/nonmatching string to prevent accidental triggering/i, | |
"A dead creature has no Hit Points and can’t regain them unless it is first revived by magic such as the Raise Dead or Revivify spell. When such a spell is cast, the spirit knows who is casting it and can refuse. The spirit of a dead creature has left the body and departed for the Outer Planes, and reviving the creature requires calling the spirit back.<BR>If the creature returns to life, the revival effect determines the creature’s current Hit Points. Unless otherwise stated, the creature returns to life with any conditions, magical contagions, or curses that were affecting it at death if the durations of those effects are still ongoing. If the creature died with any Exhaustion levels, it returns with 1 fewer level. If the creature had Attunement to one or more magic items, it is no longer attuned to them.", | |
`dead` | |
], | |
[ | |
"bardic-inspiration", | |
/You can inspire others through stirring words or music/i, | |
"Once within the next 10 minutes, the creature can roll the die and add the number rolled to one ability check, Attack roll, or saving throw it makes. The creature can wait until after it rolls The D20 before deciding to use the Bardic Inspiration die, but must decide before the DM says whether the roll succeeds or fails.", | |
`Bardic;;30979` | |
], | |
[ | |
"bloodied", | |
/nonmatching string to prevent accidental triggering/i, | |
"A creature is Bloodied while it has half its Hit Points or fewer remaining. Usually determines the effectiveness of a Swarm. It is the point at which a creature reaches half their full hit points. The DM may reveal this to the players as an indicator of how strong the monster currently is.", | |
`Bloodied;;30981` | |
], | |
[ | |
"confused", | |
/spawning delusions and provoking uncontrolled action/i, | |
"Not a true condition, but can represent the effect of the confusion spell.<BR>An affected target can’t take reactions and must roll 1d10 at the start of each of its turns to determine its behavior for that turn, consulting the table below.<BR>1d10 - Behavior for the Turn<BR>1 - The target doesn't take an action, and it uses all its movement to move. Roll 1d4 for the direction: 1, north; 2, east; 3, south; or 4, west. <BR>2-6 - The target doesn't move or take actions. <BR>7-8 - The target doesn't move, and it takes the Attack action to make one melee attack against a random creature within reach. If none are within reach, the target takes no action.<BR>9-10 - The target chooses its behavior. At the end of each of its turns, an affected target repeats the save, ending the spell on itself on a success.", | |
`Confused;;30984` | |
], | |
[ | |
"full-cover", | |
/nonmatching string to prevent accidental triggering/i, | |
"Cover provides a degree of protection to a target behind it. There are three degrees of cover, each of which provides a different benefit to a target: Half Cover (+2 bonus to AC and Dexterity saving throws), Three-Quarters Cover (+5 bonus to AC and Dexterity saving throws), and Total Cover (can’t be targeted directly). If behind more than one degree of cover, a target benefits only from the most protective degree.", | |
// `death-zone` | |
`Cover;;30985` | |
], | |
[ | |
"three-quarter-cover", | |
/nonmatching string to prevent accidental triggering/i, | |
"Cover provides a degree of protection to a target behind it. There are three degrees of cover, each of which provides a different benefit to a target: Half Cover (+2 bonus to AC and Dexterity saving throws), Three-Quarters Cover (+5 bonus to AC and Dexterity saving throws), and Total Cover (can’t be targeted directly). If behind more than one degree of cover, a target benefits only from the most protective degree.", | |
`ThreeQuarterCover;;31037` | |
], | |
[ | |
"half-cover", | |
/nonmatching string to prevent accidental triggering/i, | |
"Cover provides a degree of protection to a target behind it. There are three degrees of cover, each of which provides a different benefit to a target: Half Cover (+2 bonus to AC and Dexterity saving throws), Three-Quarters Cover (+5 bonus to AC and Dexterity saving throws), and Total Cover (can’t be targeted directly). If behind more than one degree of cover, a target benefits only from the most protective degree.", | |
`HalfCover;;31009` | |
], | |
[ | |
"diseased", | |
/nonmatching string to prevent accidental triggering/i, | |
"See the entry on <a style='background-color: transparent;padding: 0px;color: #702c91;display: inline-block;border: none;' href='https://app.roll20.net/compendium/dnd5e/Rules%3ADiseases?sharedCompendium=4665985#toc_1'>Diseases</a> in the Compendium", | |
`Dieseased;;30988` | |
], | |
[ | |
"ethereal", | |
/ethereal/i, | |
"Border Ethereal<BR>From the Border Ethereal, a traveler can see into whatever plane it overlaps, but that plane appears grayish and indistinct, its colors blurring into each other and its edges turning fuzzy, limiting visibility to 30 feet into the other plane. Conversely, the Ethereal Plane is usually imperceptible to those on the overlapped planes, except with the aid of magic.<BR>Normally, creatures in the Border Ethereal can’t attack creatures on the overlapped plane, and vice versa. A traveler on the Ethereal Plane is imperceptible to someone on the overlapped plane, and solid objects on the overlapped plane don’t hamper the movement of a creature in the Border Ethereal. The exceptions are certain magical effects (including anything made of magical force) and living beings. This makes the Ethereal Plane ideal for scouting, spying on opponents, and moving around without being detected. The Ethereal Plane also disobeys the laws of gravity; a creature there can freely move in any direction.<BR>Deep Ethereal<BR>To reach the Deep Ethereal, one typically needs a Plane Shift spell, a Gate spell, or a magical portal. Visitors to the Deep Ethereal are engulfed by roiling mist. Scattered throughout the plane are curtains of vaporous color, and passing through a curtain leads a traveler to a region of the Border Ethereal connected to a specific Inner Plane, the Material Plane, the Feywild, or the Shadowfell. The color of the curtain indicates the plane whose Border Ethereal the curtain conceals; see the Ethereal Curtains table. The curtains are also distinguishable by texture and temperature, each one reflecting something of the nature of the plane beyond.", | |
`Ethereal;;30990` | |
], | |
[ | |
"flying", | |
/nonmatching string to prevent accidental triggering/i, | |
"A variety of effects allow a creature to fly. While flying, you fall if you have the Incapacitated or Prone condition or your Fly Speed is reduced to 0. You can stay aloft in those circumstances if you can hover.", | |
`Flying;;31003` | |
], | |
[ | |
"haste", | |
/as a wave of lethargy sweeps over it/i, | |
"The target’s speed is doubled, it gains a +2 bonus to AC, it has advantage on Dexterity Saving Throws, and it gains an additional Action on each of its turns. That Action can be used only to take the Attack (one weapon attack only), Dash, Disengage, Hide, or Use an Object Action.<BR>When the spell ends, the target can’t move or take actions until after its next turn, as a wave of lethargy sweeps over it.", | |
`Haste;;31011` | |
], | |
[ | |
"hexed", | |
/You place a curse on a creature that you can see within range/i, | |
"You place a curse on a creature that you can see within range. Until the spell ends, you deal an extra 1d6 Necrotic damage to the target whenever you hit it with an attack roll. Also, choose one ability when you cast the spell. The target has Disadvantage on ability checks made with the chosen ability.<BR>If the target drops to 0 Hit Points before this spell ends, you can take a Bonus Action on a later turn to curse a new creature.", | |
`Hexed;;31013` | |
], | |
[ | |
"hexblade-curse", | |
/Starting at 1st Level, you gain the ability to place a baleful curse on someone/i, | |
"As a Bonus Action, choose one creature you can see within 30 feet of you. The target is Cursed for 1 minute. The curse ends early if the target dies, you die, or you are Incapacitated. Until the curse ends, you gain the following benefits:<BR>You gain a bonus to Damage Rolls against the Cursed target. The bonus equals your Proficiency Bonus.<BR>Any Attack roll you make against the Cursed target is a critical hit on a roll of 19 or 20 on The D20.<BR>If the Cursed target dies, you regain Hit Points equal to your Warlock level + your Charisma modifier (minimum of 1 hit point).<BR>You can’t use this feature again until you finish a short or Long Rest.", | |
`Hexed2;;31015` | |
], | |
[ | |
"hidden", | |
/nonmatching string to prevent accidental triggering/i, | |
"With the Hide action, you try to conceal yourself. To do so, you must succeed on a DC 15 Dexterity (Stealth) check while you’re Heavily Obscured or behind Three-Quarters Cover or Total Cover, and you must be out of any enemy’s line of sight; if you can see a creature, you can discern whether it can see you.<BR>On a successful check, you have the Invisible condition. Make note of your check’s total, which is the DC for a creature to find you with a Wisdom (Perception) check.<BR>The condition ends on you immediately after any of the following occurs: you make a sound louder than a whisper, an enemy finds you, you make an attack roll, or you cast a spell with a Verbal component.", | |
`Hidden;;31017` | |
], | |
[ | |
"TempHP", | |
/nonmatching string to prevent accidental triggering/i, | |
"Temporary Hit Points aren’t actual hit points; they are a buffer against damage, a pool of Hit Points that protect you from injury.<BR>When you have temporary Hit Points and take damage, the temporary Hit Points are lost first, and any leftover damage carries over to your normal Hit Points. For example, if you have 5 temporary Hit Points and take 7 damage, you lose the temporary Hit Points and then take 2 damage.<BR>Because temporary Hit Points are separate from your actual Hit Points, they can exceed your hit point maximum. A character can, therefore, be at full Hit Points and receive temporary Hit Points.<BR>Healing can’t restore temporary Hit Points, and they can’t be added together. If you have temporary Hit Points and receive more of them, you decide whether to keep the ones you have or to gain the new ones. For example, if a spell grants you 12 temporary Hit Points when you already have 10, you can have 12 or 10, not 22.<BR>If you have 0 Hit Points, receiving temporary Hit Points doesn’t restore you to consciousness or stabilize you. They can still absorb damage directed at you while you’re in that state, but only true Healing can save you.<BR>Unless a feature that grants you temporary Hit Points has a Duration, they last until they’re depleted or you finish a Long Rest.", | |
`TempHP;;31036` | |
], | |
[ | |
"favored", | |
/mystical bond with Nature to mark the target as your Favored enemy/i, | |
"Concentration.<BR>The first time on each of your turns that you hit the Favored enemy and deal damage to it, including when you mark it, you can increase that damage by 1d4.<BR>You can use this feature to mark a Favored enemy a number of times equal to your Proficiency bonus, and you regain all expended uses when you finish a Long Rest.<BR>This feature's extra damage increases when you reach certain levels in this class: to 1d6 at 6th Level and to 1d8 at 14th level.", | |
`Marked;;31023` | |
], | |
[ | |
"marked", | |
/(mystically mark it as your quarry|You magically mark one creature you can see within range as your quarry)/i, | |
"You magically mark one creature you can see within range as your quarry. Until the spell ends, you deal an extra 1d6 Force damage to the target whenever you hit it with an attack roll. You also have Advantage on any Wisdom (Perception or Survival) check you make to find it.<BR>If the target drops to 0 Hit Points before this spell ends, you can take a Bonus Action to move the mark to a new creature you can see within range.<BR>Using a Higher-Level Spell Slot. Your Concentration can last longer with a spell slot of level 3–4 (up to 8 hours) or 5+ (up to 24 hours).", | |
`Marked2;;31024` | |
], | |
[ | |
"raging", | |
/On your turn, you can enter a rage as a Bonus Action/i, | |
"While active, your Rage follows the rules below.<BR>Damage Resistance. You have Resistance to Bludgeoning, Piercing, and Slashing damage.<BR>Rage Damage. When you make an attack using Strength—with either a weapon or an Unarmed Strike—and deal damage to the target, you gain a bonus to the damage that increases as you gain levels as a Barbarian, as shown in the Rage Damage column of the Barbarian Features table.<BR>Strength Advantage. You have Advantage on Strength checks and Strength saving throws.<BR>No Concentration or Spells. You can’t maintain Concentration, and you can’t cast spells.<BR>Duration. The Rage lasts until the end of your next turn, and it ends early if you don Heavy armor or have the Incapacitated condition. If your Rage is still active on your next turn, you can extend the Rage for another round by doing one of the following:<BR>Make an attack roll against an enemy.<BR>Force an enemy to make a saving throw.<BR>Take a Bonus Action to extend your Rage.", | |
`Raging;;31032` | |
], | |
[ | |
"slowed", | |
/You alter time around up to six creatures of your choice/i, | |
"Each target must succeed on a Wisdom saving throw or be affected by this spell for the duration.<BR>An affected target’s Speed is halved, it takes a −2 penalty to AC and Dexterity saving throws, and it can’t take Reactions. On its turns, it can take either an action or a Bonus Action, not both, and it can make only one attack if it takes the Attack action. If it casts a spell with a Somatic component, there is a 25 percent chance the spell fails as a result of the target making the spell’s gestures too slowly.<BR>An affected target repeats the save at the end of each of its turns, ending the spell on itself on a success.", | |
`Slow;;31034` | |
], | |
[ | |
"Torch", | |
/nonmatching string to prevent accidental triggering/i, | |
"A Torch burns for 1 hour, casting Bright Light in a 20-foot radius and Dim Light for an additional 20 feet. When you take the Attack action, you can attack with the Torch, using it as a Simple Melee weapon. On a hit, the target takes 1 Fire damage.", | |
`Torch;;31038` | |
], | |
[ | |
"dying", | |
/nonmatching string to prevent accidental triggering/i, | |
"When a creature drops to 0 Hit Points, it either dies outright or falls unconscious, as explained below.<BR>Instant Death<BR>Here are the main ways a creature can die instantly.<BR>Monster Death.<BR>A monster dies the instant it drops to 0 Hit Points, although a Dungeon Master can ignore this rule for an individual monster and treat it like a character.<BR>Hit Point Maximum of 0.<BR>A creature dies if its Hit Point maximum reaches 0. Certain effects drain life energy, reducing a creature’s Hit Point maximum.<BR>Massive Damage.<BR>When damage reduces a character to 0 Hit Points and damage remains, the character dies if the remainder equals or exceeds their Hit Point maximum. For example, if your character has a Hit Point maximum of 12, currently has 6 Hit Points, and takes 18 damage, the character drops to 0 Hit Points, but 12 damage remains. The character then dies, since 12 equals their Hit Point maximum.<BR>Character Demise<BR>If your character dies, others might find a magical way to revive your character, such as with the Raise Dead spell. Or talk with the DM about making a new character to join the group.<BR>Falling<BR>Unconscious<BR>If you reach 0 Hit Points and don’t die instantly, you have the Unconscious condition until you regain any Hit Points, and you now face making Death Saving Throws (see below).<BR>Knocking Out a Creature<BR>When you would reduce a creature to 0 Hit Points with a melee attack, you can instead reduce the creature to 1 Hit Point and give it the Unconscious condition. It then starts a Short Rest, at the end of which that condition ends on it. The condition ends early if the creature regains any Hit Points or if someone takes an action to administer first aid to it, making a successful DC 10 Wisdom (Medicine) check.<BR>Death Saving Throws<BR>Whenever you start your turn with 0 Hit Points, you must make a Death Saving Throw to determine whether you creep closer to death or hang on to life. Unlike other saving throws, this one isn’t tied to an ability score. You’re in the hands of fate now.<BR>Three Successes/Failures.<BR>Roll 1d20. If the roll is 10 or higher, you succeed. Otherwise, you fail. A success or failure has no effect by itself. On your third success, you become Stable. On your third failure, you die.<BR>The successes and failures don’t need to be consecutive; keep track of both until you collect three of a kind. The number of both is reset to zero when you regain any Hit Points or become Stable.<BR>Rolling a 1 or 20.<BR>When you roll a 1 on the d20 for a Death Saving Throw, you suffer two failures. If you roll a 20 on the d20, you regain 1 Hit Point.<BR>Damage at 0 Hit Points.<BR>If you take any damage while you have 0 Hit Points, you suffer a Death Saving Throw failure. If the damage is from a Critical Hit, you suffer two failures instead. If the damage equals or exceeds your Hit Point maximum, you die.<BR>Stabilizing a Character<BR>You can take the Help action to try to stabilize a creature with 0 Hit Points, which requires a successful DC 10 Wisdom (Medicine) check.<BR>A Stable creature doesn’t make Death Saving Throws even though it has 0 Hit Points, but it still has the Unconscious condition. If the creature takes damage, it stops being Stable and starts making Death Saving Throws again. A Stable creature that isn’t healed regains 1 Hit Point after 1d4 hours.", | |
`Dying;;35392` | |
], | |
[ | |
"burrowing", | |
/nonmatching string to prevent accidental triggering/i, | |
"A creature that has a Burrow Speed can use that speed to move through sand, earth, mud, or ice. The creature can’t burrow through solid rock unless the creature has a trait that allows it to do so. See also “Speed.", | |
`Burrowing;;40390` | |
], | |
[ | |
"dodging", | |
/nonmatching string to prevent accidental triggering/i, | |
"If you take the Dodge action, you gain the following benefits: until the start of your next turn, any attack roll made against you has Disadvantage if you can see the attacker, and you make Dexterity saving throws with Advantage.<BR>You lose these benefits if you have the Incapacitated condition or if your Speed is 0.", | |
`Dodging;;185503` | |
], | |
[ | |
"inspiration", | |
/nonmatching string to prevent accidental triggering/i, | |
"If you (a player character) have Heroic Inspiration, you can expend it to reroll any die immediately after rolling it, and you must use the new roll.<BR>If you gain Heroic Inspiration but already have it, it’s lost unless you give it to a player character who lacks it.", | |
`Inspiration;;31019` | |
], | |
[ | |
"TemporaryHP", | |
/nonmatching string to prevent accidental triggering/i, | |
"Temporary Hit Points aren’t actual hit points; they are a buffer against damage, a pool of Hit Points that protect you from injury.<BR>When you have temporary Hit Points and take damage, the temporary Hit Points are lost first, and any leftover damage carries over to your normal Hit Points. For example, if you have 5 temporary Hit Points and take 7 damage, you lose the temporary Hit Points and then take 2 damage.<BR>Because temporary Hit Points are separate from your actual Hit Points, they can exceed your hit point maximum. A character can, therefore, be at full Hit Points and receive temporary Hit Points.<BR>Healing can’t restore temporary Hit Points, and they can’t be added together. If you have temporary Hit Points and receive more of them, you decide whether to keep the ones you have or to gain the new ones. For example, if a spell grants you 12 temporary Hit Points when you already have 10, you can have 12 or 10, not 22.<BR>If you have 0 Hit Points, receiving temporary Hit Points doesn’t restore you to consciousness or stabilize you. They can still absorb damage directed at you while you’re in that state, but only true Healing can save you.<BR>Unless a feature that grants you temporary Hit Points has a Duration, they last until they’re depleted or you finish a Long Rest.", | |
`TempHP2;;3914974` | |
] | |
] | |
// END SET STATUS CONDITIONS OR TOKEN MARKERS | |
let buttons = ""; | |
let reportText = ""; | |
function makeButton(conditionName, descriptionText, tokenMarker, tokenID) { | |
let tmLabel = `<span style="font-family: pictos">L</span>`; | |
let markerName = ((tokenMarker.includes("::")) ? tokenMarker.replace(/::/, ";;") : tokenMarker); | |
markerName = ((tokenMarker.includes(";;")) ? tokenMarker.split(";;")[0] : tokenMarker); | |
if ('undefined' !== typeof libTokenMarkers && undefined !== libTokenMarkers.getStatus(markerName).url) { | |
let tmImage = ((tokenMarker.includes(";;")) ? libTokenMarkers.getStatus(markerName).url.split(/\?/)[0] : libTokenMarkers.getStatus(markerName).url); | |
if (undefined !== tmImage && tmImage.length > 0) { | |
tmLabel = `<img src="${tmImage}"style="margin-top:-1px; height:12px;">`; | |
} | |
} | |
buttons = buttons + `<div style="display:inline-block"><a href="!pcondef ${conditionName}" title="${descriptionText.replace(/<BR>/g, " ").replace(regexForTitles, "incapacitated")}" style=${publicButtonStyle}>${printChar}</a><a href="!condef ${conditionName}" title="${descriptionText.replace(/<BR>/g, " ").replace(regexForTitles, "incapacitated")}" style=${buttonstyle}>${conditionName}</a><a href="!condef-toggle ${tokenMarker} ${((undefined !== tokenID) ? " --ignore-selected --ids " + tokenID : "")}" style=${markerButtonStyle}>${tmLabel}</a></div>`; | |
} | |
//Concentration Observer | |
function concentrationCheck(obj, prev) { | |
if (obj.get("statusmarkers").includes(condefConcentrationMarker) || obj.get(condefConcentrationMarker)) { | |
// if (obj.get(condefConcentrationMarker)) { | |
if (prev["bar1_value"] > obj.get("bar1_value")) { | |
let final_conc_DC = 10; | |
let calc_conc_DC = (prev["bar1_value"] - obj.get("bar1_value")) / 2; | |
if (calc_conc_DC > final_conc_DC) { | |
final_conc_DC = Math.floor(calc_conc_DC); | |
} | |
// let tokenName = obj.get("name"); | |
let theMessage = `! &{template:spell} {{name=Concentration}}{{savedc=${final_conc_DC}}} {{description=Make a DC ${final_conc_DC} Constitution saving throw}}{{Concentration=1}}`; | |
// let theMessage = `this should print`; | |
sendChat("gm", theMessage); | |
} | |
} | |
} | |
//Event Handlers | |
on("change:graphic:bar1_value", concentrationCheck); | |
if (typeof(TokenMod) === 'object') TokenMod.ObserveTokenChange(concentrationCheck); | |
if ('undefined' !== typeof SmartAoE && SmartAoE.ObserveTokenChange) { | |
SmartAoE.ObserveTokenChange(function(obj, prev) { | |
concentrationCheck(obj, prev); | |
}); | |
} | |
//Condition report creator. Use !condef for GM only, pcondef for player report. Follow by condition names separated by spaces. !condef-all returns buttons for all conditions, for reference | |
on('chat:message', function(msg) { | |
if ('api' === msg.type && msg.content.match(/^!(condef|pcondef|condef-all|condef-report|condef-toggle)/)) { | |
let args = msg.content.split(" "); | |
let sender = msg.who; | |
if (msg.content === '!condef-all') { | |
let message = `! &{template:noecho} {{description= blinded condition charmed condition deafened condition exhausted condition frightened condition grappled condition incapacitated condition invisible condition paralyzed condition petrified condition poisoned condition prone condition restrained condition stunned condition unconscious condition}}`; | |
sendChat("gm", message, null, { | |
noarchive: true | |
}); | |
message = ""; | |
return; | |
} | |
let messagePrefix = ((msg.content.includes('pcondef')) ? '' : '/w ' + sender + ' '); | |
let theCommand = ((msg.content.includes("pcondef")) ? "!pcondef" : "!condef"); | |
//selected vs target handler | |
if (msg.content.includes('condef-toggle ') && msg.content.length > 15) { | |
let tokenMarker = msg.content.split('condef-toggle ')[1]; | |
let message = ''; | |
if (msg.selected) { | |
//message = `!token-mod --set statusmarkers|!${tokenMarker}`; | |
let ids = msg.selected.reduce((m,o)=>[...m,o._id],[]); | |
message = `!token-mod --api-as ${msg.playerid} --set statusmarkers|!${tokenMarker} --ids ${ids.join(' ')}`; | |
//message = `!token-mod --api-as ${msg.playerid} --set statusmarkers|!${tokenMarker}`; | |
} else { | |
message = messagePrefix + buttonboxUnshifted + '<a style = ' + buttonstyle + ' href ="!token-mod --set statusmarkers|!' + tokenMarker + ' --ids @{target|token_id}">No token is selected.<BR>Click here to pick a target.</a></div>'; | |
} | |
sendChat("", message, null, { | |
noarchive: true | |
}); | |
return; | |
} | |
if (msg.content === '!condef-report') { | |
buttons = ""; | |
let selected = (msg.selected); | |
if (selected) { | |
_.each(selected, function(token) { | |
let tok = getObj("graphic", token._id); | |
let tokName = tok.get("name") || "unnamed token"; | |
let tokID = tok.get("_id"); | |
let markers = tok.get("statusmarkers").replace(/::/g, ";;"); | |
if (markers) { | |
for (let i = 0; i < conditionsArray.length; i++) { | |
let name = conditionsArray[i][0]; | |
let descriptionText = conditionsArray[i][2]; | |
let tokenMarker = conditionsArray[i][3]; | |
if (markers.includes(tokenMarker)) { | |
makeButton(name, descriptionText, tokenMarker, tokID); | |
} | |
} | |
let message = buttonbox + "<span style= 'font-weight:bold; margin: 0px 2px 0px 3px'>" + tokName + "</span>" + buttons + "</div>"; | |
sendChat("", messagePrefix + message, null, { | |
noarchive: true | |
}); | |
buttons = ""; | |
} | |
}); | |
} else { | |
let message = buttonbox + "Select one or more tokens with conditions on them" + "</div>"; | |
sendChat("", messagePrefix + message, null, { | |
noarchive: true | |
}); | |
} | |
return; | |
} | |
for (let i = 0; i < conditionsArray.length; i++) { | |
let reportName = conditionsArray[i][0]; | |
let reportDescription = conditionsArray[i][2]; | |
if (undefined !== args[1] && args[1] === reportName) { | |
reportDescription = reportDescription.replace("!condef", theCommand); | |
reportText = `<div style=${((messagePrefix === "") ? preportstyle : reportstyle)}><div style=${conditionnamestyle}>${reportName} </div>${reportDescription}</div>`; | |
} | |
} | |
if (undefined !== reportText && reportText.length > 0) { | |
sendChat("", messagePrefix + reportText, null, { | |
noarchive: true | |
}); | |
} | |
} | |
//Roll Template Interception | |
if ((undefined !== msg.rolltemplate && msg.rolltemplate.match(/npcfullatk|npcdmg|npcaction|traits|atkdmg|spell|condefinitions|spelloutput|noecho/g))||(msg.content.match(/dnd-2024/g))) { | |
//log (msg.content); | |
let sender = msg.who; | |
let messagePrefix = '/w ' + sender + ' '; | |
let saveAbility = ""; | |
let saveMatches = ""; | |
let theAbility = ""; | |
let saveDC = ""; | |
let conCheck = ""; | |
let concentrationButton = ""; | |
saveMatches = msg.content.match(/DC\s(\d\d)\s(Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma)\ssaving throw/i); | |
if (msg.rolltemplate !== "spell" && msg.rolltemplate !== "atkdmg" && null !== saveMatches && saveMatches.length === 3) { | |
saveDC = saveMatches[1]; | |
saveAbility = saveMatches[2]; | |
} | |
//msg echo to console is disabled | |
if (msg.rolltemplate === "spell" || msg.rolltemplate === "atkdmg" || msg.rolltemplate === "spelloutput" || (msg.content.match(/dnd-2024 dnd-2024--/g))) { | |
/*log(msg.content);*/ | |
saveAbility = msg.content.match(/(Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma)\ssav(e|ing throw)/i) || ""; | |
if (saveAbility.length > 0) { | |
saveAbility = saveAbility[1] || ""; | |
} | |
saveDC = ((msg.rolltemplate === "spell" || msg.rolltemplate === "spelloutput") ? msg.content.match(/{{savedc=(\d+)}}/) : msg.content.match(/{{mod=DC(\d+)}}/)) || msg.content.match(/DC\s(\d+)/) || ""; | |
conCheck = ((msg.rolltemplate === "spell" && msg.content.match(/{{name=Concentration/)) ? "Concentration Check" : ""); | |
// if (conCheck!==""){ | |
// makeButton("Concentrating", "makes a con check", "concentrating"); | |
// } | |
// concentrationButton = ((conCheck==="") ? "" : "<BR>" + buttons); | |
//log("concentrationButton = " + concentrationButton); | |
if (saveDC.length > 0) { | |
saveDC = saveDC[1] || ""; | |
} | |
} | |
if (undefined !== saveAbility && null !== saveAbility) { | |
theAbility = saveAbility.replace(/Strength/i, "str") | |
.replace(/Dexterity/i, "dex") | |
.replace(/Constitution/i, "con") | |
.replace(/Intelligence/i, "int") | |
.replace(/Wisdom/i, "wis") | |
.replace(/Charisma/i, "cha"); | |
} | |
let saveButton = ""; | |
if (theAbility.match(/(str|dex|con|int|wis|cha)/)) { | |
//for regular saves | |
saveButton = `<a href="! %{target|npc_${theAbility}}" style=${saveButtonstyle}>DC${saveDC} ${theAbility}</a> <span style = "color:#fff">${conCheck}${concentrationButton}</span>`; | |
//for groupcheck | |
if (groupCheckIsInstalled) { | |
saveAbility = saveAbility.charAt(0).toUpperCase() + saveAbility.slice(1); | |
saveButton = `<a href="!group-check --${saveAbility} Save" style=${groupSaveButtonstyle}>DC${saveDC} ${theAbility}</a> <span style = "color:#fff">${conCheck}${concentrationButton}</span>`; | |
if (applyDamageIsInstalled && conCheck !== "Concentration Check") { | |
saveButton = saveButton + `<a href="!group-check --hideformula --public --${saveAbility} Save --process --subheader vs DC ${saveDC} --button ApplyDamage !apply-damage ~dmg ?{Damage} ~type ?{Damage on Save|Half,half|None,none} ~DC ${saveDC} ~saves RESULTS(,) ~ids IDS(,)" style=${applyDamageButtonstyle}>Dmg</a>`; | |
} | |
} | |
} | |
for (let i = 0; i < conditionsArray.length; i++) { | |
let name = conditionsArray[i][0]; | |
//let regex = conditionsArray[i][1]; | |
let descriptionText = conditionsArray[i][2]; | |
let tokenMarker = conditionsArray[i][3]; | |
if (undefined !== name) { | |
if (msg.content.match(conditionsArray[i][1])) { | |
makeButton(name, descriptionText, tokenMarker); | |
} | |
} | |
} | |
let GMSaveButton = saveButton; | |
if (!playerIsGM(msg.playerid) && msg.playerid !== "API") { | |
saveButton = ""; | |
} | |
if (buttons.length > 0 || saveButton.length > 0) { | |
let message = buttonbox + saveButton + buttons + "</div>"; | |
sendChat("", messagePrefix + message, null, { | |
noarchive: true | |
}); | |
if (!messagePrefix.includes(' (GM)') && msg.rolltemplate !== "noecho") { | |
message = buttonbox + GMSaveButton + buttons + "</div>"; | |
if (conCheck !== "Concentration Check"){ | |
sendChat("", '/w gm ' + message, null, { | |
noarchive: true | |
}); | |
} | |
} | |
buttons = ""; | |
} | |
} | |
}); | |
}); | |
{ try { throw new Error(''); } catch (e) { API_Meta.Condefinition.lineCount = (parseInt(e.stack.split(/\n/)[1].replace(/^.*:(\d+):.*$/, '$1'), 10) - API_Meta.Condefinition.offset); } } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment