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

Repeating Section Sheetworker - trouble getting the last part to work...

1728622324

Edited 1728622395
Steve
Pro
Sheet Author
Right, so this is nearly  working how I want it. It successfully populates the repeating section and equips the weapon (by "clicking" the equip button) on actiation. On deactivation, it successfully removes the Vorpal Blade entry. However,  it does not equip the weapon in the first row after removing the Vorpal Blade. I'd actually prefer it to equip the 'last used' weapon, but I have not successfully managed that either. I have been successful in generating an empty new row and equipping that to clear the Vorpal Blade stats, but then I'm left with a bunch of empty rows after casting the spell a few times. on("change:vorpal_blade", function() {     getAttrs(["vorpal_blade"], function(values) {         const vorpalBladeStatus = parseInt(values.vorpal_blade) || 0;         // When Vorpal Blade is set to "Active" (1)         if (vorpalBladeStatus === 1) {             getSectionIDs("repeating_meleeweapons", function(ids) {                 let foundVorpalBlade = false;                                  // Iterate over the rows to check if the Vorpal Blade is already present                 ids.forEach(function(id) {                     getAttrs([`repeating_meleeweapons_${id}_meleeweaponname`], function(weaponValues) {                         const weaponName = weaponValues[`repeating_meleeweapons_${id}_meleeweaponname`] || "";                         if (weaponName === "Vorpal Blade") {                             foundVorpalBlade = true;                             setAttrs({                                 [`clicked:repeating_meleeweapons_${id}_equippedmeleewep`]: 1                             });                         }                     });                 });                 // If not found, create the Vorpal Blade entry                 if (!foundVorpalBlade) {                     const newRowId = generateRowID();                     const newWeaponAttrs = {};                     newWeaponAttrs[`repeating_meleeweapons_${newRowId}_meleeweaponname`] = 'Vorpal Blade';                     newWeaponAttrs[`repeating_meleeweapons_${newRowId}_meleeweapon`] = 'Sword';                     newWeaponAttrs[`repeating_meleeweapons_${newRowId}_magicmeleeweaponbonus`] = 3;                     newWeaponAttrs[`repeating_meleeweapons_${newRowId}_meleeabr`] = 'd8';                     newWeaponAttrs[`repeating_meleeweapons_${newRowId}_meleedamage`] = '4';                     newWeaponAttrs[`repeating_meleeweapons_${newRowId}_meleeothereffects`] = 'In the caster’s hand there appears a magic sword— as black as midnight, with a coruscating nimbus of green fire.';                     setAttrs(newWeaponAttrs, function() {                         setAttrs({                             [`clicked:repeating_meleeweapons_${newRowId}_equippedmeleewep`]: 1                         });                     });                 }             });         // When Vorpal Blade is set to "Inactive" (0)         } else {             getSectionIDs("repeating_meleeweapons", function(ids) {                 let foundVorpalBlade = false;                                  // Iterate over the rows to check for the Vorpal Blade entry                 ids.forEach(function(id) {                     getAttrs([`repeating_meleeweapons_${id}_meleeweaponname`], function(weaponValues) {                         const weaponName = weaponValues[`repeating_meleeweapons_${id}_meleeweaponname`] || "";                                                  // If Vorpal Blade is found, remove it                         if (weaponName === "Vorpal Blade") {                             removeRepeatingRow(`repeating_meleeweapons_${id}`);                         }                     });                 });                 // Equip the first available row after removal                 if (ids.length > 0) {                     setAttrs({                         [`clicked:repeating_meleeweapons_${ids[0]}_equippedmeleewep`]: 1                     });                 }             });         }     }); });
1728630929

Edited 1728631051
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
The issue is that your setAttrs is incorrect. You are trying to set an attribute named clicked:repeating_meleeweapons_-someID_equippedmeleewep . That is not a valid attribute name construction in Roll20; it's the event listener for a button, which you can't trigger via setAttrs. Assuming that equippedmeleewep is an attribute, you want this for your setAttrs: setAttrs({     [`clicked:repeating_meleeweapons_${ids[0]}_equippedmeleewep`]: 1 }); There's also some code quality things to think about here: Running  getSectionIDS  inside a getAttrs call and then doing another getAttrs call is a very inefficient way to do this and while it won't cause noticeable lag yet, if you use this construction in something that needs a few more levels of nesting, you'll start to notice lag in your sheet.   getAttrs  (and   setAttrs ) take the same amount of time to return regardless of whether you are working with one attribute or 10000 attributes, so using multiple nested gets or sets is just adding time to how long it takes the sheetworker to run.   Running multiple getAttrs in a forEach loop will be extremely slow.  A better construction is to get all of the IDs you need at once and then get all your attributes at once: on("change:vorpal_blade", function () { getSectionIDs("repeating_meleeweapons", function (ids) { // create the array of all the attributes we want to get by iterating over the ids const getArr = ids.reduce((arr, id) => { // get the weaponname and equipped status so you can reequip the previous weapon arr.push(`repeating_meleeweapons_${id}_meleeweaponname`, `repeating_meleeweapons_${id}_equippedmeleewep`); return arr; }, ['vorpal_blade', 'last_weapon_id']); // last_weapon_id is an attribute that you would need to make to store the previously equipped weapon's row ID so that you could swap back to the previously equipped weapon. While you don't technically need to add it to the html, it's usually best to do so as a hidden input for attributes like this. // now get all the attribute values getAttrs(getArr, (values) => { const vorpalBladeStatus = parseInt(values.vorpal_blade) || 0; // an empty object to store our changes in. // this way we can use a single setAttrs const setObj = {}; // instead of iterating over each id, we can just find the id we want             // While this still iterates, it will stop as soon as it successfully finds the id, which             // makes it a little more performant.             // You could instead do this logic assignment in the reduce operation above, but that can get messy const vorpalID = ids.find(id => values[`repeating_meleeweapons_${id}_meleeweaponname`] === 'Vorpal Blade'); // we can just check if status is truthy because 0 roughly equals false and any other number roughly equals true. if (vorpalBladeStatus) { if (vorpalID) { setObj['repeating_meleeweapons_${id}_equippedmeleewep'] = 1; } else { const newRowId = generateRowID(); setObj[`repeating_meleeweapons_${newRowId}_meleeweaponname`] = 'Vorpal Blade'; setObj[`repeating_meleeweapons_${newRowId}_meleeweapon`] = 'Sword'; setObj[`repeating_meleeweapons_${newRowId}_magicmeleeweaponbonus`] = 3; setObj[`repeating_meleeweapons_${newRowId}_meleeabr`] = 'd8'; setObj[`repeating_meleeweapons_${newRowId}_meleedamage`] = '4'; setObj[`repeating_meleeweapons_${newRowId}_meleeothereffects`] = 'In the caster’s hand there appears a magic sword— as black as midnight, with a coruscating nimbus of green fire.'; setObj['repeating_meleeweapons_${newRowId}_equippedmeleewep'] = 1; } // find the currently equipped weapon const equippedID = ids.find(id => values[`repeating_meleeweapons_${id}_equippedmeleewep`] * 1 === 1); values.last_weapon_id = equippedID || ''; } else { if (vorpalID) { removeRepeatingRow(`repeating_meleeweapons_${vorpalID}`); // we need to remove the vorpal sword ID from the ids array // first we find where it is in the array of ids const vorpalIndex = ids.findIndex(id => id === vorpalID); // then we remove it ids.splice(vorpalIndex, 1); } // set our ID to equip to the value of last_weapon_id or the first id in the ids array. const toEquipID = values.last_weapon_id || ids[0]; // if there is an id to equip, then set it's equip state to 1. if (toEquipID) { setObj[`repeating_meleeweapons_${toEquipID}_equippedmeleewep`] = 1; } } // finally, apply all of our changes setAttrs(setObj) }); }); }); I also added code for handling the equipping of the previous weapon.
1728644520
Steve
Pro
Sheet Author
Okay, with a couple of minor edits (there was a missing semi-colon at the end setAttrs, a couple of ' were changed to `, and it wouldn't do anything without restoring the 'clicked:' to the equippedmeleewep lines) I got your revised code working to the same point as my previous code... ie: It populates, equips and deletes Vorpal Blade - but it does not re-equip the previous weapon: on("change:vorpal_blade", function () {     getSectionIDs("repeating_meleeweapons", function (ids) {         // create the array of all the attributes we want to get by iterating over the ids         const getArr = ids.reduce((arr, id) => {             // get the weaponname and equipped status so you can reequip the previous weapon             arr.push(`repeating_meleeweapons_${id}_meleeweaponname`, `repeating_meleeweapons_${id}_equippedmeleewep`);             return arr;         }, ['vorpal_blade', 'last_weapon_id']);         // last_weapon_id is an attribute that you would need to make to store the previously equipped weapon's row ID so that you could swap back to the previously equipped weapon. While you don't technically need to add it to the html, it's usually best to do so as a hidden input for attributes like this.         // now get all the attribute values         getAttrs(getArr, (values) => {             const vorpalBladeStatus = parseInt(values.vorpal_blade) || 0;             // an empty object to store our changes in.             // this way we can use a single setAttrs             const setObj = {};             // instead of iterating over each id, we can just find the id we want             // While this still iterates, it will stop as soon as it successfully finds the id, which             // makes it a little more performant.             // You could instead do this logic assignment in the reduce operation above, but that can get messy             const vorpalID = ids.find(id => values[`repeating_meleeweapons_${id}_meleeweaponname`] === 'Vorpal Blade');             // we can just check if status is truthy because 0 roughly equals false and any other number roughly equals true.             if (vorpalBladeStatus) {                 if (vorpalID) {                     setObj[`clicked:repeating_meleeweapons_${id}_equippedmeleewep`] = 1;                 } else {                     const newRowId = generateRowID();                     setObj[`repeating_meleeweapons_${newRowId}_meleeweaponname`] = 'Vorpal Blade';                     setObj[`repeating_meleeweapons_${newRowId}_meleeweapon`] = 'Sword';                     setObj[`repeating_meleeweapons_${newRowId}_magicmeleeweaponbonus`] = 3;                     setObj[`repeating_meleeweapons_${newRowId}_meleeabr`] = 'd8';                     setObj[`repeating_meleeweapons_${newRowId}_meleedamage`] = '4';                     setObj[`repeating_meleeweapons_${newRowId}_meleeothereffects`] = 'In the caster’s hand there appears a magic sword— as black as midnight, with a coruscating nimbus of green fire.';                     setObj[`clicked:repeating_meleeweapons_${newRowId}_equippedmeleewep`] = 1;                 }                 // find the currently equipped weapon                 const equippedID = ids.find(id => values[`repeating_meleeweapons_${id}_equippedmeleewep`] * 1 === 1);                 values.last_weapon_id = equippedID || '';             } else {                 if (vorpalID) {                     removeRepeatingRow(`repeating_meleeweapons_${vorpalID}`);                     // we need to remove the vorpal sword ID from the ids array                     // first we find where it is in the array of ids                     const vorpalIndex = ids.findIndex(id => id === vorpalID);                     // then we remove it                     ids.splice(vorpalIndex, 1);                 }                 // set our ID to equip to the value of last_weapon_id or the first id in the ids array.                 const toEquipID = values.last_weapon_id || ids[0];                 // if there is an id to equip, then set it's equip state to 1.                 if (toEquipID) {                   setObj[`clicked:repeating_meleeweapons_${toEquipID}_equippedmeleewep`] = 1;                 }             }             // finally, apply all of our changes             setAttrs(setObj);         });     }); }); And this little guy is sitting in my HTML: <input type="hidden" name="attr_last_weapon_id" value="0" /> I feel like whatever is stopping that last thing from happening is something minor and silly, but I just can't see it...
1728657116
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Share your html? The clicked should not be working. It's not valid attribute syntax.
1728658319
GiGs
Pro
Sheet Author
API Scripter
You still have this at the end setObj[`clicked:repeating_meleeweapons_${toEquipID}_equippedmeleewep`] = 1; As Scott said earlier, that is not valid and should probably be setObj[`repeating_meleeweapons_${toEquipID}_equippedmeleewep`] = 1;
1728708967

Edited 1728709085
Steve
Pro
Sheet Author
Okay, the repeating section:         <div class="weapons">             <div class="meleeweapons">                 <h2>Melee Weapons</h2>                 <fieldset class="repeating_meleeweapons">                     <input type="hidden" name="attr_hide" value="0" class="equip-toggle">                     <div class="hidden-row">                         Weapon name <input type="text" name="attr_meleeweaponname" class="eightmidtextinput" />                         <br>                         Weapon type <input type="text" name="attr_meleeweapon" list="meleeweapon" class="eightmidtextinput" />                         <br>                         Magic Bonus <input type="number" name="attr_magicmeleeweaponbonus" min="0" max="3" value="0" class="fourshorttextinput" />                         Armour Bypass Roll <input type="text" name="attr_meleeabr" value="0" class="fourshorttextinput" />                         Damage <input type="text" name="attr_meleedamage" value="0" size="4" class="fourshorttextinput" />                         Other Effects <textarea name="attr_meleeothereffects">                         </textarea>                         <br>                         <button type="action" name="act_equippedmeleewep">Equip/Update</button>                     </div>                 </fieldset>             </div> The spell:                     <div class="spell-entry">                         <div class="spell_name"><span><strong>Vorpal Blade</strong></span></div>                         <div class="spell_duration"><span>Duration: Spell Expiry Roll applies</span></div>                         <div class="spell_desc">                             <p>Description: The caster summons a magical sword as black as midnight, surrounded by green fire. This weapon grants the Sorcerer a +3 bonus to attack and defence while wielding it. It deals <strong>1d8 +3 Armour Bypass</strong> and <strong>7 HP damage</strong> on a successful hit. If the caster puts down the weapon, it vanishes immediately. If offered to another, it strikes the Sorcerer once and disappears forever.</p>                         </div>                         <span>Activate Spell:</span>                         <select name="attr_vorpal_blade">                             <option value="0">Inactive</option>                             <option value="1">Active</option>                         </select>                         <input type="hidden" name="attr_last_weapon_id" value="0" />                     </div> Here's a screen recording of me using it - in this video I had changed the final entry: GiGs  said: You still have this at the end setObj[`clicked:repeating_meleeweapons_${toEquipID}_equippedmeleewep`] = 1; As Scott said earlier, that is not valid and should  probably  be setObj[`repeating_meleeweapons_${toEquipID}_equippedmeleewep`] = 1;  But the others remain as 'clicked', because without it those parts do not work either. Hmmm, also to be sure to be complete, here are the other repeating section sheetworkers: on("clicked:repeating_meleeweapons:equippedmeleewep", function(eventInfo) { // Get the row ID of the clicked button const rowId = eventInfo.triggerName.split('_')[2]; getSectionIDs('repeating_meleeweapons', function(ids) { const output = {}; // Initialize 'output' here ids.forEach(function(id) { output[`repeating_meleeweapons_${id}_hide`] = (id == rowId) ? 1 : 0; }); // Define the fields to retrieve from the current row const fields = [ `repeating_meleeweapons_${rowId}_meleeweaponname`, `repeating_meleeweapons_${rowId}_meleeweapon`, `repeating_meleeweapons_${rowId}_magicmeleeweaponbonus`, `repeating_meleeweapons_${rowId}_meleeabr`, `repeating_meleeweapons_${rowId}_meleedamage`, `repeating_meleeweapons_${rowId}_meleeothereffects` ]; // Get the attributes of the current row getAttrs(fields, function(values) { // Add the equipped weapon attributes to the existing 'output' object output.equippedmeleeweaponname = values[`repeating_meleeweapons_${rowId}_meleeweaponname`] || ""; output.equippedmeleeweapontype = values[`repeating_meleeweapons_${rowId}_meleeweapon`] || ""; output.equippedmeleeweaponmagicbonus = parseInt(values[`repeating_meleeweapons_${rowId}_magicmeleeweaponbonus`]) || 0; output.equippedmeleeweaponabr = values[`repeating_meleeweapons_${rowId}_meleeabr`] || "0d0"; output.equippedmeleeweapondamage = values[`repeating_meleeweapons_${rowId}_meleedamage`] || "0"; output.equippedmeleeweaponother = values[`repeating_meleeweapons_${rowId}_meleeothereffects`] || ""; // Set the output attributes (now including both hide and equipped weapon attributes) setAttrs(output); }); }); }); on('change:unarmed_combat change:oak_fists change:repeating_meleeweapons', function(event) { getSectionIDs('repeating_meleeweapons', function(ids) { const id = event.sourceAttribute.split('_')[2]; // Retrieve attributes and ensure unarmed_combat and oak_fists are set to 0 if unchecked getAttrs(['unarmed_combat', 'oak_fists', event.sourceAttribute], function(v) { let weaponName = v[`repeating_meleeweapons_${id}_meleeweapon`] || ''; let unarmed_combatActive = parseInt(v['unarmed_combat']) || 0; let oak_fistsActive = parseInt(v['oak_fists']) || 0; // Ensure unarmed_combat is set to 0 if unchecked if (v['unarmed_combat'] !== "1") { setAttrs({ unarmed_combat: "0" }); unarmed_combatActive = 0; } // Ensure oak_fists is set to 0 if unchecked if (v['oak_fists'] !== "1") { setAttrs({ oak_fists: "0" }); oak_fistsActive = 0; } // Initialize weapon options const weaponOptions = { "Battleaxe": {abr: "d8", damage: "6", warlockweapongroupmelee: 5}, "Cudgel": {abr: "d3", damage: "3", warlockweapongroupmelee: 8}, "Dagger": {abr: "d4", damage: "3", warlockweapongroupmelee: 2}, "Flail": {abr: "d6", damage: "4", warlockweapongroupmelee: 1}, "Halberd": {abr: "d10", damage: "5", warlockweapongroupmelee: 3}, "Mace": {abr: "d6", damage: "4", warlockweapongroupmelee: 1}, "Morning star": {abr: "d6", damage: "5", warlockweapongroupmelee: 1}, "Shortsword": {abr: "d8", damage: "3", warlockweapongroupmelee: 2}, "Spear": {abr: "2d4", damage: "4", warlockweapongroupmelee: 3}, "Staff": {abr: "d6", damage: "3", warlockweapongroupmelee: 3}, "Sword": {abr: "d8", damage: "4", warlockweapongroupmelee: 2}, "Two-handed sword": {abr: "d10", damage: "5", warlockweapongroupmelee: 4}, "Unarmed combat": {abr: "d3", damage: "2", warlockweapongroupmelee: 8}, "Footman’s Flail": {abr: "d6", damage: "5", warlockweapongroupmelee: 3}, "Holy Water Sprinkler": {abr: "d6", damage: "5", warlockweapongroupmelee: 1}, "Longsword": {abr: "2d4", damage: "4", warlockweapongroupmelee: 4}, "Pollaxe": {abr: "d12", damage: "4", warlockweapongroupmelee: 3}, "Scourge": {abr: "d2", damage: "3", warlockweapongroupmelee: 3}, "War Axe": {abr: "d6", damage: "5", warlockweapongroupmelee: 5}, "Warhammer": {abr: "d10", damage: "3", warlockweapongroupmelee: 5}, "War Lance": {abr: "2d4", damage: "6", warlockweapongroupmelee: 3}, }; // Override if Unarmed Combat or Oak Fists is selected and active if ((weaponName === 'Unarmed combat' && unarmed_combatActive === 1) || (weaponName === 'Unarmed combat' && oak_fistsActive === 1)) { weaponOptions[weaponName] = {abr: "d6", damage: "3", warlockweapongroupmelee: 8, ismaingauchedefenceweapon: 0}; } // Apply the abr, damage, warlockweapongroupmelee, and ismaingauchedefenceweapon dynamically based on the weapon if (weaponOptions[weaponName]) { const { abr, damage, warlockweapongroupmelee, ismaingauchedefenceweapon } = weaponOptions[weaponName]; setAttrs({ [`repeating_meleeweapons_${id}_meleeabr`]: abr, [`repeating_meleeweapons_${id}_meleedamage`]: damage, [`repeating_meleeweapons_${id}_warlockweapongroupmelee`]: warlockweapongroupmelee, [`repeating_meleeweapons_${id}_ismaingauchedefenceweapon`]: ismaingauchedefenceweapon }); } }); }); });
1728743732

Edited 1728743784
GiGs
Pro
Sheet Author
API Scripter
Steve said: GiGs  said: You still have this at the end setObj[`clicked:repeating_meleeweapons_${toEquipID}_equippedmeleewep`] = 1; As Scott said earlier, that is not valid and should  probably  be setObj[`repeating_meleeweapons_${toEquipID}_equippedmeleewep`] = 1;  But the others remain as 'clicked', because without it those parts do not work either. I'm not commenting on the rest since I havent had time to read it yet, but I want to comment here: The only place you should have, and should ever have, the 'clicked: ' part is the very first line of a sheet worker, the event handler , this part: on("clicked:repeating_meleeweapons:equippedmeleewep", function(eventInfo) { Event handlers have their own syntax for things in repeating sections. But it is saying: watch any action buttons on a row named equippedmeleewep inside the repeating section repeating_meleeweapons and if that button is clicked, start this sheet worker. The word clicked: is only used for event handlers, and should not be anywhere else in your code.
1728785782

Edited 1728786430
Steve
Pro
Sheet Author
While I do understand what you are saying GiGs, I can say without a doubt that this line:   if (vorpalBladeStatus) {                 if (vorpalID) {                     setObj[`clicked:repeating_meleeweapons_${id}_equippedmeleewep`] = 1;                 } else {                     const newRowId = generateRowID();                     setObj[`repeating_meleeweapons_${newRowId}_meleeweaponname`] = 'Vorpal Blade';                     setObj[`repeating_meleeweapons_${newRowId}_meleeweapon`] = 'Sword';                     setObj[`repeating_meleeweapons_${newRowId}_magicmeleeweaponbonus`] = 3;                     setObj[`repeating_meleeweapons_${newRowId}_meleeabr`] = 'd8';                     setObj[`repeating_meleeweapons_${newRowId}_meleedamage`] = '4';                     setObj[`repeating_meleeweapons_${newRowId}_meleeothereffects`] = 'In the caster’s hand there appears a magic sword— as black as midnight, with a coruscating nimbus of green fire.';                      setObj[`clicked:repeating_meleeweapons_${newRowId}_equippedmeleewep`] = 1;                 }                 // find the currently equipped weapon                 const equippedID = ids.find(id => values[`repeating_meleeweapons_${id}_equippedmeleewep`] * 1 === 1);                 values.last_weapon_id = equippedID || ''; works the way it is and "equips" the Vorpal Blade weapon, and I take `clicked:` out of that section leaving just the attribute, ir does not work. Not being an expert, or even truly competent, in any real way I can't tell why it  does  work, when clearly it  should  not. I can only tell you that I've tested it, and that it does.
1728804333

Edited 1728804501
GiGs
Pro
Sheet Author
API Scripter
You are correct that that should not work. It makes me wonder if there is an attribute of that literal name outside the repeating section, but if it's changing your repeating section, that can't be the explanation. I think I'd have to see your full sheet code to beging to fiure out what's going on there. I wonder what console.log({setObj}) (placed just before the setAttrs) reveals about that attribute. also, does it show up in the Attributes list on the Attributes & Abilities tab.
1728827174
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
It looks like you've discovered new behavior Steve, where "setting" the clicked of a button triggers it  I'll have to explore this more later today.
1728861920
Steve
Pro
Sheet Author
Okay, so here's the console log on setting vorpal blade active and inactive: active =('1'): { setObj : {…} } setObj : clicked:repeating_meleeweapons_-O97B56BQ3cM2ve9hxTA_equippedmeleewep clicked:repeating_meleeweapons_-O97B56BQ3cM2ve9hxTA_equippedmeleewep : 1 repeating_meleeweapons_-O97B56BQ3cM2ve9hxTA_magicmeleeweaponbonus : 3 repeating_meleeweapons_-O97B56BQ3cM2ve9hxTA_meleeabr : "d8" repeating_meleeweapons_-O97B56BQ3cM2ve9hxTA_meleedamage : "4" repeating_meleeweapons_-O97B56BQ3cM2ve9hxTA_meleeothereffects : "In the caster’s hand there appears a magic sword— as black as midnight, with a coruscating nimbus of green fire." repeating_meleeweapons_-O97B56BQ3cM2ve9hxTA_meleeweapon : "Sword" repeating_meleeweapons_-O97B56BQ3cM2ve9hxTA_meleeweaponname : "Vorpal Blade" [[Prototype]] : Object [[Prototype]] : Object constructor : ƒ  Object() hasOwnProperty : ƒ  hasOwnProperty() isPrototypeOf : ƒ  isPrototypeOf() propertyIsEnumerable : ƒ  propertyIsEnumerable() toLocaleString : ƒ  toLocaleString() toString : ƒ  toString() valueOf : ƒ  valueOf() __defineGetter__ : ƒ  __defineGetter__() __defineSetter__ : ƒ  __defineSetter__() __lookupGetter__ : ƒ  __lookupGetter__() __lookupSetter__ : ƒ  __lookupSetter__() __proto__ : (...) get __proto__ : ƒ  __proto__() set __proto__ : ƒ  __proto__() inactive (='0'): setObj: repeating_meleeweapons_0_equippedmeleewep: 1[[Prototype]]: Object[[Prototype]]: Object vtt.bundle.b41dc960ae3bd4e335f4.js:47234 SHEET WORKER ERROR: You attempted to set an attribute beginning with 'repeating_' but did not include a Row ID or Attribute Name in repeating_meleeweaponseating_meleeweapons_0_equippedmeleewep
1728862403
Steve
Pro
Sheet Author
Just to be sure: I made sure I 'equipped' a different weapon. I set Vorpal Blade active. I equipped a different weapon, and deleted the vorpal blade entry manually. I set to inactive. { setObj : {…} } setObj : clicked:repeating_meleeweapons_-O97D2Qmvin0qomy4u8C_equippedmeleewep : 1 repeating_meleeweapons_-O97D2Qmvin0qomy4u8C_magicmeleeweaponbonus : 3 repeating_meleeweapons_-O97D2Qmvin0qomy4u8C_meleeabr : "d8" repeating_meleeweapons_-O97D2Qmvin0qomy4u8C_meleedamage : "4" repeating_meleeweapons_-O97D2Qmvin0qomy4u8C_meleeothereffects : "In the caster’s hand there appears a magic sword— as black as midnight, with a coruscating nimbus of green fire." repeating_meleeweapons_-O97D2Qmvin0qomy4u8C_meleeweapon : "Sword" repeating_meleeweapons_-O97D2Qmvin0qomy4u8C_meleeweaponname : "Vorpal Blade" [[Prototype]] : Object [[Prototype]] : Object VM4:3177 { setObj : {…} } setObj : repeating_meleeweapons_0_equippedmeleewep : 1 [[Prototype]] : Object [[Prototype]] : Object vtt.bundle.b41dc96 … .js:47234 SHEET WORKER ERROR: You attempted to set an attribute beginning with 'repeating_' but did not include a Row ID or Attribute Name in repeating_meleeweaponseating_meleeweapons_0_equippedmeleewep VM4:3177 { setObj : {…} } setObj : clicked:repeating_meleeweapons_-O97DCPuY089kWmYLuHH_equippedmeleewep : 1 repeating_meleeweapons_-O97DCPuY089kWmYLuHH_magicmeleeweaponbonus : 3 repeating_meleeweapons_-O97DCPuY089kWmYLuHH_meleeabr : "d8" repeating_meleeweapons_-O97DCPuY089kWmYLuHH_meleedamage : "4" repeating_meleeweapons_-O97DCPuY089kWmYLuHH_meleeothereffects : "In the caster’s hand there appears a magic sword— as black as midnight, with a coruscating nimbus of green fire." repeating_meleeweapons_-O97DCPuY089kWmYLuHH_meleeweapon : "Sword" repeating_meleeweapons_-O97DCPuY089kWmYLuHH_meleeweaponname : "Vorpal Blade" [[Prototype]] : Object [[Prototype]] : Object