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

D&D 2024 Sheet and random monster HP

So, I've used the 5th Edition OGL by Roll20 Companion API for a long time to roll random HP for my monsters, but in my new campaign we're using the 2024 sheet by Roll20, and I can't get it to work. I'm guessing it hasn't been updated for the new sheet, since the old one is still in use in many games, which is understandable. Is there an alternative "roll monster HP" API out there for the 2024 sheet, or can some wizard from the school of code whip me up a "spell scroll" to copy for such a feature? Thanks in advance for any contribution :D (and thanks to Gauss who pointed out my mistake in posting this in macros section)
Here's a quick and dirty thing I threw together. Note: It requires your sandbox to be set to Experimental, it won't work on Default because it relies on the new `getSheetItem` function. Note 2: Unfortunately there's a bug with the experimental sandbox that doesn't allow me to use the roll commands, so it's doing a "pseudo roll"... but looking into the companion script you were using previous I think it was doing the same basic thing.  (function() { 'use strict'; const VERSION = '0.1'; const SCRIPT_NAME = '5e2024_rollhp'; const beaconAttr = 'npc_hpformula'; const sendError = function(who, msg) { sendChat(SCRIPT_NAME, '/w "' + who + '" ' + msg); }; const isExperimentalSandbox = function() { try { const sv = Campaign().sandboxVersion || ''; return (String(sv).toLowerCase() === 'experimental'); } catch (e) { return false; } }; const processFormula = function(formula) { if (!formula) return undefined; formula = `${formula}`.trim(); const diceRE = /[+-]?\s*\d*d\d+(?:\s*[+-]\s*\d+)?/i; const match = formula.match(diceRE); if (match) return match[0].replace(/\s+/g,''); const num = parseInt(formula, 10); if (!isNaN(num)) return `${num}`; return undefined; }; const localRoll = function(expression) { if (!expression) return 0; let expr = `${expression}`.replace(/\s+/g,''); expr = expr.replace(/^-/, '0-'); expr = expr.replace(/-/g, '+-'); const parts = expr.split('+').filter(Boolean); let total = 0; for (const p of parts) { if (!p) continue; const m = p.match(/^(-?\d*)d(\d+)$/i); if (m) { let n = m[1] === '' || m[1] === '+' ? 1 : parseInt(m[1],10); if (m[1] === '-') n = -1; const sides = parseInt(m[2],10); const count = Math.abs(n); let sign = n < 0 ? -1 : 1; for (let i=0;i<count;i++) { const r = Math.floor(Math.random()*sides)+1; total += sign*r; } continue; } const k = parseInt(p,10); if (!isNaN(k)) { total += k; continue; } } return total; }; const rollAndApply = function(token, expression, who) { if (!token || !expression) return; const bar = 'bar1'; // Experimental sandbox; inline sendChat rolls are unreliable here. Use local roll. const hp = Math.max(Math.round(localRoll(expression)), 0); const sets = {}; sets[bar + '_value'] = `${hp}`; sets[bar + '_max'] = `${hp}`; token.set(sets); sendChat(SCRIPT_NAME, '/w "' + who + '" Rolled (local) and set HP for token "' + token.get('name') + '" to ' + hp); }; const handleSelection = async function(selected, who) { if (!selected || selected.length === 0) { sendChat(SCRIPT_NAME, '/w "' + who + '" No tokens selected.'); return; } if (!isExperimentalSandbox() || typeof getSheetItem !== 'function') { sendChat(SCRIPT_NAME, '/w "' + who + '" Error: This minimal Beacon-only script requires the Experimental API sandbox and Beacon sheet support (getSheetItem).'); return; } let total = 0; let skipped = 0; for (const sel of selected) { const token = getObj('graphic', sel._id); if (!token || token.get('isdrawing') || token.get('subtype') !== 'token') { skipped++; continue; } const charId = token.get('represents'); if (!charId) { skipped++; continue; } if ('' !== token.get('bar1_link')) { skipped++; continue; } let formula = undefined; try { const val = await getSheetItem(charId, beaconAttr, 'current'); if (val !== null && val !== undefined && `${val}`.trim() !== '') { formula = val; } } catch (e) { log(`${SCRIPT_NAME} getSheetItem error: ${e}`); } if (!formula) { skipped++; continue; } const expression = processFormula(formula); if (!expression) { skipped++; continue; } rollAndApply(token, expression, who); total++; } sendChat(SCRIPT_NAME, '/w "' + who + '" Rolled HP for ' + total + ' token(s), skipped ' + skipped + '.'); }; const handleInput = async function(msg_orig) { if (msg_orig.type !== 'api') return; const content = msg_orig.content; if (!/^!5e2024-rollhp(\b|$)/i.test(content)) return; const who = (getObj('player', msg_orig.playerid) || { get: () => 'API' }).get('_displayname'); if (!playerIsGM(msg_orig.playerid)) { sendError(who, 'Only GM may run this command.'); return; } await handleSelection(msg_orig.selected, who); }; const registerEventHandlers = function() { on('chat:message', handleInput); }; on('ready', function() { log('-=> ' + SCRIPT_NAME + ' v' + VERSION + ' <=-'); registerEventHandlers(); }); })(); To use, from your mod/api scripts settings click "New Script" and name it whatever you want, then copy and paste the above code into the script and click save. Once the sandbox is restarted, in game you can select a group of NPC tokens and type `!5e2024-rollhp` in chat.  I noticed in the OGL companion api script it looks like it also creates a token when you roll HP from the NPC sheet... I can look into doing something similar with this one. Anyways it's very quick and dirty but if you notice any issues let me know and I can see about giving it a fix. Seems to work fine in my basic quick testing though. *disclaimer* I am tired and didn't spend much time on this :P
Thanks! It works exactly as I need it to, no need for further refinement for my case. I changed the command for it, and if anyone else wants to, it is this line: if (!/^!5e2024-rollhp(\b|$)/i.test(content)) return; You just change the "5e2024-rollhp" to anything else you want. I just used "!rollhp" for ease :D Thanks again Aikepah