Advertisement Create a free account

How do i set NPC/monsters passive perception and Hp globally? 5e OGL

1570557964
Nick
Pro
Hi there guys I'm having a weird issue can you help me out Passive perception for monsters or NPC issues:  When I set the passive_wisdom for passive perception for NPCs and monsters it doesn't display passive perception but its wisdom mod. but that does work for player pcs. so I tried changing it to Npc_senses. which works for monsters that only have the passive perception listed in the senses part. but if you do it for any monsters that have tremor sense or darkvision it will display the darkvision number, not the passive perception. I also tried NPc_perception but that doesn't display the passive.  is there a way around this? Setting NPC/ monster hp: In the settings I have for the hp bar set it to hp as standard., but the issue im having is that it will show the second bar the max hp but in the first bar where it matters its greyed out or not entered. here is a photo of that.  This happens every time I drag in a new monster from the monster manual.  but the pre-generated characters from the module I own have the hp generated in a different circle than I would like and have it displaying. what gives?
1570560252
keithcurtis
Forum Champion
API Scripter
I don't think this is doable with the OGL sheet, unfortunately. Roll20 wraps that up into a text string (or probably more accurately, never parses it out from its text string). To set the HP bar, change your campaign defaults outside of the game in the campaign settings page. Under the section for sheet defaults (not token defaults), set bar 3 current and max to "hp_max", but don't link them. If you want to apply these settings to existing content, you'll need to do that in-game under the settings tab, at the bottom under Experimental Features. Here is a shot from my campaign, which uses bar 1.
1570560870
Nick
Pro
keithcurtis said: I don't think this is doable with the OGL sheet, unfortunately. Roll20 wraps that up into a text string (or probably more accurately, never parses it out from its text string). To set the HP bar, change your campaign defaults outside of the game in the campaign settings page. Under the section for sheet defaults (not token defaults), set bar 3 current and max to "hp_max", but don't link them. If you want to apply these settings to existing content, you'll need to do that in-game under the settings tab, at the bottom under Experimental Features. Here is a shot from my campaign, which uses bar 1. okay thank you. thats now fixed. but now i need to change the pre-generated characters from the module. then I have all the tokens fixed. 
1570561510
Nick
Pro
i found these settings for the game itself. but im wondering if you put ac and hp_max in these boxes it may change. have you tried this before?
1570562463
keithcurtis
Forum Champion
API Scripter
Ignore those boxes. Use the ones for the sheet. To change pre generated characters from the module, you might be out of luck. I don't think applying settings changes default tokens for monsters already in the game. Only ones deployed on the tabletop or subsequently dragged in from a compendium.
1570562740
Nick
Pro
keithcurtis said: Ignore those boxes. Use the ones for the sheet. To change pre generated characters from the module, you might be out of luck. I don't think applying settings changes default tokens for monsters already in the game. Only ones deployed on the tabletop or subsequently dragged in from a compendium. does that mean ill have to use a token mod macro to format things every time I do an encounter with pre-generated characters? ill have to format each one?
1570563353
keithcurtis
Forum Champion
API Scripter
I think it will only come into play if you deviate from the module and drag in a fresh instance of a module character. Those already on maps, or those you drag in from a compendium should be fine. Token-mod (since you are a pro user) can re-set the default tokens based on whatever you have selected on the map, but it cannot change token bar placement (above, below, etc.) as these have still not been given API access.
1570563655
Nick
Pro
keithcurtis said: I think it will only come into play if you deviate from the module and drag in a fresh instance of a module character. Those already on maps, or those you drag in from a compendium should be fine. Token-mod (since you are a pro user) can re-set the default tokens based on whatever you have selected on the map, but it cannot change token bar placement (above, below, etc.) as these have still not been given API access. or the other solution is i retool all my macros and set it up in uniform with the module setup. which is gunna be a ball ache but its the only way i can think about doing it that doesnt mess up the module tokens. 
1570578515

