From c8489312c02ca74cfa35f14691b58f2f6b08856c Mon Sep 17 00:00:00 2001 From: Vasileios Pasialiokis <whiterocket@outlook.com> Date: Wed, 4 Apr 2018 01:06:43 +0300 Subject: [PATCH] RAO work --- src/js/rulesAssistantOptions.tw | 183 +++++++++++++++++++++++++++++--- src/js/utilJS.tw | 18 ++++ src/uncategorized/initRules.tw | 3 +- 3 files changed, 189 insertions(+), 15 deletions(-) diff --git a/src/js/rulesAssistantOptions.tw b/src/js/rulesAssistantOptions.tw index 963f2397d22..1e2dccea9cd 100644 --- a/src/js/rulesAssistantOptions.tw +++ b/src/js/rulesAssistantOptions.tw @@ -27,8 +27,13 @@ window.rulesAssistantOptions = (function() { const root = new Root(tmp) } + function onreturn(e, cb) { + if (e.keyCode === 13) cb() + } + + // create a new rule and reload function newRule(root) { - const id = V.defaultRules.length === 0? 1: V.defaultRules[V.defaultRules.length-1].ID + 1 + const id = generateNewID() v.defaultRules.push({ ID: id, name: `Rule ${id}`, @@ -143,9 +148,40 @@ window.rulesAssistantOptions = (function() { bellyImplantVol: -1, } }) + V.currentRule = V.defaultRules[V.defaultRules.length-1] + reload(root) + } + + function removeRule(root) { + const idx = V.defaultRules.findIndex(rule => rule.ID === V.currentRule.ID) + V.defaultRules.splice(idx, 1) + V.currentRule = idx < V.defaultRules.length ? idx : V.defaultRules.length - 1 reload(root) } + function lowerPriority(root) { + if (V.defaultRules.length === 1) return // nothing to swap with + const idx = V.defaultRules.findIndex(rule => rule.ID === V.currentRule.ID) + if (idx === 0) return // no lower rule + arraySwap(V.defaultRules, idx, idx-1) + reload(root) + } + + function higherPriority(root) { + if (V.defaultRules.length === 1) return // nothing to swap with + const idx = V.defaultRules.findIndex(rule => rule.ID === V.currentRule.ID) + if (idx === V.defaultRules.length - 1) return // no higher rule + arraySwap(V.defaultRules, idx, idx+1) + reload(root) + } + + function changeName(name, root) { + if (name === V.currentRule.name) return + V.currentRule = name + reload(root) + } + + // reload the passage function reload(root) { root.element.remove() rulesAssistantOptions() @@ -194,7 +230,7 @@ window.rulesAssistantOptions = (function() { value.classList.add("rajs-value") // call the variable binding when the input field is no longer being edited, and when the enter key is pressed value.onfocusout = () => { this.propagateChange() } - value.onkeypress = (e) => { if (e.keyCode === 13) this.propagateChange() } + value.onkeypress = (e) => { onreturn(e, () => { this.propagateChange() })} } else { value = document.createElement("strong") } @@ -228,15 +264,38 @@ window.rulesAssistantOptions = (function() { propagateChange() { if (this.onchange instanceof Function) - this.onchange(this.getValue()) + this.onchange(this.getValue(), this.selectedItem.data) } } + const parse = { + integer(string) { + let n = parseInt(string, 10) + return n === NaN? 0: n + }, + boobs(string) { + return Math.clamp(parse.integer(n), 0, 48000) + }, + butt(string) { + return Math.clamp(parse.integer(n), 0, 10) + }, + lips(string) { + return Math.clamp(parse.integer(n), 0, 100) + }, + dick(string) { + return Math.clamp(parse.integer(n), 0, 10) + }, + balls(string) { + return Math.clamp(parse.integer(n), 0, 10) + }, + } + // a clickable item of a list class ListItem extends Element { - constructor(displayvalue, setvalue) { + constructor(displayvalue, setvalue, data) { super(displayvalue) - this.setvalue = setvalue + this.setvalue = setvalue ? setvalue : displayvalue + this.data = this.setvalue ? this.setvalue : displayvalue this.selected = false } @@ -277,6 +336,7 @@ window.rulesAssistantOptions = (function() { } } + // similar to list, but is just a collection of buttons class Options extends Element { constructor(elements=[]) { elements.forEach(element => { this.appendChild(element) }) @@ -289,6 +349,7 @@ window.rulesAssistantOptions = (function() { } } + // options equivalent of ListItem class OptionsItem extends Element { constructor(label, onclick) { super(label) @@ -303,6 +364,7 @@ window.rulesAssistantOptions = (function() { } } + // rule import field class NewRuleField extends Element { constructor(root) { super() @@ -326,7 +388,7 @@ window.rulesAssistantOptions = (function() { const text = this.textarea.value try { const rule = JSON.parse(text) - rule.ID = V.defaultRules.length === 0? rule.ID: V.defaultRules[V.defaultRules.length-1].ID + 1 + if (!rule.ID) rule.ID = generateNewID() reload(this.root) } catch (e) { alert(e) @@ -334,22 +396,30 @@ window.rulesAssistantOptions = (function() { } } + // the base element, parent of all elements class Root extends Element { - render(element) { - const greeting = document.createElement("p") - greeting.innerHTML = `<em>${properTitle()}, I will review your slaves and make changes that will have a beneficial effect. Apologies, ${properTitle()}, but this function is... not fully complete. It may have some serious limitations. Please use the 'no default setting' option to identify areas I should not address.</em>` - element.appendChild(greeting) - + constructor() { + super() if(V.defaultRules.length === 0) { const paragraph = document.createElement("p") paragraph.innerHTML = "<strong>No rules</strong>" - element.appendChild(paragraph) - element.appendChild(new NoRules(root)) - return element + this.appendChild(new Element(paragraph)) + this.appendChild(new NoRules(this)) + return } + this.appendChild(new RuleSelector(this)) + this.appendChild(new RuleOptions(this)) + } + + render(element) { + const greeting = document.createElement("p") + greeting.innerHTML = `<em>${properTitle()}, I will review your slaves and make changes that will have a beneficial effect. Apologies, ${properTitle()}, but this function is... not fully complete. It may have some serious limitations. Please use the 'no default setting' option to identify areas I should not address.</em>` + element.appendChild(greeting) + return element } } + // optoins displayed when there are no rules class NoRules extends Options { constructor(root) { super() @@ -361,5 +431,90 @@ window.rulesAssistantOptions = (function() { } } + // buttons for selecting the current rule + class RuleSelector extends List { + constructor(root) { + super("Current rule:") + if (!V.currentRule) V.currentRule = V.defaultRules[0] + V.defaultRules.forEach(rule => { + const item = new ListItem(rule.name, rule.name, rule) + this.appendChild(item) + if (rule.ID === V.currentRule.ID) item.select() + }) + this.onchange = function (rulename, rule) { + V.currentRule = rule + reload(root) + } + } + } + + // buttons for doing transformations on rules + class RuleOptions extends Options { + constructor(root) { + super() + this.appendChild(new OptionsItem("New Rule", () => newRule(root))) + this.appendChild(new OptionsItem("Remove Rule", () => removeRule(root))) + this.appendChild(new OptionsItem("Apply rules", () => this.appendChild(new ApplicationLog()))) + this.appendChild(new OptionsItem("Lower Priotity", () => lowerPriority(root))) + this.appendChild(new OptionsItem("Higher Priority", () => higherPriority(root))) + this.appendChild(new OptionsItem("Rename", () => this.appendChild(new RenameField(root)))) + this.appendChild(new OptionsItem("Export this rule", () => this.appendChild(new ExportField()))) + this.appendChild(new OptionsItem("Export all rules", () => this.appendChild(new ExportField(true)))) + this.appendChild(new OptionsItem("Import a rule", () => this.appendChild(new NewRuleField()))) + } + } + + class ApplicationLog extends Element { + render() { + const elem = document.createElement("div") + elem.innerHTML = DefaultRules() + return elem + } + } + + class RenameField extends Element { + constructor(root) { + super() + this.element.onfocusout = () => changeName(this.element.value, root) + this.element.onkeypress = (e) => onreturn(e, () => changeName(this.element.value, root)) + } + + render() { + const elem = document.createElement("div") + elem.setAttribute("type", "text") + elem.setAttribute("value", V.currentRule.name) + } + } + + // parent section for condition editing + class ConditionEditor extends Element { + constructor() { + super() + this.appendChild(new ConditionFunction()) + this.appendChild(new AssignmentInclusion()) + this.appendChild(new AssignmentExclusion()) + this.appendChild(new FacilityInclusion()) + this.appendChild(new SpecialExclusion()) + this.appendChild(new SpecificInclusionExclusion()) + } + + render() { + const element = document.createElement("div") + return element + } + } + + // parent section for effect editing + class EffectEditor extends Element { + constructor() { + // TODO + } + + render() { + const element = document.createElement("div") + return element + } + } + return rulesAssistantOptions })() diff --git a/src/js/utilJS.tw b/src/js/utilJS.tw index 461526f826c..3c0fafa3e95 100644 --- a/src/js/utilJS.tw +++ b/src/js/utilJS.tw @@ -505,3 +505,21 @@ window.between = function between(a, low, high) { if (high === null) high = Infinity; return (a > low && a < high); }; + +// generate a random, almost unique ID +// if two are generated the same second every second, +// duplicates appear approximately once every 100 trillion years +// this is ~7000 times the age of the universe +window.generateNewID = function generateNewID() { + let randint = "" + for(let i = 0; i < 12; i++) + randint += jsEither("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + const timestamp = Date.now(); + return randint + timestamp.toString(36); +}; + +window.arraySwap(array, a, b) { + const tmp = array[a] + array[b] = array[a] + array[a] = tmp +} diff --git a/src/uncategorized/initRules.tw b/src/uncategorized/initRules.tw index 87d7caad95a..22326405055 100644 --- a/src/uncategorized/initRules.tw +++ b/src/uncategorized/initRules.tw @@ -114,7 +114,8 @@ surgery_holes: "not default setting", underArmHColor: "no default setting", underArmHStyle: "no default setting", - drug: "no default setting" + drug: "no default setting", + pregSpeed: "no default setting" } }>> <<set $defaultRules.push(_activeRule)>> -- GitLab