diff --git a/belt.js b/belt.js index 2b79cde..ab14243 100644 --- a/belt.js +++ b/belt.js @@ -23,9 +23,9 @@ class Belt { } } -export function getBelts(data) { +function _getBeltsImpl(d) { let belts = new Map() - for (let belt of data.belts) { + for (let belt of d) { belts.set(belt.key_name, new Belt( belt.key_name, belt.name, @@ -34,3 +34,11 @@ export function getBelts(data) { } return belts } + +export function getBelts(data) { + return _getBeltsImpl(data.belts) +} + +export function getPipes(data) { + return _getBeltsImpl(data.pipes) +} diff --git a/calc.css b/calc.css index 602c774..a221a0d 100644 --- a/calc.css +++ b/calc.css @@ -117,10 +117,10 @@ div#miner_settings, div#alt_recipe_settings { input.prec { width: 4em; } -#belt_selector input[type="radio"] { +.belt-setting input[type="radio"] { display: none; } -#belt_selector input[type="radio"] + label { +.belt-setting input[type="radio"] + label { cursor: pointer; background: var(--light); border-radius: 4px; @@ -130,10 +130,10 @@ input.prec { margin: 2px; padding: 2px; } -#belt_selector input[type="radio"] + label:hover { +.belt-setting input[type="radio"] + label:hover { background: var(--bright); } -#belt_selector input[type="radio"]:checked + label { +.belt-setting input[type="radio"]:checked + label { background: var(--accent); } #recipe_toggles .toggle { diff --git a/calc.html b/calc.html index 9a06aa9..f72227c 100644 --- a/calc.html +++ b/calc.html @@ -146,7 +146,12 @@ Belt: - + + + + + Pipe: + diff --git a/data/data.json b/data/data.json index 4629bd3..d91576f 100644 --- a/data/data.json +++ b/data/data.json @@ -31,12 +31,25 @@ "rate": 1200 } ], + "pipes": [ + { + "name": "Pipeline Mk.1", + "key_name": "pipe1", + "rate": 300 + }, + { + "name": "Pipeline Mk.2", + "key_name": "pipe2", + "rate": 600 + } + ], "buildings": [ { "name": "Constructor", "key_name": "constructor", "category": "crafting1", "power": 4, + "somersloop_slots": 1, "max": 1 }, { @@ -44,6 +57,7 @@ "key_name": "assembler", "category": "crafting2", "power": 15, + "somersloop_slots": 2, "max": 2 }, { @@ -51,6 +65,7 @@ "key_name": "manufacturer", "category": "crafting3", "power": 55, + "somersloop_slots": 4, "max": 4 }, { @@ -58,6 +73,7 @@ "key_name": "smelter", "category": "smelting1", "power": 4, + "somersloop_slots": 1, "max": 1 }, { @@ -65,6 +81,7 @@ "key_name": "foundry", "category": "smelting2", "power": 16, + "somersloop_slots": 2, "max": 2 }, { @@ -72,6 +89,7 @@ "key_name": "oil-refinery", "category": "refining", "power": 30, + "somersloop_slots": 2, "max": 1 }, { @@ -79,6 +97,7 @@ "key_name": "packager", "category": "packaging", "power": 10, + "somersloop_slots": null, "max": 2 }, { @@ -86,6 +105,7 @@ "key_name": "blender", "category": "blending", "power": 75, + "somersloop_slots": 4, "max": 4 }, { @@ -93,6 +113,7 @@ "key_name": "accelerator", "category": "accelerating", "power": 0, + "somersloop_slots": 4, "max": 3 }, { @@ -100,6 +121,8 @@ "key_name": "converter", "category": "converting", "power": 0, + "power_range": [100, 400], + "somersloop_slots": 2, "max": 2 }, { @@ -107,6 +130,8 @@ "key_name": "quantum-encoder", "category": "encoding", "power": 0, + "power_range": [0, 2000], + "somersloop_slots": 4, "max": 4 }, { @@ -114,6 +139,7 @@ "key_name": "nuclear-power-plant", "category": "nuke-reacting", "power": 0, + "somersloop_slots": null, "max": 2 } ], @@ -3063,6 +3089,7 @@ "key_name": "plutonium-pellet", "category": "accelerating", "time": 60, + "power_range": [250, 750], "ingredients": [ ["non-fissile-uranium", 100], ["uranium-waste", 25] @@ -3089,6 +3116,7 @@ "key_name": "alt-plutonium-cell", "category": "accelerating", "time": 120, + "power_range": [250, 750], "ingredients": [ ["non-fissile-uranium", 150], ["aluminum-casing", 20] @@ -3874,6 +3902,7 @@ "key_name": "nuclear-pasta", "category": "accelerating", "time": 120, + "power_range": [500, 1500], "ingredients": [ ["copper-powder", 200], ["pressure-conversion-cube", 1] @@ -3978,6 +4007,7 @@ "key_name": "diamonds", "category": "accelerating", "time": 2, + "power_range": [250, 750], "ingredients": [ ["coal", 20] ], @@ -3990,6 +4020,7 @@ "key_name": "alt-diamonds-petroleum", "category": "accelerating", "time": 2, + "power_range": [250, 750], "ingredients": [ ["petroleum-coke", 24] ], @@ -4002,6 +4033,7 @@ "key_name": "alt-diamonds-turbo", "category": "accelerating", "time": 3, + "power_range": [250, 750], "ingredients": [ ["coal", 30], ["packaged-turbofuel", 2] @@ -4015,6 +4047,7 @@ "key_name": "alt-diamonds-oil", "category": "accelerating", "time": 3, + "power_range": [250, 750], "ingredients": [ ["crude-oil", 10] ], @@ -4027,6 +4060,7 @@ "key_name": "alt-diamonds-cloudy", "category": "accelerating", "time": 3, + "power_range": [250, 750], "ingredients": [ ["coal", 12], ["limestone", 24] @@ -4038,7 +4072,7 @@ { "name": "Alternate: Pink Diamonds", "key_name": "alt-diamonds-pink", - "category": "accelerating", + "category": "converting", "time": 4, "ingredients": [ ["coal", 8], @@ -4139,6 +4173,7 @@ "key_name": "dark-matter-crystal", "category": "accelerating", "time": 2, + "power_range": [500, 1500], "ingredients": [ ["diamonds", 1], ["dark-matter-residue", 5] @@ -4152,6 +4187,7 @@ "key_name": "alt-dark-matter-crystal", "category": "accelerating", "time": 3, + "power_range": [500, 1500], "ingredients": [ ["dark-matter-residue", 10] ], @@ -4164,6 +4200,7 @@ "key_name": "alt-dark-matter-trap", "category": "accelerating", "time": 2, + "power_range": [500, 1500], "ingredients": [ ["time-crystal", 1], ["dark-matter-residue", 5] @@ -4177,6 +4214,7 @@ "key_name": "ficsonium", "category": "accelerating", "time": 6, + "power_range": [500, 1500], "ingredients": [ ["plutonium-waste", 1], ["singularity-cell", 1], diff --git a/display.js b/display.js index b65c31d..ca35c8b 100644 --- a/display.js +++ b/display.js @@ -290,11 +290,18 @@ export function displayItems(spec, totals) { }) itemRow.selectAll("tt.surplus-rate") .text(d => spec.format.alignRate(totals.surplus.has(d.item) ? totals.surplus.get(d.item) : zero)) - itemRow.selectAll("img.belt-icon") + let beltRow = itemRow.filter(d => d.item.phase === "solid") + beltRow.selectAll("img.belt-icon") .attr("src", spec.belt.icon.path()) .attr("title", spec.belt.name) - itemRow.selectAll("tt.belt-count") + beltRow.selectAll("tt.belt-count") .text(d => spec.format.alignCount(spec.getBeltCount(totals.items.get(d.item)))) + let pipeRow = itemRow.filter(d => d.item.phase === "fluid") + pipeRow.selectAll("img.belt-icon") + .attr("src", spec.pipe.icon.path()) + .attr("title", spec.pipe.name) + pipeRow.selectAll("tt.belt-count") + .text(d => spec.format.alignCount(spec.getPipeCount(totals.items.get(d.item)))) let buildingRow = row.filter(d => d.building !== null) let buildingCell = buildingRow.selectAll("td.building-icon") buildingCell.selectAll("*").remove() diff --git a/factory.js b/factory.js index ff61a64..3ab42ac 100644 --- a/factory.js +++ b/factory.js @@ -35,6 +35,7 @@ export let resourcePurities = [ export let DEFAULT_PURITY = resourcePurities[1] export let DEFAULT_BELT = "belt1" +export let DEFAULT_PIPE = "pipe1" const OVERCLOCK_POWER_EXPONENT = Math.log2(2.5) @@ -45,6 +46,7 @@ class FactorySpecification { this.recipes = null this.buildings = null this.belts = null + this.pipes = null this.itemTiers = [] @@ -73,7 +75,7 @@ class FactorySpecification { this.lastMetadata = null this.lastSolution = null } - setData(items, recipes, buildings, belts) { + setData(items, recipes, buildings, belts, pipes) { this.items = items let tierMap = new Map() this.defaultDisable = new Set() @@ -139,6 +141,8 @@ class FactorySpecification { } this.belts = belts this.belt = belts.get(DEFAULT_BELT) + this.pipes = pipes + this.pipe = belts.get(DEFAULT_PIPE) this.initMinerSettings() this.defaultPriority = this.getDefaultPriorityArray() this.priority = null @@ -391,6 +395,9 @@ class FactorySpecification { getBeltCount(rate) { return rate.div(this.belt.rate) } + getPipeCount(rate) { + return rate.div(this.pipe.rate) + } getPowerUsage(recipe, rate) { let building = this.getBuilding(recipe) if (building === null) { diff --git a/fragment.js b/fragment.js index efb97d4..34c3032 100644 --- a/fragment.js +++ b/fragment.js @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License.*/ import { DEFAULT_RATE, DEFAULT_RATE_PRECISION, DEFAULT_COUNT_PRECISION } from "./align.js" import { DEFAULT_TAB, currentTab, DEFAULT_VISUALIZER, visualizerType, DEFAULT_RENDER, visualizerRender } from "./events.js" -import { spec, DEFAULT_PURITY, DEFAULT_BELT } from "./factory.js" +import { spec, DEFAULT_PURITY, DEFAULT_BELT, DEFAULT_PIPE } from "./factory.js" import { Rational } from "./rational.js" export function formatSettings() { @@ -33,6 +33,9 @@ export function formatSettings() { if (spec.belt.key !== DEFAULT_BELT) { settings += "belt=" + spec.belt.key + "&" } + if (spec.pipe.key !== DEFAULT_PIPE) { + settings += "pipe=" + spec.pipe.key + "&" + } if (visualizerType !== DEFAULT_VISUALIZER) { settings += "vt=" + visualizerType + "&" } diff --git a/init.js b/init.js index c98e831..48b840d 100644 --- a/init.js +++ b/init.js @@ -11,7 +11,7 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/ -import { getBelts } from "./belt.js" +import { getBelts, getPipes } from "./belt.js" import { getBuildings } from "./building.js" import { spec } from "./factory.js" import { loadSettings } from "./fragment.js" @@ -25,7 +25,8 @@ function loadData(settings) { let recipes = getRecipes(data, items) let buildings = getBuildings(data) let belts = getBelts(data) - spec.setData(items, recipes, buildings, belts) + let pipes = getPipes(data) + spec.setData(items, recipes, buildings, belts, pipes) renderSettings(settings) diff --git a/settings.js b/settings.js index aeef365..2043b7a 100644 --- a/settings.js +++ b/settings.js @@ -14,7 +14,7 @@ limitations under the License.*/ import { DEFAULT_RATE, DEFAULT_RATE_PRECISION, DEFAULT_COUNT_PRECISION, longRateNames } from "./align.js" import { dropdown } from "./dropdown.js" import { DEFAULT_TAB, clickTab, DEFAULT_VISUALIZER, visualizerType, setVisualizerType, DEFAULT_RENDER, visualizerRender, setVisualizerRender } from "./events.js" -import { spec, resourcePurities, DEFAULT_BELT } from "./factory.js" +import { spec, resourcePurities, DEFAULT_BELT, DEFAULT_PIPE } from "./factory.js" import { getRecipeGroups } from "./groups.js" import { Rational } from "./rational.js" @@ -153,6 +153,11 @@ function beltHandler(event, belt) { spec.updateSolution() } +function pipeHandler(event, pipe) { + spec.pipe = pipe + spec.updateSolution() +} + function renderBelts(settings) { let beltKey = DEFAULT_BELT if (settings.has("belt")) { @@ -160,6 +165,12 @@ function renderBelts(settings) { } spec.belt = spec.belts.get(beltKey) + let pipeKey = DEFAULT_PIPE + if (settings.has("pipe")) { + pipeKey = settings.get("pipe") + } + spec.pipe = spec.pipes.get(pipeKey) + let belts = [] for (let [beltKey, belt] of spec.belts) { belts.push(belt) @@ -179,6 +190,26 @@ function renderBelts(settings) { beltOption.append("label") .attr("for", d => "belt." + d.key) .append(d => d.icon.make(32)) + + let pipes = [] + for (let [pipeKey, pipe] of spec.pipes) { + pipes.push(pipe) + } + form = d3.select("#pipe_selector") + form.selectAll("*").remove() + let pipeOption = form.selectAll("span") + .data(pipes) + .join("span") + pipeOption.append("input") + .attr("id", d => "pipe." + d.key) + .attr("type", "radio") + .attr("name", "pipe") + .attr("value", d => d.key) + .attr("checked", d => d === spec.pipe ? "" : null) + .on("change", pipeHandler) + pipeOption.append("label") + .attr("for", d => "pipe." + d.key) + .append(d => d.icon.make(32)) } // visualizer