Edited 1570675216
The Aaron
Forum Champion
API Scripter
Ok, I wrote this script that should do what you want.  Just copy the contents into the API in a new script and save. it.  It will start working on the Game fixing all the tokens.  You'll see output like: When it's done, you should have everything set the way you want it, with all tokens and characters updated.  For NPCs, it will set their hp current to max and max to max, for PCs, it will set the current to whatever the current is, and the max to the max. Here's the script.  As usual, I suggest trying this on a copy of the Game before doing it on the real deal. on('ready',()=>{ const attr = (c,n) => (findObjs({ type: 'attribute', characterid: c.id, name: n })[0]||{get:()=>0}); let characters = {}; const fixToken = (t) => { let c = getObj('character',t.get('represents')); if(c){ let npc = (attr(c,'npc').get('current')>0); let ac = attr(c, (npc ? 'npc_ac' : 'ac')); let wis = attr(c,'wisdom_mod'); let per_skill = attr(c,'perception_prof'); let per_base = attr(c,'npc_perception_base'); let senses = (`${attr(c,'npc_senses').get('current')}`.match(/passive\s+perception\s+(\d+)/i)||[0,0])[1]; let hp = attr(c,'hp'); let pb = attr(c,'pb'); let pw = attr(c,'passive_wisdom'); let passivePerception = 10 + (npc ? parseInt(per_base.get('current')) : (parseInt(wis.get('current')) + parseInt(((`${per_skill.get('current')}`.length>0) ? pb.get('current') : 0)))); t.set({ bar1_link: ( ac ? ac.id : (npc ? 'sheetattr_npc_ac' : 'sheetattr_ac' )), bar2_link: (npc ? '' : (pw ? pw.id : 'sheetattr_passive_wisdom')), bar3_link: ( npc ? '' : hp.id), bar1_value: ac.get('current'), bar2_value: (parseInt(senses) || passivePerception), bar3_value: (npc ? hp.get('max') : hp.get('current')), bar1_max: '', bar2_max: '', bar3_max: hp.get('max') }); let p = getObj('page',t.get('pageid')); let scale = parseFloat(p.get('snapping_increment')); if( !characters.hasOwnProperty(c.id) && c.get('name') === t.get('name')) { let w = parseInt(t.get('width')); let h = parseInt(t.get('height')); if(scale<1){ let mod = 1/scale; t.set({ height: Math.floor(h*mod), width: Math.floor(w*mod) }); } setDefaultTokenForCharacter(c,t); if(scale<1){ t.set({ height: h, width: w }); } characters[c.id] = true; } } }; on('chat:message', (msg) => { if('api'===msg.type && /^!fix-bars\b/i.test(msg.content) && playerIsGM(msg.playerid)) { let args = msg.content.split(/\s+/).map(s => s.toLowerCase()); let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname'); let workQueue = {}; if(args.includes('--all')){ workQueue = findObjs({type:'graphic'}); } else if(msg.selected){ workQueue = msg.selected .map(o=>getObj('graphic',o._id)) .filter(g=>undefined !== g) ; } else { sendChat('Fix Bars', `/w "${who}" <div>Select one or more tokens to fix bar mappings on, or use <code>!fix-bars --all</code> to fix bar mappings on all tokens in the game.</div>`); return; } let count = 0; let timeMark = Date.now(); const drainQueue = ()=>{ let t = workQueue.shift(); if(t){ fixToken(t); ++count; if((Date.now()-timeMark)>5000){ timeMark = Date.now(); sendChat('Fixing Tokens',`/w gm ...${count}`); } setTimeout(drainQueue,0); } else { characters = {}; sendChat('Fixing Tokens',`/w gm Finished Fixing Tokens`); } }; sendChat('Fixing Tokens',`/w gm Fixing ${workQueue.length} Tokens`); drainQueue(); } }); }); Edit: Changed script to default to using the passive Perception number in npc senses, falling back on calculation. (Thanks Keith!) Edit 2: Updated the script to fix the map scale causing the token to be small.  Also made some speed improvements. Edit 3: Change to only set default token if the name of the Token matches the name of the Character.  Fix for scaling issues. Edit 4: Changed to require the !fix-bars command to be run instead of kicking off immediately.  If you have nothing selected, it will fix all tokens.  If you have some set of tokens selected, it will only fix those tokens (and the default token for the character), but not any other tokens representing that character. Edit 5: Added --all option to fix all tokens, and help output if nothing is selected to tell you what to do.
1570621947
Nick
Pro
The Aaron said: Ok, I wrote this script that should do what you want.  Just copy the contents into the API in a new script and save. it.  It will start working on the Game fixing all the tokens.  You'll see output like: When it's done, you should have everything set the way you want it, with all tokens and characters updated.  For NPCs, it will set their hp current to max and max to max, for PCs, it will set the current to whatever the current is, and the max to the max. Here's the script.  As usual, I suggest trying this on a copy of the Game before doing it on the real deal. on('ready',()=>{ const attr = (c,n) => (findObjs({ type: 'attribute', characterid: c.id, name: n })[0]||{get:()=>0}); const fixToken = (t) => { let c = getObj('character',t.get('represents')); if(c){ let npc = (attr(c,'npc').get('current')>0); let ac = attr(c, (npc ? 'npc_ac' : 'ac')); let wis = attr(c,'wisdom_mod'); let per_skill = attr(c,'perception_prof'); let per_base = attr(c,'npc_perception_base'); let senses = (`${attr(c,'npc_senses').get('current')}`.match(/passive\s+perception\s+(\d+)/i)||[0,0])[1]; let hp = attr(c,'hp'); let pb = attr(c,'pb'); let pw = attr(c,'passive_wisdom'); let passivePerception = 10 + (npc ? parseInt(per_base.get('current')) : (parseInt(wis.get('current')) + parseInt(((`${per_skill.get('current')}`.length>0) ? pb.get('current') : 0)))); t.set({ bar1_link: ( ac ? ac.id : (npc ? 'sheetattr_npc_ac' : 'sheetattr_ac' )), bar2_link: (npc ? '' : (pw ? pw.id : 'sheetattr_passive_wisdom')), bar3_link: ( npc ? '' : hp.id), bar1_value: ac.get('current'), bar2_value: (parseInt(senses) || passivePerception), bar3_value: (npc ? hp.get('max') : hp.get('current')), bar1_max: '', bar2_max: '', bar3_max: hp.get('max') }); setDefaultTokenForCharacter(c,t); } }; const workQueue = findObjs({type:'graphic'}); let count = 0; let timeMark = Date.now(); const drainQueue = ()=>{ let t = workQueue.shift(); if(t){ fixToken(t); ++count; if((Date.now()-timeMark)>5000){ timeMark = Date.now(); sendChat('Fixing Tokens',`/w gm ...${count}`); } setTimeout(drainQueue,0); } else { sendChat('Fixing Tokens',`/w gm Finished Fixing Tokens`); } }; sendChat('Fixing Tokens',`/w gm Fixing ${workQueue.length} Tokens`); drainQueue(); }); Edit: Changed script to default to using the passive Perception number in npc senses, falling back on calculation. (Thanks Keith!) you are a legend!  im doing it on a test game to see if the problem gets fixed. and if it does ill do it on the original game. for usability is there a way of having the code activate after seleting a menu in the chat window of what you want each bar to do? so that this could possibly become a standard feature. so people can set their own values? just an idea. 
1570622141
Nick
Pro
The Aaron said: Ok, I wrote this script that should do what you want.  Just copy the contents into the API in a new script and save. it.  It will start working on the Game fixing all the tokens.  You'll see output like: When it's done, you should have everything set the way you want it, with all tokens and characters updated.  For NPCs, it will set their hp current to max and max to max, for PCs, it will set the current to whatever the current is, and the max to the max. Here's the script.  As usual, I suggest trying this on a copy of the Game before doing it on the real deal. on('ready',()=>{ const attr = (c,n) => (findObjs({ type: 'attribute', characterid: c.id, name: n })[0]||{get:()=>0}); const fixToken = (t) => { let c = getObj('character',t.get('represents')); if(c){ let npc = (attr(c,'npc').get('current')>0); let ac = attr(c, (npc ? 'npc_ac' : 'ac')); let wis = attr(c,'wisdom_mod'); let per_skill = attr(c,'perception_prof'); let per_base = attr(c,'npc_perception_base'); let senses = (`${attr(c,'npc_senses').get('current')}`.match(/passive\s+perception\s+(\d+)/i)||[0,0])[1]; let hp = attr(c,'hp'); let pb = attr(c,'pb'); let pw = attr(c,'passive_wisdom'); let passivePerception = 10 + (npc ? parseInt(per_base.get('current')) : (parseInt(wis.get('current')) + parseInt(((`${per_skill.get('current')}`.length>0) ? pb.get('current') : 0)))); t.set({ bar1_link: ( ac ? ac.id : (npc ? 'sheetattr_npc_ac' : 'sheetattr_ac' )), bar2_link: (npc ? '' : (pw ? pw.id : 'sheetattr_passive_wisdom')), bar3_link: ( npc ? '' : hp.id), bar1_value: ac.get('current'), bar2_value: (parseInt(senses) || passivePerception), bar3_value: (npc ? hp.get('max') : hp.get('current')), bar1_max: '', bar2_max: '', bar3_max: hp.get('max') }); setDefaultTokenForCharacter(c,t); } }; const workQueue = findObjs({type:'graphic'}); let count = 0; let timeMark = Date.now(); const drainQueue = ()=>{ let t = workQueue.shift(); if(t){ fixToken(t); ++count; if((Date.now()-timeMark)>5000){ timeMark = Date.now(); sendChat('Fixing Tokens',`/w gm ...${count}`); } setTimeout(drainQueue,0); } else { sendChat('Fixing Tokens',`/w gm Finished Fixing Tokens`); } }; sendChat('Fixing Tokens',`/w gm Fixing ${workQueue.length} Tokens`); drainQueue(); }); Edit: Changed script to default to using the passive Perception number in npc senses, falling back on calculation. (Thanks Keith!) IT WORKS!!! OMFG!!! wow. even on the pre-generated characters on the maps before dragging in tokens. it works!! you beauty!!. im going to put this in my main game right now! 
1570622689
Nick
Pro
so the token values are fixed. but when dragging in the tokens. they are smaller than the squares. so they need to have a resize value to fit the squares. 
1570622827
Nick
Pro
okay some of them have the resizing issue. not all of them from the pre-generated characters. 
1570635707
The Aaron
Forum Champion
API Scripter
That has to do with the size of the token on the last map that was processed. Some of the maps must have the units set to .5. 
1570636203
Nick
Pro
The Aaron said: That has to do with the size of the token on the last map that was processed. Some of the maps must have the units set to .5.  what do you think about making a menu for others to select the values? and then having this as a standard api in the api library? 
1570657305
The Aaron
Forum Champion
API Scripter
I adjusted the script to fix the issue with the token size. I like the idea of a script that could do this in a general sense, and it could be mostly achieved. However, the above is highly dependent on the OGL Character Sheet because of the way passive perception is calculated, determining npc or not, and what the ac stat is.  On sane character sheets, it could be reduced to a command telling it the attributes you want in each bar and how you want them linked.  I'll ponder a way to abstract the OGL specific bits into a useable form for humans.
1570657455
The Aaron
Forum Champion
API Scripter
There is one other issue I'm not sure how to fix presently, but it's rare.  In the case of Strahd, the token you drag out will say "Strahd von Zarovich (Illusion)" because the last token representing Strahd happens to be an illusion version that only varies by its token name.  I can think of how to fix that on future games, but not how to retroactively fix it on yours... well... now I just thought of a way... hmm...
1570658060
Nick
Pro
The Aaron said: There is one other issue I'm not sure how to fix presently, but it's rare.  In the case of Strahd, the token you drag out will say "Strahd von Zarovich (Illusion)" because the last token representing Strahd happens to be an illusion version that only varies by its token name.  I can think of how to fix that on future games, but not how to retroactively fix it on yours... well... now I just thought of a way... hmm... did you just edit the script? do i copy the above or new script?
1570658148
Nick
Pro
nevermind just saw the edit.
1570658439
Nick
Pro
The Aaron said: I adjusted the script to fix the issue with the token size. I like the idea of a script that could do this in a general sense, and it could be mostly achieved. However, the above is highly dependent on the OGL Character Sheet because of the way passive perception is calculated, determining npc or not, and what the ac stat is.  On sane character sheets, it could be reduced to a command telling it the attributes you want in each bar and how you want them linked.  I'll ponder a way to abstract the OGL specific bits into a useable form for humans. is snap to grid part of your coding? because it isnt snapping to grid but it is the right size now. your doing great work dude :) 
1570667148
The Aaron
Forum Champion
API Scripter
Snap to grid isn't, but it could be.  Check and see if the token in question has Advanced->Is Drawing set.  Also be sure that the map you're dropping it on has a grid and has snap enabled.
1570667319
The Aaron
Forum Champion
API Scripter
Ok, updated the above script again, this time adding setting default token only on same named tokens, and fixing a scaling issue.
1570667842
Nick
Pro
The Aaron said: Snap to grid isn't, but it could be.  Check and see if the token in question has Advanced->Is Drawing set.  Also be sure that the map you're dropping it on has a grid and has snap enabled. how do i check this? ive looked here  grid snap is enabled but as you can see this is what happens after a drag.   I was also just thinking that a one click button/script for player pc sheet attributes would be useful too. because this script is a life saver. 
1570668349
Nick
Pro
i just clicked on the assasin one. and its not working.   here is the assasin sheet.  i think maybe because it has a comma in the senses description for some odd reason. 
1570669069
Nick
Pro
okay so the behaviour of snapping to grid works but only after youve snapped the drag in manually. currently the token behaviours upon dragging dont snap. but they will go where you want them to. and then snap after youve snapped them. if that makes sense. 
1570670954
The Aaron
Forum Champion
API Scripter
Ah!  Yeah, they don't snap on drop into the map, only on next move.  Kind of strange, but there it is.  I could write a script that would snap them on drop, but I'm not sure how necessary that would really be. =D
1570671455
Nick
Pro
The Aaron said: Ah!  Yeah, they don't snap on drop into the map, only on next move.  Kind of strange, but there it is.  I could write a script that would snap them on drop, but I'm not sure how necessary that would really be. =D maybe build that in? i know its pedantic but id like to specify when i move my tokens like that with the alt key. did you look into the comma thing in the senses part? is that a typo on that sheet in particular? maybe add it just in case it occurs on more than one sheet?  
1570672995
The Aaron
Forum Champion
API Scripter
The issue is there are no tokens for the assassin on any of the pages.  If you drag one out and save the script, it will fix it.  Which reminds me, you'll want to disable the script when you don't want it to operate.  Probably I should add a command to make it fix them all, and perhaps fix the selected ones... Ok, I updated the above script to only become active when you run: !fix-bars If you have any tokens selected, it will operate on only those tokens (Note: That will not fix duplicates of the tokens on other pages, just the selected ones and the default token for the character).  If you have nothing selected, it will operate on all tokens.
1570673299

