From bbc6e52d170141806f5511592fb6b18f39fe978d Mon Sep 17 00:00:00 2001 From: ChtiKenny Date: Tue, 8 Jun 2021 12:51:34 +0200 Subject: [PATCH] corrected indentation and added a separate js file for ease of reading --- ShadowbaneInquisition/Shadowbane.html | 2432 ++++++++++++------------- ShadowbaneInquisition/SheetWorker.js | 1271 +++++++++++++ 2 files changed, 2470 insertions(+), 1233 deletions(-) create mode 100644 ShadowbaneInquisition/SheetWorker.js diff --git a/ShadowbaneInquisition/Shadowbane.html b/ShadowbaneInquisition/Shadowbane.html index 0ecc02ec9e..a721a4599f 100644 --- a/ShadowbaneInquisition/Shadowbane.html +++ b/ShadowbaneInquisition/Shadowbane.html @@ -3968,1310 +3968,1276 @@ NOTE: replace worker by javascript for IDE functionality --> diff --git a/ShadowbaneInquisition/SheetWorker.js b/ShadowbaneInquisition/SheetWorker.js new file mode 100644 index 0000000000..36fdc181b7 --- /dev/null +++ b/ShadowbaneInquisition/SheetWorker.js @@ -0,0 +1,1271 @@ + // repeating sections data array + const BUFF = { + active: 'active_r', + ws: 'WS_mod_r', + bs: 'BS_mod_r', + str: 'STR_mod_r', + tou: 'TOU_mod_r', + agi: 'AGI_mod_r', + int: 'INT_mod_r', + per: 'PER_mod_r', + wp: 'WP_mod_r', + fel: 'FEL_mod_r', + inf: 'INF_mod_r' + }, + GEAR = { + carry: 'gear_carry_r', + name: 'gear_name_r', + craftsmanship: 'gear_crafts_r', + quantity: 'gear_quantity_r', + availability: 'gear_avail_r', + weight: 'gear_weight_r' + }, + R_WEAPON = { + name : 'R_weapon_name', + class : 'R_weapon_class', + range : 'R_weapon_range', + damage : 'R_weapon_dam-roll', + pen : 'R_weapon_pen', + type : 'R_weapon_type', + max : 'R_weapon_max', + min : 'R_weapon_min', + vengeful : 'R_weapon_vengeful', + accurate : 'R_weapon_accurate', + burst : 'R_weapon_burst', + auto : 'R_weapon_auto', + mag : 'R_weapon_mag', + mag_max : 'R_weapon_mag_max', + trained : 'R_weapon_trained', + mod1 : 'R_weapon_mod1', + reload : 'R_weapon_reload', + weight : 'R_weapon_weight', + domain : 'R_weapon_domain' + } + + + // ___________________________________________________________________________ + // __________________________Script for Ammo API______________________________ + // ___________________________________________________________________________ + on("sheet:opened change:repeating_rangedweapons:r_weapon_attack change:repeating_rangedweapons:r_weapon_burst change:repeating_rangedweapons:r_weapon_auto remove:repeating_rangedweapons change:repeating_vehiclerangedweapons:v_r_weapon_attack change:repeating_vehiclerangedweapons:v_r_weapon_burst change:repeating_vehiclerangedweapons:v_r_weapon_auto remove:repeating_vehiclerangedweapons", function() { + getSectionIDs("rangedweapons", function(idarray) { + // first get the attribute names for all rows in put in one array + const fieldnames = []; + idarray.forEach(id => fieldnames.push( + `repeating_rangedweapons_${id}_R_weapon_attack`, + `repeating_rangedweapons_${id}_R_weapon_burst`, + `repeating_rangedweapons_${id}_R_weapon_auto` + )); + getAttrs(fieldnames, values => { + // create a variable to hold all the attribute values you re going to create. + const attr = {}; + // now loop through the rows again + idarray.forEach(id => { + let row = 'repeating_rangedweapons_' + id; + let attack = +values[`${row}_R_weapon_attack`] || 0, + burst = +values[`${row}_R_weapon_burst`] || 0, + auto = +values[`${row}_R_weapon_auto`] || 0; + + let ammo = attack === -10 ? -auto : (attack === 0 ? -burst : -1); + + attr[`${row}_id`] = id; // id of the repeating element + attr[`${row}_ammo`] = ammo; // number of ammo to use + }); + setAttrs(attr); + }); + }); + getSectionIDs("vehiclerangedweapons", function(idarray) { + // first get the attribute names for all rows in put in one array + const fieldnames = []; + idarray.forEach(id => fieldnames.push( + `repeating_vehiclerangedweapons_${id}_V_R_weapon_attack`, + `repeating_vehiclerangedweapons_${id}_V_R_weapon_burst`, + `repeating_vehiclerangedweapons_${id}_V_R_weapon_auto` + )); + getAttrs(fieldnames, values => { + // create a variable to hold all the attribute values you re going to create. + const attr = {}; + // now loop through the rows again + idarray.forEach(id => { + let row = 'repeating_vehiclerangedweapons_' + id; + let attack = +values[`${row}_V_R_weapon_attack`] || 0, + burst = +values[`${row}_V_R_weapon_burst`] || 0, + auto = +values[`${row}_V_R_weapon_auto`] || 0; + + let ammo = attack === -10 ? -auto : (attack === 0 ? -burst : -1); + + attr[`${row}_id`] = id; // id of the repeating element + attr[`${row}_ammo`] = ammo; // number of ammo to use + }); + setAttrs(attr); + }); + }); + }); + + // ___________________________________________________________________________ + // __________________Skills unnatural bonus sheet worker______________________ + // ___________________________________________________________________________ + /** + * skillRoll description + * @param {string} skill - name of the skill + * @param {string} focus - short name of the characteristic + */ + const skillRoll = (skill, focus) => { + let attr = {}; + attr[`${skill}_focus`] = `@{${focus}Total}`; + attr[`${skill}_unnat`]=`@{${focus.toUpperCase()}_unnat}`; + return attr; + }; + let skills = [ + 'acrobatics','athletics','awareness','charm','command','commerce','deceive','dodge','inquiry', + 'interrogation','intimidate','logic','medicae','nav_surface','nav_stellar','nav_warp','op_aero','op_surface','op_void', + 'parry','psyniscience','scrutiny','security','sleight','stealth','survival','tech_use', + 'linguistics','common-lore','scholastic-lore','forbidden-lore','trade' + ]; + let repeatingSkills = ['skill','linguistics','common-lore','scholastic-lore','forbidden-lore','trade']; + on('sheet:opened ' + skills.map(skill => `change:${skill}_char change:${skill}_name`).join(' ') + repeatingSkills.map(skill => `change:repeating_${skill}:${skill}_r_char change:repeating_${skill}:${skill}_name`).join(' '), function () { + console.log('== UPDATING SKILLS =='); + getAttrs(skills.map( skill => `${skill}_char`), (values) => { + let attr = {}; + for (var [skill, focus] of Object.entries(values)) { + attr = {...attr, ...skillRoll(skill.replace('_char', ''), focus)}; + } + setAttrs(attr); + }); + repeatingSkills.forEach(field => { + var repSkills = []; + getSectionIDs(field, ids => { + ids.forEach( id => { + repSkills.push(`repeating_${field}_${id}_${field}_r_char`); + }); + getAttrs(repSkills, (values) => { + let attr = {}; + for (var [skill, focus] of Object.entries(values)) { + attr = {...attr, ...skillRoll(skill.replace('_char', ''), focus)}; + } + if (attr) setAttrs(attr); + console.table(values) + console.table(attr) + }); + }); + }); + console.log('== SKILLS UPDATED =='); + }); + + + // ___________________________________________________________________________ + // ____________________Movement and Weight sheet worker_______________________ + // ___________________________and Fatigue Pts_________________________________ + let fieldsMWF = [ + 'size', 'fatigue', 'carry', 'weight_total', + 'ws', 'ws_unnat', 'ws_advancement', 'ws_mod', + 'bs', 'bs_unnat', 'bs_advancement', 'bs_mod', + 'str', 'str_unnat', 'str_advancement', 'str_mod', + 'tou', 'tou_unnat', 'tou_advancement', 'tou_mod', + 'int', 'int_unnat', 'int_advancement', 'int_mod', + 'per', 'per_unnat', 'per_advancement', 'per_mod', + 'wp', 'wp_unnat', 'wp_advancement', 'wp_mod', + 'fel', 'fel_unnat', 'fel_advancement', 'fel_mod', + 'inf', 'inf_unnat', + 'agi', 'agi_unnat', 'agi_advancement', 'agi_mod', 'agi_mov_mod', 'armor_agi', 'armor_limit', + 'fatigue_ignore', 'psykana_class' + ]; + on('sheet:opened ' + fieldsMWF.map(field => 'change:' + field).join(' '), function(e) { + // console.log(e); + getAttrs(fieldsMWF, function(values) { + // SIZE + var size = parseInt(values['size'], 10) || 0; + // FATIGUE + var fatigue = parseInt(values['fatigue'], 10) || 0; + var fatigueIgnore = parseInt(values['fatigue_ignore'], 10) || 0; + if (fatigueIgnore) fatigue = 0; + // CARRY + var carry = parseInt(values['carry'], 10) || 0; + var weight_total = parseInt(values['weight_total'], 10) || 0; + // STATS + function Stat(stat) { + this.base = parseInt(values[`${stat}`], 10) || 0 + this.modifier = parseInt(values[`${stat}_mod`], 10) || 0 + this.advancement = parseInt(values[`${stat}_advancement`], 10) || 0 + this.unnat = parseInt(values[`${stat}_unnat`], 10) || 0 + this.total = this.base + this.modifier + this.advancement + this.bonus = () => Math.floor(this.total / 10 + this.unnat) + } + // WS + var ws = new Stat('ws') + if (ws.bonus() < fatigue) ws.total = Math.ceil(ws.total / 2) + // BS + var bs = new Stat('bs') + if (bs.bonus() < fatigue) bs.total = Math.ceil(bs.total / 2) + // STR + var str = new Stat('str') + if (str.bonus() < fatigue) str.total = Math.ceil(str.total / 2) + // TOU + var tou = new Stat('tou') + if (tou.bonus() < fatigue) tou.total = Math.ceil(tou.total / 2) + // AGI + var agi = new Stat('agi') + agi_mov_mod = parseInt(values['agi_mov_mod'], 10) || 0, + armor_agi = parseInt(values['armor_agi'], 10) || 0, + armor_limit = parseInt(values['armor_limit'], 10) || 0; + if (weight_total > carry) agi.total -= 10 + if (armor_limit) agi.total = (agi.total > armor_agi ) ? armor_agi : agi.total + if (agi.bonus() < fatigue) agi.total = Math.ceil(agi.total / 2) + // INT + var int = new Stat('int') + if (int.bonus() < fatigue) int.total = Math.ceil(int.total / 2) + // PER + var per = new Stat('per') + if (per.bonus() < fatigue) per.total = Math.ceil(per.total / 2) + // WP + var wp = new Stat('wp') + if (wp.bonus() < fatigue) wp.total = Math.ceil(wp.total / 2) + // FEL + var fel = new Stat('fel') + // Blank FEL halfing + var blank = values['psykana_class'] + if (blank === '-1') fel.total = Math.ceil(fel.total / 2); + if (fel.bonus() < fatigue) fel.total = Math.ceil(fel.total / 2) + // INF + var inf = new Stat('inf') + if (inf.bonus() < fatigue) inf.total = Math.ceil(inf.total / 2) + + var move_mod = agi.bonus() + size + agi_mov_mod; + var carry_mod = str.bonus() + tou.bonus(); + var carry_calc; + + // 40k system does their carry weight off a sheet-table + + switch (carry_mod) { + case 1: carry_calc = 2.25; break; + case 2: carry_calc = 4.5; break; + case 3: carry_calc = 9; break; + case 4: carry_calc = 18; break; + case 5: carry_calc = 27; break; + case 6: carry_calc = 36; break; + case 7: carry_calc = 45; break; + case 8: carry_calc = 56; break; + case 9: carry_calc = 67; break; + case 10: carry_calc = 78; break; + case 11: carry_calc = 90; break; + case 12: carry_calc = 112; break; + case 13: carry_calc = 225; break; + case 14: carry_calc = 337; break; + case 15: carry_calc = 450; break; + case 16: carry_calc = 675; break; + case 17: carry_calc = 900; break; + case 18: carry_calc = 1350; break; + case 19: carry_calc = 1800; break; + case 20: carry_calc = 2250; break; + } + + // normal, no unnatural + setAttrs({ + half_move: (move_mod), + full_move: (move_mod * 2), + charge_move: (move_mod * 3), + run_move: (move_mod * 6), + carry: (carry_calc * 1), //taking out the * 1 seems to cause attr_carry to freeze when carry_mod is set to 1 or 0 + lift: (carry_calc * 2), + push: (carry_calc * 4), + bsTotal: (bs.total), + bsB: (bs.bonus()), + wsTotal: (ws.total), + wsB: (ws.bonus()), + strTotal: (str.total), + strB: (str.bonus()), + touTotal: (tou.total), + touB: (tou.bonus()), + agiTotal: (agi.total), + agiB: (agi.bonus()), + intTotal: (int.total), + intB: (int.bonus()), + perTotal: (per.total), + perB: (per.bonus()), + wpTotal: (wp.total), + wpB: (wp.bonus()), + felTotal: (fel.total), + felB: (fel.bonus()), + infTotal: (inf.total), + infB: (inf.bonus()), + }); + + // 0 mod movement override + if (move_mod <= 0) { + setAttrs({ + half_move: (0.5), + full_move: (1), + charge_move: (2), + run_move: (3) + }); + } + + // 0 mod carry override + if (carry_mod <=0) { + setAttrs({ + carry: (0.9), + lift: (2.25), + push: (4.5) + }); + } + + }); + }); + + + + // ___________________________________________________________________________ + // ________________________Fatigue and Armor sheet worker_____________________ + // ___________________________________________________________________________ + let fieldsFA = [ + 'fatigue_mod', + 'tou', 'tou_unnat', 'tou_advancement', 'tou_mod', + 'wp', 'wp_unnat', 'wp_advancement', + 'armor_head', 'armor_arm_right', 'armor_body', 'armor_arm_left', 'armor_leg_right', 'armor_leg_left' + ]; + on('sheet:opened ' + fieldsFA.map(field => 'change:' + field).join(' '), function() { + getAttrs(fieldsFA, function(values) { + var fatigue_mod = parseInt(values['fatigue_mod'], 10) || 0; + + var toughness = parseInt(values['tou'], 10) || 0; + var toughness_unnat = parseInt(values['tou_unnat'], 10) || 0; + var toughness_advancement = parseInt(values['tou_advancement'], 10) || 0; + var toughness_modifier = parseInt(values['tou_mod'], 10) || 0; + var toughness_bonus = Math.floor((toughness + toughness_advancement + toughness_modifier) / 10 + toughness_unnat); + var toughness_mod = Math.floor((toughness + toughness_advancement) / 10 + toughness_unnat); + + var willpower = parseInt(values['wp'], 10) || 0; + var willpower_unnat = parseInt(values['wp_unnat'], 10) || 0; + var willpower_advancement = parseInt(values['wp_advancement'], 10) || 0; + var willpower_mod = Math.floor((willpower + willpower_advancement) / 10 + willpower_unnat); + + var armor_head = parseInt(values['armor_head'], 10) || 0; + var armor_arm_right = parseInt(values['armor_arm_right'], 10) || 0; + var armor_body = parseInt(values['armor_body'], 10) || 0; + var armor_arm_left = parseInt(values['armor_arm_left'], 10) || 0; + var armor_leg_right = parseInt(values['armor_leg_right'], 10) || 0; + var armor_leg_left = parseInt(values['armor_leg_left'], 10) || 0; + + // normal, no modifiers ___________________________________________________ + setAttrs({ + soak_head: (armor_head + toughness_bonus), + soak_arm_right: (armor_arm_right + toughness_bonus), + soak_body: (armor_body + toughness_bonus), + soak_arm_left: (armor_arm_left + toughness_bonus), + soak_leg_right: (armor_leg_right + toughness_bonus), + soak_leg_left: (armor_leg_left + toughness_bonus), + fatigue_max: (toughness_mod + willpower_mod + fatigue_mod) + }); + + }); + }); + + + + // ___________________________________________________________________________ + // ____________________Tabs sheet worker______________________________________ + // ___________________________________________________________________________ + const buttonlist = ['core','equipment','advancements','journal','vehicle','psykana','settings']; + buttonlist.forEach(button => { + on(`clicked:${button}`, function() { + setAttrs({ + sheetTab: button + }); + }); + }); + + // ___________________________________________________________________________ + // ____________________Inventory Tabs sheet worker____________________________ + // ___________________________________________________________________________ + const buttonListIventory = ['all', 'weapon', 'armour', 'gear', 'tool', 'consumables', 'ammo', 'cyberntic', 'other']; + buttonListIventory.forEach(button => { + on(`clicked:inv_${button}`, function() { + setAttrs({ + equipmentTab: button + }); + }); + }); + + + // ___________________________________________________________________________ + // ____________________insanity/corruption sheet worker_______________________ + // ___________________________________________________________________________ + on('sheet:opened change:insanity_pts change:corruption_pts', function() { + getAttrs(['insanity_pts', 'corruption_pts'], function(values) { + var insanity_pts = parseInt(values['insanity_pts'], 0) || 0; + var corruption_pts = parseInt(values['corruption_pts'], 10) || 0; + + function insanity (points) { + if (points <= 9) return ('Stable') + if (points <= 39) return ('Unsettled') + if (points <= 59) return ('Disturbed') + if (points <= 79) return ('Unhinged') + if (points <= 99) return ('Deranged') + return ('Terminally Insane') + } + + function corruption (points) { + if (points <= 9) return ('Pure') + if (points <= 39) return ('Tainted') + if (points <= 59) return ('Soiled') + if (points <= 79) return ('Debased') + if (points <= 99) return ('Profane') + return ('Damned') + } + setAttrs({ + insanity_degree: (insanity(insanity_pts)), + corruption_degree: (corruption(corruption_pts)) + }) + + }); + }); + + + + // ___________________________________________________________________________ + // _______________________psychic info sheet worker___________________________ + // ___________________________________________________________________________ + + const PSY_RANK = {} + + let fieldsPsy = ['psykana_class', 'psykana_limit', 'psy_push', 'psy_rating','psykana_sustain','psykana_sustain_count']; + on('sheet:opened ' + fieldsPsy.map(field => 'change:' + field).join(' '), function() { + getAttrs(fieldsPsy, function(values) { + var psykana_class = parseInt(values['psykana_class'])||0; + var psykana_limit = parseInt(values['psykana_limit'])||0; + var psy_push = parseInt(values['psy_push'])||0; + var psy_rating = parseInt(values['psy_rating'], 10) || 0; + var psykana_sustain = parseInt(values['psykana_sustain'], 10) || 0; + var psykana_sustain_count = parseInt(values['psykana_sustain_count'], 10) || 0; + var psykana_limit_factor = 0; + var push_addend_epr = 0; + var sustain_count_addend = 0; + var unfettered_addend = 0; + var push_addend_pp = 0; + var sustain_addend = 0; + + // psy rating calc + switch (psykana_limit) { + case 0: + psykana_limit_factor = 0.5; + setAttrs({ + psy_roll: ('cf>96') + }); + break; + case 1: + psykana_limit_factor = 1; + setAttrs({ + psy_roll: ('cf11cf22cf33cf44cf55cf66cf77cf88cf99cf100') + }); + break; + case 2: + psykana_limit_factor = 1; + push_addend_epr = psy_push; + if (psykana_class == 0) { + setAttrs({ + psy_roll: ('cs1cs11cs22cs33cs44cs55cs66cs77cs88cs99cs100cf>0') + //psy_roll: ('cf>0') + }); + } else { + setAttrs({ + psy_roll: ('cf>0') + }); + } + break; + } + + if (psykana_sustain == -5) { + sustain_count_addend = psykana_sustain_count; + } + var epr = Math.ceil(psy_rating * psykana_limit_factor) + push_addend_epr; + + // phenomena calc + if (psykana_class == 2 && psykana_limit == 1) { + unfettered_addend = 10; + } + if (psykana_class == 0 && psykana_limit == 2) { + push_addend_pp = 10; + } + if (psykana_class == 1 && psykana_limit == 2) { + push_addend_pp = 5 * psy_push; + } + if (psykana_class == 2 && psykana_limit == 2) { + push_addend_pp = 10 * psy_push; + } + if (psykana_sustain == -5) { + sustain_addend = 5 * sustain_count_addend; + } + var pp = unfettered_addend + push_addend_pp + sustain_addend; + + //output + setAttrs({ + effective_psy_rating: epr, + psykana_phenomena: pp + }); + }); + }); + + + + // ___________________________________________________________________________ + // ____________________gear cost/weight sheet worker__________________________ + // ___________________________________________________________________________ + on('change:repeating_rangedweapons remove:repeating_rangedweapons change:repeating_meleeweapons remove:repeating_meleeweapons', function() { + repeatingWeight("R_weapon_weight_t","rangedweapons",[['weight',"R_weapon_weight"],['carry',"R_weapon_carry"]]), + repeatingWeight("M_weapon_weight_t","meleeweapons",[['weight',"M_weapon_weight"],['carry',"M_weapon_carry"]]); + }); + + on('change:M_weapon_weight_t change:R_weapon_weight_t change:gear_carry change:gear_weight change:gear_quantity change:repeating_gear remove:repeating_gear', () => { + getSectionIDs(`repeating_gear`, idArray => { + const fieldset_weight = []; + const fieldset_quantity = []; + const fieldset_carry = []; + idArray.forEach(id => fieldset_weight.push (`repeating_gear_${id}_gear_weight_r`)); + idArray.forEach(id => fieldset_quantity.push (`repeating_gear_${id}_gear_quantity_r`)); + idArray.forEach(id => fieldset_carry.push (`repeating_gear_${id}_gear_carry_r`)); + getAttrs(['M_weapon_weight_t','R_weapon_weight_t','weight_total', 'gear_carry', 'gear_weight', 'gear_quantity', ...fieldset_weight, ...fieldset_quantity, ...fieldset_carry], v => { + const getValue = (id, field) => parseFloat(v[`repeating_gear_${id}_${field}`]) || 0 + const weight_base = parseFloat(v.gear_weight) * parseFloat(v.gear_quantity) * parseFloat(v.gear_carry) + const weight_repeating = idArray.reduce((total, id) => total + (getValue(id, 'gear_weight_r') * getValue(id, 'gear_quantity_r') * getValue(id, 'gear_carry_r')), 0) + const weapon_weight = parseFloat(v.M_weapon_weight_t) + parseFloat(v.R_weapon_weight_t) + setAttrs({ + weight_total: weight_base + weight_repeating + weapon_weight, + }); + }); + }); + }); + + // ___________________________________________________________________________ + // ____________________Advancement XP sheet worker_______________________________ + // ___________________________________________________________________________ + on('change:xp_total change:advancement_costL change:advancement_costR change:repeating_advancements remove:repeating_advancements', () => { + // get section IDs because of operation both inside and outside of fieldset + getSectionIDs(`repeating_advancements`, idArray => { + const fieldnames = []; + idArray.forEach(id => fieldnames.push ( + `repeating_advancements_${id}_advancement_costL_r`, + `repeating_advancements_${id}_advancement_costR_r` + )); + // spread operator to get every array value + getAttrs(['xp_total', 'advancement_costL', 'advancement_costR', ...fieldnames], v => { + const getValue = (id, field) => parseFloat(v[`repeating_advancements_${id}_${field}`]) || 0 + const cost = parseFloat(v.gear_cost) || 0 + const left = parseFloat(v.advancement_costL) || 0 + const right = parseFloat(v.advancement_costR) || 0 + const left_r = idArray.reduce((total, id) => total + getValue(id,'advancement_costL_r'),0) + const right_r = idArray.reduce((total, id) => total + getValue(id,'advancement_costR_r'),0) + const spent = left + right + left_r + right_r + const total = parseFloat(v.xp_total) || 0 + setAttrs({ + xp_spent: spent, + xp_current: total - spent + }); + }); + }); + }); + + + + // ___________________________________________________________________________ + // __________________________General sum sheet worker_________________________ + // ___________________________________________________________________________ + /** + * [repeatingWeight description] + * @param {[type]} destination [description] + * @param {[type]} section [description] + * @param {[type]} fields [description] + */ + const repeatingWeight = (destination, section, fields) => { + getSectionObjects(section, fields, items => { + const sumTotal = items.filter(item => item.carry !== '0').reduce((total, item) => total + parseFloat(item.weight),0); + setAttrs({[destination]: sumTotal}); + }) + } + + // ___________________________________________________________________________ + // _________________________ weapon damage primitive _________________________ + // ___________________________________________________________________________ + /** + * calculate real damage roll + * @param {string} source row id of the weapon + */ + const calcDmg = function (sources, fields) { + var redice = /^(\d+)?(d\d+)(.*)?/; + + getAttrs(fields, v => { + let attr = {}; + sources.forEach( source => { + // to avoid retyping long strings because i'm lazy + var dam = source + 'weapon_dam-roll', + ven = source + 'weapon_vengeful', // crit + min = source + 'weapon_min', // proven + max = source + 'weapon_max', // primitive + set = source + 'weapon_setting'; // overcharge/load / maximal + + let dmg = redice.exec(v[dam]); + ven = parseInt(v[ven], 10) || 0, + min = parseInt(v[min], 10) || 0, + max = parseInt(v[max], 10) || 0, + set = parseInt(v[set], 10) || 0; + + if (!dmg) { + console.log('no damage found'); + attr[`${source}weapon_real_dmg`] = v[dam]; + } else { + let dicenum = parseInt(dmg[1], 10) || 1, + dicetype = dmg[2], + mod = dmg[3]; + + let damTotal = '{'; + if (set === 3) dicenum ++; + + for (var i = 0; i < dicenum; i++) { + if (i) damTotal += ', ' + if (min > 0) damTotal += '{'; + if (max > 0) damTotal += '{'; + damTotal += (dicetype == 'd5') ? 'ceil(1d10/2)' : '1d10'; + if (ven > 0) damTotal += 'cs>' + ven; + if (min > 0) damTotal += ', {' + min + '}}kh1'; + if (max > 0) damTotal += ', {' + max + '}}kl1'; + } + damTotal += '}'; + if (mod) damTotal += mod; + if (set === 2) damTotal += '+1'; + if (set === 4) { + damTotal += '+2'; + attr[`${source}weapon_pen2`] = 2; + } else { + attr[`${source}weapon_pen2`] = 0; + } + attr[`${source}weapon_real_dmg`] = damTotal; + } + }); + setAttrs(attr); + }); + }; + + let fieldsDMG = [ + 'vehiclerangedweapons:V_R_weapon_dam-roll', 'vehiclerangedweapons:V_R_weapon_vengeful', 'vehiclerangedweapons:V_R_weapon_min', 'vehiclerangedweapons:V_R_weapon_max', 'vehiclerangedweapons:V_R_weapon_setting', + 'rangedweapons:R_weapon_dam-roll', 'rangedweapons:R_weapon_vengeful', 'rangedweapons:R_weapon_min', 'rangedweapons:R_weapon_max', 'rangedweapons:R_weapon_setting', + 'vehiclemeleeweapons:V_M_weapon_dam-roll', 'vehiclemeleeweapons:V_M_weapon_vengeful', 'vehiclemeleeweapons:V_M_weapon_min', 'vehiclemeleeweapons:V_M_weapon_max', + 'meleeweapons:M_weapon_dam-roll', 'meleeweapons:M_weapon_vengeful', 'meleeweapons:M_weapon_min', 'meleeweapons:M_weapon_max', + ]; + on('sheet:opened ' + fieldsDMG.map(field => 'change:repeating_' + field).join(' '), () => { + getSectionIDs('rangedweapons', (idArray) => { + let sources = []; + let fieldnames = []; + idArray.forEach( id => { + sources.push(`repeating_rangedweapons_${id}_R_`); + fieldnames.push( + `repeating_rangedweapons_${id}_R_weapon_dam-roll`, + `repeating_rangedweapons_${id}_R_weapon_vengeful`, + `repeating_rangedweapons_${id}_R_weapon_min`, + `repeating_rangedweapons_${id}_R_weapon_max`, + `repeating_rangedweapons_${id}_R_weapon_setting` + ); + }); + calcDmg(sources, fieldnames); + }); + getSectionIDs('meleeweapons', (idArray) => { + let sources = []; + let fieldnames = []; + idArray.forEach( id => { + sources.push(`repeating_meleeweapons_${id}_M_`); + fieldnames.push( + `repeating_meleeweapons_${id}_M_weapon_dam-roll`, + `repeating_meleeweapons_${id}_M_weapon_vengeful`, + `repeating_meleeweapons_${id}_M_weapon_min`, + `repeating_meleeweapons_${id}_M_weapon_max` + ); + }); + calcDmg(sources, fieldnames); + }); + getSectionIDs('vehiclerangedweapons', (idArray) => { + let sources = []; + let fieldnames = []; + idArray.forEach( id => { + sources.push(`repeating_vehiclerangedweapons_${id}_V_R_`); + fieldnames.push( + `repeating_vehiclerangedweapons_${id}_V_R_weapon_dam-roll`, + `repeating_vehiclerangedweapons_${id}_V_R_weapon_vengeful`, + `repeating_vehiclerangedweapons_${id}_V_R_weapon_min`, + `repeating_vehiclerangedweapons_${id}_V_R_weapon_max`, + `repeating_vehiclerangedweapons_${id}_V_R_weapon_setting` + ); + }); + calcDmg(sources, fieldnames); + }); + getSectionIDs('vehiclemeleeweapons', (idArray) => { + let sources = []; + let fieldnames = []; + idArray.forEach( id => { + sources.push(`repeating_vehiclemeleeweapons_${id}_V_M_`); + fieldnames.push( + `repeating_vehiclemeleeweapons_${id}_V_M_weapon_dam-roll`, + `repeating_vehiclemeleeweapons_${id}_V_M_weapon_vengeful`, + `repeating_vehiclemeleeweapons_${id}_V_M_weapon_min`, + `repeating_vehiclemeleeweapons_${id}_V_M_weapon_max` + ); + }); + calcDmg(sources, fieldnames); + }); + console.log('DAMAGES UPDATED'); + }); + + // ___________________________________________________________________________ + // __________________________ get repeating objects __________________________ + // ___________________________________________________________________________ + // TODO: add class suport + /** + * get the attributes from a repeating section and pass them in an array of objects + * @param {String} section - name of the repeating section + * @param {Array} fields - list of the attributes + * @param {Function} callback - function to pass the array of objects + */ + const getSectionObjects = function (section, fields, callback) { + if (!Array.isArray(fields)) fields = [fields]; + getSectionIDs(`repeating_${section}`, idArray => { + const attrArray = idArray.reduce( (m,id) => [...m, ...(Object.values(fields).map(field => `repeating_${section}_${id}_${field}`))],[]); + getAttrs(attrArray, v => { + const objects = []; + idArray.forEach(id => { + let obj = { _id : id, _source: `repeating_${section}_${id}` }; + for (var property in fields) { + obj[property] = v[`repeating_${section}_${id}_${fields[property]}`] + } + objects.push(obj) + }); + callback(objects); + }); + }); + } + + // ___________________________________________________________________________ + // ________________________________ Importer _________________________________ + // ___________________________________________________________________________ + on('clicked:import_clear', () => { + setAttrs({ + import_value: '' + }); + }); + on('clicked:import', () => { + getAttrs(['import_value'], (v) => { + try { + var data = JSON.parse(v.import_value); + } catch(e) { + setAttrs({import_value: 'ERROR: verify if you have copied the totality of the Export'}); return console.log(e); + } + console.log('Importing Character'); + var attributes = {} + + // emptying the repeating sections + const sectionList = [ + 'conditions', + 'skill', + 'linguistics', + 'common-lore', + 'scholastic-lore', + 'forbidden-lore', + 'trade', + 'abilities', + 'traits', + 'rangedweapons', + 'meleeweapons', + 'gear', + 'cybernetics', + 'aptitudes', + 'advancements', + 'disorders', + 'mutations', + 'objectives', + 'notes', + 'vehicles', + 'vehiclerangedweapons', + 'vehiclemeleeweapons', + 'minormanifestation', + 'psynotes', + 'psychicabilities' + ]; + sectionList.forEach( section => { + getSectionIDs(`repeating_${section}`, idArray => { + idArray.forEach(id => removeRepeatingRow(`repeating_${section}_${id}`)) + }) + }) + + // info Block + attributes = {...attributes, ...mapInfo(data)} + + // STATS + attributes = {...attributes, ...mapStat('WS', data?.weaponSkill)}; + attributes = {...attributes, ...mapStat('BS', data?.ballisticSkill)}; + attributes = {...attributes, ...mapStat('STR', data?.strenght)}; + attributes = {...attributes, ...mapStat('TOU', data?.toughness)}; + attributes = {...attributes, ...mapStat('AGI', data?.agility)}; + attributes = {...attributes, ...mapStat('INT', data?.intelligence)}; + attributes = {...attributes, ...mapStat('PER', data?.perception)}; + attributes = {...attributes, ...mapStat('WP', data?.willpower)}; + attributes = {...attributes, ...mapStat('FEL', data?.fellowship)}; + attributes = {...attributes, ...mapStat('INF', data?.influence)}; + + // WOUNDS, FATE, FATIGUE, FORCEFIELD + attributes = {...attributes, ...mapWounds(data?.wounds)}; + attributes = {...attributes, ...mapFate(data?.fate)}; + attributes = {...attributes, ...mapFatigue(data?.fatigue)}; + attributes = {...attributes, ...mapForceField(data?.forcefield)}; + + // CONDITIONS + data?.conditions?.forEach((condition) => { + attributes = {...attributes, ...mapCondition(condition)}; + }); + + // SKILLS, REPEATING SKILLS + data?.skills?.forEach(skill => { + attributes = {...attributes, ...mapSkill(skill)}; + }); + data?.lores?.common?.forEach(skill => { + attributes = {...attributes, ...mapRepeatingSkill(skill, 'common-lore')}; + }); + data?.lores?.scholastic?.forEach(skill => { + attributes = {...attributes, ...mapRepeatingSkill(skill, 'scholastic-lore')}; + }); + data?.lores?.forbidden?.forEach(skill => { + attributes = {...attributes, ...mapRepeatingSkill(skill, 'forbidden-lore')}; + }); + data?.linguistics?.forEach(skill => { + attributes = {...attributes, ...mapRepeatingSkill(skill, 'linguistics')}; + }); + data?.trades?.forEach(skill => { + attributes = {...attributes, ...mapRepeatingSkill(skill, 'trade')}; + }); + + // TALENTS, TRAITS + data?.abilities?.forEach(ability => { + attributes = {...attributes, ...mapAbility(ability, 'abilities')}; + }); + data?.traits?.forEach(trait => { + attributes = {...attributes, ...mapTrait(trait)}; + }); + + // INVENTORY + data?.inventory?.weapons?.ranged?.forEach( weapon => { + attributes = {...attributes, ...mapRangedWeapon(weapon)}; + }); + data?.inventory?.weapons?.melee?.forEach( weapon => { + attributes = {...attributes, ...mapMeleeWeapon(weapon)}; + }); + data?.inventory?.gears?.forEach( gear => { + attributes = {...attributes, ...mapGear(gear)}; + }); + // data?.inventory?.tools?.forEach( tool => { + // attributes = {...attributes, ...mapTool(tool)}; + // }); + // data?.inventory?.consumables?.forEach( drug => { + // attributes = {...attributes, ...mapDrug(drug)}; + // }); + attributes = {...attributes, ...mapOldArmor(data?.inventory?.armor)}; + // data?.inventory?.armors?.forEach( armor => { + // attributes = {...attributes, ...mapArmor(armor)}; + // }); + // data?.inventory?.ammos?.forEach( ammo => { + // attributes = {...attributes, ...mapAmmo(ammo)}; + // }); + data?.inventory?.cybernetics?.forEach( cybernetic => { + attributes = {...attributes, ...mapCybernetic(cybernetic)}; + }); + + // ADVANCEMENTS + attributes = {...attributes, ...mapAptitudes(data?.advancements?.aptitudes)}; + attributes = {...attributes, ...mapAdvance(data?.advancements?.advances)}; + for (var training in data?.advancements?.training) { + attributes[`weapons_training_${training}`] = data?.advancements?.training[training]; + } + + // INSANITY, CORRUPTION + attributes[`insanity_pts`] = data?.insanity?.points; + data?.insanity?.disorders?.forEach( disorder => { + attributes = {...attributes, ...mapDisorder(disorder)}; + }) + attributes[`corruption_pts`] = data?.corruption?.points; + data?.corruption?.mutations?.forEach( mutation => { + attributes = {...attributes, ...mapMutation(mutation)}; + }) + + // OBJECTIVES, NOTES + data?.objectives?.forEach( objective => { + attributes = {...attributes, ...mapObjective(objective)}; + }); + data?.notes?.forEach( note => { + attributes = {...attributes, ...mapNote(note)}; + }); + + // VEHICLES + data?.vehicles?.list?.forEach( vehicle => { + attributes = {...attributes, ...mapVehicle(vehicle)}; + }); + data?.vehicles?.weapons?.ranged?.forEach( weapon => { + attributes = {...attributes, ...mapRangedWeapon(weapon, true)}; + }); + data?.vehicles?.weapons?.melee?.forEach( weapon => { + attributes = {...attributes, ...mapMeleeWeapon(weapon, true)}; + }); + + // PSYKANA + attributes = {...attributes, ...mapPsykana(data?.psykana)}; + data?.psykana?.minor?.forEach( minor => { + attributes = {...attributes, ...mapPsyMinor(minor)} + }) + data?.psykana?.notes?.forEach( note => { + attributes = {...attributes, ...mapPsyNote(note)} + }) + data?.psykana?.powers?.forEach( power => { + attributes = {...attributes, ...mapPsyPower(power)} + }) + + console.log('setting attributes'); + attributes.import_value = 'Success: Character Imported Successfully\n\nRemember to add the token manually'; + setAttrs(attributes, true); + }) + }) + + // Update to new version + let oldVariables = [ + 'gear_carry','gear_name','gear_crafts', 'gear_quantity','gear_avail','gear_weight','gear_pg#','gear_desc' + ] + on('sheet:opened', () => { + getAttrs(oldVariables, values => { + var attributes = {} + let gear = {carry: values['gear_carry'], name: values['gear_name'], craft: values['gear_crafts'], quantity: values['gear_quantity'], avail: values['gear_avail'], weight: values['gear_weight'], desc: values['gear_desc']} + if (!gear.name == '') attributes = {...attributes, ...mapGear(gear)} + console.table(gear) + console.log(attributes) + }) + }) + + // functions + const mapInfo = (data) => { + let attr = {}; + attr['character_name'] = data.name || ''; + attr['Homeworld'] = data.homeworld || ''; + attr['Background'] = data.background || ''; + attr['Role'] = data.role || ''; + attr['EliteAdvances'] = data.eliteAdvances || ''; + attr['Notes'] = data.note || ''; + attr['Player'] = data.player || ''; + attr['appearance'] = data.appearance || ''; + attr['Quirks'] = data.quirks || ''; + attr['Divination'] = data.divination || ''; + attr['Superstition'] = data.superstition || ''; + attr['size'] = data.size || ''; + attr['xp_total'] = data.xp || ''; + attr['agi_mov_mod'] = data.movementModifier || ''; + return attr; + }; + const mapStat = (statName, stat) => { + let attr = {}; + attr[`${statName}`] = stat.base || 0; + attr[`${statName}_advancement`] = stat.advancement || 0; + attr[`${statName}_mod`] = stat.modifier || 0; + attr[`${statName}_unnat`] = stat.unnatural || 0; + return attr; + }; + const mapWounds = (wounds) => { + let attr = {}; + attr['wounds'] = wounds.current || ''; + attr['wounds_max'] = wounds.max || ''; + attr['head'] = wounds.critical?.head || ''; + attr['body'] = wounds.critical?.body || ''; + attr['arm_left'] = wounds.critical?.arm_left || ''; + attr['arm_right'] = wounds.critical?.arm_right || ''; + attr['leg_left'] = wounds.critical?.leg_left || ''; + attr['leg_right'] = wounds.critical?.leg_right || ''; + return attr; + }; + const mapFate = (fate) => { + let attr = {}; + attr['fate'] = fate.current || ''; + attr['fate_max'] = fate.max || ''; + attr['settings_fate'] = fate.setting || ''; + return attr; + }; + const mapFatigue = (fatigue) => { + let attr = {}; + attr['fatigue'] = fatigue.current || ''; + attr['fatigue_mod'] = fatigue.modifier || ''; + return attr; + }; + const mapForceField = (forcefield) => { + let attr = {}; + attr['forcefield_name'] = forcefield.name || ''; + attr['forcefield_protection'] = forcefield.protection || ''; + attr['forcefield_overload'] = forcefield.overload || ''; + return attr; + }; + const mapCondition = (condition) => { + if (!condition) return ; + let attr = {}, + section = 'condition', + id = generateRowID(); + attr[`repeating_${section}_${id}_condition_r`] = condition.name || ''; + attr[`repeating_${section}_${id}_condition_desc_r`] = condition.description || ''; + return attr; + }; + const mapSkill = (skill) => { + if (!skill) return ; + let attr = {} + attr[`mod2_${skill.name}`] = skill.modifier || 0; + attr[`mod3_${skill.name}`] = skill.level || 0; + return attr; + }; + const mapRepeatingSkill = (skill, section) => { + if (!skill) return ; + let attr = {}, + id = generateRowID(); + attr[`repeating_${section}_${id}_${section}_name`] = skill.name || ''; + attr[`repeating_${section}_${id}_${section}_r_mod2`] = skill.modifier || ''; + attr[`repeating_${section}_${id}_${section}_r_mod3`] = skill.level || ''; + return attr; + }; + const mapAbility = (ability) => { + if (!ability) return ; + let attr = {}, + section = 'abilities', + id = generateRowID(); + attr[`repeating_${section}_${id}_ability_r`] = ability.name || ''; + attr[`repeating_${section}_${id}_ability_desc_r`] = ability.description || ''; + return attr; + }; + const mapTrait = (trait) => { + if (!trait) return ; + let attr = {}, + section = 'traits', + id = generateRowID(); + attr[`repeating_${section}_${id}_trait_r`] = trait.name || ''; + attr[`repeating_${section}_${id}_trait_desc_r`] = trait.description || ''; + return attr; + } + const mapAptitudes = (aptitudes) => { + var attr = {}; + var section = 'aptitudes'; + for (var i = 0; i < aptitudes?.length; i += 3) { + let id = generateRowID(); + attr[`repeating_${section}_${id}_aptitude_nameL_r`] = aptitudes[i] || ''; + attr[`repeating_${section}_${id}_aptitude_nameM_r`] = aptitudes[i+1] || ''; + attr[`repeating_${section}_${id}_aptitude_nameR_r`] = aptitudes[i+2] || ''; + } + return attr; + }; + const mapRangedWeapon = (weapon, vehicle) => { + if (!weapon) return ; + let attr = {}, + section = (vehicle) ? 'vehiclerangedweapons' : 'rangedweapons', + id = generateRowID(); + if (vehicle) id += '_V'; + attr[`repeating_${section}_${id}_R_weapon_name`] = weapon.name || ''; + attr[`repeating_${section}_${id}_R_weapon_class`] = weapon.class || ''; + attr[`repeating_${section}_${id}_R_weapon_range`] = weapon.range || ''; + attr[`repeating_${section}_${id}_R_weapon_dam-roll`] = weapon.damage || ''; + attr[`repeating_${section}_${id}_R_weapon_pen`] = weapon.pen || ''; + attr[`repeating_${section}_${id}_R_weapon_type`] = weapon.type || ''; + attr[`repeating_${section}_${id}_R_weapon_max`] = weapon.max || ''; + attr[`repeating_${section}_${id}_R_weapon_min`] = weapon.min || ''; + attr[`repeating_${section}_${id}_R_weapon_vengeful`] = weapon.vengeful || ''; + attr[`repeating_${section}_${id}_R_weapon_accurate`] = weapon.accurate || ''; + attr[`repeating_${section}_${id}_R_weapon_burst`] = weapon.burst || ''; + attr[`repeating_${section}_${id}_R_weapon_auto`] = weapon.auto || ''; + attr[`repeating_${section}_${id}_R_weapon_mag`] = weapon.mag || ''; + attr[`repeating_${section}_${id}_R_weapon_mag_max`] = weapon.mag_max || ''; + attr[`repeating_${section}_${id}_R_weapon_trained`] = weapon.trained || ''; + attr[`repeating_${section}_${id}_R_weapon_mod1`] = weapon.mod1 || ''; + attr[`repeating_${section}_${id}_R_weapon_reload`] = weapon.reload || ''; + attr[`repeating_${section}_${id}_R_weapon_weight`] = weapon.weight || ''; + attr[`repeating_${section}_${id}_R_weapon_domain`] = weapon.domain || ''; + attr[`repeating_${section}_${id}_R_weapon_mishap_chance`] = weapon.mishap_chance || ''; + attr[`repeating_${section}_${id}_R_weapon_carry`] = weapon.carry || ''; + attr[`repeating_${section}_${id}_R_weapon_ability_r`] = weapon.special || ''; + attr[`repeating_${section}_${id}_R_weapon_ability_desc_r`] = weapon.description || ''; + return attr; + } + const mapMeleeWeapon = (weapon, vehicle) => { + if (!weapon) return ; + let attr = {}, + section = (vehicle) ? 'vehiclemeleeweapons' : 'meleeweapons', + id = generateRowID(); + if (vehicle) id += '_V'; + attr[`repeating_${section}_${id}_M_weapon_name`] = weapon.name || ''; + attr[`repeating_${section}_${id}_M_weapon_class`] = weapon.class || ''; + attr[`repeating_${section}_${id}_M_weapon_reach`] = weapon.reach || ''; + attr[`repeating_${section}_${id}_M_weapon_dam-roll`] = weapon.damage || ''; + attr[`repeating_${section}_${id}_M_weapon_pen`] = weapon.pen || ''; + attr[`repeating_${section}_${id}_M_weapon_type`] = weapon.type || ''; + attr[`repeating_${section}_${id}_M_weapon_max`] = weapon.max || ''; + attr[`repeating_${section}_${id}_M_weapon_min`] = weapon.min || ''; + attr[`repeating_${section}_${id}_M_weapon_vengeful`] = weapon.vengeful || ''; + attr[`repeating_${section}_${id}_M_weapon_trained`] = weapon.trained || ''; + attr[`repeating_${section}_${id}_M_weapon_mod1`] = weapon.mod1 || ''; + attr[`repeating_${section}_${id}_M_weapon_weight`] = weapon.weight || ''; + attr[`repeating_${section}_${id}_M_weapon_domain`] = weapon.domain || ''; + attr[`repeating_${section}_${id}_M_weapon_carry`] = weapon.carry || ''; + attr[`repeating_${section}_${id}_M_weapon_ability_r`] = weapon.special || ''; + attr[`repeating_${section}_${id}_M_weapon_ability_desc_r`] = weapon.description || ''; + return attr; + } + const mapGear = (gear) => { + if (!gear) return ; + let attr = {}, + section = 'gear', + id = generateRowID(); + attr[`repeating_${section}_${id}_gear_carry`] = gear.carry || ''; + attr[`repeating_${section}_${id}_gear_name_r`] = gear.name || ''; + attr[`repeating_${section}_${id}_gear_crafts_r`] = gear.craftsmanship || ''; + attr[`repeating_${section}_${id}_gear_quantity_r`] = gear.quantity || ''; + attr[`repeating_${section}_${id}_gear_avail_r`] = gear.availability || ''; + attr[`repeating_${section}_${id}_gear_weight_r`] = gear.weight || ''; + attr[`repeating_${section}_${id}_ability_desc_r`] = gear.description || ''; + return attr; + } + const mapCybernetic = (cybernetic) => { + if (!cybernetic) return ; + let attr = {}, + section = 'cybernetics', + id = generateRowID(); + attr[`repeating_${section}_${id}_cybernetic_name_r`] = cybernetic.name || ''; + attr[`repeating_${section}_${id}_cybernetic_location_r`] = cybernetic.location || ''; + attr[`repeating_${section}_${id}_cybernetic_desc_r`] = cybernetic.description || ''; + return attr; + } + const mapOldArmor = (armor) => { + let attr = {}; + attr.armor_AGI = armor.maxAgi || ''; + attr.armor_limit = armor.limit || ''; + attr.armor_head = armor.head || ''; + attr.armor_body = armor.body || ''; + attr.armor_arm_right = armor.arm_right || ''; + attr.armor_arm_left = armor.arm_left || ''; + attr.armor_leg_right = armor.leg_right || ''; + attr.armor_leg_left = armor.leg_left || ''; + attr.armor_name = armor.description || ''; + return attr; + } + const mapAdvance = (advance) => { + var attr = {}; + var section = 'advancements'; + for (var i = 0; i < advance?.length; i += 2) { + let id = generateRowID(); + attr[`repeating_${section}_${id}_advancement_nameL_r`] = advance[i]?.name || ''; + attr[`repeating_${section}_${id}_advancement_costL_r`] = advance[i]?.cost || ''; + attr[`repeating_${section}_${id}_advancement_nameR_r`] = advance[i+1]?.name || ''; + attr[`repeating_${section}_${id}_advancement_costR_r`] = advance[i+1]?.cost || ''; + } + return attr; + }; + const mapDisorder = (disorder) => { + if (!disorder) return; + let attr = {}, + section = 'disorders', + id = generateRowID(); + attr[`repeating_${section}_${id}_disorder_r`] = disorder.name || ''; + attr[`repeating_${section}_${id}_disorder_desc_r`] = disorder.description || ''; + return attr; + } + const mapMutation = (mutation) => { + if (!mutation) return; + let attr = {}, + section = 'mutations', + id = generateRowID(); + attr[`repeating_${section}_${id}_mutation_r`] = mutation.name || ''; + attr[`repeating_${section}_${id}_mutation_desc_r`] = mutation.description || ''; + return attr; + } + const mapObjective = (objective) => { + if (!objective) return; + let attr = {}, + section = 'objectives', + id = generateRowID(); + attr[`repeating_${section}_${id}_objective_r`] = objective.name || ''; + attr[`repeating_${section}_${id}_objective_completed`] = objective.complete || ''; + return attr; + } + const mapNote = (note) => { + if (!note) return; + let attr = {}, + section = 'notes', + id = generateRowID(); + attr[`repeating_${section}_${id}_notes`] = note.name || ''; + return attr; + } + const mapVehicle = (vehicle) => { + if (!vehicle) return; + let attr = {}, + section = 'vehicles', + id = generateRowID(); + attr[`repeating_${section}_${id}_vehicle-name`] = vehicle.name || ''; + attr[`repeating_${section}_${id}_vehicle-size`] = vehicle.size || ''; + attr[`repeating_${section}_${id}_vehicle-world`] = vehicle.world || ''; + attr[`repeating_${section}_${id}_vehicle-type`] = vehicle.type || ''; + attr[`repeating_${section}_${id}_vehicle-tactical`] = vehicle.tactical || ''; + attr[`repeating_${section}_${id}_vehicle-cruising`] = vehicle.cruising || ''; + attr[`repeating_${section}_${id}_vehicle-maneuver`] = vehicle.maneuver || ''; + attr[`repeating_${section}_${id}_vehicle-crew`] = vehicle.crew || ''; + attr[`repeating_${section}_${id}_vehicle-compliment`] = vehicle.compliment || ''; + attr[`repeating_${section}_${id}_vehicle-integrity`] = vehicle.integrity || ''; + attr[`repeating_${section}_${id}_vehicle-integrity_max`] = vehicle.integrity_max || ''; + attr[`repeating_${section}_${id}_vehicle-armor-front`] = vehicle['armor-front'] || ''; + attr[`repeating_${section}_${id}_vehicle-armor-side`] = vehicle['armor-side'] || ''; + attr[`repeating_${section}_${id}_vehicle-armor-rear`] = vehicle['armor-rear'] || ''; + attr[`repeating_${section}_${id}_armaments`] = vehicle.armaments || ''; + attr[`repeating_${section}_${id}_armaments_desc`] = vehicle.armaments_desc || ''; + attr[`repeating_${section}_${id}_vehicle_traits`] = vehicle.traits || ''; + attr[`repeating_${section}_${id}_vehicle_traits_desc`] = vehicle.traits_desc || ''; + attr[`repeating_${section}_${id}_modifications`] = vehicle.modifications || ''; + attr[`repeating_${section}_${id}_modifications_desc`] = vehicle.modifications_desc || ''; + return attr; + } + const mapPsykana = (psykana) => { + let attr = {}; + attr[`psykana_class`] = psykana.class || ''; + attr[`psykana_limit`] = psykana.limit || ''; + attr[`psy_rating`] = psykana.rating || ''; + attr[`psy_push`] = psykana.push || ''; + attr[`psykana_sustain`] = psykana.sustain || ''; + attr[`focus_mod`] = psykana.focus_mod || ''; + attr[`psykana_sustain_count`] = psykana.sustain_count || ''; + return attr; + }; + const mapPsyMinor = (minor) => { + if (!minor) return + let attr = {}, + section = 'minormanifestation', + id = generateRowID(); + attr[`repeating_${section}_${id}_P_minor_r`] = minor.name || ''; + attr[`repeating_${section}_${id}_P_minor_desc_r`] = minor.description || ''; + return attr; + } + const mapPsyNote = (note) => { + if (!note) return + let attr = {}, + section = 'psynotes', + id = generateRowID(); + attr[`repeating_${section}_${id}_P_note_r`] = note.name || ''; + attr[`repeating_${section}_${id}_P_note_desc_r`] = note.description || ''; + return attr; + } + const mapPsyPower = (power) => { + if (!power) return; + let attr = {}, + section = 'psychicabilities', + id = generateRowID(); + attr[`repeating_${section}_${id}_P_name`] = power.name || ''; + attr[`repeating_${section}_${id}_P_subtype`] = power.subtype || ''; + attr[`repeating_${section}_${id}_P_range`] = power.range || ''; + attr[`repeating_${section}_${id}_P_dam-roll`] = power.damage || ''; + attr[`repeating_${section}_${id}_P_type`] = power.type || ''; + attr[`repeating_${section}_${id}_P_pen`] = power.pen || ''; + attr[`repeating_${section}_${id}_P_focus`] = power.focus || ''; + attr[`repeating_${section}_${id}_P_mod1`] = power.mod || ''; + attr[`repeating_${section}_${id}_P_multi`] = power.multi || ''; + attr[`repeating_${section}_${id}_P_action`] = power.action || ''; + attr[`repeating_${section}_${id}_P_sustained`] = power.sustained || ''; + attr[`repeating_${section}_${id}_P_hitloc`] = power.hitloc || ''; + attr[`repeating_${section}_${id}_P_ability_r`] = power.ability || ''; + attr[`repeating_${section}_${id}_P_desc_r`] = power.desc || ''; + return attr; + } \ No newline at end of file