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

Updating totals from fieldsets

Another fieldset question! (Sorry, I'm a .NET developer, so I'm spoiled by my IDE and getting to do whatever I want with my UI, being limited to JUST HTML and CSS makes me squirm a little). Is there a way to automatically update totals from a specific "column" in a fieldset? In this case, I'd like to keep a running total of the weight a character is carrying. I know how to do this with JavaScript, but that adds a step. I was hoping for instantaneous calculation, so the moment they add 10kg worth of fancy chandeliers to their inventory, the total updates. Any ideas?
1420571296
Lithl
Pro
Sheet Author
API Scripter
You should be able to use on('change:attribute', function(obj, prev) {...}); for that. Iterate over the character's attributes with the appropriate names to calculate the total, and update the value of the "total" attribute.
o.O I did not know I could catch events from the character sheet in the API. I thought it only listened to the chat log and main game window. This is amazing.
I assume obj is the control... what is prev?
1420574820

Edited 1420575032
Lithl
Pro
Sheet Author
API Scripter
prev stores the state of the object prior to the change. Note that prev is a regular JavaScript object, not a Roll20 object. So you'd use for example prev._characterid rather than obj.get('characterid') You can register event callbacks for any object type, for add , change , or destroy . You can also restrict the change event to specific properties of the object type, such as change:attribute:current , which will fire when the 'current' property of an attribute changes, but won't fire for a change to an attribute's 'max' property.
Ran into an issue with this... I have a detailed ability score table (because some of our players are absolutely terrible at remembering from where their temporary bonuses are coming). The four primary values that are used are: STR_Mod, STR_Value, STR_BaseMod and STR_BaseValue, where the Base stats are the stats with ONLY permanent effects (dice roll, racial bonus, inherent bonuses, etc), and the other stats are include the base stat and temporary effects (belt of giant strength, etc). When I change the STR_Roll attribute, and it updates the STR_Value attribute, how do I catch the update of the STR_Value, since that's the one I care about. I know I could listen for changes on all of the contributing values of STR_Value, and just grab the STR_Value off of the character, but I was hoping there was a way to catch a change in an auto-calculated field, instead of listening for every last contributor to that field.
1420744862
Lithl
Pro
Sheet Author
API Scripter
The problem is that STR_Value isn't actually changing at all. For example, if STR_Value is "@{STR_Roll} + 1" and you change STR_Roll from 5 to 6, STR_Value is still "@{STR_Roll} + 1".
That makes sense. It's inconvenient in this instance, but it makes sense.
Is there a way to retrieve the calculated value of an autocalculated field without repeating the calculation in the API? According to what I've read, attributes don't exist until their value no longer matches the value property of the object. For example, <input type="number" name="attr_goldcoins" value="0"/> does not create an attribute titled "goldcoins" with a value of 0. If I overwite the value at runtime, it creates the attribute with the new value. At least that's how I understand it. If I apply that to what you've said above, then there's no way to grab auto-caluclated attribute values from the character sheet, because they never technically change values. Is this correct? Is there another way? EDIT: I think I've figured it out. From the wiki: Note that fields which have auto-calculated values will return the formula rather than the result of the value. You can then pass that formula to sendChat() to use the dice engine to calculate the result for you automatically. The problem I ran into is the "getAttrByName" function (also found in the wiki) somehow created an attribute of the same name even though the other one technically existed. So now, whenever I call "STR_Value", I get 0 (the default value I passed when calling getAttrByName the first time) instead of the formula that creates STR_Value.
Nevermind, I don't got it. on('change:attribute', function(obj, prev){ var character = getCharacterById(obj.get("_characterid")); if(obj.get("name").indexOf("STR_") == 0 || obj.get("name") == "size"){ setCarryingCapacity(character, getAttrByIdAndName(character.get("_id"), "STR_Value", 0,false)); } }); STR_Value should return (@{STR_Base}+@{STR_Enh}+@{STR_Temp_Misc_1}+@{STR_Temp_Misc_2}+@{STR_Temp_Misc_3}) STR_Base should return (@{STR_Roll}+@{STR_Racial}+@{STR_Inherent}+@{STR_Size}+@{STR_Perm_Misc}) and STR_Size should return ((ceil(((@{size}-1)/999999999)*((@{size}-1)/999999999))*(-1)+1)*(-10))+((ceil(((@{size}-2)/999999999)*((@{size}-2)/999999999))*(-1)+1)*(-10))+((ceil(((@{size}-3)/999999999)*((@{size}-3)/999999999))*(-1)+1)*(-8))+((ceil(((@{size}-4)/999999999)*((@{size}-4)/999999999))*(-1)+1)*(-4))+((ceil(((@{size}-5)/999999999)*((@{size}-5)/999999999))*(-1)+1)*(0))+((ceil(((@{size}-6)/999999999)*((@{size}-6)/999999999))*(-1)+1)*(8))+((ceil(((@{size}-7)/999999999)*((@{size}-7)/999999999))*(-1)+1)*(16))+((ceil(((@{size}-8)/999999999)*((@{size}-8)/999999999))*(-1)+1)*(24))+((ceil(((@{size}-9)/999999999)*((@{size}-9)/999999999))*(-1)+1)*(32))+((ceil(((@{size}-10)/999999999)*((@{size}-10)/999999999))*(-1)+1)*(40))+((ceil(((@{size}-11)/999999999)*((@{size}-11)/999999999))*(-1)+1)*(48))+((ceil(((@{size}-12)/999999999)*((@{size}-12)/999999999))*(-1)+1)*(56)) The problem (I think) is somewhere in the following code... function getAttrByIdAndName(characterId, attributeName, defaultValue, getMax){ var valueType = "current"; if(getMax === "true"){ valueType = "max"; } var attribute = findObjs({ type: 'attribute', characterid: characterId, name: attributeName })[0]; if(!attribute){ attribute = createObj('attribute', { characterid: characterId, name: attributeName, current: defaultValue, max: defaultValue }); } return attribute; } after the var attribute = findObjs({...})[0], the attribute variable is still undefined, and I cannot for the life of me figure out why. I've been staring at this code for too long. Hopefully a second set of eyes will help.