diff --git a/src/js/datatypeCleanupJS.js b/src/js/datatypeCleanupJS.js index 798b625e242d795b0d7071fb9c3a8529ed6ecdae..2e4f99dd086bf02a88e772622314ceb7d69bf1ca 100644 --- a/src/js/datatypeCleanupJS.js +++ b/src/js/datatypeCleanupJS.js @@ -1958,8 +1958,11 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() { /** @param {App.RA.Rule} rule */ function ruleCleanup(rule) { - cleanupConditions(rule.condition); - cleanupSetters(rule.set); + // ensure rule has all required propertirs + let newRule = App.RA.ruleDeepAssign(emptyDefaultRule(), rule) + cleanupConditions(newRule.condition); + cleanupSetters(newRule.set); + return newRule; } /** @param {App.RA.RuleConditions} cond */ @@ -1976,11 +1979,10 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() { /** @param {Object} o */ function replaceDefaultValues(o) { - for (const k in o) { - const v = o[k]; + for (const [k, v] of Object.entries(o)) { if (v === "no default setting" || v === "no default change" || Number.isNaN(v) || v === undefined) { o[k] = null; - } else if (typeof v === 'object') { + } else if (v !== null && typeof v === 'object') { replaceDefaultValues(v); } } @@ -2016,14 +2018,6 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() { settersSchemeCleanup(set); replaceDefaultValues(set); - function ensureProps(obj, props) { - props.forEach(prop => { - if (obj[prop] === undefined) { - obj[prop] = null; - } - }); - } - function transformValues(obj, props, cb) { props.forEach(p => { let v = obj[p]; @@ -2040,7 +2034,7 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() { case 'string': return App.RA.makeTarget('==', parseInt(val)); case 'object': - if (val.hasOwnProperty('val') && Number.isNaN(val.val)) { + if (val.hasOwnProperty('val') && (val.val === null || Number.isNaN(val.val))) { return null; } return val; @@ -2049,16 +2043,6 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() { } } - ensureProps(set, [ - 'haircuts', 'label', 'removeLabel', 'skinColor', 'markings', - 'earwear', 'toyHole', 'pornFeed', 'legAccessory', 'hyper_drugs' - ]); - - ensureProps(set.surgery, [ - 'hears', 'smells', 'tastes', - 'tummy', 'vasectomy' - ]); - if (!([true, false, null].includes(set.preg))) { set.preg = (set.preg === -1); } diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js index 77e6fdd53c089921faf0bb26dbc532fc9e8854c0..260edbf6bf01da0e5de5df84bc71cde51e181edd 100644 --- a/src/js/rulesAssistant.js +++ b/src/js/rulesAssistant.js @@ -66,41 +66,10 @@ window.mergeRules = function(rules) { return emptyDefaultRule().set; } - function isObject(o) { - return (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o)); - } - - function deepAssign(target, source) { - for (const key in source) { - if (!source.hasOwnProperty(key)) { - continue; - } - if (isObject(source[key])) { - if (!target.hasOwnProperty(key) || target[key] === null) { - target[key] = {}; - } - deepAssign(target[key], source[key]); - } else { - // A rule overrides any preceding ones if, - // * there are no preceding ones, - // * or it sets autoBrand, - // * or it does not set autoBrand and is not null - const overrides = ( - target[key] === undefined || target[key] === null || - (key === "autoBrand" && source[key]) || - (key !== "autoBrand" && source[key] !== null)); - if (overrides) { - target[key] = source[key]; - } - } - } - } - const combinedRule = emptyDefaultRule().set; - const otherRules = rules.slice(1); - otherRules.forEach(rule => { - deepAssign(combinedRule, rule); + rules.forEach(rule => { + App.RA.ruleDeepAssign(combinedRule, rule); }); return combinedRule; }; @@ -569,3 +538,34 @@ App.RA.shallShrink = function(current, target, step = 1) { ((current > target.val) && (target.cond === '<=' || target.cond === '<')) || (current === target.val && target.cond === '<')); }; + +App.RA.ruleDeepAssign = function deepAssign(target, source) { + function isObject(o) { + return (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o)); + } + + for (const key in source) { + if (!source.hasOwnProperty(key)) { + continue; + } + if (isObject(source[key])) { + if (!target.hasOwnProperty(key) || target[key] === null) { + target[key] = {}; + } + deepAssign(target[key], source[key]); + } else { + // A rule overrides any preceding ones if, + // * there are no preceding ones, + // * or it sets autoBrand, + // * or it does not set autoBrand and is not null + const overrides = ( + target[key] === undefined || target[key] === null || + (key === "autoBrand" && source[key]) || + (key !== "autoBrand" && source[key] !== null)); + if (overrides) { + target[key] = source[key]; + } + } + } + return target; +}; diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js index 59e3f09dfa27e72740b7882b23a4e8eb1e2f3539..d744e95b59cd4f37490755484e147e5713201de5 100644 --- a/src/js/rulesAssistantOptions.js +++ b/src/js/rulesAssistantOptions.js @@ -294,6 +294,9 @@ window.rulesAssistantOptions = (function() { constructor(prefix, data = [], allowNullValue = true, textinput = false) { super(prefix, data, allowNullValue, textinput); this.values = new Map(); + if (allowNullValue) { + this.values.set(null, "no default setting"); + } data.forEach(d => { if (Array.isArray(d) && d.length > 1) { this.values.set(d[1], d[0]); @@ -301,6 +304,7 @@ window.rulesAssistantOptions = (function() { this.values.set(d, d); } }); + this.selectedValue = null; } createEditor() { @@ -317,7 +321,12 @@ window.rulesAssistantOptions = (function() { return res; } + getData(what) { + return this.selectedValue; + } + setValue(what) { + this.selectedValue = what; if (this.values.has(what)) { super.setValue(this.values.get(what)); } else { @@ -541,12 +550,10 @@ window.rulesAssistantOptions = (function() { const rule = JSON.parse(text); if (rule instanceof Array) { rule.forEach(r => { - App.Entity.Utils.RARuleDatatypeCleanup(r); - V.defaultRules.push(r); + V.defaultRules.push(App.Entity.Utils.RARuleDatatypeCleanup(r)); }); } else { - App.Entity.Utils.RARuleDatatypeCleanup(rule); - V.defaultRules.push(rule); + V.defaultRules.push(App.Entity.Utils.RARuleDatatypeCleanup(rule)); } reload(this.root); } catch (e) { diff --git a/src/uncategorized/BackwardsCompatibility.tw b/src/uncategorized/BackwardsCompatibility.tw index 3dbdc9305c550e98db9868f29ceb0f6f72d6e620..dcd201d406a5943d02250561ebc8135511f2cd96 100644 --- a/src/uncategorized/BackwardsCompatibility.tw +++ b/src/uncategorized/BackwardsCompatibility.tw @@ -3600,9 +3600,7 @@ Updating gene pool records: Done<br> Updating Rules Assistant data... -<<for _rule range $defaultRules>> - <<run App.Entity.Utils.RARuleDatatypeCleanup(_rule)>> -<</for>> +<<set $defaultRules = $defaultRules.map(rule => App.Entity.Utils.RARuleDatatypeCleanup(rule))>> Done<br> /* Sec Exp */