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

[Sheet Worker] Some help with this small piece of code?

1538491759

Edited 1538492702
Leothedino
Sheet Author
Hey guys... again :P Still trying to get my head around Sheet Workers. I am trying my hand at a piece of code that will generate an attribute of /1 or /2 depending on one input box being equal to or less than another. Here is what I have so far:  on("sheet:opened change:hp", function() { getAttrs(["wound_threshold","hp"], function(values) { let wound_threshold = parseInt(values.wound_threshold)||0; let hp = parseInt(values.hp)||0; if (wound_threshold >= hp) { wound_mod = "/2"; } else if (wound_threshold <= hp) { wound_mod = "/1"; } setAttrs({ "wound_mod":wound_mod }); }); }); Anybody able to point out what I did wrong? Apologies if the code is utterly offensive to some of you. I took it from elsewhere I tried my hand at working with it. EDIT: Corrected a typo in the code, wasn't what seems to be the issue, however.
1538494689
Finderski
Plus
Sheet Author
Compendium Curator
Couple potential problems I see... 1. You have >= and <= and really only one thing can equal that, so we need to know which is.  I believe it should stop after the first evaluation, which leads too.... 2. I'd recommend changing the ELSE IF to just ELSE and get rid of the evaluation, because if the first evaluation failed, then this should be what happens. Are you getting an error message? If so, what is it? I'd also recommend adding some console.log statements to the code, like right after the variable assignment and perhaps right after the evaluations to see which branch things are going down. Something like... let wound_threshold = parseInt(values.wound_threshold)||0; let hp = parseInt(values.hp)||0; console.log("wt: " + wound_threshold); console.log("hp: " + hp); That'll help you know assignments are correct.
1538494885
GiGs
Pro
Sheet Author
API Scripter
grr, i was writing a reply but got logged out before i posted it for some reason. In addition to Finderskis comments, you dont declare wound_mod. on("sheet:opened change:hp", function() { getAttrs(["wound_threshold","hp"], function(values) { let wound_threshold = parseInt(values.wound_threshold)||0; let hp = parseInt(values.hp)||0; let wound_mod = ""; console.log("wt: " + wound_threshold); console.log("hp: " + hp); if (wound_threshold >= hp) { wound_mod = "/2"; } else { wound_mod = "/1"; } console.log("wm: " + wound_mod); setAttrs({ "wound_mod":wound_mod }); }); }); I'd also check the attributes in your character sheet, make sure they are spelled the same.
Stupid question, but where might the results of those console.logs go, if they were to work? So far, nothings working with the fixed examples above.
1538499537
Finderski
Plus
Sheet Author
Compendium Curator
In Chrome go to View => Developer => Developer Tools That will open a window on the right of Chrome and across the top of that window will be a series of links: Elements, Console, Sources, etc... Click on Console and that will show you any error messages that are coming up as well as the output of anything from console.log.
1538499985
GiGs
Pro
Sheet Author
API Scripter
Pressing F12 gets you most of the way there too.
Ok, been sat here for an hour or so trying to make this work, and it's just not. Perhaps it's a case that what I want to do  isn't actually possible? Here is an example (and this example doesn't work, either):  <!--TWO STATS FOR THE SHEET WORKER--> <input name='attr_hp' type='number' value='0' default> <input name='attr_wound_threshold' type='number' value='0' default> <!--EXAMPLE USE--> <input name='attr_example' type='number' value='[[1d20@{wound_mod}]]'> <!-- SHEET WORKER --> <script type="text/worker"> on("sheet:opened change:hp", function() { getAttrs(["wound_threshold","hp"], function(values) { let wound_threshold = parseInt(values.wound_threshold)||0; let hp = parseInt(values.hp)||0; let wound_mod = ""; console.log("wt: " + wound_threshold); console.log("hp: " + hp); if (wound_threshold >= hp) { wound_mod = "/2"; } else { wound_mod = "/1"; } console.log("wm: " + wound_mod); setAttrs({ "wound_mod":wound_mod }); }); }); </script> Note: I am aware this would be easier with a dropdown menu, but it's not a possibility with what I am currently working on.
1538503947
Finderski
Plus
Sheet Author
Compendium Curator
Try changing wound_threshold to woundthreshold?
Ok, just tried that, I changed all instances of wound_threshold throughout, to woundthreshold . It's still not working. :(
1538504311