Edited 1570673314
Nick
Pro
The Aaron said: The issue is there are no tokens for the assassin on any of the pages.  If you drag one out and save the script, it will fix it.  Which reminds me, you'll want to disable the script when you don't want it to operate.  Probably I should add a command to make it fix them all, and perhaps fix the selected ones... Ok, I updated the above script to only become active when you run: !fix-bars If you have any tokens selected, it will operate on only those tokens (Note: That will not fix duplicates of the tokens on other pages, just the selected ones and the default token for the character).  If you have nothing selected, it will operate on all tokens. in that case maybe have a pop up saying are you sure you want to fix all bars when a token is not selected? just for user clarity.
1570673647
Nick
Pro
The Aaron said: The issue is there are no tokens for the assassin on any of the pages.  If you drag one out and save the script, it will fix it.  Which reminds me, you'll want to disable the script when you don't want it to operate.  Probably I should add a command to make it fix them all, and perhaps fix the selected ones... Ok, I updated the above script to only become active when you run: !fix-bars If you have any tokens selected, it will operate on only those tokens (Note: That will not fix duplicates of the tokens on other pages, just the selected ones and the default token for the character).  If you have nothing selected, it will operate on all tokens. that fixed the Assasin instantly. this is great stuff. i was just thinking that to make this more flexible for other users, because they may not want their setup the way i have it. and to make this idea more universal for them. just a thought. 
1570675265
The Aaron
Forum Champion
API Scripter
I added --all to instruct it to fix all tokens, and a help message:
1570718877
Nick
Pro
The Aaron said: I added --all to instruct it to fix all tokens, and a help message: theres a coding error because i get this error from the script.: syntaxerror: unexpected token } i disabled the script and the api scripts started to work. luckily because the script can be a one time use it isnt required to be running. but id like it to be so just in case i come across a stray token that hasnt formatted properly. 
I hope it will soon be displayed in the settings, it would be convenient!