That looks essentially right, except for a typo (and the fact that it needs to be changed due to our other discussion). Regarding dual use of spell_ring, here's an (almost complete) example. The salient point is this: the actual attribute value of spell_ring is @{foo_air}. If you use it in a formula/roll, it will just plug in the actual value of attribute foo_air - on the other hand, in sheet worker scripts, the value will be read as "@{foo_air}", not "2". <input type="number" name="attr_foo_air" value="0" />
<input type="number" name="attr_foo_earth" value="0" />
<input type="number" name="attr_air_affinity" value="0" />
<input type="number" name="attr_earth_affinity" value="0" />
<fieldset class="repeating_spells">
<select name="attr_spell_ring">
<option value="0" selected>-</option>
<option value="@{foo_air}">Air</option>
<option value="@{foo_earth}">Earth</option>
</select><br>
<input type="hidden" name="attr_spell_affinity" value="0" />
</fieldset>
<script type="text/worker">
var elements = ['air', 'earth'],
elementAttrs = [...elements.map(s => `foo_${s}`), ...elements.map(s => `${s}_affinity`)],
getSpellAffinityByRing = function (prefix, setting, values) {
switch (values[`${prefix}_spell_ring`]) {
case '@{foo_air}':
setting[`${prefix}_spell_affinity`] = values.air_affinity;
break;
case '@{foo_earth}':
setting[`${prefix}_spell_affinity`] = values.earth_affinity;
break;
default:
setting[`${prefix}_spell_affinity`] = '0';
}
};
// Handle changes for foo_bla and bla_affinity: process all repeating sections
on(elementAttrs.map(s => `change:${s}`).join(' '), function () {
getSectionIDs('repeating_spells', function (idArray) {
let allAttrs = idArray.map(id => `repeating_spells_${id}_spell_ring`).concat(elementAttrs);
getAttrs(allAttrs, function (values) {
let setting = {};
idArray.forEach(id => getSpellAffinityByRing(`repeating_spells_${id}`, setting, values));
setAttrs(setting);
});
});
});
// Only do stuff within one row whenever spell_ring_type changes
on('change:repeating_spells:spell_ring', function (e) {
getAttrs([...elementAttrs, 'repeating_spells_spell_ring'], function (values) {
let setting = {};
getSpellAffinityByRing('repeating_spells', setting, values);
setAttrs(setting);
});
});
//Conversion code
var convertFromOldSheet = function () {
// Non-repeating attributes to rename
let conversionData = {
'airAffinity': 'air_affinity',
'earthAffinity': 'earth_affinity'
};
// Non-repeating attribute renaming
getAttrs(Object.keys(conversionData), function (values) {
let setting = {};
Object.keys(conversionData).forEach(function (oldAttr) {
if (values[oldAttr] != null) {
// set value of new attribute to value of old one
setting[conversionData[oldAttr]] = values[oldAttr];
// blank old attribute
setting[oldAttr] = '';
}
});
setAttrs(setting);
});
// spellRingConversion
getSectionIDs('repeating_spells', function (idArray) {
getAttrs(idArray.map(id => `repeating_spells_${id}_spellRing`), function (values) {
let setting = {};
idArray.forEach(function (id) {
switch (values[`repeating_spells_${id}_spellRing`]) {
case '@{Air}':
setting[`repeating_spells_${id}_spell_ring`] = '@{foo_air}';
break;
case '@{Earth}':
setting[`repeating_spells_${id}_spell_ring`] = '@{foo_earth}';
break;
default:
setting[`repeating_spells_${id}_spell_ring`] = '0';
}
});
setAttrs(setting);
});
});
};
on('sheet:opened', function () {
let currentVersion = 1.0;
getAttrs(['version'], function (v) {
if (!v.version) {
convertFromOldSheet();
};
setAttrs({
version: currentVersion
});
});
});
</script>