Edited 1538504548
GiGs
Pro
Sheet Author
API Scripter
Perhaps it's a case that what I  want to do  isn't actually possible?  This is definitely not true. What you're trying is an extremely trivial use of sheetworkers, and should easily work. I'm not sure why it isn't, but you're not giving us much to work with. What is the console log telling you? Are the variables being set properly? What exactly is going wrong? It's possible the error could be something else on the sheet. Do you have multiple script blocks? that used to cause issues. Your example attribute is an attribute, not a button. So its value may be being set, but there's no way to roll it. Is that your issue? If so you want something like <button  type='roll' name='roll_example' value='[[1d20@{wound_mod}]]'></button> A couple of thoughts: You don't have an attribute for the Wound_mod. That shouldnt be a problem, but it's worth adding it anyway. While testing, set it as text so you can see what its value is being set as. <input name='attr_wound_mod' type='text' value=''> When you know everything is working, change it to a hidden input. <input name='attr_wound_mod' type='hidden' value=''> Is default a valid parameter of the input there? I've never seen that before. I'd remove that, its not necessary. I'm talking about changing <input name='attr_hp' type='number' value='0' default> to  <input name='attr_hp' type='number' value='0'> I have to say though, this is a weird way to do what you want. Why not put the "/" in the roll formula, and just have wound_mod be a number. e.g.  value='[[1d20/@{wound_mod}]]' and          if (wound_threshold >= hp) { wound_mod = "2"; } else { wound_mod = "1"; } I dont think this is the issue, it just seems more appropriate. (Personally I'd use a multiplier and change to 2 to 0.5, that just looks neater to me, but it's the same thing.)
1538506759

Edited 1538506843
Leothedino
Sheet Author
Why am I doing this? I need a dropdown box with three options:  Healthy ,  Wounded  and  Death State . Healthy (/1)  keeps the stat at full,  Wounded (/2)  halves it and  Death State (/3)  makes the stat one third of what it was. Let's call this dropdown 'attr_condition' For the sake of examples, I have five stats: Strength, Agility, Willpower, Intellect, Charisma. Under any normal circumstance I can do this to get the final stat result: value='[[floor(@{max_strength}+@{stat_mod_strength}+@{additional_modifiers}@{condition})]]' Only, in this example Strength, Intellect & Charisma  are the only three stats that are effected by Healthy, Wounded and Death State . Agility & Willpower only get effected by Healthy and Death State . Wounded is not applied to these two stats, ever. So... my dropdown menu fails. I can't keep my page clean with one singular condition menu because it's situationally used across the list of stats. So what I did instead was think "Ah, Wounded actually applies to Strength, Intellect & Charisma when they reach the Wound Threshold stat, I could probably just make that an automatic thing, and leave a dropdown menu for all of them that affects what they -do- all have in common, Healthy and Death State ." As you say GG, it's trivial. But I am doing my absolute best without rushing to the forums every 30 seconds. Only really asking for help when I am desperate for some. 
1538507596
GiGs
Pro
Sheet Author
API Scripter
Thanks for the information on why you need it. But you didnt answer my question about what was or wasnt happening with the script. Do you see the variables in the console log? Are they being set properly? is the wound_mod attribute being set properly? Does the button I suggested work?  I want to help you, but you havent answered any of the trouble-shooting questions I've asked in my posts, so I'm just flailing in the dark.
1538507765
GiGs
Pro
Sheet Author
API Scripter
This formula wont give correct results by the way: value='[[floor(@{max_strength}+@{stat_mod_strength}+@{additional_modifiers}@{condition})]]' you need brackets value='[[floor( (@{max_strength}+@{stat_mod_strength}+@{additional_modifiers})@{condition})]]' Again I suggest changing the condition to a number, and putting the divider in the formula. value='[[floor( (@{max_strength}+@{stat_mod_strength}+@{additional_modifiers})/@{condition})]]' It's better for error checking.
1538508027
GiGs
Pro
Sheet Author
API Scripter
By the way you could have a universal condition dropdown, and have two condition stats set by it. Then in your strength, etc use value='[[floor( (@{max_strength}+@{stat_mod_strength}+@{additional_modifiers})/@{condition})]]' and in agility and will use value='[[floor( (@{max_agility}+@{stat_mod_agility}+@{additional_modifiers})/@{condition_limited})]]' These two condition attributes could be set using autocalc fields or the sheet worker we are working on.
Noted, i'll try it before the weekend. Thank you for your help.  The logs weren't returning any errors, aside from google analytics at the top of the page. It's just my amateur lack of knowledge in this field, I guess.
1538508445
GiGs
Pro
Sheet Author
API Scripter
Were the logs returning anything at all? Did you see the values being set?
They did, correctly. So it has to be something to do with my code. I've run out of time to battle this beast tonight, so I am going to have to face it head on later in the week. Thanks again, sorry if I frustrated you.
1538510694

Edited 1538510915
Finderski
Plus
Sheet Author
Compendium Curator
Try getting rid of the underscore in wound_mod...I remember hearing something that sheet workers don't like - or _ or something...maybe both?  It's something to try anyway. Edit: Meaning, I know _ are used in some very specific uses cases (e.g. repeating sections and _max), but it may cause problems if used in something other than those uses cases...
1538511374

