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 .
×

Help with ammo script.

Hello, So, my players an I have been having difficulty keeping track of ammunition in Dark Heresy 2nd ed advanced api character sheet with the ammo API however when I use a ranged weapon the ammo does not decrease and I get the error: Attribute [repeating_Rangedweapons__Rangedweaponclip] was not found. Please verify that you have the right name. I don't know anything about coding, and the response I googled was more to do with a coding fix which went straight over my head. Any help would be greatly appreciated. Thank you.
1675376974
The Aaron
Roll20 Production Team
API Scripter
Can you post the !ammo command you are executing?  If the Character Sheet is doing it for you, you can click in the chat and push up to find it.
It's not when using a command, it's when using the hit button in the character sheet. This is copy & pasted from the chat window. DM Not So Fatz (GM): Ragnien 'Hit The Dirt' Omek fires Lasgun! Ragnien 'Hit The Dirt' Omek has a modified target of  89  and rolled a  43 . Ragnien 'Hit The Dirt' Omek succeeds by  5 degree(s) . (From ): Attribute [repeating_Rangedweapons__Rangedweaponclip] was not found. Please verify that you have the right name.
1675381789
The Aaron
Roll20 Production Team
API Scripter
Right.  Behind the scenes, the character sheet is issuing several chat commands to produce that.  if you click in chat after clicking that hit button, then push the up arrow on the keyboard, it will load the previous chat command, which should include the !ammo command being issued by the character sheet.  One thing I can tell by looking is that there is an ID missing in that attribute reference, or at least a positional ID.  It should say something like  repeating_Rangedweapons_-jk1234fa4523_Rangedweaponclip  or  repeating_Rangedweapons_$1_Rangedweaponclip  instead of just having  repeating_Rangedweapons__Rangedweaponclip  there.
1675391589

Edited 1675393054
Aaron- what if you homebrew an attack and go thru the process you just decribed and nothing comes up in the description tab. How can you bring it up or can you ? I made an Eldritch Blast in a game and for some reason it doesnt want to give me that info- which I would like to use to make a macro for the bad guy. I tried using Keiths Token Action but its for 5E and useless to me. NVM, My roll20 bugged out- when I refreshed it started working again.
This is what comes up after clicking the up arrow in the chat afterwards. ***@{Ragnien 'Hit The Dirt' Omek|character_name} fires Lasgun!*** !roll40k @{Ragnien 'Hit The Dirt' Omek|character_name}, @{Ragnien 'Hit The Dirt' Omek|BallisticSkill}, [[(?{Aim | Half aim (+10),+10| No aim (+0),+0 | Full aim (+20),+20} + ?{Range | Point Blank (+30),+30 | Short Range (+10),+10 | Standard range (+0),+0 | Long Range (-10),-10 | Extreme Range (-30),-30} + ?{Rate of Fire/Attack Type|Standard (+10),+10 | Semi auto (+0),+0 | Full Auto (-10),-10 | Called Shot (-20),-20 | Suppressing Fire (-20),-20} + ?{Modifier|0})]] !ammo @{Ragnien 'Hit The Dirt' Omek|character_id} repeating_Rangedweapons__Rangedweaponclip [[?{Ammo?|Single,-1|Semi-Auto,-3|Full Auto,-0}*?{Firing Mode?|Normal,1|Overcharge,2|Maximal,3|Overload,4}]]
1675406889
The Aaron
Roll20 Production Team
API Scripter
Ok, the problem is definitely in east the character sheet is outputting. I don't know what would cause it to fail to output the id. If you change the character's name to just Ragnien Omek, does it work?
I tried with a different character sheet and got the same result. ***@{Mordric Zarkov|character_name} fires Shotgun!*** !roll40k @{Mordric Zarkov|character_name}, @{Mordric Zarkov|BallisticSkill}, [[(?{Aim | Half aim (+10),+10| No aim (+0),+0 | Full aim (+20),+20} + ?{Range | Point Blank (+30),+30 | Short Range (+10),+10 | Standard range (+0),+0 | Long Range (-10),-10 | Extreme Range (-30),-30} + ?{Rate of Fire/Attack Type|Standard (+10),+10 | Semi auto (+0),+0 | Full Auto (-10),-10 | Called Shot (-20),-20 | Suppressing Fire (-20),-20} + ?{Modifier|0})]] !ammo @{Mordric Zarkov|character_id} repeating_Rangedweapons__Rangedweaponclip [[?{Ammo?|Single,-1|Semi-Auto,-_|Full Auto,-_}*?{Firing Mode?|Normal,1|Overcharge,2|Maximal,3|Overload,4}]]
(The result that came up first) Mordric Zarkov fires Shotgun! Mordric Zarkov has a modified target of  81  and rolled a  70 . Mordric Zarkov succeeds by  2 degree(s) . (From ): Attribute [repeating_Rangedweapons__Rangedweaponclip] was not found. Please verify that you have the right name.
1675455382
The Aaron
Roll20 Production Team
API Scripter
Right, I don't mean with a single instance of the character sheet, I mean with the character sheet code. I'll have to look at it and see if I can spot the issue. Which sheet is it?
I changed the name on the character sheet and it still does the same thing. Dark Heresy: 2nd Edition (Advanced API) is the character sheet.
1675514151

