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

Changing character name with sheetworker scripts

1709849482

Edited 1709849577
Hello all, I was trying to change the HTML file of the character sheet I'm currently overhauling, to replace the string "name" with "character_name", thus allowing for quickchange between name of the character sheet & name in the sheet proper. The code that I was proposing was working fine in my test sheet: Previously : <label data-i18n-title="enter name" title="enter name"> <input data-i18n-placeholder="name" name="attr_name" placeholder="name" title="@{name}" type="text" value=""/> Proposed : <label data-i18n-title="enter character name" title="enter character name"> <input data-i18n-placeholder="name" name="attr_character_name" placeholder="name" title="@{character_name}" type="text" value=""/> Alas, since the sheet is already live, the pull request was blocked, as it would impact ongoing games. I was advised to use sheetworker scripts to enable the change instead. That's cool, no worries, and I understand the logic behind it, however I'm not that savvy with scripts apart from basic stuff and I was wondering if there's a simple way of doing it. I do have some sheetworkers already included in the HTML file : <script type="text/worker">const attributes = { damage: ['strength', 'size'], healing: ['strength', 'constitution'], movement: ['strength', 'dexterity'], hp: ['size', 'constitution'], unconcious: ['total_hit_points'], knights: ['old_knights', 'middle_aged_knights', 'young_knights'], annualglory: ['annual_glory_rewards_traits', 'annual_glory_rewards_chivalry', 'annual_glory_rewards_holdings', 'annual_glory_rewards_passions', 'annual_glory_rewards_religion'] } attributes.movement.forEach(attr => { on(`change:${attr}`, (eventinfo) => { attributeSumDivide(attributes.movement, 'movement_rate'); }); }) attributes.damage.forEach(attr => { on(`change:${attr}`, (eventinfo) => { attributeSumDivide(attributes.damage, 'damage'); }); }) attributes.healing.forEach(attr => { on(`change:${attr}`, (eventinfo) => { attributeSumDivide(attributes.healing, 'healing_rate'); }); }) attributes.hp.forEach(attr => { on(`change:${attr}`, (eventinfo) => { sumOfCalculator(attributes.hp, 'total_hit_points'); }); }) attributes.unconcious.forEach(attr => { on(`change:${attr}`, (eventinfo) => { unconciousCalculator(attributes.unconcious, 'unconcious'); }); }) attributes.knights.forEach(attr => { on(`change:${attr}`, (eventinfo) => { sumOfCalculator(attributes.knights, 'total_family_knights'); }); }) attributes.knights.forEach(attr => { on(`change:${attr}`, (eventinfo) => { sumOfCalculator(attributes.annualglory, 'annual_glory_rewards_total'); }); }) //When performing calculations in King Arthur Pendragon / Paladin, round //0.5 and higher fractions upward and lesser fractions downward. //For example, a character with a Damage value of 4.43 would //have an effective value of 4, while a character with a Damage val- //ue of 4.5 would have a 5. const roundFraction = sum => sum >= 0.5 ? Math.ceil(sum) : Math.floor(sum) const divideBy = (sum, num) => sum/num; const totalAttributes = values => { let sum = 0 Object.values(values).forEach(num => sum += parseInt(num) || 0) return sum } const attributeSumDivide = (attributes, set) => { getAttrs(attributes, (values) => { const divide = set == 'damage' ? 6 : 10; let sum = totalAttributes(values); sum = divideBy(sum, divide) ; setAttrs({ [`${set}`]: roundFraction(sum) }); }); }; const sumOfCalculator = (attributes, set) => { getAttrs(attributes, (values) => { setAttrs({ [`${set}`]: totalAttributes(values) }); }); }; const unconciousCalculator = (attributes, set) => { getAttrs(attributes, (values) => { let sum = totalAttributes(values); sum = divideBy(sum, 4) ; setAttrs({ [`${set}`]: roundFraction(sum) }); }); };</script> Do I need to add a const attribute & then a formula in order to enable the change? Many thanks in advance to all kind souls who would be happy to help me :)
1709855546
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
At it's base this is a pretty simple sheetworker, but I'd recommend adding a version attribute to your sheet and then keying the change off of that: <input type="hidden" name="attr_sheet_version"> and then your sheetworker js would be: on('sheet:opened',() => { getAttrs(['sheet_version','name'],(attributes) => { const setObj = {}; // if the sheet is from before version control (or note that this could also just be a new sheet), and if the name attribute has something stored in it, then update the character_name if(attributes.sheet_version === '' && attributes.name){ setObj.character_name = attributes.name; } // do other verison upgrades as you maintain the sheet // then apply the changes. setAttrs(setObj,{silent:true}); }) })
1709888152

Edited 1709904502
Hi Scott, Thank you so very much for taking the time to reply & provide some help :) I already have an attribute version in the sheet <input name="attr_version" type="hidden" value="1"/> Should I use this instead, or add a specific "attr_sheet_version" line with value xyz? If using this "attr_version", then my code should be : on('sheet:opened',() => { getAttrs(['version','name'],(attributes) => { const setObj = {}; // if the sheet is from before version control (or note that this could also just be a new sheet), and if the name attribute has something stored in it, then update the character_name if(attributes.version === '1' && attributes.name){ setObj.character_name = attributes.name; } // do other verison upgrades as you maintain the sheet // then apply the changes. setAttrs(setObj,{silent:true}); }) })  Correct ? And where should I place the script in the overall script I copied/pasted ? Thank you again :)
1709906792
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Ah! Great! If you already have a version attribute, then use that.  The sheetworker can go anywhere, but it should be before you update the version number to the new version number in the sheet workers.
1709908379

Edited 1709908500
Oh, so in the script, rather than the "1", I should use something else, or am I not understanding correctly? Thanks again
1709914714
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
yes, so your version attribute should be updated by the script, not by updating it's default value.
1709933453

Edited 1709933493
Would you be so kind as to insert the JS script in the code I shared earlier on? I am trying to make it work but it doesn't seem to have any effect I'm probably inserting tree he JS script wrong in the overall onr.  Thank you so much again for your hrlp
1709939012

Edited 1709939024
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Sure, so for version control stuff, I'd actually recommend doing some functionalization so that you can do later updates more easily. This will seem like a lot for a single update, but after you need to run a few updates it pays for itself. There is a question first though; have you always had a version number on the live version of the sheet?
Hello again Scott,  Yes, that line was always there. There's a copyright section at the bottom of the sheet and the version is indicated there. I found the line I shared at the very top of the sheet with some other attributes
So here's what I did : <input name="attr_sheet_version" type="hidden" value="1"> on('sheet:opened',() => { getAttrs(['sheet_version','name'],(attributes) => { const setObj = {}; if(attributes.sheet_version === '1' && attributes.name){ setObj.character_name = attributes.name; } setAttrs(setObj,{silent:true}); }); }) So it does the change (hurray!), however for it to be effective, you have to close & reopen the sheet. Is there a way to make the change instant, as when you use character_name directly as an attribute?
1710430779
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
doing updates on sheet opened is the best way. Users won't get the updated code unless they refresh their game, in which case they will be opening the sheet anyways.
I see, but no way that add a command to make the change instant as well?