Edited 1538511420
GiGs
Pro
Sheet Author
API Scripter
underscores should be fine in attribute names. It's other characters like dashes that cause issues. Leo, thats important information. I honestly didnt know if the sheet worker was firing or not, but now we know it is working, which narrows down to two possibilities: The sheet worker isn't outputting the result properly. The sheet worker is outputting the result, but something after that is failing. You can determine which this is by creating this attribute anywhere on the sheet - i recommend right at the top. Dont worry about layout, this is a temporary attribute: <input name='attr_wound_mod' type='text' value=''> Then change the hp value till its less than the wound threshold, and see if the wound_mod attribute changes. And then change hp to higher than wound_threshold, and see if the attribute changes again. If this works, we know there's nothing wrong with the sheet worker, and the problem is elsewhere (in your formula, perhaps) If it doesnt work, we know the sheet worker output is faulty, and we can check that. When you have time, give those steps a try.
1538533455

Edited 1538533734
Leothedino
Sheet Author
A little update GG. I made a quick test custom sheet and placed all of the above code into it, including a new line just to test the attribute. It works perfectly.  So, I took it across to my sheet and it half works there. If I lower the sheets HP then it adjusts when it passes the Wound Threshold stat exactly as it should, but once this happens won't change back or move ever again if I go back above the Wound Threshold. Is there anything I should keep an eye out for, or is what I said a bit too vague? I did check the logs, absolutely no errors happening on the sheet currently. EDIT: A brand new generated character actually works fine, but once I input some stats in that's when it breaks. I might be able to hunt down the issue knowing that, we'll see.
1538536623

Edited 1538536724
Is attr_wound_threshold based on hit points in any way? For example, is it always 50% of your max hit points? If so, it might be easier to do math in the sheetworker and return modified stats for Str, Agi, etc., than to generate a wound_mod attribute (unless wound_mod is used in other calculations). You might also need the sheetworker to run if the ability scores themselves change ( e.g., What happens if I get some piece of magic or equipment that increases my Agility? What if my max HP goes up?). You will also need the sheetworker to run when they recover from wounding to set their abilities back to normal.
1538536774

Edited 1538536939
GiGs
Pro
Sheet Author
API Scripter
Can you post the updated code for the relevant sections, both the sheetworker and the relevant bits of html? edit: also, Rabulias is onto something. You can use the sheet worker to update multiple attributes, so you could use to replace the current method completely.
1538538775

Edited 1538538957
Leothedino
Sheet Author
I worked it out, actually. Turns out getting the attribute -from- a disabled field was a bad idea (I always thought it was just sending it to a Disable field that was bad). The HP stat is derived from two other stats, so a sum had to be done to get the HP first. The moment I made Wound Threshold  something the player needs to input (AKA work out themselves) this sheet worker runs perfectly. EDIT: I could GG, but there is just so much code, not sure i'd be able to cut the right parts out at this stage. :(
1538539497
GiGs
Pro
Sheet Author
API Scripter
aha, yes, disabled fields would mess things up. When using sheet workers, its best to bypass any attributes with autocalc fields completely. You can recreate the autocalc calculation within the sheet worker.
Thanks for your patience man, we got there in the end. When I had that 'eureka' moment, I nearly spilt my drink! :D  One last thing, I've decided to set a third outcome if HP actually just reaches zero. It gets divided by 3. Does this look right? (It's in bold )   on("sheet:opened change:hp", function() { getAttrs(["woundthreshold","hp"], function(values) { let woundthreshold = parseInt(values.woundthreshold)||0; let hp = parseInt(values.hp)||0; let wound_mod = ""; console.log("wt: " + woundthreshold); console.log("hp: " + hp); if (woundthreshold >= hp) { wound_mod = "/2"; } else if (hp = 0) { wound_mod = "/3"; } else { wound_mod = "/1"; } console.log("wm: " + wound_mod); setAttrs({ "wound_mod":wound_mod }); }); }); If not, no problemo, it's just a quality of life thing, I can live without it. Again, many... many thanks! 
1538540269

Edited 1538540315
GiGs
Pro
Sheet Author
API Scripter
javascript is a bit funny when it comes to equal signs. When you are assigning a value, you use single equals (e.g. wound_mod = "/2") When you are comparing  two values, you use double or triple equals: } else if (hp === 0) { Triple is better, you dont really need to worry about it. When you use the single equals for comparisons like this, it doesnt compare them, it imemdiately sets the value (so in this case, the hp variable in the function would instantly become zero) which would mess up your function. So, try to remember, for comparisons use triple equals, and setting values use single equals. That said, maybe you want o or below? } else if (hp <= 0) {
1538540440
GiGs
Pro
Sheet Author
API Scripter
By the way, i still think you should change that first line on("sheet:opened change:hp change:woundthreshold", function() { This way the worker will work properly when either of those two values change.
Ah yes, good catch there. That could have been disastrous later down the line!