Edited 1675514263
Oosh
Sheet Author
API Scripter
I had a very brief look - it seems like there's a function missing from the sheet to set an attribute called @{my_hidden_row_id}. It's used to insert the row ID into the !ammo command, but as far as I can see there's no function anywhere to actually set a value to it. Has the ammo function ever actually worked on this sheet? If Aaron comes to the same conclusion, the sheet probably just needs a worker added to set a value on that attribute whenever a row is added. But I might have missed something.
I couldn't say for certain if it has ever worked. It's my first time using it. For me, no it hasn't. But for someone else I don't know.
1675560497

Edited 1675588050
Oosh
Sheet Author
API Scripter
You can try this mod script if you like, to see if it fixes the issue. It doesn't run passively so you'll need to run it on a test game which already has character sheets in it containing entries in the rangedweapons section. If it fixes the issue, it's at least a workaround until the sheet can be updated. Paste the below in to a new API/Mod script, and type !ammofix into chat when the sandbox restarts. /* globals on, sendChat, getObj, findObjs, createObj */ (() => { const repeatingSectionName = `Rangedweapons`, repeatingAttributeName = `my_hidden_row_id`, scriptName = 'heresyAmmoFix'; const rx = { rowId: /_(-[0-z-]{19})_/, targetSection: new RegExp(`^repeating_${repeatingSectionName}_`, 'i'), } on('ready', () => { watchRepeatingAttributes(); on('chat:message', (message) => { if (/^!ammofix/i.test(message.content)) { indexHeresyRepeatingRows(); } }); }); const watchRepeatingAttributes = () => { on('add:attribute', (newAttribute) => { if (rx.targetSection.test(newAttribute.get('name'))) { const rowId = (newAttribute.get('name').match(rx.rowId)||[])[1]; const targetAttribute = rowId ? `repeating_${repeatingSectionName}_${rowId}_${repeatingAttributeName}` : null; const character = targetAttribute ? getObj('character', newAttribute.get('characterid')) : null; if (character) { setOrCreateAttribute(character, targetAttribute, rowId); } } }); } const getRepeatingRowIds = (character) => { const allAttributes = findObjs({ type: 'attribute', characterid: character.id }); return allAttributes.reduce((output, attribute) => { if (rx.targetSection.test(attribute.get('name'))) { const rowId = (attribute.get('name').match(rx.rowId)||[])[1]; if (rowId && !(output.includes(rowId))) { return [ ...output, rowId ]; } } return output; }, []); } const setOrCreateAttribute = (character, attributeName, newValue, newMaxValue) => { if (newValue == null) return false; const existingAttribute = findObjs({ type: 'attribute', characterid: character.id, name: attributeName })[0]; if (existingAttribute) { existingAttribute.set({ current: newValue }); if (newMaxValue != null) existingAttribute.set({ max: newMaxValue }); } else { const newAttribute = createObj('attribute', { characterid: character.id, name: attributeName, current: newValue }); if (newMaxValue != null) newAttribute.set({ max: newMaxValue }); } // console.log(`Created/updated attribute with ${newValue}`); return true; } const indexHeresyRepeatingRows = async (characterId) => { const characterArray = characterId ? [ getObj('character', characterId) ] : findObjs({ type: 'character' }); if (characterArray && characterArray.length) { await Promise.all(characterArray.map(character => { const rowIds = getRepeatingRowIds(character, repeatingSectionName); rowIds.forEach(rowId => { setOrCreateAttribute(character, `repeating_${repeatingSectionName}_${rowId}_${repeatingAttributeName}`, rowId); }); })); sendChat(scriptName, 'Finished processing sheets.'); } else sendChat(scriptName, 'No characters found.'); } })();
Do I run this in conjunction with the previous ammo script?
That worked! Thank you so much! Do I need to do that command each time I start the game?
1675588225

Edited 1675588546
Oosh
Sheet Author
API Scripter
No problem - I've modified the code above. If you grab the new version, it'll now watch the repeating_rangedweapons section for added attributes, and populate that row ID attribute whenever needed. You'll still need to run !ammofix for everything which already exists in the game, but the new event handler should handle everything going forward. If the sandbox is down when someone adds an attack to their sheet it'll be missed - in that case just run !ammofix again and it'll go through everything currently in the game. I'll see if I can point one of the sheet authors here so they can update the sheet. DM Not So Fatz said: Do I need to do that command each time I start the game? The script sets the attribute value permanently, so anything it modifies should stay modified. So leave the new version of the script active in your game, and it should catch any ranged attacks added to any sheets, but you only need to manually run !ammofix initially (to modify the character sheets already in the campaign when the script is added), and again if you notice any attacks aren't working properly, and are giving the same error message you had before. Otherwise, just having the script running in the Campaign should take care of it.